diff --git a/Src/Newtonsoft.Json.Portable40.sln b/Src/Newtonsoft.Json.Portable40.sln index 8b361b36..2bf5057a 100644 --- a/Src/Newtonsoft.Json.Portable40.sln +++ b/Src/Newtonsoft.Json.Portable40.sln @@ -1,6 +1,8 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2012 +# Visual Studio 2013 +VisualStudioVersion = 12.0.21005.1 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Lib", "Lib", "{620042D9-2753-48F5-BEDE-3905248781D2}" ProjectSection(SolutionItems) = preProject Lib\NUnit\DotNet\nunit.framework.dll = Lib\NUnit\DotNet\nunit.framework.dll diff --git a/Src/Newtonsoft.Json.Tests/Bson/BsonReaderTests.cs b/Src/Newtonsoft.Json.Tests/Bson/BsonReaderTests.cs index a07fdbf6..e30b0467 100644 --- a/Src/Newtonsoft.Json.Tests/Bson/BsonReaderTests.cs +++ b/Src/Newtonsoft.Json.Tests/Bson/BsonReaderTests.cs @@ -46,364 +46,318 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Bson { - [TestFixture] - public class BsonReaderTests : TestFixtureBase - { - private const char Euro = '\u20ac'; - - [Test] - public void CloseInput() + [TestFixture] + public class BsonReaderTests : TestFixtureBase { - MemoryStream ms = new MemoryStream(); - BsonReader reader = new BsonReader(ms); + private const char Euro = '\u20ac'; - Assert.IsTrue(ms.CanRead); - reader.Close(); - Assert.IsFalse(ms.CanRead); + [Test] + public void CloseInput() + { + MemoryStream ms = new MemoryStream(); + BsonReader reader = new BsonReader(ms); - ms = new MemoryStream(); - reader = new BsonReader(ms) { CloseInput = false }; + Assert.IsTrue(ms.CanRead); + reader.Close(); + Assert.IsFalse(ms.CanRead); - Assert.IsTrue(ms.CanRead); - reader.Close(); - Assert.IsTrue(ms.CanRead); - } + ms = new MemoryStream(); + reader = new BsonReader(ms) { CloseInput = false }; - [Test] - public void ReadSingleObject() - { - byte[] data = HexToBytes("0F-00-00-00-10-42-6C-61-68-00-01-00-00-00-00"); - MemoryStream ms = new MemoryStream(data); - BsonReader reader = new BsonReader(ms); + Assert.IsTrue(ms.CanRead); + reader.Close(); + Assert.IsTrue(ms.CanRead); + } - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + [Test] + public void ReadSingleObject() + { + byte[] data = HexToBytes("0F-00-00-00-10-42-6C-61-68-00-01-00-00-00-00"); + MemoryStream ms = new MemoryStream(data); + BsonReader reader = new BsonReader(ms); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("Blah", reader.Value); - Assert.AreEqual(typeof(string), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.AreEqual(1L, reader.Value); - Assert.AreEqual(typeof(long), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("Blah", reader.Value); + Assert.AreEqual(typeof(string), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); + Assert.AreEqual(1L, reader.Value); + Assert.AreEqual(typeof(long), reader.ValueType); - Assert.IsFalse(reader.Read()); - Assert.AreEqual(JsonToken.None, reader.TokenType); - } + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - [Test] - public void ReadGuid_Text() - { - byte[] data = HexToBytes("31-00-00-00-02-30-00-25-00-00-00-64-38-32-31-65-65-64-37-2D-34-62-35-63-2D-34-33-63-39-2D-38-61-63-32-2D-36-39-32-38-65-35-37-39-62-37-30-35-00-00"); + Assert.IsFalse(reader.Read()); + Assert.AreEqual(JsonToken.None, reader.TokenType); + } - MemoryStream ms = new MemoryStream(data); - BsonReader reader = new BsonReader(ms); - reader.ReadRootValueAsArray = true; + [Test] + public void ReadGuid_Text() + { + byte[] data = HexToBytes("31-00-00-00-02-30-00-25-00-00-00-64-38-32-31-65-65-64-37-2D-34-62-35-63-2D-34-33-63-39-2D-38-61-63-32-2D-36-39-32-38-65-35-37-39-62-37-30-35-00-00"); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + MemoryStream ms = new MemoryStream(data); + BsonReader reader = new BsonReader(ms); + reader.ReadRootValueAsArray = true; - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("d821eed7-4b5c-43c9-8ac2-6928e579b705", reader.Value); - Assert.AreEqual(typeof(string), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("d821eed7-4b5c-43c9-8ac2-6928e579b705", reader.Value); + Assert.AreEqual(typeof(string), reader.ValueType); - Assert.IsFalse(reader.Read()); - Assert.AreEqual(JsonToken.None, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - ms = new MemoryStream(data); - reader = new BsonReader(ms); - reader.ReadRootValueAsArray = true; + Assert.IsFalse(reader.Read()); + Assert.AreEqual(JsonToken.None, reader.TokenType); - JsonSerializer serializer = new JsonSerializer(); - IList l = serializer.Deserialize>(reader); + ms = new MemoryStream(data); + reader = new BsonReader(ms); + reader.ReadRootValueAsArray = true; - Assert.AreEqual(1, l.Count); - Assert.AreEqual(new Guid("D821EED7-4B5C-43C9-8AC2-6928E579B705"), l[0]); - } + JsonSerializer serializer = new JsonSerializer(); + IList l = serializer.Deserialize>(reader); - [Test] - public void ReadGuid_Bytes() - { - byte[] data = HexToBytes("1D-00-00-00-05-30-00-10-00-00-00-04-D7-EE-21-D8-5C-4B-C9-43-8A-C2-69-28-E5-79-B7-05-00"); + Assert.AreEqual(1, l.Count); + Assert.AreEqual(new Guid("D821EED7-4B5C-43C9-8AC2-6928E579B705"), l[0]); + } - MemoryStream ms = new MemoryStream(data); - BsonReader reader = new BsonReader(ms); - reader.ReadRootValueAsArray = true; + [Test] + public void ReadGuid_Bytes() + { + byte[] data = HexToBytes("1D-00-00-00-05-30-00-10-00-00-00-04-D7-EE-21-D8-5C-4B-C9-43-8A-C2-69-28-E5-79-B7-05-00"); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + MemoryStream ms = new MemoryStream(data); + BsonReader reader = new BsonReader(ms); + reader.ReadRootValueAsArray = true; - Guid g = new Guid("D821EED7-4B5C-43C9-8AC2-6928E579B705"); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Bytes, reader.TokenType); - CollectionAssert.AreEqual(g.ToByteArray(), (byte[])reader.Value); - Assert.AreEqual(typeof(byte[]), reader.ValueType); + Guid g = new Guid("D821EED7-4B5C-43C9-8AC2-6928E579B705"); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Bytes, reader.TokenType); + CollectionAssert.AreEqual(g.ToByteArray(), (byte[])reader.Value); + Assert.AreEqual(typeof(byte[]), reader.ValueType); - Assert.IsFalse(reader.Read()); - Assert.AreEqual(JsonToken.None, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - ms = new MemoryStream(data); - reader = new BsonReader(ms); - reader.ReadRootValueAsArray = true; + Assert.IsFalse(reader.Read()); + Assert.AreEqual(JsonToken.None, reader.TokenType); - JsonSerializer serializer = new JsonSerializer(); - IList l = serializer.Deserialize>(reader); + ms = new MemoryStream(data); + reader = new BsonReader(ms); + reader.ReadRootValueAsArray = true; - Assert.AreEqual(1, l.Count); - Assert.AreEqual(g, l[0]); - } + JsonSerializer serializer = new JsonSerializer(); + IList l = serializer.Deserialize>(reader); - [Test] - public void ReadDouble() - { - byte[] data = HexToBytes("10-00-00-00-01-30-00-8F-C2-F5-28-5C-FF-58-40-00"); + Assert.AreEqual(1, l.Count); + Assert.AreEqual(g, l[0]); + } - MemoryStream ms = new MemoryStream(data); - BsonReader reader = new BsonReader(ms); - reader.ReadRootValueAsArray = true; + [Test] + public void ReadDouble() + { + byte[] data = HexToBytes("10-00-00-00-01-30-00-8F-C2-F5-28-5C-FF-58-40-00"); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + MemoryStream ms = new MemoryStream(data); + BsonReader reader = new BsonReader(ms); + reader.ReadRootValueAsArray = true; - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual(99.99d, reader.Value); - Assert.AreEqual(typeof(double), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual(99.99d, reader.Value); + Assert.AreEqual(typeof(double), reader.ValueType); - Assert.IsFalse(reader.Read()); - Assert.AreEqual(JsonToken.None, reader.TokenType); - } + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - [Test] - public void ReadDouble_Decimal() - { - byte[] data = HexToBytes("10-00-00-00-01-30-00-8F-C2-F5-28-5C-FF-58-40-00"); + Assert.IsFalse(reader.Read()); + Assert.AreEqual(JsonToken.None, reader.TokenType); + } - MemoryStream ms = new MemoryStream(data); - BsonReader reader = new BsonReader(ms); - reader.FloatParseHandling = FloatParseHandling.Decimal; - reader.ReadRootValueAsArray = true; + [Test] + public void ReadDouble_Decimal() + { + byte[] data = HexToBytes("10-00-00-00-01-30-00-8F-C2-F5-28-5C-FF-58-40-00"); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + MemoryStream ms = new MemoryStream(data); + BsonReader reader = new BsonReader(ms); + reader.FloatParseHandling = FloatParseHandling.Decimal; + reader.ReadRootValueAsArray = true; - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual(99.99m, reader.Value); - Assert.AreEqual(typeof(decimal), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual(99.99m, reader.Value); + Assert.AreEqual(typeof(decimal), reader.ValueType); - Assert.IsFalse(reader.Read()); - Assert.AreEqual(JsonToken.None, reader.TokenType); - } + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - [Test] - public void ReadValues() - { - byte[] data = HexToBytes("8C-00-00-00-12-30-00-FF-FF-FF-FF-FF-FF-FF-7F-12-31-00-FF-FF-FF-FF-FF-FF-FF-7F-10-32-00-FF-FF-FF-7F-10-33-00-FF-FF-FF-7F-10-34-00-FF-00-00-00-10-35-00-7F-00-00-00-02-36-00-02-00-00-00-61-00-01-37-00-00-00-00-00-00-00-F0-45-01-38-00-FF-FF-FF-FF-FF-FF-EF-7F-01-39-00-00-00-00-E0-FF-FF-EF-47-08-31-30-00-01-05-31-31-00-05-00-00-00-02-00-01-02-03-04-09-31-32-00-40-C5-E2-BA-E3-00-00-00-09-31-33-00-40-C5-E2-BA-E3-00-00-00-00"); - MemoryStream ms = new MemoryStream(data); - BsonReader reader = new BsonReader(ms); + Assert.IsFalse(reader.Read()); + Assert.AreEqual(JsonToken.None, reader.TokenType); + } + + [Test] + public void ReadValues() + { + byte[] data = HexToBytes("8C-00-00-00-12-30-00-FF-FF-FF-FF-FF-FF-FF-7F-12-31-00-FF-FF-FF-FF-FF-FF-FF-7F-10-32-00-FF-FF-FF-7F-10-33-00-FF-FF-FF-7F-10-34-00-FF-00-00-00-10-35-00-7F-00-00-00-02-36-00-02-00-00-00-61-00-01-37-00-00-00-00-00-00-00-F0-45-01-38-00-FF-FF-FF-FF-FF-FF-EF-7F-01-39-00-00-00-00-E0-FF-FF-EF-47-08-31-30-00-01-05-31-31-00-05-00-00-00-02-00-01-02-03-04-09-31-32-00-40-C5-E2-BA-E3-00-00-00-09-31-33-00-40-C5-E2-BA-E3-00-00-00-00"); + MemoryStream ms = new MemoryStream(data); + BsonReader reader = new BsonReader(ms); #pragma warning disable 612,618 - reader.JsonNet35BinaryCompatibility = true; + reader.JsonNet35BinaryCompatibility = true; #pragma warning restore 612,618 - reader.ReadRootValueAsArray = true; - reader.DateTimeKindHandling = DateTimeKind.Utc; + reader.ReadRootValueAsArray = true; + reader.DateTimeKindHandling = DateTimeKind.Utc; - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.AreEqual(long.MaxValue, reader.Value); - Assert.AreEqual(typeof(long), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); + Assert.AreEqual(long.MaxValue, reader.Value); + Assert.AreEqual(typeof(long), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.AreEqual(long.MaxValue, reader.Value); - Assert.AreEqual(typeof(long), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); + Assert.AreEqual(long.MaxValue, reader.Value); + Assert.AreEqual(typeof(long), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.AreEqual((long)int.MaxValue, reader.Value); - Assert.AreEqual(typeof(long), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); + Assert.AreEqual((long)int.MaxValue, reader.Value); + Assert.AreEqual(typeof(long), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.AreEqual((long)int.MaxValue, reader.Value); - Assert.AreEqual(typeof(long), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); + Assert.AreEqual((long)int.MaxValue, reader.Value); + Assert.AreEqual(typeof(long), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.AreEqual((long)byte.MaxValue, reader.Value); - Assert.AreEqual(typeof(long), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); + Assert.AreEqual((long)byte.MaxValue, reader.Value); + Assert.AreEqual(typeof(long), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.AreEqual((long)sbyte.MaxValue, reader.Value); - Assert.AreEqual(typeof(long), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); + Assert.AreEqual((long)sbyte.MaxValue, reader.Value); + Assert.AreEqual(typeof(long), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("a", reader.Value); - Assert.AreEqual(typeof(string), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("a", reader.Value); + Assert.AreEqual(typeof(string), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual((double)decimal.MaxValue, reader.Value); - Assert.AreEqual(typeof(double), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual((double)decimal.MaxValue, reader.Value); + Assert.AreEqual(typeof(double), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual((double)double.MaxValue, reader.Value); - Assert.AreEqual(typeof(double), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual((double)double.MaxValue, reader.Value); + Assert.AreEqual(typeof(double), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual((double)float.MaxValue, reader.Value); - Assert.AreEqual(typeof(double), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual((double)float.MaxValue, reader.Value); + Assert.AreEqual(typeof(double), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Boolean, reader.TokenType); - Assert.AreEqual(true, reader.Value); - Assert.AreEqual(typeof(bool), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Boolean, reader.TokenType); + Assert.AreEqual(true, reader.Value); + Assert.AreEqual(typeof(bool), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Bytes, reader.TokenType); - CollectionAssert.AreEquivalent(new byte[] { 0, 1, 2, 3, 4 }, (byte[])reader.Value); - Assert.AreEqual(typeof(byte[]), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Bytes, reader.TokenType); + CollectionAssert.AreEquivalent(new byte[] { 0, 1, 2, 3, 4 }, (byte[])reader.Value); + Assert.AreEqual(typeof(byte[]), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Date, reader.TokenType); - Assert.AreEqual(new DateTime(2000, 12, 29, 12, 30, 0, DateTimeKind.Utc), reader.Value); - Assert.AreEqual(typeof(DateTime), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Date, reader.TokenType); + Assert.AreEqual(new DateTime(2000, 12, 29, 12, 30, 0, DateTimeKind.Utc), reader.Value); + Assert.AreEqual(typeof(DateTime), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Date, reader.TokenType); - Assert.AreEqual(new DateTime(2000, 12, 29, 12, 30, 0, DateTimeKind.Utc), reader.Value); - Assert.AreEqual(typeof(DateTime), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Date, reader.TokenType); + Assert.AreEqual(new DateTime(2000, 12, 29, 12, 30, 0, DateTimeKind.Utc), reader.Value); + Assert.AreEqual(typeof(DateTime), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - Assert.IsFalse(reader.Read()); - Assert.AreEqual(JsonToken.None, reader.TokenType); - } + Assert.IsFalse(reader.Read()); + Assert.AreEqual(JsonToken.None, reader.TokenType); + } - [Test] - public void ReadObjectBsonFromSite() - { - byte[] data = HexToBytes("20-00-00-00-02-30-00-02-00-00-00-61-00-02-31-00-02-00-00-00-62-00-02-32-00-02-00-00-00-63-00-00"); + [Test] + public void ReadObjectBsonFromSite() + { + byte[] data = HexToBytes("20-00-00-00-02-30-00-02-00-00-00-61-00-02-31-00-02-00-00-00-62-00-02-32-00-02-00-00-00-63-00-00"); - MemoryStream ms = new MemoryStream(data); - BsonReader reader = new BsonReader(ms); + MemoryStream ms = new MemoryStream(data); + BsonReader reader = new BsonReader(ms); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("0", reader.Value); - Assert.AreEqual(typeof(string), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("0", reader.Value); + Assert.AreEqual(typeof(string), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("a", reader.Value); - Assert.AreEqual(typeof(string), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("a", reader.Value); + Assert.AreEqual(typeof(string), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("1", reader.Value); - Assert.AreEqual(typeof(string), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("1", reader.Value); + Assert.AreEqual(typeof(string), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("b", reader.Value); - Assert.AreEqual(typeof(string), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("b", reader.Value); + Assert.AreEqual(typeof(string), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("2", reader.Value); - Assert.AreEqual(typeof(string), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("2", reader.Value); + Assert.AreEqual(typeof(string), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("c", reader.Value); - Assert.AreEqual(typeof(string), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("c", reader.Value); + Assert.AreEqual(typeof(string), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - Assert.IsFalse(reader.Read()); - Assert.AreEqual(JsonToken.None, reader.TokenType); - } + Assert.IsFalse(reader.Read()); + Assert.AreEqual(JsonToken.None, reader.TokenType); + } - [Test] - public void ReadArrayBsonFromSite() - { - byte[] data = HexToBytes("20-00-00-00-02-30-00-02-00-00-00-61-00-02-31-00-02-00-00-00-62-00-02-32-00-02-00-00-00-63-00-00"); - - MemoryStream ms = new MemoryStream(data); - BsonReader reader = new BsonReader(ms); - - Assert.AreEqual(false, reader.ReadRootValueAsArray); - Assert.AreEqual(DateTimeKind.Local, reader.DateTimeKindHandling); - - reader.ReadRootValueAsArray = true; - reader.DateTimeKindHandling = DateTimeKind.Utc; - - Assert.AreEqual(true, reader.ReadRootValueAsArray); - Assert.AreEqual(DateTimeKind.Utc, reader.DateTimeKindHandling); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("a", reader.Value); - Assert.AreEqual(typeof(string), reader.ValueType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("b", reader.Value); - Assert.AreEqual(typeof(string), reader.ValueType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("c", reader.Value); - Assert.AreEqual(typeof(string), reader.ValueType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - - Assert.IsFalse(reader.Read()); - Assert.AreEqual(JsonToken.None, reader.TokenType); - } - - [Test] - public void ReadAsInt32BadString() - { - ExceptionAssert.Throws( - "Could not convert string to integer: a. Path '[0]'.", - () => - { + [Test] + public void ReadArrayBsonFromSite() + { byte[] data = HexToBytes("20-00-00-00-02-30-00-02-00-00-00-61-00-02-31-00-02-00-00-00-62-00-02-32-00-02-00-00-00-63-00-00"); MemoryStream ms = new MemoryStream(data); @@ -421,1093 +375,1139 @@ namespace Newtonsoft.Json.Tests.Bson Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - reader.ReadAsInt32(); - }); - } + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("a", reader.Value); + Assert.AreEqual(typeof(string), reader.ValueType); - [Test] - public void ReadBytes() - { - byte[] data = HexToBytes("2B-00-00-00-02-30-00-02-00-00-00-61-00-02-31-00-02-00-00-00-62-00-05-32-00-0C-00-00-00-02-48-65-6C-6C-6F-20-77-6F-72-6C-64-21-00"); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("b", reader.Value); + Assert.AreEqual(typeof(string), reader.ValueType); - MemoryStream ms = new MemoryStream(data); - BsonReader reader = new BsonReader(ms, true, DateTimeKind.Utc); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("c", reader.Value); + Assert.AreEqual(typeof(string), reader.ValueType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + + Assert.IsFalse(reader.Read()); + Assert.AreEqual(JsonToken.None, reader.TokenType); + } + + [Test] + public void ReadAsInt32BadString() + { + ExceptionAssert.Throws( + "Could not convert string to integer: a. Path '[0]'.", + () => + { + byte[] data = HexToBytes("20-00-00-00-02-30-00-02-00-00-00-61-00-02-31-00-02-00-00-00-62-00-02-32-00-02-00-00-00-63-00-00"); + + MemoryStream ms = new MemoryStream(data); + BsonReader reader = new BsonReader(ms); + + Assert.AreEqual(false, reader.ReadRootValueAsArray); + Assert.AreEqual(DateTimeKind.Local, reader.DateTimeKindHandling); + + reader.ReadRootValueAsArray = true; + reader.DateTimeKindHandling = DateTimeKind.Utc; + + Assert.AreEqual(true, reader.ReadRootValueAsArray); + Assert.AreEqual(DateTimeKind.Utc, reader.DateTimeKindHandling); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + + reader.ReadAsInt32(); + }); + } + + [Test] + public void ReadBytes() + { + byte[] data = HexToBytes("2B-00-00-00-02-30-00-02-00-00-00-61-00-02-31-00-02-00-00-00-62-00-05-32-00-0C-00-00-00-02-48-65-6C-6C-6F-20-77-6F-72-6C-64-21-00"); + + MemoryStream ms = new MemoryStream(data); + BsonReader reader = new BsonReader(ms, true, DateTimeKind.Utc); #pragma warning disable 612,618 - reader.JsonNet35BinaryCompatibility = true; + reader.JsonNet35BinaryCompatibility = true; #pragma warning restore 612,618 - Assert.AreEqual(true, reader.ReadRootValueAsArray); - Assert.AreEqual(DateTimeKind.Utc, reader.DateTimeKindHandling); + Assert.AreEqual(true, reader.ReadRootValueAsArray); + Assert.AreEqual(DateTimeKind.Utc, reader.DateTimeKindHandling); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("a", reader.Value); - Assert.AreEqual(typeof(string), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("a", reader.Value); + Assert.AreEqual(typeof(string), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("b", reader.Value); - Assert.AreEqual(typeof(string), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("b", reader.Value); + Assert.AreEqual(typeof(string), reader.ValueType); - byte[] encodedStringData = reader.ReadAsBytes(); - Assert.IsNotNull(encodedStringData); - Assert.AreEqual(JsonToken.Bytes, reader.TokenType); - Assert.AreEqual(encodedStringData, reader.Value); - Assert.AreEqual(typeof(byte[]), reader.ValueType); + byte[] encodedStringData = reader.ReadAsBytes(); + Assert.IsNotNull(encodedStringData); + Assert.AreEqual(JsonToken.Bytes, reader.TokenType); + Assert.AreEqual(encodedStringData, reader.Value); + Assert.AreEqual(typeof(byte[]), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - Assert.IsFalse(reader.Read()); - Assert.AreEqual(JsonToken.None, reader.TokenType); + Assert.IsFalse(reader.Read()); + Assert.AreEqual(JsonToken.None, reader.TokenType); - string decodedString = Encoding.UTF8.GetString(encodedStringData, 0, encodedStringData.Length); - Assert.AreEqual("Hello world!", decodedString); - } + string decodedString = Encoding.UTF8.GetString(encodedStringData, 0, encodedStringData.Length); + Assert.AreEqual("Hello world!", decodedString); + } - [Test] - public void ReadOid() - { - byte[] data = HexToBytes("29000000075F6964004ABBED9D1D8B0F02180000010274657374000900000031323334C2A335360000"); + [Test] + public void ReadOid() + { + byte[] data = HexToBytes("29000000075F6964004ABBED9D1D8B0F02180000010274657374000900000031323334C2A335360000"); - MemoryStream ms = new MemoryStream(data); - BsonReader reader = new BsonReader(ms); + MemoryStream ms = new MemoryStream(data); + BsonReader reader = new BsonReader(ms); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("_id", reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("_id", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Bytes, reader.TokenType); - CollectionAssert.AreEquivalent(HexToBytes("4ABBED9D1D8B0F0218000001"), (byte[])reader.Value); - Assert.AreEqual(typeof(byte[]), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Bytes, reader.TokenType); + CollectionAssert.AreEquivalent(HexToBytes("4ABBED9D1D8B0F0218000001"), (byte[])reader.Value); + Assert.AreEqual(typeof(byte[]), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("test", reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("test", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("1234£56", reader.Value); - Assert.AreEqual(typeof(string), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("1234£56", reader.Value); + Assert.AreEqual(typeof(string), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - Assert.IsFalse(reader.Read()); - Assert.AreEqual(JsonToken.None, reader.TokenType); - } + Assert.IsFalse(reader.Read()); + Assert.AreEqual(JsonToken.None, reader.TokenType); + } - [Test] - public void ReadNestedArray() - { - string hexdoc = "82-00-00-00-07-5F-69-64-00-4A-78-93-79-17-22-00-00-00-00-61-CF-04-61-00-5D-00-00-00-01-30-00-00-00-00-00-00-00-F0-3F-01-31-00-00-00-00-00-00-00-00-40-01-32-00-00-00-00-00-00-00-08-40-01-33-00-00-00-00-00-00-00-10-40-01-34-00-00-00-00-00-00-00-14-50-01-35-00-00-00-00-00-00-00-18-40-01-36-00-00-00-00-00-00-00-1C-40-01-37-00-00-00-00-00-00-00-20-40-00-02-62-00-05-00-00-00-74-65-73-74-00-00"; + [Test] + public void ReadNestedArray() + { + string hexdoc = "82-00-00-00-07-5F-69-64-00-4A-78-93-79-17-22-00-00-00-00-61-CF-04-61-00-5D-00-00-00-01-30-00-00-00-00-00-00-00-F0-3F-01-31-00-00-00-00-00-00-00-00-40-01-32-00-00-00-00-00-00-00-08-40-01-33-00-00-00-00-00-00-00-10-40-01-34-00-00-00-00-00-00-00-14-50-01-35-00-00-00-00-00-00-00-18-40-01-36-00-00-00-00-00-00-00-1C-40-01-37-00-00-00-00-00-00-00-20-40-00-02-62-00-05-00-00-00-74-65-73-74-00-00"; - byte[] data = HexToBytes(hexdoc); + byte[] data = HexToBytes(hexdoc); - MemoryStream ms = new MemoryStream(data); - BsonReader reader = new BsonReader(ms); + MemoryStream ms = new MemoryStream(data); + BsonReader reader = new BsonReader(ms); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("_id", reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("_id", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Bytes, reader.TokenType); - CollectionAssert.AreEquivalent(HexToBytes("4A-78-93-79-17-22-00-00-00-00-61-CF"), (byte[])reader.Value); - Assert.AreEqual(typeof(byte[]), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Bytes, reader.TokenType); + CollectionAssert.AreEquivalent(HexToBytes("4A-78-93-79-17-22-00-00-00-00-61-CF"), (byte[])reader.Value); + Assert.AreEqual(typeof(byte[]), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("a", reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("a", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - for (int i = 1; i <= 8; i++) - { - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Float, reader.TokenType); + for (int i = 1; i <= 8; i++) + { + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Float, reader.TokenType); - double value = (i != 5) - ? Convert.ToDouble(i) - : 5.78960446186581E+77d; + double value = (i != 5) + ? Convert.ToDouble(i) + : 5.78960446186581E+77d; - Assert.AreEqual(value, reader.Value); - } + Assert.AreEqual(value, reader.Value); + } - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("b", reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("b", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("test", reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("test", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - Assert.IsFalse(reader.Read()); - Assert.AreEqual(JsonToken.None, reader.TokenType); - } + Assert.IsFalse(reader.Read()); + Assert.AreEqual(JsonToken.None, reader.TokenType); + } - [Test] - public void ReadNestedArrayIntoLinq() - { - string hexdoc = "87-00-00-00-05-5F-69-64-00-0C-00-00-00-00-4A-78-93-79-17-22-00-00-00-00-61-CF-04-61-00-5D-00-00-00-01-30-00-00-00-00-00-00-00-F0-3F-01-31-00-00-00-00-00-00-00-00-40-01-32-00-00-00-00-00-00-00-08-40-01-33-00-00-00-00-00-00-00-10-40-01-34-00-00-00-00-00-00-00-14-50-01-35-00-00-00-00-00-00-00-18-40-01-36-00-00-00-00-00-00-00-1C-40-01-37-00-00-00-00-00-00-00-20-40-00-02-62-00-05-00-00-00-74-65-73-74-00-00"; + [Test] + public void ReadNestedArrayIntoLinq() + { + string hexdoc = "87-00-00-00-05-5F-69-64-00-0C-00-00-00-00-4A-78-93-79-17-22-00-00-00-00-61-CF-04-61-00-5D-00-00-00-01-30-00-00-00-00-00-00-00-F0-3F-01-31-00-00-00-00-00-00-00-00-40-01-32-00-00-00-00-00-00-00-08-40-01-33-00-00-00-00-00-00-00-10-40-01-34-00-00-00-00-00-00-00-14-50-01-35-00-00-00-00-00-00-00-18-40-01-36-00-00-00-00-00-00-00-1C-40-01-37-00-00-00-00-00-00-00-20-40-00-02-62-00-05-00-00-00-74-65-73-74-00-00"; - byte[] data = HexToBytes(hexdoc); + byte[] data = HexToBytes(hexdoc); - BsonReader reader = new BsonReader(new MemoryStream(data)); + BsonReader reader = new BsonReader(new MemoryStream(data)); #pragma warning disable 612,618 - reader.JsonNet35BinaryCompatibility = true; + reader.JsonNet35BinaryCompatibility = true; #pragma warning restore 612,618 - JObject o = (JObject)JToken.ReadFrom(reader); - Assert.AreEqual(3, o.Count); + JObject o = (JObject)JToken.ReadFrom(reader); + Assert.AreEqual(3, o.Count); - MemoryStream ms = new MemoryStream(); - BsonWriter writer = new BsonWriter(ms); - o.WriteTo(writer); - writer.Flush(); + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); + o.WriteTo(writer); + writer.Flush(); - string bson = BytesToHex(ms.ToArray()); - Assert.AreEqual(hexdoc, bson); - } + string bson = BytesToHex(ms.ToArray()); + Assert.AreEqual(hexdoc, bson); + } - [Test] - public void OidAndBytesAreEqual() - { - byte[] data1 = HexToBytes( - "82-00-00-00-07-5F-69-64-00-4A-78-93-79-17-22-00-00-00-00-61-CF-04-61-00-5D-00-00-00-01-30-00-00-00-00-00-00-00-F0-3F-01-31-00-00-00-00-00-00-00-00-40-01-32-00-00-00-00-00-00-00-08-40-01-33-00-00-00-00-00-00-00-10-40-01-34-00-00-00-00-00-00-00-14-50-01-35-00-00-00-00-00-00-00-18-40-01-36-00-00-00-00-00-00-00-1C-40-01-37-00-00-00-00-00-00-00-20-40-00-02-62-00-05-00-00-00-74-65-73-74-00-00"); + [Test] + public void OidAndBytesAreEqual() + { + byte[] data1 = HexToBytes( + "82-00-00-00-07-5F-69-64-00-4A-78-93-79-17-22-00-00-00-00-61-CF-04-61-00-5D-00-00-00-01-30-00-00-00-00-00-00-00-F0-3F-01-31-00-00-00-00-00-00-00-00-40-01-32-00-00-00-00-00-00-00-08-40-01-33-00-00-00-00-00-00-00-10-40-01-34-00-00-00-00-00-00-00-14-50-01-35-00-00-00-00-00-00-00-18-40-01-36-00-00-00-00-00-00-00-1C-40-01-37-00-00-00-00-00-00-00-20-40-00-02-62-00-05-00-00-00-74-65-73-74-00-00"); - BsonReader reader1 = new BsonReader(new MemoryStream(data1)); + BsonReader reader1 = new BsonReader(new MemoryStream(data1)); #pragma warning disable 612,618 - reader1.JsonNet35BinaryCompatibility = true; + reader1.JsonNet35BinaryCompatibility = true; #pragma warning restore 612,618 - // oid - JObject o1 = (JObject)JToken.ReadFrom(reader1); + // oid + JObject o1 = (JObject)JToken.ReadFrom(reader1); - byte[] data2 = HexToBytes( - "87-00-00-00-05-5F-69-64-00-0C-00-00-00-02-4A-78-93-79-17-22-00-00-00-00-61-CF-04-61-00-5D-00-00-00-01-30-00-00-00-00-00-00-00-F0-3F-01-31-00-00-00-00-00-00-00-00-40-01-32-00-00-00-00-00-00-00-08-40-01-33-00-00-00-00-00-00-00-10-40-01-34-00-00-00-00-00-00-00-14-50-01-35-00-00-00-00-00-00-00-18-40-01-36-00-00-00-00-00-00-00-1C-40-01-37-00-00-00-00-00-00-00-20-40-00-02-62-00-05-00-00-00-74-65-73-74-00-00"); + byte[] data2 = HexToBytes( + "87-00-00-00-05-5F-69-64-00-0C-00-00-00-02-4A-78-93-79-17-22-00-00-00-00-61-CF-04-61-00-5D-00-00-00-01-30-00-00-00-00-00-00-00-F0-3F-01-31-00-00-00-00-00-00-00-00-40-01-32-00-00-00-00-00-00-00-08-40-01-33-00-00-00-00-00-00-00-10-40-01-34-00-00-00-00-00-00-00-14-50-01-35-00-00-00-00-00-00-00-18-40-01-36-00-00-00-00-00-00-00-1C-40-01-37-00-00-00-00-00-00-00-20-40-00-02-62-00-05-00-00-00-74-65-73-74-00-00"); - BsonReader reader2 = new BsonReader(new MemoryStream(data2)); + BsonReader reader2 = new BsonReader(new MemoryStream(data2)); #pragma warning disable 612,618 - reader2.JsonNet35BinaryCompatibility = true; + reader2.JsonNet35BinaryCompatibility = true; #pragma warning restore 612,618 - // bytes - JObject o2 = (JObject)JToken.ReadFrom(reader2); + // bytes + JObject o2 = (JObject)JToken.ReadFrom(reader2); - Assert.IsTrue(o1.DeepEquals(o2)); - } + Assert.IsTrue(o1.DeepEquals(o2)); + } - [Test] - public void ReadRegex() - { - string hexdoc = "15-00-00-00-0B-72-65-67-65-78-00-74-65-73-74-00-67-69-6D-00-00"; + [Test] + public void ReadRegex() + { + string hexdoc = "15-00-00-00-0B-72-65-67-65-78-00-74-65-73-74-00-67-69-6D-00-00"; - byte[] data = HexToBytes(hexdoc); + byte[] data = HexToBytes(hexdoc); - MemoryStream ms = new MemoryStream(data); - BsonReader reader = new BsonReader(ms); + MemoryStream ms = new MemoryStream(data); + BsonReader reader = new BsonReader(ms); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("regex", reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("regex", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual(@"/test/gim", reader.Value); - Assert.AreEqual(typeof(string), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual(@"/test/gim", reader.Value); + Assert.AreEqual(typeof(string), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - Assert.IsFalse(reader.Read()); - Assert.AreEqual(JsonToken.None, reader.TokenType); - } + Assert.IsFalse(reader.Read()); + Assert.AreEqual(JsonToken.None, reader.TokenType); + } - [Test] - public void ReadCode() - { - string hexdoc = "1A-00-00-00-0D-63-6F-64-65-00-0B-00-00-00-49-20-61-6D-20-63-6F-64-65-21-00-00"; + [Test] + public void ReadCode() + { + string hexdoc = "1A-00-00-00-0D-63-6F-64-65-00-0B-00-00-00-49-20-61-6D-20-63-6F-64-65-21-00-00"; - byte[] data = HexToBytes(hexdoc); + byte[] data = HexToBytes(hexdoc); - MemoryStream ms = new MemoryStream(data); - BsonReader reader = new BsonReader(ms); + MemoryStream ms = new MemoryStream(data); + BsonReader reader = new BsonReader(ms); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("code", reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("code", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual(@"I am code!", reader.Value); - Assert.AreEqual(typeof(string), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual(@"I am code!", reader.Value); + Assert.AreEqual(typeof(string), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - Assert.IsFalse(reader.Read()); - Assert.AreEqual(JsonToken.None, reader.TokenType); - } + Assert.IsFalse(reader.Read()); + Assert.AreEqual(JsonToken.None, reader.TokenType); + } - [Test] - public void ReadUndefined() - { - string hexdoc = "10-00-00-00-06-75-6E-64-65-66-69-6E-65-64-00-00"; + [Test] + public void ReadUndefined() + { + string hexdoc = "10-00-00-00-06-75-6E-64-65-66-69-6E-65-64-00-00"; - byte[] data = HexToBytes(hexdoc); + byte[] data = HexToBytes(hexdoc); - MemoryStream ms = new MemoryStream(data); - BsonReader reader = new BsonReader(ms); + MemoryStream ms = new MemoryStream(data); + BsonReader reader = new BsonReader(ms); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("undefined", reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("undefined", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Undefined, reader.TokenType); - Assert.AreEqual(null, reader.Value); - Assert.AreEqual(null, reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Undefined, reader.TokenType); + Assert.AreEqual(null, reader.Value); + Assert.AreEqual(null, reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - Assert.IsFalse(reader.Read()); - Assert.AreEqual(JsonToken.None, reader.TokenType); - } + Assert.IsFalse(reader.Read()); + Assert.AreEqual(JsonToken.None, reader.TokenType); + } - [Test] - public void ReadLong() - { - string hexdoc = "13-00-00-00-12-6C-6F-6E-67-00-FF-FF-FF-FF-FF-FF-FF-7F-00"; + [Test] + public void ReadLong() + { + string hexdoc = "13-00-00-00-12-6C-6F-6E-67-00-FF-FF-FF-FF-FF-FF-FF-7F-00"; - byte[] data = HexToBytes(hexdoc); + byte[] data = HexToBytes(hexdoc); - MemoryStream ms = new MemoryStream(data); - BsonReader reader = new BsonReader(ms); + MemoryStream ms = new MemoryStream(data); + BsonReader reader = new BsonReader(ms); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("long", reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("long", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.AreEqual(long.MaxValue, reader.Value); - Assert.AreEqual(typeof(long), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); + Assert.AreEqual(long.MaxValue, reader.Value); + Assert.AreEqual(typeof(long), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - Assert.IsFalse(reader.Read()); - Assert.AreEqual(JsonToken.None, reader.TokenType); - } + Assert.IsFalse(reader.Read()); + Assert.AreEqual(JsonToken.None, reader.TokenType); + } - [Test] - public void ReadReference() - { - string hexdoc = "1E-00-00-00-0C-6F-69-64-00-04-00-00-00-6F-69-64-00-01-02-03-04-05-06-07-08-09-0A-0B-0C-00"; + [Test] + public void ReadReference() + { + string hexdoc = "1E-00-00-00-0C-6F-69-64-00-04-00-00-00-6F-69-64-00-01-02-03-04-05-06-07-08-09-0A-0B-0C-00"; - byte[] data = HexToBytes(hexdoc); + byte[] data = HexToBytes(hexdoc); - MemoryStream ms = new MemoryStream(data); - BsonReader reader = new BsonReader(ms); + MemoryStream ms = new MemoryStream(data); + BsonReader reader = new BsonReader(ms); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("oid", reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("oid", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("$ref", reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("$ref", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("oid", reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("oid", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("$id", reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("$id", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Bytes, reader.TokenType); - CollectionAssert.AreEquivalent(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }, (byte[])reader.Value); - Assert.AreEqual(typeof(byte[]), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Bytes, reader.TokenType); + CollectionAssert.AreEquivalent(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }, (byte[])reader.Value); + Assert.AreEqual(typeof(byte[]), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - Assert.IsFalse(reader.Read()); - Assert.AreEqual(JsonToken.None, reader.TokenType); - } + Assert.IsFalse(reader.Read()); + Assert.AreEqual(JsonToken.None, reader.TokenType); + } - [Test] - public void ReadCodeWScope() - { - string hexdoc = "75-00-00-00-0F-63-6F-64-65-57-69-74-68-53-63-6F-70-65-00-61-00-00-00-35-00-00-00-66-6F-72-20-28-69-6E-74-20-69-20-3D-20-30-3B-20-69-20-3C-20-31-30-30-30-3B-20-69-2B-2B-29-0D-0A-7B-0D-0A-20-20-61-6C-65-72-74-28-61-72-67-31-29-3B-0D-0A-7D-00-24-00-00-00-02-61-72-67-31-00-15-00-00-00-4A-73-6F-6E-2E-4E-45-54-20-69-73-20-61-77-65-73-6F-6D-65-2E-00-00-00"; + [Test] + public void ReadCodeWScope() + { + string hexdoc = "75-00-00-00-0F-63-6F-64-65-57-69-74-68-53-63-6F-70-65-00-61-00-00-00-35-00-00-00-66-6F-72-20-28-69-6E-74-20-69-20-3D-20-30-3B-20-69-20-3C-20-31-30-30-30-3B-20-69-2B-2B-29-0D-0A-7B-0D-0A-20-20-61-6C-65-72-74-28-61-72-67-31-29-3B-0D-0A-7D-00-24-00-00-00-02-61-72-67-31-00-15-00-00-00-4A-73-6F-6E-2E-4E-45-54-20-69-73-20-61-77-65-73-6F-6D-65-2E-00-00-00"; - byte[] data = HexToBytes(hexdoc); + byte[] data = HexToBytes(hexdoc); - MemoryStream ms = new MemoryStream(data); - BsonReader reader = new BsonReader(ms); + MemoryStream ms = new MemoryStream(data); + BsonReader reader = new BsonReader(ms); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("codeWithScope", reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("codeWithScope", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("$code", reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("$code", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual(@"for (int i = 0; i < 1000; i++) + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual(@"for (int i = 0; i < 1000; i++) { alert(arg1); }", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("$scope", reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("$scope", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("arg1", reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("arg1", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("Json.NET is awesome.", reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("Json.NET is awesome.", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - Assert.IsFalse(reader.Read()); - Assert.AreEqual(JsonToken.None, reader.TokenType); - } + Assert.IsFalse(reader.Read()); + Assert.AreEqual(JsonToken.None, reader.TokenType); + } - [Test] - public void ReadEndOfStream() - { - BsonReader reader = new BsonReader(new MemoryStream()); - Assert.IsFalse(reader.Read()); - } + [Test] + public void ReadEndOfStream() + { + BsonReader reader = new BsonReader(new MemoryStream()); + Assert.IsFalse(reader.Read()); + } - [Test] - public void ReadLargeStrings() - { - string bson = - "4E-02-00-00-02-30-2D-31-2D-32-2D-33-2D-34-2D-35-2D-36-2D-37-2D-38-2D-39-2D-31-30-2D-31-31-2D-31-32-2D-31-33-2D-31-34-2D-31-35-2D-31-36-2D-31-37-2D-31-38-2D-31-39-2D-32-30-2D-32-31-2D-32-32-2D-32-33-2D-32-34-2D-32-35-2D-32-36-2D-32-37-2D-32-38-2D-32-39-2D-33-30-2D-33-31-2D-33-32-2D-33-33-2D-33-34-2D-33-35-2D-33-36-2D-33-37-2D-33-38-2D-33-39-2D-34-30-2D-34-31-2D-34-32-2D-34-33-2D-34-34-2D-34-35-2D-34-36-2D-34-37-2D-34-38-2D-34-39-2D-35-30-2D-35-31-2D-35-32-2D-35-33-2D-35-34-2D-35-35-2D-35-36-2D-35-37-2D-35-38-2D-35-39-2D-36-30-2D-36-31-2D-36-32-2D-36-33-2D-36-34-2D-36-35-2D-36-36-2D-36-37-2D-36-38-2D-36-39-2D-37-30-2D-37-31-2D-37-32-2D-37-33-2D-37-34-2D-37-35-2D-37-36-2D-37-37-2D-37-38-2D-37-39-2D-38-30-2D-38-31-2D-38-32-2D-38-33-2D-38-34-2D-38-35-2D-38-36-2D-38-37-2D-38-38-2D-38-39-2D-39-30-2D-39-31-2D-39-32-2D-39-33-2D-39-34-2D-39-35-2D-39-36-2D-39-37-2D-39-38-2D-39-39-00-22-01-00-00-30-2D-31-2D-32-2D-33-2D-34-2D-35-2D-36-2D-37-2D-38-2D-39-2D-31-30-2D-31-31-2D-31-32-2D-31-33-2D-31-34-2D-31-35-2D-31-36-2D-31-37-2D-31-38-2D-31-39-2D-32-30-2D-32-31-2D-32-32-2D-32-33-2D-32-34-2D-32-35-2D-32-36-2D-32-37-2D-32-38-2D-32-39-2D-33-30-2D-33-31-2D-33-32-2D-33-33-2D-33-34-2D-33-35-2D-33-36-2D-33-37-2D-33-38-2D-33-39-2D-34-30-2D-34-31-2D-34-32-2D-34-33-2D-34-34-2D-34-35-2D-34-36-2D-34-37-2D-34-38-2D-34-39-2D-35-30-2D-35-31-2D-35-32-2D-35-33-2D-35-34-2D-35-35-2D-35-36-2D-35-37-2D-35-38-2D-35-39-2D-36-30-2D-36-31-2D-36-32-2D-36-33-2D-36-34-2D-36-35-2D-36-36-2D-36-37-2D-36-38-2D-36-39-2D-37-30-2D-37-31-2D-37-32-2D-37-33-2D-37-34-2D-37-35-2D-37-36-2D-37-37-2D-37-38-2D-37-39-2D-38-30-2D-38-31-2D-38-32-2D-38-33-2D-38-34-2D-38-35-2D-38-36-2D-38-37-2D-38-38-2D-38-39-2D-39-30-2D-39-31-2D-39-32-2D-39-33-2D-39-34-2D-39-35-2D-39-36-2D-39-37-2D-39-38-2D-39-39-00-00"; + [Test] + public void ReadLargeStrings() + { + string bson = + "4E-02-00-00-02-30-2D-31-2D-32-2D-33-2D-34-2D-35-2D-36-2D-37-2D-38-2D-39-2D-31-30-2D-31-31-2D-31-32-2D-31-33-2D-31-34-2D-31-35-2D-31-36-2D-31-37-2D-31-38-2D-31-39-2D-32-30-2D-32-31-2D-32-32-2D-32-33-2D-32-34-2D-32-35-2D-32-36-2D-32-37-2D-32-38-2D-32-39-2D-33-30-2D-33-31-2D-33-32-2D-33-33-2D-33-34-2D-33-35-2D-33-36-2D-33-37-2D-33-38-2D-33-39-2D-34-30-2D-34-31-2D-34-32-2D-34-33-2D-34-34-2D-34-35-2D-34-36-2D-34-37-2D-34-38-2D-34-39-2D-35-30-2D-35-31-2D-35-32-2D-35-33-2D-35-34-2D-35-35-2D-35-36-2D-35-37-2D-35-38-2D-35-39-2D-36-30-2D-36-31-2D-36-32-2D-36-33-2D-36-34-2D-36-35-2D-36-36-2D-36-37-2D-36-38-2D-36-39-2D-37-30-2D-37-31-2D-37-32-2D-37-33-2D-37-34-2D-37-35-2D-37-36-2D-37-37-2D-37-38-2D-37-39-2D-38-30-2D-38-31-2D-38-32-2D-38-33-2D-38-34-2D-38-35-2D-38-36-2D-38-37-2D-38-38-2D-38-39-2D-39-30-2D-39-31-2D-39-32-2D-39-33-2D-39-34-2D-39-35-2D-39-36-2D-39-37-2D-39-38-2D-39-39-00-22-01-00-00-30-2D-31-2D-32-2D-33-2D-34-2D-35-2D-36-2D-37-2D-38-2D-39-2D-31-30-2D-31-31-2D-31-32-2D-31-33-2D-31-34-2D-31-35-2D-31-36-2D-31-37-2D-31-38-2D-31-39-2D-32-30-2D-32-31-2D-32-32-2D-32-33-2D-32-34-2D-32-35-2D-32-36-2D-32-37-2D-32-38-2D-32-39-2D-33-30-2D-33-31-2D-33-32-2D-33-33-2D-33-34-2D-33-35-2D-33-36-2D-33-37-2D-33-38-2D-33-39-2D-34-30-2D-34-31-2D-34-32-2D-34-33-2D-34-34-2D-34-35-2D-34-36-2D-34-37-2D-34-38-2D-34-39-2D-35-30-2D-35-31-2D-35-32-2D-35-33-2D-35-34-2D-35-35-2D-35-36-2D-35-37-2D-35-38-2D-35-39-2D-36-30-2D-36-31-2D-36-32-2D-36-33-2D-36-34-2D-36-35-2D-36-36-2D-36-37-2D-36-38-2D-36-39-2D-37-30-2D-37-31-2D-37-32-2D-37-33-2D-37-34-2D-37-35-2D-37-36-2D-37-37-2D-37-38-2D-37-39-2D-38-30-2D-38-31-2D-38-32-2D-38-33-2D-38-34-2D-38-35-2D-38-36-2D-38-37-2D-38-38-2D-38-39-2D-39-30-2D-39-31-2D-39-32-2D-39-33-2D-39-34-2D-39-35-2D-39-36-2D-39-37-2D-39-38-2D-39-39-00-00"; - BsonReader reader = new BsonReader(new MemoryStream(HexToBytes(bson))); + BsonReader reader = new BsonReader(new MemoryStream(HexToBytes(bson))); - StringBuilder largeStringBuilder = new StringBuilder(); - for (int i = 0; i < 100; i++) - { - if (i > 0) - largeStringBuilder.Append("-"); + StringBuilder largeStringBuilder = new StringBuilder(); + for (int i = 0; i < 100; i++) + { + if (i > 0) + largeStringBuilder.Append("-"); - largeStringBuilder.Append(i.ToString(CultureInfo.InvariantCulture)); - } - string largeString = largeStringBuilder.ToString(); + largeStringBuilder.Append(i.ToString(CultureInfo.InvariantCulture)); + } + string largeString = largeStringBuilder.ToString(); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual(largeString, reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual(largeString, reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual(largeString, reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual(largeString, reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - Assert.IsFalse(reader.Read()); - Assert.AreEqual(JsonToken.None, reader.TokenType); - } + Assert.IsFalse(reader.Read()); + Assert.AreEqual(JsonToken.None, reader.TokenType); + } - [Test] - public void ReadEmptyStrings() - { - string bson = "0C-00-00-00-02-00-01-00-00-00-00-00"; + [Test] + public void ReadEmptyStrings() + { + string bson = "0C-00-00-00-02-00-01-00-00-00-00-00"; - BsonReader reader = new BsonReader(new MemoryStream(HexToBytes(bson))); + BsonReader reader = new BsonReader(new MemoryStream(HexToBytes(bson))); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("", reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("", reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - Assert.IsFalse(reader.Read()); - Assert.AreEqual(JsonToken.None, reader.TokenType); - } + Assert.IsFalse(reader.Read()); + Assert.AreEqual(JsonToken.None, reader.TokenType); + } - [Test] - public void WriteAndReadEmptyListsAndDictionaries() - { - MemoryStream ms = new MemoryStream(); - BsonWriter writer = new BsonWriter(ms); + [Test] + public void WriteAndReadEmptyListsAndDictionaries() + { + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); - writer.WriteStartObject(); - writer.WritePropertyName("Arguments"); - writer.WriteStartObject(); - writer.WriteEndObject(); - writer.WritePropertyName("List"); - writer.WriteStartArray(); - writer.WriteEndArray(); - writer.WriteEndObject(); + writer.WriteStartObject(); + writer.WritePropertyName("Arguments"); + writer.WriteStartObject(); + writer.WriteEndObject(); + writer.WritePropertyName("List"); + writer.WriteStartArray(); + writer.WriteEndArray(); + writer.WriteEndObject(); - string bson = BitConverter.ToString(ms.ToArray()); + string bson = BitConverter.ToString(ms.ToArray()); - Assert.AreEqual("20-00-00-00-03-41-72-67-75-6D-65-6E-74-73-00-05-00-00-00-00-04-4C-69-73-74-00-05-00-00-00-00-00", bson); + Assert.AreEqual("20-00-00-00-03-41-72-67-75-6D-65-6E-74-73-00-05-00-00-00-00-04-4C-69-73-74-00-05-00-00-00-00-00", bson); - BsonReader reader = new BsonReader(new MemoryStream(HexToBytes(bson))); + BsonReader reader = new BsonReader(new MemoryStream(HexToBytes(bson))); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("Arguments", reader.Value.ToString()); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("Arguments", reader.Value.ToString()); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("List", reader.Value.ToString()); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("List", reader.Value.ToString()); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - Assert.IsFalse(reader.Read()); - Assert.AreEqual(JsonToken.None, reader.TokenType); - } + Assert.IsFalse(reader.Read()); + Assert.AreEqual(JsonToken.None, reader.TokenType); + } - [Test] - public void DateTimeKindHandling() - { - DateTime value = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc); - - MemoryStream ms = new MemoryStream(); - BsonWriter writer = new BsonWriter(ms); - - writer.WriteStartObject(); - writer.WritePropertyName("DateTime"); - writer.WriteValue(value); - writer.WriteEndObject(); - - byte[] bson = ms.ToArray(); - - JObject o; - BsonReader reader; - - reader = new BsonReader(new MemoryStream(bson), false, DateTimeKind.Utc); - o = (JObject)JToken.ReadFrom(reader); - Assert.AreEqual(value, (DateTime)o["DateTime"]); - - reader = new BsonReader(new MemoryStream(bson), false, DateTimeKind.Local); - o = (JObject)JToken.ReadFrom(reader); - Assert.AreEqual(value.ToLocalTime(), (DateTime)o["DateTime"]); - - reader = new BsonReader(new MemoryStream(bson), false, DateTimeKind.Unspecified); - o = (JObject)JToken.ReadFrom(reader); - Assert.AreEqual(DateTime.SpecifyKind(value, DateTimeKind.Unspecified), (DateTime)o["DateTime"]); - } - - [Test] - public void UnspecifiedDateTimeKindHandling() - { - DateTime value = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Unspecified); - - MemoryStream ms = new MemoryStream(); - BsonWriter writer = new BsonWriter(ms); - writer.DateTimeKindHandling = DateTimeKind.Unspecified; - - writer.WriteStartObject(); - writer.WritePropertyName("DateTime"); - writer.WriteValue(value); - writer.WriteEndObject(); - - byte[] bson = ms.ToArray(); - - JObject o; - BsonReader reader; - - reader = new BsonReader(new MemoryStream(bson), false, DateTimeKind.Unspecified); - o = (JObject)JToken.ReadFrom(reader); - Assert.AreEqual(value, (DateTime)o["DateTime"]); - } - - [Test] - public void LocalDateTimeKindHandling() - { - DateTime value = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Local); - - MemoryStream ms = new MemoryStream(); - BsonWriter writer = new BsonWriter(ms); - - writer.WriteStartObject(); - writer.WritePropertyName("DateTime"); - writer.WriteValue(value); - writer.WriteEndObject(); - - byte[] bson = ms.ToArray(); - - JObject o; - BsonReader reader; - - reader = new BsonReader(new MemoryStream(bson), false, DateTimeKind.Local); - o = (JObject)JToken.ReadFrom(reader); - Assert.AreEqual(value, (DateTime)o["DateTime"]); - } - - private string WriteAndReadStringValue(string val) - { - MemoryStream ms = new MemoryStream(); - BsonWriter bs = new BsonWriter(ms); - bs.WriteStartObject(); - bs.WritePropertyName("StringValue"); - bs.WriteValue(val); - bs.WriteEnd(); - - ms.Seek(0, SeekOrigin.Begin); - - BsonReader reader = new BsonReader(ms); - // object - reader.Read(); - // property name - reader.Read(); - // string - reader.Read(); - return (string)reader.Value; - } - - private string WriteAndReadStringPropertyName(string val) - { - MemoryStream ms = new MemoryStream(); - BsonWriter bs = new BsonWriter(ms); - bs.WriteStartObject(); - bs.WritePropertyName(val); - bs.WriteValue("Dummy"); - bs.WriteEnd(); - - ms.Seek(0, SeekOrigin.Begin); - - BsonReader reader = new BsonReader(ms); - // object - reader.Read(); - // property name - reader.Read(); - return (string)reader.Value; - } - - [Test] - public void TestReadLenStringValueShortTripleByte() - { - StringBuilder sb = new StringBuilder(); - //sb.Append('1',127); //first char of euro at the end of the boundry. - //sb.Append(euro, 5); - //sb.Append('1',128); - sb.Append(Euro); - - string expected = sb.ToString(); - Assert.AreEqual(expected, WriteAndReadStringValue(expected)); - } - - [Test] - public void TestReadLenStringValueTripleByteCharBufferBoundry0() - { - StringBuilder sb = new StringBuilder(); - sb.Append('1', 127); //first char of euro at the end of the boundry. - sb.Append(Euro, 5); - sb.Append('1', 128); - sb.Append(Euro); - - string expected = sb.ToString(); - Assert.AreEqual(expected, WriteAndReadStringValue(expected)); - } - - [Test] - public void TestReadLenStringValueTripleByteCharBufferBoundry1() - { - StringBuilder sb = new StringBuilder(); - sb.Append('1', 126); - sb.Append(Euro, 5); //middle char of euro at the end of the boundry. - sb.Append('1', 128); - sb.Append(Euro); - - string expected = sb.ToString(); - string result = WriteAndReadStringValue(expected); - Assert.AreEqual(expected, result); - } - - [Test] - public void TestReadLenStringValueTripleByteCharOne() - { - StringBuilder sb = new StringBuilder(); - sb.Append(Euro, 1); //Just one triple byte char in the string. - - string expected = sb.ToString(); - Assert.AreEqual(expected, WriteAndReadStringValue(expected)); - } - - [Test] - public void TestReadLenStringValueTripleByteCharBufferBoundry2() - { - StringBuilder sb = new StringBuilder(); - sb.Append('1', 125); - sb.Append(Euro, 5); //last char of the eruo at the end of the boundry. - sb.Append('1', 128); - sb.Append(Euro); - - string expected = sb.ToString(); - Assert.AreEqual(expected, WriteAndReadStringValue(expected)); - } - - [Test] - public void TestReadStringValue() - { - string expected = "test"; - Assert.AreEqual(expected, WriteAndReadStringValue(expected)); - } - - [Test] - public void TestReadStringValueLong() - { - StringBuilder sb = new StringBuilder(); - sb.Append('t', 150); - string expected = sb.ToString(); - Assert.AreEqual(expected, WriteAndReadStringValue(expected)); - } - - [Test] - public void TestReadStringPropertyNameShortTripleByte() - { - StringBuilder sb = new StringBuilder(); - //sb.Append('1',127); //first char of euro at the end of the boundry. - //sb.Append(euro, 5); - //sb.Append('1',128); - sb.Append(Euro); - - string expected = sb.ToString(); - Assert.AreEqual(expected, WriteAndReadStringPropertyName(expected)); - } - - [Test] - public void TestReadStringPropertyNameTripleByteCharBufferBoundry0() - { - StringBuilder sb = new StringBuilder(); - sb.Append('1', 127); //first char of euro at the end of the boundry. - sb.Append(Euro, 5); - sb.Append('1', 128); - sb.Append(Euro); - - string expected = sb.ToString(); - string result = WriteAndReadStringPropertyName(expected); - Assert.AreEqual(expected, result); - } - - [Test] - public void TestReadStringPropertyNameTripleByteCharBufferBoundry1() - { - StringBuilder sb = new StringBuilder(); - sb.Append('1', 126); - sb.Append(Euro, 5); //middle char of euro at the end of the boundry. - sb.Append('1', 128); - sb.Append(Euro); - - string expected = sb.ToString(); - Assert.AreEqual(expected, WriteAndReadStringPropertyName(expected)); - } - - [Test] - public void TestReadStringPropertyNameTripleByteCharOne() - { - StringBuilder sb = new StringBuilder(); - sb.Append(Euro, 1); //Just one triple byte char in the string. - - string expected = sb.ToString(); - Assert.AreEqual(expected, WriteAndReadStringPropertyName(expected)); - } - - [Test] - public void TestReadStringPropertyNameTripleByteCharBufferBoundry2() - { - StringBuilder sb = new StringBuilder(); - sb.Append('1', 125); - sb.Append(Euro, 5); //last char of the eruo at the end of the boundry. - sb.Append('1', 128); - sb.Append(Euro); - - string expected = sb.ToString(); - Assert.AreEqual(expected, WriteAndReadStringPropertyName(expected)); - } - - [Test] - public void TestReadStringPropertyName() - { - string expected = "test"; - Assert.AreEqual(expected, WriteAndReadStringPropertyName(expected)); - } - - [Test] - public void TestReadStringPropertyNameLong() - { - StringBuilder sb = new StringBuilder(); - sb.Append('t', 150); - string expected = sb.ToString(); - Assert.AreEqual(expected, WriteAndReadStringPropertyName(expected)); - } - - [Test] - public void ReadRegexWithOptions() - { - string hexdoc = "1A-00-00-00-0B-72-65-67-65-78-00-61-62-63-00-69-00-0B-74-65-73-74-00-00-00-00"; - - byte[] data = HexToBytes(hexdoc); - - MemoryStream ms = new MemoryStream(data); - BsonReader reader = new BsonReader(ms); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("/abc/i", reader.Value); - Assert.AreEqual(typeof(string), reader.ValueType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("//", reader.Value); - Assert.AreEqual(typeof(string), reader.ValueType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - - Assert.IsFalse(reader.Read()); - Assert.AreEqual(JsonToken.None, reader.TokenType); - } - - [Test] - public void CanRoundTripStackOverflowData() - { - var doc = - @"{ + [Test] + public void DateTimeKindHandling() + { + DateTime value = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc); + + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); + + writer.WriteStartObject(); + writer.WritePropertyName("DateTime"); + writer.WriteValue(value); + writer.WriteEndObject(); + + byte[] bson = ms.ToArray(); + + JObject o; + BsonReader reader; + + reader = new BsonReader(new MemoryStream(bson), false, DateTimeKind.Utc); + o = (JObject)JToken.ReadFrom(reader); + Assert.AreEqual(value, (DateTime)o["DateTime"]); + + reader = new BsonReader(new MemoryStream(bson), false, DateTimeKind.Local); + o = (JObject)JToken.ReadFrom(reader); + Assert.AreEqual(value.ToLocalTime(), (DateTime)o["DateTime"]); + + reader = new BsonReader(new MemoryStream(bson), false, DateTimeKind.Unspecified); + o = (JObject)JToken.ReadFrom(reader); + Assert.AreEqual(DateTime.SpecifyKind(value, DateTimeKind.Unspecified), (DateTime)o["DateTime"]); + } + + [Test] + public void UnspecifiedDateTimeKindHandling() + { + DateTime value = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Unspecified); + + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); + writer.DateTimeKindHandling = DateTimeKind.Unspecified; + + writer.WriteStartObject(); + writer.WritePropertyName("DateTime"); + writer.WriteValue(value); + writer.WriteEndObject(); + + byte[] bson = ms.ToArray(); + + JObject o; + BsonReader reader; + + reader = new BsonReader(new MemoryStream(bson), false, DateTimeKind.Unspecified); + o = (JObject)JToken.ReadFrom(reader); + Assert.AreEqual(value, (DateTime)o["DateTime"]); + } + + [Test] + public void LocalDateTimeKindHandling() + { + DateTime value = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Local); + + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); + + writer.WriteStartObject(); + writer.WritePropertyName("DateTime"); + writer.WriteValue(value); + writer.WriteEndObject(); + + byte[] bson = ms.ToArray(); + + JObject o; + BsonReader reader; + + reader = new BsonReader(new MemoryStream(bson), false, DateTimeKind.Local); + o = (JObject)JToken.ReadFrom(reader); + Assert.AreEqual(value, (DateTime)o["DateTime"]); + } + + private string WriteAndReadStringValue(string val) + { + MemoryStream ms = new MemoryStream(); + BsonWriter bs = new BsonWriter(ms); + bs.WriteStartObject(); + bs.WritePropertyName("StringValue"); + bs.WriteValue(val); + bs.WriteEnd(); + + ms.Seek(0, SeekOrigin.Begin); + + BsonReader reader = new BsonReader(ms); + // object + reader.Read(); + // property name + reader.Read(); + // string + reader.Read(); + return (string)reader.Value; + } + + private string WriteAndReadStringPropertyName(string val) + { + MemoryStream ms = new MemoryStream(); + BsonWriter bs = new BsonWriter(ms); + bs.WriteStartObject(); + bs.WritePropertyName(val); + bs.WriteValue("Dummy"); + bs.WriteEnd(); + + ms.Seek(0, SeekOrigin.Begin); + + BsonReader reader = new BsonReader(ms); + // object + reader.Read(); + // property name + reader.Read(); + return (string)reader.Value; + } + + [Test] + public void TestReadLenStringValueShortTripleByte() + { + StringBuilder sb = new StringBuilder(); + //sb.Append('1',127); //first char of euro at the end of the boundry. + //sb.Append(euro, 5); + //sb.Append('1',128); + sb.Append(Euro); + + string expected = sb.ToString(); + Assert.AreEqual(expected, WriteAndReadStringValue(expected)); + } + + [Test] + public void TestReadLenStringValueTripleByteCharBufferBoundry0() + { + StringBuilder sb = new StringBuilder(); + sb.Append('1', 127); //first char of euro at the end of the boundry. + sb.Append(Euro, 5); + sb.Append('1', 128); + sb.Append(Euro); + + string expected = sb.ToString(); + Assert.AreEqual(expected, WriteAndReadStringValue(expected)); + } + + [Test] + public void TestReadLenStringValueTripleByteCharBufferBoundry1() + { + StringBuilder sb = new StringBuilder(); + sb.Append('1', 126); + sb.Append(Euro, 5); //middle char of euro at the end of the boundry. + sb.Append('1', 128); + sb.Append(Euro); + + string expected = sb.ToString(); + string result = WriteAndReadStringValue(expected); + Assert.AreEqual(expected, result); + } + + [Test] + public void TestReadLenStringValueTripleByteCharOne() + { + StringBuilder sb = new StringBuilder(); + sb.Append(Euro, 1); //Just one triple byte char in the string. + + string expected = sb.ToString(); + Assert.AreEqual(expected, WriteAndReadStringValue(expected)); + } + + [Test] + public void TestReadLenStringValueTripleByteCharBufferBoundry2() + { + StringBuilder sb = new StringBuilder(); + sb.Append('1', 125); + sb.Append(Euro, 5); //last char of the eruo at the end of the boundry. + sb.Append('1', 128); + sb.Append(Euro); + + string expected = sb.ToString(); + Assert.AreEqual(expected, WriteAndReadStringValue(expected)); + } + + [Test] + public void TestReadStringValue() + { + string expected = "test"; + Assert.AreEqual(expected, WriteAndReadStringValue(expected)); + } + + [Test] + public void TestReadStringValueLong() + { + StringBuilder sb = new StringBuilder(); + sb.Append('t', 150); + string expected = sb.ToString(); + Assert.AreEqual(expected, WriteAndReadStringValue(expected)); + } + + [Test] + public void TestReadStringPropertyNameShortTripleByte() + { + StringBuilder sb = new StringBuilder(); + //sb.Append('1',127); //first char of euro at the end of the boundry. + //sb.Append(euro, 5); + //sb.Append('1',128); + sb.Append(Euro); + + string expected = sb.ToString(); + Assert.AreEqual(expected, WriteAndReadStringPropertyName(expected)); + } + + [Test] + public void TestReadStringPropertyNameTripleByteCharBufferBoundry0() + { + StringBuilder sb = new StringBuilder(); + sb.Append('1', 127); //first char of euro at the end of the boundry. + sb.Append(Euro, 5); + sb.Append('1', 128); + sb.Append(Euro); + + string expected = sb.ToString(); + string result = WriteAndReadStringPropertyName(expected); + Assert.AreEqual(expected, result); + } + + [Test] + public void TestReadStringPropertyNameTripleByteCharBufferBoundry1() + { + StringBuilder sb = new StringBuilder(); + sb.Append('1', 126); + sb.Append(Euro, 5); //middle char of euro at the end of the boundry. + sb.Append('1', 128); + sb.Append(Euro); + + string expected = sb.ToString(); + Assert.AreEqual(expected, WriteAndReadStringPropertyName(expected)); + } + + [Test] + public void TestReadStringPropertyNameTripleByteCharOne() + { + StringBuilder sb = new StringBuilder(); + sb.Append(Euro, 1); //Just one triple byte char in the string. + + string expected = sb.ToString(); + Assert.AreEqual(expected, WriteAndReadStringPropertyName(expected)); + } + + [Test] + public void TestReadStringPropertyNameTripleByteCharBufferBoundry2() + { + StringBuilder sb = new StringBuilder(); + sb.Append('1', 125); + sb.Append(Euro, 5); //last char of the eruo at the end of the boundry. + sb.Append('1', 128); + sb.Append(Euro); + + string expected = sb.ToString(); + Assert.AreEqual(expected, WriteAndReadStringPropertyName(expected)); + } + + [Test] + public void TestReadStringPropertyName() + { + string expected = "test"; + Assert.AreEqual(expected, WriteAndReadStringPropertyName(expected)); + } + + [Test] + public void TestReadStringPropertyNameLong() + { + StringBuilder sb = new StringBuilder(); + sb.Append('t', 150); + string expected = sb.ToString(); + Assert.AreEqual(expected, WriteAndReadStringPropertyName(expected)); + } + + [Test] + public void ReadRegexWithOptions() + { + string hexdoc = "1A-00-00-00-0B-72-65-67-65-78-00-61-62-63-00-69-00-0B-74-65-73-74-00-00-00-00"; + + byte[] data = HexToBytes(hexdoc); + + MemoryStream ms = new MemoryStream(data); + BsonReader reader = new BsonReader(ms); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("/abc/i", reader.Value); + Assert.AreEqual(typeof(string), reader.ValueType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("//", reader.Value); + Assert.AreEqual(typeof(string), reader.ValueType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + + Assert.IsFalse(reader.Read()); + Assert.AreEqual(JsonToken.None, reader.TokenType); + } + + [Test] + public void CanRoundTripStackOverflowData() + { + var doc = + @"{ ""AboutMe"": ""

I'm the Director for Research and Development for ProPhoenix, a public safety software company. This position allows me to investigate new and existing technologies and incorporate them into our product line, with the end goal being to help public safety agencies to do their jobs more effeciently and safely.

\r\n\r\n

I'm an advocate for PowerShell, as I believe it encourages administrative best practices and allows developers to provide additional access to their applications, without needing to explicity write code for each administrative feature. Part of my advocacy for PowerShell includes my blog, appearances on various podcasts, and acting as a Community Director for PowerShellCommunity.Org

\r\n\r\n

I’m also a co-host of Mind of Root (a weekly audio podcast about systems administration, tech news, and topics).

\r\n"", ""WebsiteUrl"": ""http://blog.usepowershell.com"" }"; - JObject parsed = JObject.Parse(doc); - var memoryStream = new MemoryStream(); - var bsonWriter = new BsonWriter(memoryStream); - parsed.WriteTo(bsonWriter); - bsonWriter.Flush(); - memoryStream.Position = 0; + JObject parsed = JObject.Parse(doc); + var memoryStream = new MemoryStream(); + var bsonWriter = new BsonWriter(memoryStream); + parsed.WriteTo(bsonWriter); + bsonWriter.Flush(); + memoryStream.Position = 0; - BsonReader reader = new BsonReader(memoryStream); + BsonReader reader = new BsonReader(memoryStream); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("AboutMe", reader.Value); - Assert.AreEqual(typeof(string), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("AboutMe", reader.Value); + Assert.AreEqual(typeof(string), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual(@"

I'm the Director for Research and Development for ProPhoenix, a public safety software company. This position allows me to investigate new and existing technologies and incorporate them into our product line, with the end goal being to help public safety agencies to do their jobs more effeciently and safely.

+ Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual(@"

I'm the Director for Research and Development for ProPhoenix, a public safety software company. This position allows me to investigate new and existing technologies and incorporate them into our product line, with the end goal being to help public safety agencies to do their jobs more effeciently and safely.

I'm an advocate for PowerShell, as I believe it encourages administrative best practices and allows developers to provide additional access to their applications, without needing to explicity write code for each administrative feature. Part of my advocacy for PowerShell includes my blog, appearances on various podcasts, and acting as a Community Director for PowerShellCommunity.Org

I’m also a co-host of Mind of Root (a weekly audio podcast about systems administration, tech news, and topics).

", reader.Value); - Assert.AreEqual(typeof(string), reader.ValueType); + Assert.AreEqual(typeof(string), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("WebsiteUrl", reader.Value); - Assert.AreEqual(typeof(string), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("WebsiteUrl", reader.Value); + Assert.AreEqual(typeof(string), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("http://blog.usepowershell.com", reader.Value); - Assert.AreEqual(typeof(string), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("http://blog.usepowershell.com", reader.Value); + Assert.AreEqual(typeof(string), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - Assert.IsFalse(reader.Read()); - Assert.AreEqual(JsonToken.None, reader.TokenType); - } + Assert.IsFalse(reader.Read()); + Assert.AreEqual(JsonToken.None, reader.TokenType); + } - [Test] - public void MultibyteCharacterPropertyNamesAndStrings() - { - string json = @"{ + [Test] + public void MultibyteCharacterPropertyNamesAndStrings() + { + string json = @"{ ""ΕΝΤΟΛΗ ΧΧΧ ΧΧΧΧΧΧΧΧΧ ΤΑ ΠΡΩΤΑΣΦΑΛΙΣΤΗΡΙΑ ΠΟΥ ΔΕΝ ΕΧΟΥΝ ΥΠΟΛΟΙΠΟ ΝΑ ΤΑ ΣΤΕΛΝΟΥΜΕ ΑΠΕΥΘΕΙΑΣ ΣΤΟΥΣ ΠΕΛΑΤΕΣ"": ""ΕΝΤΟΛΗ ΧΧΧ ΧΧΧΧΧΧΧΧΧ ΤΑ ΠΡΩΤΑΣΦΑΛΙΣΤΗΡΙΑ ΠΟΥ ΔΕΝ ΕΧΟΥΝ ΥΠΟΛΟΙΠΟ ΝΑ ΤΑ ΣΤΕΛΝΟΥΜΕ ΑΠΕΥΘΕΙΑΣ ΣΤΟΥΣ ΠΕΛΑΤΕΣ"" }"; - JObject parsed = JObject.Parse(json); - var memoryStream = new MemoryStream(); - var bsonWriter = new BsonWriter(memoryStream); - parsed.WriteTo(bsonWriter); - bsonWriter.Flush(); - memoryStream.Position = 0; + JObject parsed = JObject.Parse(json); + var memoryStream = new MemoryStream(); + var bsonWriter = new BsonWriter(memoryStream); + parsed.WriteTo(bsonWriter); + bsonWriter.Flush(); + memoryStream.Position = 0; - BsonReader reader = new BsonReader(memoryStream); + BsonReader reader = new BsonReader(memoryStream); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("ΕΝΤΟΛΗ ΧΧΧ ΧΧΧΧΧΧΧΧΧ ΤΑ ΠΡΩΤΑΣΦΑΛΙΣΤΗΡΙΑ ΠΟΥ ΔΕΝ ΕΧΟΥΝ ΥΠΟΛΟΙΠΟ ΝΑ ΤΑ ΣΤΕΛΝΟΥΜΕ ΑΠΕΥΘΕΙΑΣ ΣΤΟΥΣ ΠΕΛΑΤΕΣ", reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("ΕΝΤΟΛΗ ΧΧΧ ΧΧΧΧΧΧΧΧΧ ΤΑ ΠΡΩΤΑΣΦΑΛΙΣΤΗΡΙΑ ΠΟΥ ΔΕΝ ΕΧΟΥΝ ΥΠΟΛΟΙΠΟ ΝΑ ΤΑ ΣΤΕΛΝΟΥΜΕ ΑΠΕΥΘΕΙΑΣ ΣΤΟΥΣ ΠΕΛΑΤΕΣ", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("ΕΝΤΟΛΗ ΧΧΧ ΧΧΧΧΧΧΧΧΧ ΤΑ ΠΡΩΤΑΣΦΑΛΙΣΤΗΡΙΑ ΠΟΥ ΔΕΝ ΕΧΟΥΝ ΥΠΟΛΟΙΠΟ ΝΑ ΤΑ ΣΤΕΛΝΟΥΜΕ ΑΠΕΥΘΕΙΑΣ ΣΤΟΥΣ ΠΕΛΑΤΕΣ", reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("ΕΝΤΟΛΗ ΧΧΧ ΧΧΧΧΧΧΧΧΧ ΤΑ ΠΡΩΤΑΣΦΑΛΙΣΤΗΡΙΑ ΠΟΥ ΔΕΝ ΕΧΟΥΝ ΥΠΟΛΟΙΠΟ ΝΑ ΤΑ ΣΤΕΛΝΟΥΜΕ ΑΠΕΥΘΕΙΑΣ ΣΤΟΥΣ ΠΕΛΑΤΕΣ", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - } + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + } - public void UriGuidTimeSpanTestClassEmptyTest() - { - UriGuidTimeSpanTestClass c1 = new UriGuidTimeSpanTestClass(); + public void UriGuidTimeSpanTestClassEmptyTest() + { + UriGuidTimeSpanTestClass c1 = new UriGuidTimeSpanTestClass(); - var memoryStream = new MemoryStream(); - var bsonWriter = new BsonWriter(memoryStream); - JsonSerializer serializer = new JsonSerializer(); - serializer.Serialize(bsonWriter, c1); - bsonWriter.Flush(); - memoryStream.Position = 0; + var memoryStream = new MemoryStream(); + var bsonWriter = new BsonWriter(memoryStream); + JsonSerializer serializer = new JsonSerializer(); + serializer.Serialize(bsonWriter, c1); + bsonWriter.Flush(); + memoryStream.Position = 0; - var bsonReader = new BsonReader(memoryStream); + var bsonReader = new BsonReader(memoryStream); - UriGuidTimeSpanTestClass c2 = serializer.Deserialize(bsonReader); - Assert.AreEqual(c1.Guid, c2.Guid); - Assert.AreEqual(c1.NullableGuid, c2.NullableGuid); - Assert.AreEqual(c1.TimeSpan, c2.TimeSpan); - Assert.AreEqual(c1.NullableTimeSpan, c2.NullableTimeSpan); - Assert.AreEqual(c1.Uri, c2.Uri); - } + UriGuidTimeSpanTestClass c2 = serializer.Deserialize(bsonReader); + Assert.AreEqual(c1.Guid, c2.Guid); + Assert.AreEqual(c1.NullableGuid, c2.NullableGuid); + Assert.AreEqual(c1.TimeSpan, c2.TimeSpan); + Assert.AreEqual(c1.NullableTimeSpan, c2.NullableTimeSpan); + Assert.AreEqual(c1.Uri, c2.Uri); + } - public void UriGuidTimeSpanTestClassValuesTest() - { - UriGuidTimeSpanTestClass c1 = new UriGuidTimeSpanTestClass - { - Guid = new Guid("1924129C-F7E0-40F3-9607-9939C531395A"), - NullableGuid = new Guid("9E9F3ADF-E017-4F72-91E0-617EBE85967D"), - TimeSpan = TimeSpan.FromDays(1), - NullableTimeSpan = TimeSpan.FromHours(1), - Uri = new Uri("http://testuri.com") - }; + public void UriGuidTimeSpanTestClassValuesTest() + { + UriGuidTimeSpanTestClass c1 = new UriGuidTimeSpanTestClass + { + Guid = new Guid("1924129C-F7E0-40F3-9607-9939C531395A"), + NullableGuid = new Guid("9E9F3ADF-E017-4F72-91E0-617EBE85967D"), + TimeSpan = TimeSpan.FromDays(1), + NullableTimeSpan = TimeSpan.FromHours(1), + Uri = new Uri("http://testuri.com") + }; - var memoryStream = new MemoryStream(); - var bsonWriter = new BsonWriter(memoryStream); - JsonSerializer serializer = new JsonSerializer(); - serializer.Serialize(bsonWriter, c1); - bsonWriter.Flush(); - memoryStream.Position = 0; + var memoryStream = new MemoryStream(); + var bsonWriter = new BsonWriter(memoryStream); + JsonSerializer serializer = new JsonSerializer(); + serializer.Serialize(bsonWriter, c1); + bsonWriter.Flush(); + memoryStream.Position = 0; - var bsonReader = new BsonReader(memoryStream); + var bsonReader = new BsonReader(memoryStream); - UriGuidTimeSpanTestClass c2 = serializer.Deserialize(bsonReader); - Assert.AreEqual(c1.Guid, c2.Guid); - Assert.AreEqual(c1.NullableGuid, c2.NullableGuid); - Assert.AreEqual(c1.TimeSpan, c2.TimeSpan); - Assert.AreEqual(c1.NullableTimeSpan, c2.NullableTimeSpan); - Assert.AreEqual(c1.Uri, c2.Uri); - } + UriGuidTimeSpanTestClass c2 = serializer.Deserialize(bsonReader); + Assert.AreEqual(c1.Guid, c2.Guid); + Assert.AreEqual(c1.NullableGuid, c2.NullableGuid); + Assert.AreEqual(c1.TimeSpan, c2.TimeSpan); + Assert.AreEqual(c1.NullableTimeSpan, c2.NullableTimeSpan); + Assert.AreEqual(c1.Uri, c2.Uri); + } - [Test] - public void DeserializeByteArrayWithTypeNameHandling() - { - TestObject test = new TestObject("Test", new byte[] { 72, 63, 62, 71, 92, 55 }); + [Test] + public void DeserializeByteArrayWithTypeNameHandling() + { + TestObject test = new TestObject("Test", new byte[] { 72, 63, 62, 71, 92, 55 }); - JsonSerializer serializer = new JsonSerializer(); - serializer.TypeNameHandling = TypeNameHandling.All; + JsonSerializer serializer = new JsonSerializer(); + serializer.TypeNameHandling = TypeNameHandling.All; - byte[] objectBytes; - using (MemoryStream bsonStream = new MemoryStream()) - using (JsonWriter bsonWriter = new BsonWriter(bsonStream)) - { - serializer.Serialize(bsonWriter, test); - bsonWriter.Flush(); + byte[] objectBytes; + using (MemoryStream bsonStream = new MemoryStream()) + using (JsonWriter bsonWriter = new BsonWriter(bsonStream)) + { + serializer.Serialize(bsonWriter, test); + bsonWriter.Flush(); - objectBytes = bsonStream.ToArray(); - } + objectBytes = bsonStream.ToArray(); + } - using (MemoryStream bsonStream = new MemoryStream(objectBytes)) - using (JsonReader bsonReader = new BsonReader(bsonStream)) - { - // Get exception here - TestObject newObject = (TestObject)serializer.Deserialize(bsonReader); + using (MemoryStream bsonStream = new MemoryStream(objectBytes)) + using (JsonReader bsonReader = new BsonReader(bsonStream)) + { + // Get exception here + TestObject newObject = (TestObject)serializer.Deserialize(bsonReader); - Assert.AreEqual("Test", newObject.Name); - CollectionAssert.AreEquivalent(new byte[] { 72, 63, 62, 71, 92, 55 }, newObject.Data); - } - } + Assert.AreEqual("Test", newObject.Name); + CollectionAssert.AreEquivalent(new byte[] { 72, 63, 62, 71, 92, 55 }, newObject.Data); + } + } #if !(WINDOWS_PHONE || SILVERLIGHT || NET20 || NET35 || NETFX_CORE) - public void Utf8Text() - { - string badText =System.IO.File.ReadAllText(@"PoisonText.txt"); - var j = new JObject(); - j["test"] = badText; + public void Utf8Text() + { + string badText = System.IO.File.ReadAllText(@"PoisonText.txt"); + var j = new JObject(); + j["test"] = badText; - var memoryStream = new MemoryStream(); - var bsonWriter = new BsonWriter(memoryStream); - j.WriteTo(bsonWriter); - bsonWriter.Flush(); + var memoryStream = new MemoryStream(); + var bsonWriter = new BsonWriter(memoryStream); + j.WriteTo(bsonWriter); + bsonWriter.Flush(); - memoryStream.Position = 0; - JObject o = JObject.Load(new BsonReader(memoryStream)); + memoryStream.Position = 0; + JObject o = JObject.Load(new BsonReader(memoryStream)); - Assert.AreEqual(badText, (string)o["test"]); - } + Assert.AreEqual(badText, (string)o["test"]); + } #endif #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE || PORTABLE40) - public class BigIntegerTestClass - { - public BigInteger Blah { get; set; } - } + public class BigIntegerTestClass + { + public BigInteger Blah { get; set; } + } - [Test] - public void WriteBigInteger() - { - BigInteger i = BigInteger.Parse("1999999999999999999999999999999999999999999999999999999999990"); + [Test] + public void WriteBigInteger() + { + BigInteger i = BigInteger.Parse("1999999999999999999999999999999999999999999999999999999999990"); - byte[] data = HexToBytes("2A-00-00-00-05-42-6C-61-68-00-1A-00-00-00-00-F6-FF-FF-FF-FF-FF-FF-1F-B2-21-CB-28-59-84-C4-AE-03-8A-44-34-2F-4C-4E-9E-3E-01-00"); - MemoryStream ms = new MemoryStream(data); + byte[] data = HexToBytes("2A-00-00-00-05-42-6C-61-68-00-1A-00-00-00-00-F6-FF-FF-FF-FF-FF-FF-1F-B2-21-CB-28-59-84-C4-AE-03-8A-44-34-2F-4C-4E-9E-3E-01-00"); + MemoryStream ms = new MemoryStream(data); - BsonReader reader = new BsonReader(ms); + BsonReader reader = new BsonReader(ms); - JsonSerializer serializer = new JsonSerializer(); + JsonSerializer serializer = new JsonSerializer(); - BigIntegerTestClass c = serializer.Deserialize(reader); + BigIntegerTestClass c = serializer.Deserialize(reader); - Assert.AreEqual(i, c.Blah); - } + Assert.AreEqual(i, c.Blah); + } #endif - public class RegexTestClass - { - public Regex Regex { get; set; } + public class RegexTestClass + { + public Regex Regex { get; set; } + } + + [Test] + public void DeserializeRegexNonConverterBson() + { + string hex = "46-00-00-00-03-52-65-67-65-78-00-3A-00-00-00-02-70-61-74-74-65-72-6E-00-05-00-00-00-28-68-69-29-00-10-6F-70-74-69-6F-6E-73-00-05-00-00-00-12-6D-61-74-63-68-54-69-6D-65-6F-75-74-00-F0-D8-FF-FF-FF-FF-FF-FF-00-00"; + byte[] data = HexToBytes(hex); + MemoryStream ms = new MemoryStream(data); + + BsonReader reader = new BsonReader(ms); + + JsonSerializer serializer = new JsonSerializer(); + + RegexTestClass c = serializer.Deserialize(reader); + + Assert.AreEqual("(hi)", c.Regex.ToString()); + Assert.AreEqual(RegexOptions.ExplicitCapture | RegexOptions.IgnoreCase, c.Regex.Options); + } + + [Test] + public void DeserializeRegexBson() + { + string hex = "15-00-00-00-0B-52-65-67-65-78-00-28-68-69-29-00-69-75-78-00-00"; + byte[] data = HexToBytes(hex); + MemoryStream ms = new MemoryStream(data); + + BsonReader reader = new BsonReader(ms); + + JsonSerializer serializer = new JsonSerializer(); + + RegexTestClass c = serializer.Deserialize(reader); + + Assert.AreEqual("(hi)", c.Regex.ToString()); + Assert.AreEqual(RegexOptions.ExplicitCapture | RegexOptions.IgnoreCase, c.Regex.Options); + } } - - [Test] - public void DeserializeRegexNonConverterBson() - { - string hex = "46-00-00-00-03-52-65-67-65-78-00-3A-00-00-00-02-70-61-74-74-65-72-6E-00-05-00-00-00-28-68-69-29-00-10-6F-70-74-69-6F-6E-73-00-05-00-00-00-12-6D-61-74-63-68-54-69-6D-65-6F-75-74-00-F0-D8-FF-FF-FF-FF-FF-FF-00-00"; - byte[] data = HexToBytes(hex); - MemoryStream ms = new MemoryStream(data); - - BsonReader reader = new BsonReader(ms); - - JsonSerializer serializer = new JsonSerializer(); - - RegexTestClass c = serializer.Deserialize(reader); - - Assert.AreEqual("(hi)", c.Regex.ToString()); - Assert.AreEqual(RegexOptions.ExplicitCapture | RegexOptions.IgnoreCase, c.Regex.Options); - } - - [Test] - public void DeserializeRegexBson() - { - string hex = "15-00-00-00-0B-52-65-67-65-78-00-28-68-69-29-00-69-75-78-00-00"; - byte[] data = HexToBytes(hex); - MemoryStream ms = new MemoryStream(data); - - BsonReader reader = new BsonReader(ms); - - JsonSerializer serializer = new JsonSerializer(); - - RegexTestClass c = serializer.Deserialize(reader); - - Assert.AreEqual("(hi)", c.Regex.ToString()); - Assert.AreEqual(RegexOptions.ExplicitCapture | RegexOptions.IgnoreCase, c.Regex.Options); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Bson/BsonWriterTests.cs b/Src/Newtonsoft.Json.Tests/Bson/BsonWriterTests.cs index 76fac77b..c6ed4cab 100644 --- a/Src/Newtonsoft.Json.Tests/Bson/BsonWriterTests.cs +++ b/Src/Newtonsoft.Json.Tests/Bson/BsonWriterTests.cs @@ -47,284 +47,285 @@ using System.Globalization; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json.Tests.Bson { - [TestFixture] - public class BsonWriterTests : TestFixtureBase - { - [Test] - public void CloseOutput() + [TestFixture] + public class BsonWriterTests : TestFixtureBase { - MemoryStream ms = new MemoryStream(); - BsonWriter writer = new BsonWriter(ms); + [Test] + public void CloseOutput() + { + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); - Assert.IsTrue(ms.CanRead); - writer.Close(); - Assert.IsFalse(ms.CanRead); + Assert.IsTrue(ms.CanRead); + writer.Close(); + Assert.IsFalse(ms.CanRead); - ms = new MemoryStream(); - writer = new BsonWriter(ms) { CloseOutput = false }; + ms = new MemoryStream(); + writer = new BsonWriter(ms) { CloseOutput = false }; - Assert.IsTrue(ms.CanRead); - writer.Close(); - Assert.IsTrue(ms.CanRead); - } + Assert.IsTrue(ms.CanRead); + writer.Close(); + Assert.IsTrue(ms.CanRead); + } - [Test] - public void WriteSingleObject() - { - MemoryStream ms = new MemoryStream(); - BsonWriter writer = new BsonWriter(ms); + [Test] + public void WriteSingleObject() + { + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); - writer.WriteStartObject(); - writer.WritePropertyName("Blah"); - writer.WriteValue(1); - writer.WriteEndObject(); + writer.WriteStartObject(); + writer.WritePropertyName("Blah"); + writer.WriteValue(1); + writer.WriteEndObject(); - string bson = BytesToHex(ms.ToArray()); - Assert.AreEqual("0F-00-00-00-10-42-6C-61-68-00-01-00-00-00-00", bson); - } + string bson = BytesToHex(ms.ToArray()); + Assert.AreEqual("0F-00-00-00-10-42-6C-61-68-00-01-00-00-00-00", bson); + } #if !NET20 - [Test] - public void WriteValues() - { - MemoryStream ms = new MemoryStream(); - BsonWriter writer = new BsonWriter(ms); + [Test] + public void WriteValues() + { + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); - writer.WriteStartArray(); - writer.WriteValue(long.MaxValue); - writer.WriteValue((ulong)long.MaxValue); - writer.WriteValue(int.MaxValue); - writer.WriteValue((uint)int.MaxValue); - writer.WriteValue(byte.MaxValue); - writer.WriteValue(sbyte.MaxValue); - writer.WriteValue('a'); - writer.WriteValue(decimal.MaxValue); - writer.WriteValue(double.MaxValue); - writer.WriteValue(float.MaxValue); - writer.WriteValue(true); - writer.WriteValue(new byte[] { 0, 1, 2, 3, 4 }); - writer.WriteValue(new DateTimeOffset(2000, 12, 29, 12, 30, 0, TimeSpan.Zero)); - writer.WriteValue(new DateTime(2000, 12, 29, 12, 30, 0, DateTimeKind.Utc)); - writer.WriteEnd(); + writer.WriteStartArray(); + writer.WriteValue(long.MaxValue); + writer.WriteValue((ulong)long.MaxValue); + writer.WriteValue(int.MaxValue); + writer.WriteValue((uint)int.MaxValue); + writer.WriteValue(byte.MaxValue); + writer.WriteValue(sbyte.MaxValue); + writer.WriteValue('a'); + writer.WriteValue(decimal.MaxValue); + writer.WriteValue(double.MaxValue); + writer.WriteValue(float.MaxValue); + writer.WriteValue(true); + writer.WriteValue(new byte[] { 0, 1, 2, 3, 4 }); + writer.WriteValue(new DateTimeOffset(2000, 12, 29, 12, 30, 0, TimeSpan.Zero)); + writer.WriteValue(new DateTime(2000, 12, 29, 12, 30, 0, DateTimeKind.Utc)); + writer.WriteEnd(); - string bson = BytesToHex(ms.ToArray()); - Assert.AreEqual("8C-00-00-00-12-30-00-FF-FF-FF-FF-FF-FF-FF-7F-12-31-00-FF-FF-FF-FF-FF-FF-FF-7F-10-32-00-FF-FF-FF-7F-10-33-00-FF-FF-FF-7F-10-34-00-FF-00-00-00-10-35-00-7F-00-00-00-02-36-00-02-00-00-00-61-00-01-37-00-00-00-00-00-00-00-F0-45-01-38-00-FF-FF-FF-FF-FF-FF-EF-7F-01-39-00-00-00-00-E0-FF-FF-EF-47-08-31-30-00-01-05-31-31-00-05-00-00-00-00-00-01-02-03-04-09-31-32-00-40-C5-E2-BA-E3-00-00-00-09-31-33-00-40-C5-E2-BA-E3-00-00-00-00", bson); - } + string bson = BytesToHex(ms.ToArray()); + Assert.AreEqual("8C-00-00-00-12-30-00-FF-FF-FF-FF-FF-FF-FF-7F-12-31-00-FF-FF-FF-FF-FF-FF-FF-7F-10-32-00-FF-FF-FF-7F-10-33-00-FF-FF-FF-7F-10-34-00-FF-00-00-00-10-35-00-7F-00-00-00-02-36-00-02-00-00-00-61-00-01-37-00-00-00-00-00-00-00-F0-45-01-38-00-FF-FF-FF-FF-FF-FF-EF-7F-01-39-00-00-00-00-E0-FF-FF-EF-47-08-31-30-00-01-05-31-31-00-05-00-00-00-00-00-01-02-03-04-09-31-32-00-40-C5-E2-BA-E3-00-00-00-09-31-33-00-40-C5-E2-BA-E3-00-00-00-00", bson); + } #endif - [Test] - public void WriteDouble() - { - MemoryStream ms = new MemoryStream(); - BsonWriter writer = new BsonWriter(ms); + [Test] + public void WriteDouble() + { + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); - writer.WriteStartArray(); - writer.WriteValue(99.99d); - writer.WriteEnd(); + writer.WriteStartArray(); + writer.WriteValue(99.99d); + writer.WriteEnd(); - string bson = BytesToHex(ms.ToArray()); - Assert.AreEqual("10-00-00-00-01-30-00-8F-C2-F5-28-5C-FF-58-40-00", bson); - } + string bson = BytesToHex(ms.ToArray()); + Assert.AreEqual("10-00-00-00-01-30-00-8F-C2-F5-28-5C-FF-58-40-00", bson); + } - [Test] - public void WriteGuid() - { - Guid g = new Guid("D821EED7-4B5C-43C9-8AC2-6928E579B705"); + [Test] + public void WriteGuid() + { + Guid g = new Guid("D821EED7-4B5C-43C9-8AC2-6928E579B705"); - MemoryStream ms = new MemoryStream(); - BsonWriter writer = new BsonWriter(ms); + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); - writer.WriteStartArray(); - writer.WriteValue(g); - writer.WriteEnd(); + writer.WriteStartArray(); + writer.WriteValue(g); + writer.WriteEnd(); - string bson = BytesToHex(ms.ToArray()); - Console.WriteLine(bson); - Assert.AreEqual("1D-00-00-00-05-30-00-10-00-00-00-04-D7-EE-21-D8-5C-4B-C9-43-8A-C2-69-28-E5-79-B7-05-00", bson); - } + string bson = BytesToHex(ms.ToArray()); + Console.WriteLine(bson); + Assert.AreEqual("1D-00-00-00-05-30-00-10-00-00-00-04-D7-EE-21-D8-5C-4B-C9-43-8A-C2-69-28-E5-79-B7-05-00", bson); + } - [Test] - public void WriteArrayBsonFromSite() - { - MemoryStream ms = new MemoryStream(); - BsonWriter writer = new BsonWriter(ms); - writer.WriteStartArray(); - writer.WriteValue("a"); - writer.WriteValue("b"); - writer.WriteValue("c"); - writer.WriteEndArray(); - - writer.Flush(); + [Test] + public void WriteArrayBsonFromSite() + { + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); + writer.WriteStartArray(); + writer.WriteValue("a"); + writer.WriteValue("b"); + writer.WriteValue("c"); + writer.WriteEndArray(); - ms.Seek(0, SeekOrigin.Begin); + writer.Flush(); - string expected = "20-00-00-00-02-30-00-02-00-00-00-61-00-02-31-00-02-00-00-00-62-00-02-32-00-02-00-00-00-63-00-00"; - string bson = BytesToHex(ms.ToArray()); + ms.Seek(0, SeekOrigin.Begin); - Assert.AreEqual(expected, bson); - } + string expected = "20-00-00-00-02-30-00-02-00-00-00-61-00-02-31-00-02-00-00-00-62-00-02-32-00-02-00-00-00-63-00-00"; + string bson = BytesToHex(ms.ToArray()); - [Test] - public void WriteBytes() - { - byte[] data = Encoding.UTF8.GetBytes("Hello world!"); + Assert.AreEqual(expected, bson); + } - MemoryStream ms = new MemoryStream(); - BsonWriter writer = new BsonWriter(ms); - writer.WriteStartArray(); - writer.WriteValue("a"); - writer.WriteValue("b"); - writer.WriteValue(data); - writer.WriteEndArray(); + [Test] + public void WriteBytes() + { + byte[] data = Encoding.UTF8.GetBytes("Hello world!"); - writer.Flush(); + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); + writer.WriteStartArray(); + writer.WriteValue("a"); + writer.WriteValue("b"); + writer.WriteValue(data); + writer.WriteEndArray(); - ms.Seek(0, SeekOrigin.Begin); + writer.Flush(); - string expected = "2B-00-00-00-02-30-00-02-00-00-00-61-00-02-31-00-02-00-00-00-62-00-05-32-00-0C-00-00-00-00-48-65-6C-6C-6F-20-77-6F-72-6C-64-21-00"; - string bson = BytesToHex(ms.ToArray()); + ms.Seek(0, SeekOrigin.Begin); - Assert.AreEqual(expected, bson); + string expected = "2B-00-00-00-02-30-00-02-00-00-00-61-00-02-31-00-02-00-00-00-62-00-05-32-00-0C-00-00-00-00-48-65-6C-6C-6F-20-77-6F-72-6C-64-21-00"; + string bson = BytesToHex(ms.ToArray()); - BsonReader reader = new BsonReader(new MemoryStream(ms.ToArray())); - reader.ReadRootValueAsArray = true; - reader.Read(); - reader.Read(); - reader.Read(); - reader.Read(); - Assert.AreEqual(JsonToken.Bytes, reader.TokenType); - CollectionAssert.AreEquivalent(data, (byte[])reader.Value); - } + Assert.AreEqual(expected, bson); - [Test] - public void WriteNestedArray() - { - MemoryStream ms = new MemoryStream(); - BsonWriter writer = new BsonWriter(ms); - writer.WriteStartObject(); + BsonReader reader = new BsonReader(new MemoryStream(ms.ToArray())); + reader.ReadRootValueAsArray = true; + reader.Read(); + reader.Read(); + reader.Read(); + reader.Read(); + Assert.AreEqual(JsonToken.Bytes, reader.TokenType); + CollectionAssert.AreEquivalent(data, (byte[])reader.Value); + } - writer.WritePropertyName("_id"); - writer.WriteValue(HexToBytes("4A-78-93-79-17-22-00-00-00-00-61-CF")); + [Test] + public void WriteNestedArray() + { + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); + writer.WriteStartObject(); - writer.WritePropertyName("a"); - writer.WriteStartArray(); - for (int i = 1; i <= 8; i++) - { - double value = (i != 5) - ? Convert.ToDouble(i) - : 5.78960446186581E+77d; + writer.WritePropertyName("_id"); + writer.WriteValue(HexToBytes("4A-78-93-79-17-22-00-00-00-00-61-CF")); - writer.WriteValue(value); - } - writer.WriteEndArray(); + writer.WritePropertyName("a"); + writer.WriteStartArray(); + for (int i = 1; i <= 8; i++) + { + double value = (i != 5) + ? Convert.ToDouble(i) + : 5.78960446186581E+77d; - writer.WritePropertyName("b"); - writer.WriteValue("test"); + writer.WriteValue(value); + } + writer.WriteEndArray(); - writer.WriteEndObject(); + writer.WritePropertyName("b"); + writer.WriteValue("test"); - writer.Flush(); + writer.WriteEndObject(); - ms.Seek(0, SeekOrigin.Begin); + writer.Flush(); - string expected = "87-00-00-00-05-5F-69-64-00-0C-00-00-00-00-4A-78-93-79-17-22-00-00-00-00-61-CF-04-61-00-5D-00-00-00-01-30-00-00-00-00-00-00-00-F0-3F-01-31-00-00-00-00-00-00-00-00-40-01-32-00-00-00-00-00-00-00-08-40-01-33-00-00-00-00-00-00-00-10-40-01-34-00-00-00-00-00-00-00-14-50-01-35-00-00-00-00-00-00-00-18-40-01-36-00-00-00-00-00-00-00-1C-40-01-37-00-00-00-00-00-00-00-20-40-00-02-62-00-05-00-00-00-74-65-73-74-00-00"; - string bson = BytesToHex(ms.ToArray()); + ms.Seek(0, SeekOrigin.Begin); - Assert.AreEqual(expected, bson); - } + string expected = "87-00-00-00-05-5F-69-64-00-0C-00-00-00-00-4A-78-93-79-17-22-00-00-00-00-61-CF-04-61-00-5D-00-00-00-01-30-00-00-00-00-00-00-00-F0-3F-01-31-00-00-00-00-00-00-00-00-40-01-32-00-00-00-00-00-00-00-08-40-01-33-00-00-00-00-00-00-00-10-40-01-34-00-00-00-00-00-00-00-14-50-01-35-00-00-00-00-00-00-00-18-40-01-36-00-00-00-00-00-00-00-1C-40-01-37-00-00-00-00-00-00-00-20-40-00-02-62-00-05-00-00-00-74-65-73-74-00-00"; + string bson = BytesToHex(ms.ToArray()); - [Test] - public void WriteSerializedStore() - { - MemoryStream ms = new MemoryStream(); - BsonWriter writer = new BsonWriter(ms); + Assert.AreEqual(expected, bson); + } - Store s1 = new Store(); - s1.Color = StoreColor.White; - s1.Cost = 999.59m; - s1.Employees = int.MaxValue - 1; - s1.Open = true; - s1.product.Add(new Product - { - ExpiryDate = new DateTime(2000, 9, 28, 3, 59, 58, DateTimeKind.Local), - Name = "BSON!", - Price = -0.1m, - Sizes = new [] { "First", "Second" } - }); - s1.Establised = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Local); + [Test] + public void WriteSerializedStore() + { + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); - JsonSerializer serializer = new JsonSerializer(); - serializer.Serialize(writer, s1); + Store s1 = new Store(); + s1.Color = StoreColor.White; + s1.Cost = 999.59m; + s1.Employees = int.MaxValue - 1; + s1.Open = true; + s1.product.Add(new Product + { + ExpiryDate = new DateTime(2000, 9, 28, 3, 59, 58, DateTimeKind.Local), + Name = "BSON!", + Price = -0.1m, + Sizes = new[] { "First", "Second" } + }); + s1.Establised = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Local); - ms.Seek(0, SeekOrigin.Begin); - BsonReader reader = new BsonReader(ms); - Store s2 = (Store)serializer.Deserialize(reader, typeof (Store)); + JsonSerializer serializer = new JsonSerializer(); + serializer.Serialize(writer, s1); - Assert.AreNotEqual(s1, s2); - Assert.AreEqual(s1.Color, s2.Color); - Assert.AreEqual(s1.Cost, s2.Cost); - Assert.AreEqual(s1.Employees, s2.Employees); - Assert.AreEqual(s1.Escape, s2.Escape); - Assert.AreEqual(s1.Establised, s2.Establised); - Assert.AreEqual(s1.Mottos.Count, s2.Mottos.Count); - Assert.AreEqual(s1.Mottos.First(), s2.Mottos.First()); - Assert.AreEqual(s1.Mottos.Last(), s2.Mottos.Last()); - Assert.AreEqual(s1.Open, s2.Open); - Assert.AreEqual(s1.product.Count, s2.product.Count); - Assert.AreEqual(s1.RoomsPerFloor.Length, s2.RoomsPerFloor.Length); - Assert.AreEqual(s1.Symbol, s2.Symbol); - Assert.AreEqual(s1.Width, s2.Width); + ms.Seek(0, SeekOrigin.Begin); + BsonReader reader = new BsonReader(ms); + Store s2 = (Store)serializer.Deserialize(reader, typeof(Store)); - MemoryStream ms1 = new MemoryStream(); - BsonWriter writer1 = new BsonWriter(ms1); + Assert.AreNotEqual(s1, s2); + Assert.AreEqual(s1.Color, s2.Color); + Assert.AreEqual(s1.Cost, s2.Cost); + Assert.AreEqual(s1.Employees, s2.Employees); + Assert.AreEqual(s1.Escape, s2.Escape); + Assert.AreEqual(s1.Establised, s2.Establised); + Assert.AreEqual(s1.Mottos.Count, s2.Mottos.Count); + Assert.AreEqual(s1.Mottos.First(), s2.Mottos.First()); + Assert.AreEqual(s1.Mottos.Last(), s2.Mottos.Last()); + Assert.AreEqual(s1.Open, s2.Open); + Assert.AreEqual(s1.product.Count, s2.product.Count); + Assert.AreEqual(s1.RoomsPerFloor.Length, s2.RoomsPerFloor.Length); + Assert.AreEqual(s1.Symbol, s2.Symbol); + Assert.AreEqual(s1.Width, s2.Width); - serializer.Serialize(writer1, s1); + MemoryStream ms1 = new MemoryStream(); + BsonWriter writer1 = new BsonWriter(ms1); - CollectionAssert.AreEquivalent(ms.ToArray(), ms1.ToArray()); + serializer.Serialize(writer1, s1); - string s = JsonConvert.SerializeObject(s1); - byte[] textData = Encoding.UTF8.GetBytes(s); + CollectionAssert.AreEquivalent(ms.ToArray(), ms1.ToArray()); - int l1 = textData.Length; - int l2 = ms.ToArray().Length; + string s = JsonConvert.SerializeObject(s1); + byte[] textData = Encoding.UTF8.GetBytes(s); - Console.WriteLine(l1); - Console.WriteLine(l2); - } + int l1 = textData.Length; + int l2 = ms.ToArray().Length; - [Test] - public void WriteLargeStrings() - { - MemoryStream ms = new MemoryStream(); - BsonWriter writer = new BsonWriter(ms); + Console.WriteLine(l1); + Console.WriteLine(l2); + } - StringBuilder largeStringBuilder = new StringBuilder(); - for (int i = 0; i < 100; i++) - { - if (i > 0) - largeStringBuilder.Append("-"); + [Test] + public void WriteLargeStrings() + { + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); - largeStringBuilder.Append(i.ToString(CultureInfo.InvariantCulture)); - } - string largeString = largeStringBuilder.ToString(); + StringBuilder largeStringBuilder = new StringBuilder(); + for (int i = 0; i < 100; i++) + { + if (i > 0) + largeStringBuilder.Append("-"); - writer.WriteStartObject(); - writer.WritePropertyName(largeString); - writer.WriteValue(largeString); - writer.WriteEndObject(); + largeStringBuilder.Append(i.ToString(CultureInfo.InvariantCulture)); + } + string largeString = largeStringBuilder.ToString(); - string bson = BytesToHex(ms.ToArray()); - Assert.AreEqual("4E-02-00-00-02-30-2D-31-2D-32-2D-33-2D-34-2D-35-2D-36-2D-37-2D-38-2D-39-2D-31-30-2D-31-31-2D-31-32-2D-31-33-2D-31-34-2D-31-35-2D-31-36-2D-31-37-2D-31-38-2D-31-39-2D-32-30-2D-32-31-2D-32-32-2D-32-33-2D-32-34-2D-32-35-2D-32-36-2D-32-37-2D-32-38-2D-32-39-2D-33-30-2D-33-31-2D-33-32-2D-33-33-2D-33-34-2D-33-35-2D-33-36-2D-33-37-2D-33-38-2D-33-39-2D-34-30-2D-34-31-2D-34-32-2D-34-33-2D-34-34-2D-34-35-2D-34-36-2D-34-37-2D-34-38-2D-34-39-2D-35-30-2D-35-31-2D-35-32-2D-35-33-2D-35-34-2D-35-35-2D-35-36-2D-35-37-2D-35-38-2D-35-39-2D-36-30-2D-36-31-2D-36-32-2D-36-33-2D-36-34-2D-36-35-2D-36-36-2D-36-37-2D-36-38-2D-36-39-2D-37-30-2D-37-31-2D-37-32-2D-37-33-2D-37-34-2D-37-35-2D-37-36-2D-37-37-2D-37-38-2D-37-39-2D-38-30-2D-38-31-2D-38-32-2D-38-33-2D-38-34-2D-38-35-2D-38-36-2D-38-37-2D-38-38-2D-38-39-2D-39-30-2D-39-31-2D-39-32-2D-39-33-2D-39-34-2D-39-35-2D-39-36-2D-39-37-2D-39-38-2D-39-39-00-22-01-00-00-30-2D-31-2D-32-2D-33-2D-34-2D-35-2D-36-2D-37-2D-38-2D-39-2D-31-30-2D-31-31-2D-31-32-2D-31-33-2D-31-34-2D-31-35-2D-31-36-2D-31-37-2D-31-38-2D-31-39-2D-32-30-2D-32-31-2D-32-32-2D-32-33-2D-32-34-2D-32-35-2D-32-36-2D-32-37-2D-32-38-2D-32-39-2D-33-30-2D-33-31-2D-33-32-2D-33-33-2D-33-34-2D-33-35-2D-33-36-2D-33-37-2D-33-38-2D-33-39-2D-34-30-2D-34-31-2D-34-32-2D-34-33-2D-34-34-2D-34-35-2D-34-36-2D-34-37-2D-34-38-2D-34-39-2D-35-30-2D-35-31-2D-35-32-2D-35-33-2D-35-34-2D-35-35-2D-35-36-2D-35-37-2D-35-38-2D-35-39-2D-36-30-2D-36-31-2D-36-32-2D-36-33-2D-36-34-2D-36-35-2D-36-36-2D-36-37-2D-36-38-2D-36-39-2D-37-30-2D-37-31-2D-37-32-2D-37-33-2D-37-34-2D-37-35-2D-37-36-2D-37-37-2D-37-38-2D-37-39-2D-38-30-2D-38-31-2D-38-32-2D-38-33-2D-38-34-2D-38-35-2D-38-36-2D-38-37-2D-38-38-2D-38-39-2D-39-30-2D-39-31-2D-39-32-2D-39-33-2D-39-34-2D-39-35-2D-39-36-2D-39-37-2D-39-38-2D-39-39-00-00", bson); - } + writer.WriteStartObject(); + writer.WritePropertyName(largeString); + writer.WriteValue(largeString); + writer.WriteEndObject(); - [Test] - public void SerializeGoogleGeoCode() - { - string json = @"{ + string bson = BytesToHex(ms.ToArray()); + Assert.AreEqual("4E-02-00-00-02-30-2D-31-2D-32-2D-33-2D-34-2D-35-2D-36-2D-37-2D-38-2D-39-2D-31-30-2D-31-31-2D-31-32-2D-31-33-2D-31-34-2D-31-35-2D-31-36-2D-31-37-2D-31-38-2D-31-39-2D-32-30-2D-32-31-2D-32-32-2D-32-33-2D-32-34-2D-32-35-2D-32-36-2D-32-37-2D-32-38-2D-32-39-2D-33-30-2D-33-31-2D-33-32-2D-33-33-2D-33-34-2D-33-35-2D-33-36-2D-33-37-2D-33-38-2D-33-39-2D-34-30-2D-34-31-2D-34-32-2D-34-33-2D-34-34-2D-34-35-2D-34-36-2D-34-37-2D-34-38-2D-34-39-2D-35-30-2D-35-31-2D-35-32-2D-35-33-2D-35-34-2D-35-35-2D-35-36-2D-35-37-2D-35-38-2D-35-39-2D-36-30-2D-36-31-2D-36-32-2D-36-33-2D-36-34-2D-36-35-2D-36-36-2D-36-37-2D-36-38-2D-36-39-2D-37-30-2D-37-31-2D-37-32-2D-37-33-2D-37-34-2D-37-35-2D-37-36-2D-37-37-2D-37-38-2D-37-39-2D-38-30-2D-38-31-2D-38-32-2D-38-33-2D-38-34-2D-38-35-2D-38-36-2D-38-37-2D-38-38-2D-38-39-2D-39-30-2D-39-31-2D-39-32-2D-39-33-2D-39-34-2D-39-35-2D-39-36-2D-39-37-2D-39-38-2D-39-39-00-22-01-00-00-30-2D-31-2D-32-2D-33-2D-34-2D-35-2D-36-2D-37-2D-38-2D-39-2D-31-30-2D-31-31-2D-31-32-2D-31-33-2D-31-34-2D-31-35-2D-31-36-2D-31-37-2D-31-38-2D-31-39-2D-32-30-2D-32-31-2D-32-32-2D-32-33-2D-32-34-2D-32-35-2D-32-36-2D-32-37-2D-32-38-2D-32-39-2D-33-30-2D-33-31-2D-33-32-2D-33-33-2D-33-34-2D-33-35-2D-33-36-2D-33-37-2D-33-38-2D-33-39-2D-34-30-2D-34-31-2D-34-32-2D-34-33-2D-34-34-2D-34-35-2D-34-36-2D-34-37-2D-34-38-2D-34-39-2D-35-30-2D-35-31-2D-35-32-2D-35-33-2D-35-34-2D-35-35-2D-35-36-2D-35-37-2D-35-38-2D-35-39-2D-36-30-2D-36-31-2D-36-32-2D-36-33-2D-36-34-2D-36-35-2D-36-36-2D-36-37-2D-36-38-2D-36-39-2D-37-30-2D-37-31-2D-37-32-2D-37-33-2D-37-34-2D-37-35-2D-37-36-2D-37-37-2D-37-38-2D-37-39-2D-38-30-2D-38-31-2D-38-32-2D-38-33-2D-38-34-2D-38-35-2D-38-36-2D-38-37-2D-38-38-2D-38-39-2D-39-30-2D-39-31-2D-39-32-2D-39-33-2D-39-34-2D-39-35-2D-39-36-2D-39-37-2D-39-38-2D-39-39-00-00", bson); + } + + [Test] + public void SerializeGoogleGeoCode() + { + string json = @"{ ""name"": ""1600 Amphitheatre Parkway, Mountain View, CA, USA"", ""Status"": { ""code"": 200, @@ -361,426 +362,426 @@ namespace Newtonsoft.Json.Tests.Bson ] }"; - GoogleMapGeocoderStructure jsonGoogleMapGeocoder = JsonConvert.DeserializeObject(json); - - MemoryStream ms = new MemoryStream(); - BsonWriter writer = new BsonWriter(ms); - - JsonSerializer serializer = new JsonSerializer(); - serializer.Serialize(writer, jsonGoogleMapGeocoder); - - ms.Seek(0, SeekOrigin.Begin); - BsonReader reader = new BsonReader(ms); - GoogleMapGeocoderStructure bsonGoogleMapGeocoder = (GoogleMapGeocoderStructure)serializer.Deserialize(reader, typeof (GoogleMapGeocoderStructure)); - - Assert.IsNotNull(bsonGoogleMapGeocoder); - Assert.AreEqual("1600 Amphitheatre Parkway, Mountain View, CA, USA", bsonGoogleMapGeocoder.Name); - Assert.AreEqual("200", bsonGoogleMapGeocoder.Status.Code); - Assert.AreEqual("geocode", bsonGoogleMapGeocoder.Status.Request); - - IList placemarks = bsonGoogleMapGeocoder.Placemark; - Assert.IsNotNull(placemarks); - Assert.AreEqual(1, placemarks.Count); - - Placemark placemark = placemarks[0]; - Assert.AreEqual("1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA", placemark.Address); - Assert.AreEqual(8, placemark.AddressDetails.Accuracy); - Assert.AreEqual("US", placemark.AddressDetails.Country.CountryNameCode); - Assert.AreEqual("CA", placemark.AddressDetails.Country.AdministrativeArea.AdministrativeAreaName); - Assert.AreEqual("Santa Clara", placemark.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.SubAdministrativeAreaName); - Assert.AreEqual("Mountain View", placemark.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName); - Assert.AreEqual("1600 Amphitheatre Pkwy", placemark.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.Thoroughfare.ThoroughfareName); - Assert.AreEqual("94043", placemark.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.PostalCode.PostalCodeNumber); - Assert.AreEqual(-122.083739m, placemark.Point.Coordinates[0]); - Assert.AreEqual(37.423021m, placemark.Point.Coordinates[1]); - Assert.AreEqual(0m, placemark.Point.Coordinates[2]); - } - - [Test] - public void WriteEmptyStrings() - { - MemoryStream ms = new MemoryStream(); - BsonWriter writer = new BsonWriter(ms); - - writer.WriteStartObject(); - writer.WritePropertyName(""); - writer.WriteValue(""); - writer.WriteEndObject(); - - string bson = BytesToHex(ms.ToArray()); - Assert.AreEqual("0C-00-00-00-02-00-01-00-00-00-00-00", bson); - } - - [Test] - public void WriteComment() - { - ExceptionAssert.Throws("Cannot write JSON comment as BSON. Path ''.", - () => - { - MemoryStream ms = new MemoryStream(); - BsonWriter writer = new BsonWriter(ms); - - writer.WriteStartArray(); - writer.WriteComment("fail"); - }); - } - - [Test] - public void WriteConstructor() - { - ExceptionAssert.Throws("Cannot write JSON constructor as BSON. Path ''.", - () => - { - MemoryStream ms = new MemoryStream(); - BsonWriter writer = new BsonWriter(ms); - - writer.WriteStartArray(); - writer.WriteStartConstructor("fail"); - }); - } - - [Test] - public void WriteRaw() - { - ExceptionAssert.Throws("Cannot write raw JSON as BSON. Path ''.", - () => - { - MemoryStream ms = new MemoryStream(); - BsonWriter writer = new BsonWriter(ms); - - writer.WriteStartArray(); - writer.WriteRaw("fail"); - }); - } - - [Test] - public void WriteRawValue() - { - ExceptionAssert.Throws("Cannot write raw JSON as BSON. Path ''.", - () => - { - MemoryStream ms = new MemoryStream(); - BsonWriter writer = new BsonWriter(ms); - - writer.WriteStartArray(); - writer.WriteRawValue("fail"); - }); - } - - [Test] - public void Example() - { - Product p = new Product(); - p.ExpiryDate = DateTime.Parse("2009-04-05T14:45:00Z"); - p.Name = "Carlos' Spicy Wieners"; - p.Price = 9.95m; - p.Sizes = new[] { "Small", "Medium", "Large" }; - - MemoryStream ms = new MemoryStream(); - JsonSerializer serializer = new JsonSerializer(); - - // serialize product to BSON - BsonWriter writer = new BsonWriter(ms); - serializer.Serialize(writer, p); - - Console.WriteLine(BitConverter.ToString(ms.ToArray())); - // 7C-00-00-00-02-4E-61-6D-65-00-16-00-00-00-43-61-72-6C- - // 6F-73-27-20-53-70-69-63-79-20-57-69-65-6E-65-72-73-00- - // 09-45-78-70-69-72-79-44-61-74-65-00-E0-51-BD-76-20-01- - // 00-00-01-50-72-69-63-65-00-66-66-66-66-66-E6-23-40-04- - // 53-69-7A-65-73-00-2D-00-00-00-02-30-00-06-00-00-00-53- - // 6D-61-6C-6C-00-02-31-00-07-00-00-00-4D-65-64-69-75-6D- - // 00-02-32-00-06-00-00-00-4C-61-72-67-65-00-00-00 - - - ms.Seek(0, SeekOrigin.Begin); - - // deserialize product from BSON - BsonReader reader = new BsonReader(ms); - Product deserializedProduct = serializer.Deserialize(reader); - - Console.WriteLine(deserializedProduct.Name); - // Carlos' Spicy Wieners - - - Assert.AreEqual("Carlos' Spicy Wieners", deserializedProduct.Name); - Assert.AreEqual(9.95m, deserializedProduct.Price); - Assert.AreEqual(3, deserializedProduct.Sizes.Length); - } - - [Test] - public void WriteOid() - { - MemoryStream ms = new MemoryStream(); - BsonWriter writer = new BsonWriter(ms); - - byte[] oid = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; - - writer.WriteStartObject(); - writer.WritePropertyName("_oid"); - writer.WriteObjectId(oid); - writer.WriteEndObject(); - - string bson = BytesToHex(ms.ToArray()); - Assert.AreEqual("17-00-00-00-07-5F-6F-69-64-00-01-02-03-04-05-06-07-08-09-0A-0B-0C-00", bson); - - ms.Seek(0, SeekOrigin.Begin); - BsonReader reader = new BsonReader(ms); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Bytes, reader.TokenType); - CollectionAssert.AreEquivalent(oid, (byte[])reader.Value); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - } - - [Test] - public void WriteOidPlusContent() - { - MemoryStream ms = new MemoryStream(); - BsonWriter writer = new BsonWriter(ms); - - writer.WriteStartObject(); - writer.WritePropertyName("_id"); - writer.WriteObjectId(HexToBytes("4ABBED9D1D8B0F0218000001")); - writer.WritePropertyName("test"); - writer.WriteValue("1234£56"); - writer.WriteEndObject(); - - byte[] expected = HexToBytes("29000000075F6964004ABBED9D1D8B0F02180000010274657374000900000031323334C2A335360000"); - - CollectionAssert.AreEquivalent(expected, ms.ToArray()); - } - - [Test] - public void WriteRegexPlusContent() - { - MemoryStream ms = new MemoryStream(); - BsonWriter writer = new BsonWriter(ms); - - writer.WriteStartObject(); - writer.WritePropertyName("regex"); - writer.WriteRegex("abc", "i"); - writer.WritePropertyName("test"); - writer.WriteRegex(string.Empty, null); - writer.WriteEndObject(); - - byte[] expected = HexToBytes("1A-00-00-00-0B-72-65-67-65-78-00-61-62-63-00-69-00-0B-74-65-73-74-00-00-00-00"); - - CollectionAssert.AreEquivalent(expected, ms.ToArray()); - } - - [Test] - public void SerializeEmptyAndNullStrings() - { - Product p = new Product(); - p.ExpiryDate = DateTime.Parse("2009-04-05T14:45:00Z"); - p.Name = null; - p.Price = 9.95m; - p.Sizes = new[] { "Small", "", null }; - - MemoryStream ms = new MemoryStream(); - JsonSerializer serializer = new JsonSerializer(); - - BsonWriter writer = new BsonWriter(ms); - serializer.Serialize(writer, p); - - ms.Seek(0, SeekOrigin.Begin); - - BsonReader reader = new BsonReader(ms); - Product deserializedProduct = serializer.Deserialize(reader); - - Console.WriteLine(deserializedProduct.Name); - - Assert.AreEqual(null, deserializedProduct.Name); - Assert.AreEqual(9.95m, deserializedProduct.Price); - Assert.AreEqual(3, deserializedProduct.Sizes.Length); - Assert.AreEqual("Small", deserializedProduct.Sizes[0]); - Assert.AreEqual("", deserializedProduct.Sizes[1]); - Assert.AreEqual(null, deserializedProduct.Sizes[2]); - } - - [Test] - public void WriteReadEmptyAndNullStrings() - { - MemoryStream ms = new MemoryStream(); - BsonWriter writer = new BsonWriter(ms); - - writer.WriteStartArray(); - writer.WriteValue("Content!"); - writer.WriteValue(""); - writer.WriteValue((string)null); - writer.WriteEndArray(); - - ms.Seek(0, SeekOrigin.Begin); - - BsonReader reader = new BsonReader(ms); - reader.ReadRootValueAsArray = true; - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("Content!", reader.Value); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("", reader.Value); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Null, reader.TokenType); - Assert.AreEqual(null, reader.Value); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - - Assert.IsFalse(reader.Read()); - } - - [Test] - public void WriteDateTimes() - { - MemoryStream ms = new MemoryStream(); - BsonWriter writer = new BsonWriter(ms); - writer.DateTimeKindHandling = DateTimeKind.Unspecified; - - writer.WriteStartArray(); - writer.WriteValue(new DateTime(2000, 10, 12, 20, 55, 0, DateTimeKind.Utc)); - writer.WriteValue(new DateTime(2000, 10, 12, 20, 55, 0, DateTimeKind.Local)); - writer.WriteValue(new DateTime(2000, 10, 12, 20, 55, 0, DateTimeKind.Unspecified)); - writer.WriteEndArray(); - - ms.Seek(0, SeekOrigin.Begin); - - BsonReader reader = new BsonReader(ms); - reader.ReadRootValueAsArray = true; - reader.DateTimeKindHandling = DateTimeKind.Utc; - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Date, reader.TokenType); - Assert.AreEqual(new DateTime(2000, 10, 12, 20, 55, 0, DateTimeKind.Utc), reader.Value); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Date, reader.TokenType); - Assert.AreEqual(new DateTime(2000, 10, 12, 20, 55, 0, DateTimeKind.Utc), reader.Value); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Date, reader.TokenType); - Assert.AreEqual(new DateTime(2000, 10, 12, 20, 55, 0, DateTimeKind.Utc), reader.Value); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - - Assert.IsFalse(reader.Read()); - } - - [Test] - public void WriteValueOutsideOfObjectOrArray() - { - ExceptionAssert.Throws("Error writing String value. BSON must start with an Object or Array. Path ''.", - () => - { - MemoryStream stream = new MemoryStream(); - - using (BsonWriter writer = new BsonWriter(stream)) - { - writer.WriteValue("test"); - writer.Flush(); + GoogleMapGeocoderStructure jsonGoogleMapGeocoder = JsonConvert.DeserializeObject(json); + + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); + + JsonSerializer serializer = new JsonSerializer(); + serializer.Serialize(writer, jsonGoogleMapGeocoder); + + ms.Seek(0, SeekOrigin.Begin); + BsonReader reader = new BsonReader(ms); + GoogleMapGeocoderStructure bsonGoogleMapGeocoder = (GoogleMapGeocoderStructure)serializer.Deserialize(reader, typeof(GoogleMapGeocoderStructure)); + + Assert.IsNotNull(bsonGoogleMapGeocoder); + Assert.AreEqual("1600 Amphitheatre Parkway, Mountain View, CA, USA", bsonGoogleMapGeocoder.Name); + Assert.AreEqual("200", bsonGoogleMapGeocoder.Status.Code); + Assert.AreEqual("geocode", bsonGoogleMapGeocoder.Status.Request); + + IList placemarks = bsonGoogleMapGeocoder.Placemark; + Assert.IsNotNull(placemarks); + Assert.AreEqual(1, placemarks.Count); + + Placemark placemark = placemarks[0]; + Assert.AreEqual("1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA", placemark.Address); + Assert.AreEqual(8, placemark.AddressDetails.Accuracy); + Assert.AreEqual("US", placemark.AddressDetails.Country.CountryNameCode); + Assert.AreEqual("CA", placemark.AddressDetails.Country.AdministrativeArea.AdministrativeAreaName); + Assert.AreEqual("Santa Clara", placemark.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.SubAdministrativeAreaName); + Assert.AreEqual("Mountain View", placemark.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName); + Assert.AreEqual("1600 Amphitheatre Pkwy", placemark.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.Thoroughfare.ThoroughfareName); + Assert.AreEqual("94043", placemark.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.PostalCode.PostalCodeNumber); + Assert.AreEqual(-122.083739m, placemark.Point.Coordinates[0]); + Assert.AreEqual(37.423021m, placemark.Point.Coordinates[1]); + Assert.AreEqual(0m, placemark.Point.Coordinates[2]); } - }); - } - [Test] - public void DateTimeZoneHandling() - { - MemoryStream ms = new MemoryStream(); - JsonWriter writer = new BsonWriter(ms) - { - DateTimeZoneHandling = Json.DateTimeZoneHandling.Utc - }; + [Test] + public void WriteEmptyStrings() + { + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); - writer.WriteStartArray(); - writer.WriteValue(new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Unspecified)); - writer.WriteEndArray(); + writer.WriteStartObject(); + writer.WritePropertyName(""); + writer.WriteValue(""); + writer.WriteEndObject(); - Assert.AreEqual("10-00-00-00-09-30-00-C8-88-07-6B-DC-00-00-00-00", (BitConverter.ToString(ms.ToArray()))); - } + string bson = BytesToHex(ms.ToArray()); + Assert.AreEqual("0C-00-00-00-02-00-01-00-00-00-00-00", bson); + } - public class RegexTestClass - { - public Regex Regex { get; set; } - } + [Test] + public void WriteComment() + { + ExceptionAssert.Throws("Cannot write JSON comment as BSON. Path ''.", + () => + { + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); - [Test] - public void SerializeDeserializeRegex() - { - Regex r1 = new Regex("(hi)", RegexOptions.ExplicitCapture | RegexOptions.IgnoreCase); - RegexTestClass c = new RegexTestClass { Regex = r1 }; + writer.WriteStartArray(); + writer.WriteComment("fail"); + }); + } - MemoryStream ms = new MemoryStream(); - JsonSerializer serializer = new JsonSerializer(); + [Test] + public void WriteConstructor() + { + ExceptionAssert.Throws("Cannot write JSON constructor as BSON. Path ''.", + () => + { + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); - BsonWriter writer = new BsonWriter(ms); - serializer.Serialize(writer, c); + writer.WriteStartArray(); + writer.WriteStartConstructor("fail"); + }); + } - string hex = BitConverter.ToString(ms.ToArray()); + [Test] + public void WriteRaw() + { + ExceptionAssert.Throws("Cannot write raw JSON as BSON. Path ''.", + () => + { + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); - Assert.AreEqual("15-00-00-00-0B-52-65-67-65-78-00-28-68-69-29-00-69-75-78-00-00", hex); + writer.WriteStartArray(); + writer.WriteRaw("fail"); + }); + } - JObject o = (JObject)JObject.ReadFrom(new BsonReader(new MemoryStream(ms.ToArray()))); + [Test] + public void WriteRawValue() + { + ExceptionAssert.Throws("Cannot write raw JSON as BSON. Path ''.", + () => + { + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); - Console.WriteLine(o.ToString()); - //{ - // "Regex": "/(hi)/iux" - //} - } + writer.WriteStartArray(); + writer.WriteRawValue("fail"); + }); + } + + [Test] + public void Example() + { + Product p = new Product(); + p.ExpiryDate = DateTime.Parse("2009-04-05T14:45:00Z"); + p.Name = "Carlos' Spicy Wieners"; + p.Price = 9.95m; + p.Sizes = new[] { "Small", "Medium", "Large" }; + + MemoryStream ms = new MemoryStream(); + JsonSerializer serializer = new JsonSerializer(); + + // serialize product to BSON + BsonWriter writer = new BsonWriter(ms); + serializer.Serialize(writer, p); + + Console.WriteLine(BitConverter.ToString(ms.ToArray())); + // 7C-00-00-00-02-4E-61-6D-65-00-16-00-00-00-43-61-72-6C- + // 6F-73-27-20-53-70-69-63-79-20-57-69-65-6E-65-72-73-00- + // 09-45-78-70-69-72-79-44-61-74-65-00-E0-51-BD-76-20-01- + // 00-00-01-50-72-69-63-65-00-66-66-66-66-66-E6-23-40-04- + // 53-69-7A-65-73-00-2D-00-00-00-02-30-00-06-00-00-00-53- + // 6D-61-6C-6C-00-02-31-00-07-00-00-00-4D-65-64-69-75-6D- + // 00-02-32-00-06-00-00-00-4C-61-72-67-65-00-00-00 + + + ms.Seek(0, SeekOrigin.Begin); + + // deserialize product from BSON + BsonReader reader = new BsonReader(ms); + Product deserializedProduct = serializer.Deserialize(reader); + + Console.WriteLine(deserializedProduct.Name); + // Carlos' Spicy Wieners + + + Assert.AreEqual("Carlos' Spicy Wieners", deserializedProduct.Name); + Assert.AreEqual(9.95m, deserializedProduct.Price); + Assert.AreEqual(3, deserializedProduct.Sizes.Length); + } + + [Test] + public void WriteOid() + { + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); + + byte[] oid = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; + + writer.WriteStartObject(); + writer.WritePropertyName("_oid"); + writer.WriteObjectId(oid); + writer.WriteEndObject(); + + string bson = BytesToHex(ms.ToArray()); + Assert.AreEqual("17-00-00-00-07-5F-6F-69-64-00-01-02-03-04-05-06-07-08-09-0A-0B-0C-00", bson); + + ms.Seek(0, SeekOrigin.Begin); + BsonReader reader = new BsonReader(ms); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Bytes, reader.TokenType); + CollectionAssert.AreEquivalent(oid, (byte[])reader.Value); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + } + + [Test] + public void WriteOidPlusContent() + { + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); + + writer.WriteStartObject(); + writer.WritePropertyName("_id"); + writer.WriteObjectId(HexToBytes("4ABBED9D1D8B0F0218000001")); + writer.WritePropertyName("test"); + writer.WriteValue("1234£56"); + writer.WriteEndObject(); + + byte[] expected = HexToBytes("29000000075F6964004ABBED9D1D8B0F02180000010274657374000900000031323334C2A335360000"); + + CollectionAssert.AreEquivalent(expected, ms.ToArray()); + } + + [Test] + public void WriteRegexPlusContent() + { + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); + + writer.WriteStartObject(); + writer.WritePropertyName("regex"); + writer.WriteRegex("abc", "i"); + writer.WritePropertyName("test"); + writer.WriteRegex(string.Empty, null); + writer.WriteEndObject(); + + byte[] expected = HexToBytes("1A-00-00-00-0B-72-65-67-65-78-00-61-62-63-00-69-00-0B-74-65-73-74-00-00-00-00"); + + CollectionAssert.AreEquivalent(expected, ms.ToArray()); + } + + [Test] + public void SerializeEmptyAndNullStrings() + { + Product p = new Product(); + p.ExpiryDate = DateTime.Parse("2009-04-05T14:45:00Z"); + p.Name = null; + p.Price = 9.95m; + p.Sizes = new[] { "Small", "", null }; + + MemoryStream ms = new MemoryStream(); + JsonSerializer serializer = new JsonSerializer(); + + BsonWriter writer = new BsonWriter(ms); + serializer.Serialize(writer, p); + + ms.Seek(0, SeekOrigin.Begin); + + BsonReader reader = new BsonReader(ms); + Product deserializedProduct = serializer.Deserialize(reader); + + Console.WriteLine(deserializedProduct.Name); + + Assert.AreEqual(null, deserializedProduct.Name); + Assert.AreEqual(9.95m, deserializedProduct.Price); + Assert.AreEqual(3, deserializedProduct.Sizes.Length); + Assert.AreEqual("Small", deserializedProduct.Sizes[0]); + Assert.AreEqual("", deserializedProduct.Sizes[1]); + Assert.AreEqual(null, deserializedProduct.Sizes[2]); + } + + [Test] + public void WriteReadEmptyAndNullStrings() + { + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); + + writer.WriteStartArray(); + writer.WriteValue("Content!"); + writer.WriteValue(""); + writer.WriteValue((string)null); + writer.WriteEndArray(); + + ms.Seek(0, SeekOrigin.Begin); + + BsonReader reader = new BsonReader(ms); + reader.ReadRootValueAsArray = true; + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("Content!", reader.Value); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("", reader.Value); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Null, reader.TokenType); + Assert.AreEqual(null, reader.Value); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + + Assert.IsFalse(reader.Read()); + } + + [Test] + public void WriteDateTimes() + { + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); + writer.DateTimeKindHandling = DateTimeKind.Unspecified; + + writer.WriteStartArray(); + writer.WriteValue(new DateTime(2000, 10, 12, 20, 55, 0, DateTimeKind.Utc)); + writer.WriteValue(new DateTime(2000, 10, 12, 20, 55, 0, DateTimeKind.Local)); + writer.WriteValue(new DateTime(2000, 10, 12, 20, 55, 0, DateTimeKind.Unspecified)); + writer.WriteEndArray(); + + ms.Seek(0, SeekOrigin.Begin); + + BsonReader reader = new BsonReader(ms); + reader.ReadRootValueAsArray = true; + reader.DateTimeKindHandling = DateTimeKind.Utc; + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Date, reader.TokenType); + Assert.AreEqual(new DateTime(2000, 10, 12, 20, 55, 0, DateTimeKind.Utc), reader.Value); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Date, reader.TokenType); + Assert.AreEqual(new DateTime(2000, 10, 12, 20, 55, 0, DateTimeKind.Utc), reader.Value); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Date, reader.TokenType); + Assert.AreEqual(new DateTime(2000, 10, 12, 20, 55, 0, DateTimeKind.Utc), reader.Value); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + + Assert.IsFalse(reader.Read()); + } + + [Test] + public void WriteValueOutsideOfObjectOrArray() + { + ExceptionAssert.Throws("Error writing String value. BSON must start with an Object or Array. Path ''.", + () => + { + MemoryStream stream = new MemoryStream(); + + using (BsonWriter writer = new BsonWriter(stream)) + { + writer.WriteValue("test"); + writer.Flush(); + } + }); + } + + [Test] + public void DateTimeZoneHandling() + { + MemoryStream ms = new MemoryStream(); + JsonWriter writer = new BsonWriter(ms) + { + DateTimeZoneHandling = Json.DateTimeZoneHandling.Utc + }; + + writer.WriteStartArray(); + writer.WriteValue(new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Unspecified)); + writer.WriteEndArray(); + + Assert.AreEqual("10-00-00-00-09-30-00-C8-88-07-6B-DC-00-00-00-00", (BitConverter.ToString(ms.ToArray()))); + } + + public class RegexTestClass + { + public Regex Regex { get; set; } + } + + [Test] + public void SerializeDeserializeRegex() + { + Regex r1 = new Regex("(hi)", RegexOptions.ExplicitCapture | RegexOptions.IgnoreCase); + RegexTestClass c = new RegexTestClass { Regex = r1 }; + + MemoryStream ms = new MemoryStream(); + JsonSerializer serializer = new JsonSerializer(); + + BsonWriter writer = new BsonWriter(ms); + serializer.Serialize(writer, c); + + string hex = BitConverter.ToString(ms.ToArray()); + + Assert.AreEqual("15-00-00-00-0B-52-65-67-65-78-00-28-68-69-29-00-69-75-78-00-00", hex); + + JObject o = (JObject)JObject.ReadFrom(new BsonReader(new MemoryStream(ms.ToArray()))); + + Console.WriteLine(o.ToString()); + //{ + // "Regex": "/(hi)/iux" + //} + } #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE || PORTABLE40) - [Test] - public void WriteBigInteger() - { - BigInteger i = BigInteger.Parse("1999999999999999999999999999999999999999999999999999999999990"); + [Test] + public void WriteBigInteger() + { + BigInteger i = BigInteger.Parse("1999999999999999999999999999999999999999999999999999999999990"); - MemoryStream ms = new MemoryStream(); - BsonWriter writer = new BsonWriter(ms); + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); - writer.WriteStartObject(); - writer.WritePropertyName("Blah"); - writer.WriteValue(i); - writer.WriteEndObject(); + writer.WriteStartObject(); + writer.WritePropertyName("Blah"); + writer.WriteValue(i); + writer.WriteEndObject(); - string bson = BytesToHex(ms.ToArray()); - Assert.AreEqual("2A-00-00-00-05-42-6C-61-68-00-1A-00-00-00-00-F6-FF-FF-FF-FF-FF-FF-1F-B2-21-CB-28-59-84-C4-AE-03-8A-44-34-2F-4C-4E-9E-3E-01-00", bson); + string bson = BytesToHex(ms.ToArray()); + Assert.AreEqual("2A-00-00-00-05-42-6C-61-68-00-1A-00-00-00-00-F6-FF-FF-FF-FF-FF-FF-1F-B2-21-CB-28-59-84-C4-AE-03-8A-44-34-2F-4C-4E-9E-3E-01-00", bson); - ms.Seek(0, SeekOrigin.Begin); - BsonReader reader = new BsonReader(ms); + ms.Seek(0, SeekOrigin.Begin); + BsonReader reader = new BsonReader(ms); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Bytes, reader.TokenType); - CollectionAssert.AreEqual(new byte[] { 246, 255, 255, 255, 255, 255, 255, 31, 178, 33, 203, 40, 89, 132, 196, 174, 3, 138, 68, 52, 47, 76, 78, 158, 62, 1 }, (byte[])reader.Value); - Assert.AreEqual(i, new BigInteger((byte[])reader.Value)); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Bytes, reader.TokenType); + CollectionAssert.AreEqual(new byte[] { 246, 255, 255, 255, 255, 255, 255, 31, 178, 33, 203, 40, 89, 132, 196, 174, 3, 138, 68, 52, 47, 76, 78, 158, 62, 1 }, (byte[])reader.Value); + Assert.AreEqual(i, new BigInteger((byte[])reader.Value)); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - Assert.IsFalse(reader.Read()); - } + Assert.IsFalse(reader.Read()); + } #endif - } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Converters/BinaryConverterTests.cs b/Src/Newtonsoft.Json.Tests/Converters/BinaryConverterTests.cs index 4e784976..759a503d 100644 --- a/Src/Newtonsoft.Json.Tests/Converters/BinaryConverterTests.cs +++ b/Src/Newtonsoft.Json.Tests/Converters/BinaryConverterTests.cs @@ -35,6 +35,7 @@ using System.Text; using Newtonsoft.Json.Converters; #if !NETFX_CORE using NUnit.Framework; + #else using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; @@ -43,151 +44,151 @@ using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAtt namespace Newtonsoft.Json.Tests.Converters { - [TestFixture] - public class BinaryConverterTests : TestFixtureBase - { - private static readonly byte[] TestData = Encoding.UTF8.GetBytes("This is some test data!!!"); - - public class ByteArrayClass + [TestFixture] + public class BinaryConverterTests : TestFixtureBase { - public byte[] ByteArray { get; set; } - public byte[] NullByteArray { get; set; } - } + private static readonly byte[] TestData = Encoding.UTF8.GetBytes("This is some test data!!!"); + + public class ByteArrayClass + { + public byte[] ByteArray { get; set; } + public byte[] NullByteArray { get; set; } + } #if !(SILVERLIGHT || NET20 || NETFX_CORE || PORTABLE || PORTABLE40) - [Test] - public void DeserializeBinaryClass() - { - string json = @"{ + [Test] + public void DeserializeBinaryClass() + { + string json = @"{ ""Binary"": ""VGhpcyBpcyBzb21lIHRlc3QgZGF0YSEhIQ=="", ""NullBinary"": null }"; - BinaryClass binaryClass = JsonConvert.DeserializeObject(json, new BinaryConverter()); + BinaryClass binaryClass = JsonConvert.DeserializeObject(json, new BinaryConverter()); - Assert.AreEqual(new Binary(TestData), binaryClass.Binary); - Assert.AreEqual(null, binaryClass.NullBinary); - } + Assert.AreEqual(new Binary(TestData), binaryClass.Binary); + Assert.AreEqual(null, binaryClass.NullBinary); + } - [Test] - public void DeserializeBinaryClassFromJsonArray() - { - string json = @"{ + [Test] + public void DeserializeBinaryClassFromJsonArray() + { + string json = @"{ ""Binary"": [0, 1, 2, 3], ""NullBinary"": null }"; - BinaryClass binaryClass = JsonConvert.DeserializeObject(json, new BinaryConverter()); + BinaryClass binaryClass = JsonConvert.DeserializeObject(json, new BinaryConverter()); - Assert.AreEqual(new byte[] { 0, 1, 2, 3 }, binaryClass.Binary.ToArray()); - Assert.AreEqual(null, binaryClass.NullBinary); - } + Assert.AreEqual(new byte[] { 0, 1, 2, 3 }, binaryClass.Binary.ToArray()); + Assert.AreEqual(null, binaryClass.NullBinary); + } - public class BinaryClass - { - public Binary Binary { get; set; } - public Binary NullBinary { get; set; } - } + public class BinaryClass + { + public Binary Binary { get; set; } + public Binary NullBinary { get; set; } + } - [Test] - public void SerializeBinaryClass() - { - BinaryClass binaryClass = new BinaryClass(); - binaryClass.Binary = new Binary(TestData); - binaryClass.NullBinary = null; + [Test] + public void SerializeBinaryClass() + { + BinaryClass binaryClass = new BinaryClass(); + binaryClass.Binary = new Binary(TestData); + binaryClass.NullBinary = null; - string json = JsonConvert.SerializeObject(binaryClass, Formatting.Indented, new BinaryConverter()); + string json = JsonConvert.SerializeObject(binaryClass, Formatting.Indented, new BinaryConverter()); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Binary"": ""VGhpcyBpcyBzb21lIHRlc3QgZGF0YSEhIQ=="", ""NullBinary"": null }", json); - } + } #endif - [Test] - public void SerializeByteArrayClass() - { - ByteArrayClass byteArrayClass = new ByteArrayClass(); - byteArrayClass.ByteArray = TestData; - byteArrayClass.NullByteArray = null; + [Test] + public void SerializeByteArrayClass() + { + ByteArrayClass byteArrayClass = new ByteArrayClass(); + byteArrayClass.ByteArray = TestData; + byteArrayClass.NullByteArray = null; - string json = JsonConvert.SerializeObject(byteArrayClass, Formatting.Indented); + string json = JsonConvert.SerializeObject(byteArrayClass, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""ByteArray"": ""VGhpcyBpcyBzb21lIHRlc3QgZGF0YSEhIQ=="", ""NullByteArray"": null }", json); - } + } #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - public class SqlBinaryClass - { - public SqlBinary SqlBinary { get; set; } - public SqlBinary? NullableSqlBinary1 { get; set; } - public SqlBinary? NullableSqlBinary2 { get; set; } - } + public class SqlBinaryClass + { + public SqlBinary SqlBinary { get; set; } + public SqlBinary? NullableSqlBinary1 { get; set; } + public SqlBinary? NullableSqlBinary2 { get; set; } + } - [Test] - public void SerializeSqlBinaryClass() - { - SqlBinaryClass sqlBinaryClass = new SqlBinaryClass(); - sqlBinaryClass.SqlBinary = new SqlBinary(TestData); - sqlBinaryClass.NullableSqlBinary1 = new SqlBinary(TestData); - sqlBinaryClass.NullableSqlBinary2 = null; + [Test] + public void SerializeSqlBinaryClass() + { + SqlBinaryClass sqlBinaryClass = new SqlBinaryClass(); + sqlBinaryClass.SqlBinary = new SqlBinary(TestData); + sqlBinaryClass.NullableSqlBinary1 = new SqlBinary(TestData); + sqlBinaryClass.NullableSqlBinary2 = null; - string json = JsonConvert.SerializeObject(sqlBinaryClass, Formatting.Indented, new BinaryConverter()); + string json = JsonConvert.SerializeObject(sqlBinaryClass, Formatting.Indented, new BinaryConverter()); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""SqlBinary"": ""VGhpcyBpcyBzb21lIHRlc3QgZGF0YSEhIQ=="", ""NullableSqlBinary1"": ""VGhpcyBpcyBzb21lIHRlc3QgZGF0YSEhIQ=="", ""NullableSqlBinary2"": null }", json); - } + } - [Test] - public void DeserializeSqlBinaryClass() - { - string json = @"{ + [Test] + public void DeserializeSqlBinaryClass() + { + string json = @"{ ""SqlBinary"": ""VGhpcyBpcyBzb21lIHRlc3QgZGF0YSEhIQ=="", ""NullableSqlBinary1"": ""VGhpcyBpcyBzb21lIHRlc3QgZGF0YSEhIQ=="", ""NullableSqlBinary2"": null }"; - SqlBinaryClass sqlBinaryClass = JsonConvert.DeserializeObject(json, new BinaryConverter()); + SqlBinaryClass sqlBinaryClass = JsonConvert.DeserializeObject(json, new BinaryConverter()); - Assert.AreEqual(new SqlBinary(TestData), sqlBinaryClass.SqlBinary); - Assert.AreEqual(new SqlBinary(TestData), sqlBinaryClass.NullableSqlBinary1); - Assert.AreEqual(null, sqlBinaryClass.NullableSqlBinary2); - } + Assert.AreEqual(new SqlBinary(TestData), sqlBinaryClass.SqlBinary); + Assert.AreEqual(new SqlBinary(TestData), sqlBinaryClass.NullableSqlBinary1); + Assert.AreEqual(null, sqlBinaryClass.NullableSqlBinary2); + } #endif - [Test] - public void DeserializeByteArrayClass() - { - string json = @"{ + [Test] + public void DeserializeByteArrayClass() + { + string json = @"{ ""ByteArray"": ""VGhpcyBpcyBzb21lIHRlc3QgZGF0YSEhIQ=="", ""NullByteArray"": null }"; - ByteArrayClass byteArrayClass = JsonConvert.DeserializeObject(json); + ByteArrayClass byteArrayClass = JsonConvert.DeserializeObject(json); - CollectionAssert.AreEquivalent(TestData, byteArrayClass.ByteArray); - Assert.AreEqual(null, byteArrayClass.NullByteArray); - } + CollectionAssert.AreEquivalent(TestData, byteArrayClass.ByteArray); + Assert.AreEqual(null, byteArrayClass.NullByteArray); + } - [Test] - public void DeserializeByteArrayFromJsonArray() - { - string json = @"{ + [Test] + public void DeserializeByteArrayFromJsonArray() + { + string json = @"{ ""ByteArray"": [0, 1, 2, 3], ""NullByteArray"": null }"; - ByteArrayClass c = JsonConvert.DeserializeObject(json); - Assert.IsNotNull(c.ByteArray); - Assert.AreEqual(4, c.ByteArray.Length); - CollectionAssert.AreEquivalent(new byte[] { 0, 1, 2, 3 }, c.ByteArray); + ByteArrayClass c = JsonConvert.DeserializeObject(json); + Assert.IsNotNull(c.ByteArray); + Assert.AreEqual(4, c.ByteArray.Length); + CollectionAssert.AreEquivalent(new byte[] { 0, 1, 2, 3 }, c.ByteArray); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Converters/CustomCreationConverterTests.cs b/Src/Newtonsoft.Json.Tests/Converters/CustomCreationConverterTests.cs index ed95a7f9..c79b8c87 100644 --- a/Src/Newtonsoft.Json.Tests/Converters/CustomCreationConverterTests.cs +++ b/Src/Newtonsoft.Json.Tests/Converters/CustomCreationConverterTests.cs @@ -28,6 +28,7 @@ using System.Collections.Generic; using Newtonsoft.Json.Converters; #if !NETFX_CORE using NUnit.Framework; + #else using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; @@ -36,200 +37,200 @@ using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAtt namespace Newtonsoft.Json.Tests.Converters { - [TestFixture] - public class CustomCreationConverterTests : TestFixtureBase - { - public interface IPerson + [TestFixture] + public class CustomCreationConverterTests : TestFixtureBase { - string FirstName { get; set; } - string LastName { get; set; } - DateTime BirthDate { get; set; } - } - - public class Employee : IPerson - { - public string FirstName { get; set; } - public string LastName { get; set; } - public DateTime BirthDate { get; set; } - - public string Department { get; set; } - public string JobTitle { get; set; } - } - - public class PersonConverter : CustomCreationConverter - { - public override IPerson Create(Type objectType) - { - return new Employee(); - } - } - - public void DeserializeObject() - { - string json = JsonConvert.SerializeObject(new List + public interface IPerson { - new Employee + string FirstName { get; set; } + string LastName { get; set; } + DateTime BirthDate { get; set; } + } + + public class Employee : IPerson + { + public string FirstName { get; set; } + public string LastName { get; set; } + public DateTime BirthDate { get; set; } + + public string Department { get; set; } + public string JobTitle { get; set; } + } + + public class PersonConverter : CustomCreationConverter + { + public override IPerson Create(Type objectType) { - BirthDate = new DateTime(1977, 12, 30, 1, 1, 1, DateTimeKind.Utc), - FirstName = "Maurice", - LastName = "Moss", - Department = "IT", - JobTitle = "Support" - }, - new Employee - { - BirthDate = new DateTime(1978, 3, 15, 1, 1, 1, DateTimeKind.Utc), - FirstName = "Jen", - LastName = "Barber", - Department = "IT", - JobTitle = "Manager" + return new Employee(); } - }, Formatting.Indented); + } - //[ - // { - // "FirstName": "Maurice", - // "LastName": "Moss", - // "BirthDate": "\/Date(252291661000)\/", - // "Department": "IT", - // "JobTitle": "Support" - // }, - // { - // "FirstName": "Jen", - // "LastName": "Barber", - // "BirthDate": "\/Date(258771661000)\/", - // "Department": "IT", - // "JobTitle": "Manager" - // } - //] + public void DeserializeObject() + { + string json = JsonConvert.SerializeObject(new List + { + new Employee + { + BirthDate = new DateTime(1977, 12, 30, 1, 1, 1, DateTimeKind.Utc), + FirstName = "Maurice", + LastName = "Moss", + Department = "IT", + JobTitle = "Support" + }, + new Employee + { + BirthDate = new DateTime(1978, 3, 15, 1, 1, 1, DateTimeKind.Utc), + FirstName = "Jen", + LastName = "Barber", + Department = "IT", + JobTitle = "Manager" + } + }, Formatting.Indented); - List people = JsonConvert.DeserializeObject>(json, new PersonConverter()); + //[ + // { + // "FirstName": "Maurice", + // "LastName": "Moss", + // "BirthDate": "\/Date(252291661000)\/", + // "Department": "IT", + // "JobTitle": "Support" + // }, + // { + // "FirstName": "Jen", + // "LastName": "Barber", + // "BirthDate": "\/Date(258771661000)\/", + // "Department": "IT", + // "JobTitle": "Manager" + // } + //] - IPerson person = people[0]; + List people = JsonConvert.DeserializeObject>(json, new PersonConverter()); - Console.WriteLine(person.GetType()); - // Newtonsoft.Json.Tests.Employee + IPerson person = people[0]; - Console.WriteLine(person.FirstName); - // Maurice + Console.WriteLine(person.GetType()); + // Newtonsoft.Json.Tests.Employee - Employee employee = (Employee)person; + Console.WriteLine(person.FirstName); + // Maurice - Console.WriteLine(employee.JobTitle); - // Support - } + Employee employee = (Employee)person; - public class MyClass - { - public string Value { get; set; } + Console.WriteLine(employee.JobTitle); + // Support + } - [JsonConverter(typeof(MyThingConverter))] - public IThing Thing { get; set; } - } + public class MyClass + { + public string Value { get; set; } - public interface IThing - { - int Number { get; } - } + [JsonConverter(typeof(MyThingConverter))] + public IThing Thing { get; set; } + } - public class MyThing : IThing - { - public int Number { get; set; } - } + public interface IThing + { + int Number { get; } + } - public class MyThingConverter : CustomCreationConverter - { - public override IThing Create(Type objectType) - { - return new MyThing(); - } - } + public class MyThing : IThing + { + public int Number { get; set; } + } - [Test] - public void AssertDoesDeserialize() - { - const string json = @"{ + public class MyThingConverter : CustomCreationConverter + { + public override IThing Create(Type objectType) + { + return new MyThing(); + } + } + + [Test] + public void AssertDoesDeserialize() + { + const string json = @"{ ""Value"": ""A value"", ""Thing"": { ""Number"": 123 } } "; - MyClass myClass = JsonConvert.DeserializeObject(json); - Assert.IsNotNull(myClass); - Assert.AreEqual("A value", myClass.Value); - Assert.IsNotNull(myClass.Thing); - Assert.AreEqual(123, myClass.Thing.Number); - } + MyClass myClass = JsonConvert.DeserializeObject(json); + Assert.IsNotNull(myClass); + Assert.AreEqual("A value", myClass.Value); + Assert.IsNotNull(myClass.Thing); + Assert.AreEqual(123, myClass.Thing.Number); + } - [Test] - public void AssertShouldSerializeTest() - { - MyClass myClass = new MyClass - { - Value = "Foo", - Thing = new MyThing { Number = 456, } - }; - string json = JsonConvert.SerializeObject(myClass); // <-- Exception here + [Test] + public void AssertShouldSerializeTest() + { + MyClass myClass = new MyClass + { + Value = "Foo", + Thing = new MyThing { Number = 456, } + }; + string json = JsonConvert.SerializeObject(myClass); // <-- Exception here - const string expected = @"{""Value"":""Foo"",""Thing"":{""Number"":456}}"; - Assert.AreEqual(expected, json); - } + const string expected = @"{""Value"":""Foo"",""Thing"":{""Number"":456}}"; + Assert.AreEqual(expected, json); + } - internal interface IRange - { - T First { get; } - T Last { get; } - } + internal interface IRange + { + T First { get; } + T Last { get; } + } - internal class Range : IRange - { - public T First { get; set; } - public T Last { get; set; } - } + internal class Range : IRange + { + public T First { get; set; } + public T Last { get; set; } + } - internal class NullInterfaceTestClass - { - public virtual Guid Id { get; set; } - public virtual int? Year { get; set; } - public virtual string Company { get; set; } - public virtual IRange DecimalRange { get; set; } - public virtual IRange IntRange { get; set; } - public virtual IRange NullDecimalRange { get; set; } - } + internal class NullInterfaceTestClass + { + public virtual Guid Id { get; set; } + public virtual int? Year { get; set; } + public virtual string Company { get; set; } + public virtual IRange DecimalRange { get; set; } + public virtual IRange IntRange { get; set; } + public virtual IRange NullDecimalRange { get; set; } + } - internal class DecimalRangeConverter : CustomCreationConverter> - { - public override IRange Create(Type objectType) - { - return new Range(); - } - } + internal class DecimalRangeConverter : CustomCreationConverter> + { + public override IRange Create(Type objectType) + { + return new Range(); + } + } - internal class IntRangeConverter : CustomCreationConverter> - { - public override IRange Create(Type objectType) - { - return new Range(); - } - } + internal class IntRangeConverter : CustomCreationConverter> + { + public override IRange Create(Type objectType) + { + return new Range(); + } + } - [Test] - public void DeserializeAndConvertNullValue() - { - NullInterfaceTestClass initial = new NullInterfaceTestClass - { - Company = "Company!", - DecimalRange = new Range { First = 0, Last = 1 }, - Id = new Guid(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), - IntRange = new Range { First = int.MinValue, Last = int.MaxValue }, - Year = 2010, - NullDecimalRange = null - }; + [Test] + public void DeserializeAndConvertNullValue() + { + NullInterfaceTestClass initial = new NullInterfaceTestClass + { + Company = "Company!", + DecimalRange = new Range { First = 0, Last = 1 }, + Id = new Guid(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), + IntRange = new Range { First = int.MinValue, Last = int.MaxValue }, + Year = 2010, + NullDecimalRange = null + }; - string json = JsonConvert.SerializeObject(initial, Formatting.Indented); + string json = JsonConvert.SerializeObject(initial, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Id"": ""00000001-0002-0003-0405-060708090a0b"", ""Year"": 2010, ""Company"": ""Company!"", @@ -244,17 +245,17 @@ namespace Newtonsoft.Json.Tests.Converters ""NullDecimalRange"": null }", json); - NullInterfaceTestClass deserialized = JsonConvert.DeserializeObject( - json, new IntRangeConverter(), new DecimalRangeConverter()); + NullInterfaceTestClass deserialized = JsonConvert.DeserializeObject( + json, new IntRangeConverter(), new DecimalRangeConverter()); - Assert.AreEqual("Company!", deserialized.Company); - Assert.AreEqual(new Guid(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), deserialized.Id); - Assert.AreEqual(0, deserialized.DecimalRange.First); - Assert.AreEqual(1, deserialized.DecimalRange.Last); - Assert.AreEqual(int.MinValue, deserialized.IntRange.First); - Assert.AreEqual(int.MaxValue, deserialized.IntRange.Last); - Assert.AreEqual(null, deserialized.NullDecimalRange); - Assert.AreEqual(2010, deserialized.Year); + Assert.AreEqual("Company!", deserialized.Company); + Assert.AreEqual(new Guid(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), deserialized.Id); + Assert.AreEqual(0, deserialized.DecimalRange.First); + Assert.AreEqual(1, deserialized.DecimalRange.Last); + Assert.AreEqual(int.MinValue, deserialized.IntRange.First); + Assert.AreEqual(int.MaxValue, deserialized.IntRange.Last); + Assert.AreEqual(null, deserialized.NullDecimalRange); + Assert.AreEqual(2010, deserialized.Year); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Converters/DataSetConverterTests.cs b/Src/Newtonsoft.Json.Tests/Converters/DataSetConverterTests.cs index 6eb33c8c..a46753e9 100644 --- a/Src/Newtonsoft.Json.Tests/Converters/DataSetConverterTests.cs +++ b/Src/Newtonsoft.Json.Tests/Converters/DataSetConverterTests.cs @@ -39,34 +39,34 @@ using System.Data; namespace Newtonsoft.Json.Tests.Converters { - public class DataSetConverterTests : TestFixtureBase - { - [Test] - public void SerializeAndDeserialize() + public class DataSetConverterTests : TestFixtureBase { - DataSet dataSet = new DataSet("dataSet"); - dataSet.Namespace = "NetFrameWork"; - DataTable table = new DataTable(); - DataColumn idColumn = new DataColumn("id", typeof(int)); - idColumn.AutoIncrement = true; + [Test] + public void SerializeAndDeserialize() + { + DataSet dataSet = new DataSet("dataSet"); + dataSet.Namespace = "NetFrameWork"; + DataTable table = new DataTable(); + DataColumn idColumn = new DataColumn("id", typeof(int)); + idColumn.AutoIncrement = true; - DataColumn itemColumn = new DataColumn("item"); - table.Columns.Add(idColumn); - table.Columns.Add(itemColumn); - dataSet.Tables.Add(table); + DataColumn itemColumn = new DataColumn("item"); + table.Columns.Add(idColumn); + table.Columns.Add(itemColumn); + dataSet.Tables.Add(table); - for (int i = 0; i < 2; i++) - { - DataRow newRow = table.NewRow(); - newRow["item"] = "item " + i; - table.Rows.Add(newRow); - } + for (int i = 0; i < 2; i++) + { + DataRow newRow = table.NewRow(); + newRow["item"] = "item " + i; + table.Rows.Add(newRow); + } - dataSet.AcceptChanges(); + dataSet.AcceptChanges(); - string json = JsonConvert.SerializeObject(dataSet, Formatting.Indented); - - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(dataSet, Formatting.Indented); + + Assert.AreEqual(@"{ ""Table1"": [ { ""id"": 0, @@ -79,65 +79,65 @@ namespace Newtonsoft.Json.Tests.Converters ] }", json); - DataSet deserializedDataSet = JsonConvert.DeserializeObject(json); - Assert.IsNotNull(deserializedDataSet); + DataSet deserializedDataSet = JsonConvert.DeserializeObject(json); + Assert.IsNotNull(deserializedDataSet); - Assert.AreEqual(1, deserializedDataSet.Tables.Count); + Assert.AreEqual(1, deserializedDataSet.Tables.Count); - DataTable dt = deserializedDataSet.Tables[0]; + DataTable dt = deserializedDataSet.Tables[0]; - Assert.AreEqual("Table1", dt.TableName); - Assert.AreEqual(2, dt.Columns.Count); - Assert.AreEqual("id", dt.Columns[0].ColumnName); - Assert.AreEqual(typeof(long), dt.Columns[0].DataType); - Assert.AreEqual("item", dt.Columns[1].ColumnName); - Assert.AreEqual(typeof(string), dt.Columns[1].DataType); + Assert.AreEqual("Table1", dt.TableName); + Assert.AreEqual(2, dt.Columns.Count); + Assert.AreEqual("id", dt.Columns[0].ColumnName); + Assert.AreEqual(typeof(long), dt.Columns[0].DataType); + Assert.AreEqual("item", dt.Columns[1].ColumnName); + Assert.AreEqual(typeof(string), dt.Columns[1].DataType); - Assert.AreEqual(2, dt.Rows.Count); - } + Assert.AreEqual(2, dt.Rows.Count); + } - [Test] - public void SerializeMultiTableDataSet() - { - DataSet ds = new DataSet(); - ds.Tables.Add(CreateDataTable("FirstTable", 2)); - ds.Tables.Add(CreateDataTable("SecondTable", 1)); + [Test] + public void SerializeMultiTableDataSet() + { + DataSet ds = new DataSet(); + ds.Tables.Add(CreateDataTable("FirstTable", 2)); + ds.Tables.Add(CreateDataTable("SecondTable", 1)); - string json = JsonConvert.SerializeObject(ds, Formatting.Indented, new IsoDateTimeConverter()); - // { - // "FirstTable": [ - // { - // "StringCol": "Item Name", - // "Int32Col": 1, - // "BooleanCol": true, - // "TimeSpanCol": "10.22:10:15.1000000", - // "DateTimeCol": "2000-12-29T00:00:00Z", - // "DecimalCol": 64.0021 - // }, - // { - // "StringCol": "Item Name", - // "Int32Col": 2, - // "BooleanCol": true, - // "TimeSpanCol": "10.22:10:15.1000000", - // "DateTimeCol": "2000-12-29T00:00:00Z", - // "DecimalCol": 64.0021 - // } - // ], - // "SecondTable": [ - // { - // "StringCol": "Item Name", - // "Int32Col": 1, - // "BooleanCol": true, - // "TimeSpanCol": "10.22:10:15.1000000", - // "DateTimeCol": "2000-12-29T00:00:00Z", - // "DecimalCol": 64.0021 - // } - // ] - // } + string json = JsonConvert.SerializeObject(ds, Formatting.Indented, new IsoDateTimeConverter()); + // { + // "FirstTable": [ + // { + // "StringCol": "Item Name", + // "Int32Col": 1, + // "BooleanCol": true, + // "TimeSpanCol": "10.22:10:15.1000000", + // "DateTimeCol": "2000-12-29T00:00:00Z", + // "DecimalCol": 64.0021 + // }, + // { + // "StringCol": "Item Name", + // "Int32Col": 2, + // "BooleanCol": true, + // "TimeSpanCol": "10.22:10:15.1000000", + // "DateTimeCol": "2000-12-29T00:00:00Z", + // "DecimalCol": 64.0021 + // } + // ], + // "SecondTable": [ + // { + // "StringCol": "Item Name", + // "Int32Col": 1, + // "BooleanCol": true, + // "TimeSpanCol": "10.22:10:15.1000000", + // "DateTimeCol": "2000-12-29T00:00:00Z", + // "DecimalCol": 64.0021 + // } + // ] + // } - DataSet deserializedDs = JsonConvert.DeserializeObject(json, new IsoDateTimeConverter()); + DataSet deserializedDs = JsonConvert.DeserializeObject(json, new IsoDateTimeConverter()); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""FirstTable"": [ { ""StringCol"": ""Item Name"", @@ -168,14 +168,13 @@ namespace Newtonsoft.Json.Tests.Converters ] }", json); - Assert.IsNotNull(deserializedDs); + Assert.IsNotNull(deserializedDs); + } - } - - [Test] - public void DeserializeMultiTableDataSet() - { - string json = @"{ + [Test] + public void DeserializeMultiTableDataSet() + { + string json = @"{ ""FirstTable"": [ { ""StringCol"": ""Item Name"", @@ -198,100 +197,100 @@ namespace Newtonsoft.Json.Tests.Converters ] }"; - DataSet ds = JsonConvert.DeserializeObject(json); - Assert.IsNotNull(ds); + DataSet ds = JsonConvert.DeserializeObject(json); + Assert.IsNotNull(ds); - Assert.AreEqual(2, ds.Tables.Count); - Assert.AreEqual("FirstTable", ds.Tables[0].TableName); - Assert.AreEqual("SecondTable", ds.Tables[1].TableName); + Assert.AreEqual(2, ds.Tables.Count); + Assert.AreEqual("FirstTable", ds.Tables[0].TableName); + Assert.AreEqual("SecondTable", ds.Tables[1].TableName); - DataTable dt = ds.Tables[0]; - Assert.AreEqual("StringCol", dt.Columns[0].ColumnName); - Assert.AreEqual(typeof(string), dt.Columns[0].DataType); - Assert.AreEqual("Int32Col", dt.Columns[1].ColumnName); - Assert.AreEqual(typeof(long), dt.Columns[1].DataType); - Assert.AreEqual("BooleanCol", dt.Columns[2].ColumnName); - Assert.AreEqual(typeof(bool), dt.Columns[2].DataType); - Assert.AreEqual("TimeSpanCol", dt.Columns[3].ColumnName); - Assert.AreEqual(typeof(string), dt.Columns[3].DataType); - Assert.AreEqual("DateTimeCol", dt.Columns[4].ColumnName); - Assert.AreEqual(typeof(DateTime), dt.Columns[4].DataType); - Assert.AreEqual("DecimalCol", dt.Columns[5].ColumnName); - Assert.AreEqual(typeof(double), dt.Columns[5].DataType); + DataTable dt = ds.Tables[0]; + Assert.AreEqual("StringCol", dt.Columns[0].ColumnName); + Assert.AreEqual(typeof(string), dt.Columns[0].DataType); + Assert.AreEqual("Int32Col", dt.Columns[1].ColumnName); + Assert.AreEqual(typeof(long), dt.Columns[1].DataType); + Assert.AreEqual("BooleanCol", dt.Columns[2].ColumnName); + Assert.AreEqual(typeof(bool), dt.Columns[2].DataType); + Assert.AreEqual("TimeSpanCol", dt.Columns[3].ColumnName); + Assert.AreEqual(typeof(string), dt.Columns[3].DataType); + Assert.AreEqual("DateTimeCol", dt.Columns[4].ColumnName); + Assert.AreEqual(typeof(DateTime), dt.Columns[4].DataType); + Assert.AreEqual("DecimalCol", dt.Columns[5].ColumnName); + Assert.AreEqual(typeof(double), dt.Columns[5].DataType); - Assert.AreEqual(1, ds.Tables[0].Rows.Count); - Assert.AreEqual(1, ds.Tables[1].Rows.Count); - } + Assert.AreEqual(1, ds.Tables[0].Rows.Count); + Assert.AreEqual(1, ds.Tables[1].Rows.Count); + } - private DataTable CreateDataTable(string dataTableName, int rows) - { - // create a new DataTable. - DataTable myTable = new DataTable(dataTableName); - - // create DataColumn objects of data types. - DataColumn colString = new DataColumn("StringCol"); - colString.DataType = typeof(string); - myTable.Columns.Add(colString); - - DataColumn colInt32 = new DataColumn("Int32Col"); - colInt32.DataType = typeof(int); - myTable.Columns.Add(colInt32); - - DataColumn colBoolean = new DataColumn("BooleanCol"); - colBoolean.DataType = typeof(bool); - myTable.Columns.Add(colBoolean); - - DataColumn colTimeSpan = new DataColumn("TimeSpanCol"); - colTimeSpan.DataType = typeof(TimeSpan); - myTable.Columns.Add(colTimeSpan); - - DataColumn colDateTime = new DataColumn("DateTimeCol"); - colDateTime.DataType = typeof(DateTime); - colDateTime.DateTimeMode = DataSetDateTime.Utc; - myTable.Columns.Add(colDateTime); - - DataColumn colDecimal = new DataColumn("DecimalCol"); - colDecimal.DataType = typeof(decimal); - myTable.Columns.Add(colDecimal); - - for (int i = 1; i <= rows; i++) - { - DataRow myNewRow = myTable.NewRow(); - - myNewRow["StringCol"] = "Item Name"; - myNewRow["Int32Col"] = i; - myNewRow["BooleanCol"] = true; - myNewRow["TimeSpanCol"] = new TimeSpan(10, 22, 10, 15, 100); - myNewRow["DateTimeCol"] = new DateTime(2000, 12, 29, 0, 0, 0, DateTimeKind.Utc); - myNewRow["DecimalCol"] = 64.0021; - myTable.Rows.Add(myNewRow); - } - - return myTable; - } - - public class DataSetAndTableTestClass - { - public string Before { get; set; } - public DataSet Set { get; set; } - public string Middle { get; set; } - public DataTable Table { get; set; } - public string After { get; set; } - } - - [Test] - public void SerializeWithCamelCaseResolver() - { - DataSet ds = new DataSet(); - ds.Tables.Add(CreateDataTable("FirstTable", 2)); - ds.Tables.Add(CreateDataTable("SecondTable", 1)); - - string json = JsonConvert.SerializeObject(ds, Formatting.Indented, new JsonSerializerSettings + private DataTable CreateDataTable(string dataTableName, int rows) { - ContractResolver = new CamelCasePropertyNamesContractResolver() - }); + // create a new DataTable. + DataTable myTable = new DataTable(dataTableName); - Assert.AreEqual(@"{ + // create DataColumn objects of data types. + DataColumn colString = new DataColumn("StringCol"); + colString.DataType = typeof(string); + myTable.Columns.Add(colString); + + DataColumn colInt32 = new DataColumn("Int32Col"); + colInt32.DataType = typeof(int); + myTable.Columns.Add(colInt32); + + DataColumn colBoolean = new DataColumn("BooleanCol"); + colBoolean.DataType = typeof(bool); + myTable.Columns.Add(colBoolean); + + DataColumn colTimeSpan = new DataColumn("TimeSpanCol"); + colTimeSpan.DataType = typeof(TimeSpan); + myTable.Columns.Add(colTimeSpan); + + DataColumn colDateTime = new DataColumn("DateTimeCol"); + colDateTime.DataType = typeof(DateTime); + colDateTime.DateTimeMode = DataSetDateTime.Utc; + myTable.Columns.Add(colDateTime); + + DataColumn colDecimal = new DataColumn("DecimalCol"); + colDecimal.DataType = typeof(decimal); + myTable.Columns.Add(colDecimal); + + for (int i = 1; i <= rows; i++) + { + DataRow myNewRow = myTable.NewRow(); + + myNewRow["StringCol"] = "Item Name"; + myNewRow["Int32Col"] = i; + myNewRow["BooleanCol"] = true; + myNewRow["TimeSpanCol"] = new TimeSpan(10, 22, 10, 15, 100); + myNewRow["DateTimeCol"] = new DateTime(2000, 12, 29, 0, 0, 0, DateTimeKind.Utc); + myNewRow["DecimalCol"] = 64.0021; + myTable.Rows.Add(myNewRow); + } + + return myTable; + } + + public class DataSetAndTableTestClass + { + public string Before { get; set; } + public DataSet Set { get; set; } + public string Middle { get; set; } + public DataTable Table { get; set; } + public string After { get; set; } + } + + [Test] + public void SerializeWithCamelCaseResolver() + { + DataSet ds = new DataSet(); + ds.Tables.Add(CreateDataTable("FirstTable", 2)); + ds.Tables.Add(CreateDataTable("SecondTable", 1)); + + string json = JsonConvert.SerializeObject(ds, Formatting.Indented, new JsonSerializerSettings + { + ContractResolver = new CamelCasePropertyNamesContractResolver() + }); + + Assert.AreEqual(@"{ ""firstTable"": [ { ""stringCol"": ""Item Name"", @@ -321,27 +320,27 @@ namespace Newtonsoft.Json.Tests.Converters } ] }", json); - } + } - [Test] - public void SerializeDataSetProperty() - { - DataSet ds = new DataSet(); - ds.Tables.Add(CreateDataTable("FirstTable", 2)); - ds.Tables.Add(CreateDataTable("SecondTable", 1)); - - DataSetAndTableTestClass c = new DataSetAndTableTestClass + [Test] + public void SerializeDataSetProperty() { - Before = "Before", - Set = ds, - Middle = "Middle", - Table = CreateDataTable("LoneTable", 2), - After = "After" - }; + DataSet ds = new DataSet(); + ds.Tables.Add(CreateDataTable("FirstTable", 2)); + ds.Tables.Add(CreateDataTable("SecondTable", 1)); - string json = JsonConvert.SerializeObject(c, Formatting.Indented, new IsoDateTimeConverter()); + DataSetAndTableTestClass c = new DataSetAndTableTestClass + { + Before = "Before", + Set = ds, + Middle = "Middle", + Table = CreateDataTable("LoneTable", 2), + After = "After" + }; - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(c, Formatting.Indented, new IsoDateTimeConverter()); + + Assert.AreEqual(@"{ ""Before"": ""Before"", ""Set"": { ""FirstTable"": [ @@ -395,24 +394,24 @@ namespace Newtonsoft.Json.Tests.Converters ""After"": ""After"" }", json); - DataSetAndTableTestClass c2 = JsonConvert.DeserializeObject(json, new IsoDateTimeConverter()); + DataSetAndTableTestClass c2 = JsonConvert.DeserializeObject(json, new IsoDateTimeConverter()); - Assert.AreEqual(c.Before, c2.Before); - Assert.AreEqual(c.Set.Tables.Count, c2.Set.Tables.Count); - Assert.AreEqual(c.Middle, c2.Middle); - Assert.AreEqual(c.Table.Rows.Count, c2.Table.Rows.Count); - Assert.AreEqual(c.After, c2.After); - } + Assert.AreEqual(c.Before, c2.Before); + Assert.AreEqual(c.Set.Tables.Count, c2.Set.Tables.Count); + Assert.AreEqual(c.Middle, c2.Middle); + Assert.AreEqual(c.Table.Rows.Count, c2.Table.Rows.Count); + Assert.AreEqual(c.After, c2.After); + } - [Test] - public void SerializedTypedDataSet() - { - CustomerDataSet ds = new CustomerDataSet(); - ds.Customers.AddCustomersRow("234"); + [Test] + public void SerializedTypedDataSet() + { + CustomerDataSet ds = new CustomerDataSet(); + ds.Customers.AddCustomersRow("234"); - string json = JsonConvert.SerializeObject(ds, Formatting.Indented); + string json = JsonConvert.SerializeObject(ds, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Customers"": [ { ""CustomerID"": ""234"" @@ -420,39 +419,40 @@ namespace Newtonsoft.Json.Tests.Converters ] }", json); - CustomerDataSet ds1 = new CustomerDataSet(); - DataTable table = ds1.Tables["Customers"]; - DataRow row = ds1.Tables["Customers"].NewRow(); - row["CustomerID"] = "234"; + CustomerDataSet ds1 = new CustomerDataSet(); + DataTable table = ds1.Tables["Customers"]; + DataRow row = ds1.Tables["Customers"].NewRow(); + row["CustomerID"] = "234"; - table.Rows.Add(row); + table.Rows.Add(row); - string json1 = JsonConvert.SerializeObject(ds1, Formatting.Indented); + string json1 = JsonConvert.SerializeObject(ds1, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Customers"": [ { ""CustomerID"": ""234"" } ] }", json1); - } + } - [Test] - public void DeserializedTypedDataSet() - { - string json = @"{ + [Test] + public void DeserializedTypedDataSet() + { + string json = @"{ ""Customers"": [ { ""CustomerID"": ""234"" } ] }"; - - var ds = JsonConvert.DeserializeObject(json); - Assert.AreEqual("234", ds.Customers[0].CustomerID); + var ds = JsonConvert.DeserializeObject(json); + + Assert.AreEqual("234", ds.Customers[0].CustomerID); + } } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Converters/DataTableConverterTests.cs b/Src/Newtonsoft.Json.Tests/Converters/DataTableConverterTests.cs index e2163c14..45c31b4f 100644 --- a/Src/Newtonsoft.Json.Tests/Converters/DataTableConverterTests.cs +++ b/Src/Newtonsoft.Json.Tests/Converters/DataTableConverterTests.cs @@ -40,12 +40,12 @@ using Newtonsoft.Json.Tests.TestObjects; namespace Newtonsoft.Json.Tests.Converters { - public class DataTableConverterTests : TestFixtureBase - { - [Test] - public void Deserialize() + public class DataTableConverterTests : TestFixtureBase { - string json = @"[ + [Test] + public void Deserialize() + { + string json = @"[ { ""id"": 0, ""item"": ""item 0"" @@ -56,72 +56,72 @@ namespace Newtonsoft.Json.Tests.Converters } ]"; - DataTable deserializedDataTable = JsonConvert.DeserializeObject(json); - Assert.IsNotNull(deserializedDataTable); + DataTable deserializedDataTable = JsonConvert.DeserializeObject(json); + Assert.IsNotNull(deserializedDataTable); - Assert.AreEqual(string.Empty, deserializedDataTable.TableName); - Assert.AreEqual(2, deserializedDataTable.Columns.Count); - Assert.AreEqual("id", deserializedDataTable.Columns[0].ColumnName); - Assert.AreEqual(typeof(long), deserializedDataTable.Columns[0].DataType); - Assert.AreEqual("item", deserializedDataTable.Columns[1].ColumnName); - Assert.AreEqual(typeof(string), deserializedDataTable.Columns[1].DataType); + Assert.AreEqual(string.Empty, deserializedDataTable.TableName); + Assert.AreEqual(2, deserializedDataTable.Columns.Count); + Assert.AreEqual("id", deserializedDataTable.Columns[0].ColumnName); + Assert.AreEqual(typeof(long), deserializedDataTable.Columns[0].DataType); + Assert.AreEqual("item", deserializedDataTable.Columns[1].ColumnName); + Assert.AreEqual(typeof(string), deserializedDataTable.Columns[1].DataType); - Assert.AreEqual(2, deserializedDataTable.Rows.Count); + Assert.AreEqual(2, deserializedDataTable.Rows.Count); - DataRow dr1 = deserializedDataTable.Rows[0]; - Assert.AreEqual(0, dr1["id"]); - Assert.AreEqual("item 0", dr1["item"]); + DataRow dr1 = deserializedDataTable.Rows[0]; + Assert.AreEqual(0, dr1["id"]); + Assert.AreEqual("item 0", dr1["item"]); - DataRow dr2 = deserializedDataTable.Rows[1]; - Assert.AreEqual(1, dr2["id"]); - Assert.AreEqual("item 1", dr2["item"]); - } + DataRow dr2 = deserializedDataTable.Rows[1]; + Assert.AreEqual(1, dr2["id"]); + Assert.AreEqual("item 1", dr2["item"]); + } - [Test] - public void Serialize() - { - // create a new DataTable. - DataTable myTable = new DataTable("blah"); + [Test] + public void Serialize() + { + // create a new DataTable. + DataTable myTable = new DataTable("blah"); - // create DataColumn objects of data types. - DataColumn colString = new DataColumn("StringCol"); - colString.DataType = typeof(string); - myTable.Columns.Add(colString); + // create DataColumn objects of data types. + DataColumn colString = new DataColumn("StringCol"); + colString.DataType = typeof(string); + myTable.Columns.Add(colString); - DataColumn colInt32 = new DataColumn("Int32Col"); - colInt32.DataType = typeof(int); - myTable.Columns.Add(colInt32); + DataColumn colInt32 = new DataColumn("Int32Col"); + colInt32.DataType = typeof(int); + myTable.Columns.Add(colInt32); - DataColumn colBoolean = new DataColumn("BooleanCol"); - colBoolean.DataType = typeof(bool); - myTable.Columns.Add(colBoolean); + DataColumn colBoolean = new DataColumn("BooleanCol"); + colBoolean.DataType = typeof(bool); + myTable.Columns.Add(colBoolean); - DataColumn colTimeSpan = new DataColumn("TimeSpanCol"); - colTimeSpan.DataType = typeof(TimeSpan); - myTable.Columns.Add(colTimeSpan); + DataColumn colTimeSpan = new DataColumn("TimeSpanCol"); + colTimeSpan.DataType = typeof(TimeSpan); + myTable.Columns.Add(colTimeSpan); - DataColumn colDateTime = new DataColumn("DateTimeCol"); - colDateTime.DataType = typeof(DateTime); - colDateTime.DateTimeMode = DataSetDateTime.Utc; - myTable.Columns.Add(colDateTime); + DataColumn colDateTime = new DataColumn("DateTimeCol"); + colDateTime.DataType = typeof(DateTime); + colDateTime.DateTimeMode = DataSetDateTime.Utc; + myTable.Columns.Add(colDateTime); - DataColumn colDecimal = new DataColumn("DecimalCol"); - colDecimal.DataType = typeof(decimal); - myTable.Columns.Add(colDecimal); + DataColumn colDecimal = new DataColumn("DecimalCol"); + colDecimal.DataType = typeof(decimal); + myTable.Columns.Add(colDecimal); - // populate one row with values. - DataRow myNewRow = myTable.NewRow(); + // populate one row with values. + DataRow myNewRow = myTable.NewRow(); - myNewRow["StringCol"] = "Item Name"; - myNewRow["Int32Col"] = 2147483647; - myNewRow["BooleanCol"] = true; - myNewRow["TimeSpanCol"] = new TimeSpan(10, 22, 10, 15, 100); - myNewRow["DateTimeCol"] = new DateTime(2000, 12, 29, 0, 0, 0, DateTimeKind.Utc); - myNewRow["DecimalCol"] = 64.0021; - myTable.Rows.Add(myNewRow); + myNewRow["StringCol"] = "Item Name"; + myNewRow["Int32Col"] = 2147483647; + myNewRow["BooleanCol"] = true; + myNewRow["TimeSpanCol"] = new TimeSpan(10, 22, 10, 15, 100); + myNewRow["DateTimeCol"] = new DateTime(2000, 12, 29, 0, 0, 0, DateTimeKind.Utc); + myNewRow["DecimalCol"] = 64.0021; + myTable.Rows.Add(myNewRow); - string json = JsonConvert.SerializeObject(myTable, Formatting.Indented); - Assert.AreEqual(@"[ + string json = JsonConvert.SerializeObject(myTable, Formatting.Indented); + Assert.AreEqual(@"[ { ""StringCol"": ""Item Name"", ""Int32Col"": 2147483647, @@ -131,131 +131,131 @@ namespace Newtonsoft.Json.Tests.Converters ""DecimalCol"": 64.0021 } ]", json); - } + } - public class TestDataTableConverter : JsonConverter - { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - DataTable d = (DataTable)value; - writer.WriteValue(d.TableName); - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - //reader.Read(); - DataTable d = new DataTable((string)reader.Value); - - return d; - } - - public override bool CanConvert(Type objectType) - { - return (objectType == typeof(DataTable)); - } - } - - [Test] - public void PassedInJsonConverterOverridesInternalConverter() - { - DataTable t1 = new DataTable("Custom"); - - string json = JsonConvert.SerializeObject(t1, Formatting.Indented, new TestDataTableConverter()); - Assert.AreEqual(@"""Custom""", json); - - DataTable t2 = JsonConvert.DeserializeObject(json, new TestDataTableConverter()); - Assert.AreEqual(t1.TableName, t2.TableName); - } - - [Test] - public void SerializeDataTableWithNull() - { - var table = new DataTable(); - table.Columns.Add("item"); - table.Columns.Add("price", typeof(double)); - table.Rows.Add("shirt", 49.99); - table.Rows.Add("pants", 54.99); - table.Rows.Add("shoes"); // no price - - var json = JsonConvert.SerializeObject(table); - Assert.AreEqual(@"[" - + @"{""item"":""shirt"",""price"":49.99}," - + @"{""item"":""pants"",""price"":54.99}," - + @"{""item"":""shoes"",""price"":null}]", json); - } - - [Test] - public void SerializeDataTableWithNullAndIgnoreNullHandling() - { - var table = new DataTable(); - table.Columns.Add("item"); - table.Columns.Add("price", typeof(double)); - table.Rows.Add("shirt", 49.99); - table.Rows.Add("pants", 54.99); - table.Rows.Add("shoes"); // no price - - var json = JsonConvert.SerializeObject(table, Formatting.None, new JsonSerializerSettings + public class TestDataTableConverter : JsonConverter { - NullValueHandling = NullValueHandling.Ignore - }); - Assert.AreEqual(@"[" - + @"{""item"":""shirt"",""price"":49.99}," - + @"{""item"":""pants"",""price"":54.99}," - + @"{""item"":""shoes""}]", json); - } + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + DataTable d = (DataTable)value; + writer.WriteValue(d.TableName); + } - [Test] - public void DerializeDataTableWithImplicitNull() - { - const string json = @"[" - + @"{""item"":""shirt"",""price"":49.99}," - + @"{""item"":""pants"",""price"":54.99}," - + @"{""item"":""shoes""}]"; - var table = JsonConvert.DeserializeObject(json); - Assert.AreEqual("shirt", table.Rows[0]["item"]); - Assert.AreEqual("pants", table.Rows[1]["item"]); - Assert.AreEqual("shoes", table.Rows[2]["item"]); - Assert.AreEqual(49.99, (double)table.Rows[0]["price"], 0.01); - Assert.AreEqual(54.99, (double)table.Rows[1]["price"], 0.01); - CustomAssert.IsInstanceOfType(typeof(System.DBNull), table.Rows[2]["price"]); - } + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + //reader.Read(); + DataTable d = new DataTable((string)reader.Value); - [Test] - public void DerializeDataTableWithExplicitNull() - { - const string json = @"[" - + @"{""item"":""shirt"",""price"":49.99}," - + @"{""item"":""pants"",""price"":54.99}," - + @"{""item"":""shoes"",""price"":null}]"; - var table = JsonConvert.DeserializeObject(json); - Assert.AreEqual("shirt", table.Rows[0]["item"]); - Assert.AreEqual("pants", table.Rows[1]["item"]); - Assert.AreEqual("shoes", table.Rows[2]["item"]); - Assert.AreEqual(49.99, (double)table.Rows[0]["price"], 0.01); - Assert.AreEqual(54.99, (double)table.Rows[1]["price"], 0.01); - CustomAssert.IsInstanceOfType(typeof(System.DBNull), table.Rows[2]["price"]); - } + return d; + } - [Test] - public void SerializeKeyValuePairWithDataTableKey() - { - DataTable table = new DataTable(); - DataColumn idColumn = new DataColumn("id", typeof(int)); - idColumn.AutoIncrement = true; + public override bool CanConvert(Type objectType) + { + return (objectType == typeof(DataTable)); + } + } - DataColumn itemColumn = new DataColumn("item"); - table.Columns.Add(idColumn); - table.Columns.Add(itemColumn); + [Test] + public void PassedInJsonConverterOverridesInternalConverter() + { + DataTable t1 = new DataTable("Custom"); - DataRow r = table.NewRow(); - r["item"] = "item!"; - r.EndEdit(); - table.Rows.Add(r); + string json = JsonConvert.SerializeObject(t1, Formatting.Indented, new TestDataTableConverter()); + Assert.AreEqual(@"""Custom""", json); - KeyValuePair pair = new KeyValuePair(table, 1); - string serializedpair = JsonConvert.SerializeObject(pair, Formatting.Indented); + DataTable t2 = JsonConvert.DeserializeObject(json, new TestDataTableConverter()); + Assert.AreEqual(t1.TableName, t2.TableName); + } - Assert.AreEqual(@"{ + [Test] + public void SerializeDataTableWithNull() + { + var table = new DataTable(); + table.Columns.Add("item"); + table.Columns.Add("price", typeof(double)); + table.Rows.Add("shirt", 49.99); + table.Rows.Add("pants", 54.99); + table.Rows.Add("shoes"); // no price + + var json = JsonConvert.SerializeObject(table); + Assert.AreEqual(@"[" + + @"{""item"":""shirt"",""price"":49.99}," + + @"{""item"":""pants"",""price"":54.99}," + + @"{""item"":""shoes"",""price"":null}]", json); + } + + [Test] + public void SerializeDataTableWithNullAndIgnoreNullHandling() + { + var table = new DataTable(); + table.Columns.Add("item"); + table.Columns.Add("price", typeof(double)); + table.Rows.Add("shirt", 49.99); + table.Rows.Add("pants", 54.99); + table.Rows.Add("shoes"); // no price + + var json = JsonConvert.SerializeObject(table, Formatting.None, new JsonSerializerSettings + { + NullValueHandling = NullValueHandling.Ignore + }); + Assert.AreEqual(@"[" + + @"{""item"":""shirt"",""price"":49.99}," + + @"{""item"":""pants"",""price"":54.99}," + + @"{""item"":""shoes""}]", json); + } + + [Test] + public void DerializeDataTableWithImplicitNull() + { + const string json = @"[" + + @"{""item"":""shirt"",""price"":49.99}," + + @"{""item"":""pants"",""price"":54.99}," + + @"{""item"":""shoes""}]"; + var table = JsonConvert.DeserializeObject(json); + Assert.AreEqual("shirt", table.Rows[0]["item"]); + Assert.AreEqual("pants", table.Rows[1]["item"]); + Assert.AreEqual("shoes", table.Rows[2]["item"]); + Assert.AreEqual(49.99, (double)table.Rows[0]["price"], 0.01); + Assert.AreEqual(54.99, (double)table.Rows[1]["price"], 0.01); + CustomAssert.IsInstanceOfType(typeof(System.DBNull), table.Rows[2]["price"]); + } + + [Test] + public void DerializeDataTableWithExplicitNull() + { + const string json = @"[" + + @"{""item"":""shirt"",""price"":49.99}," + + @"{""item"":""pants"",""price"":54.99}," + + @"{""item"":""shoes"",""price"":null}]"; + var table = JsonConvert.DeserializeObject(json); + Assert.AreEqual("shirt", table.Rows[0]["item"]); + Assert.AreEqual("pants", table.Rows[1]["item"]); + Assert.AreEqual("shoes", table.Rows[2]["item"]); + Assert.AreEqual(49.99, (double)table.Rows[0]["price"], 0.01); + Assert.AreEqual(54.99, (double)table.Rows[1]["price"], 0.01); + CustomAssert.IsInstanceOfType(typeof(System.DBNull), table.Rows[2]["price"]); + } + + [Test] + public void SerializeKeyValuePairWithDataTableKey() + { + DataTable table = new DataTable(); + DataColumn idColumn = new DataColumn("id", typeof(int)); + idColumn.AutoIncrement = true; + + DataColumn itemColumn = new DataColumn("item"); + table.Columns.Add(idColumn); + table.Columns.Add(itemColumn); + + DataRow r = table.NewRow(); + r["item"] = "item!"; + r.EndEdit(); + table.Rows.Add(r); + + KeyValuePair pair = new KeyValuePair(table, 1); + string serializedpair = JsonConvert.SerializeObject(pair, Formatting.Indented); + + Assert.AreEqual(@"{ ""Key"": [ { ""id"": 0, @@ -265,42 +265,43 @@ namespace Newtonsoft.Json.Tests.Converters ""Value"": 1 }", serializedpair); - var pair2 = (KeyValuePair)JsonConvert.DeserializeObject(serializedpair, typeof(KeyValuePair)); + var pair2 = (KeyValuePair)JsonConvert.DeserializeObject(serializedpair, typeof(KeyValuePair)); - Assert.AreEqual(1, pair2.Value); - Assert.AreEqual(1, pair2.Key.Rows.Count); - Assert.AreEqual("item!", pair2.Key.Rows[0]["item"]); - } + Assert.AreEqual(1, pair2.Value); + Assert.AreEqual(1, pair2.Key.Rows.Count); + Assert.AreEqual("item!", pair2.Key.Rows[0]["item"]); + } - [Test] - public void SerializedTypedDataTable() - { - CustomerDataSet.CustomersDataTable dt = new CustomerDataSet.CustomersDataTable(); - dt.AddCustomersRow("432"); + [Test] + public void SerializedTypedDataTable() + { + CustomerDataSet.CustomersDataTable dt = new CustomerDataSet.CustomersDataTable(); + dt.AddCustomersRow("432"); - string json = JsonConvert.SerializeObject(dt, Formatting.Indented); + string json = JsonConvert.SerializeObject(dt, Formatting.Indented); - Assert.AreEqual(@"[ + Assert.AreEqual(@"[ { ""CustomerID"": ""432"" } ]", json); - } + } - [Test] - public void DeserializedTypedDataTable() - { - string json = @"[ + [Test] + public void DeserializedTypedDataTable() + { + string json = @"[ { ""CustomerID"": ""432"" } ]"; - var dt = JsonConvert.DeserializeObject(json); + var dt = JsonConvert.DeserializeObject(json); - Assert.AreEqual("432", dt[0].CustomerID); + Assert.AreEqual("432", dt[0].CustomerID); + } } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Converters/ExpandoObjectConverterTests.cs b/Src/Newtonsoft.Json.Tests/Converters/ExpandoObjectConverterTests.cs index 41c3f26e..0984a0cb 100644 --- a/Src/Newtonsoft.Json.Tests/Converters/ExpandoObjectConverterTests.cs +++ b/Src/Newtonsoft.Json.Tests/Converters/ExpandoObjectConverterTests.cs @@ -48,40 +48,40 @@ using Newtonsoft.Json.Tests.TestObjects; namespace Newtonsoft.Json.Tests.Converters { - [TestFixture] - public class ExpandoObjectConverterTests : TestFixtureBase - { - public class ExpandoContainer + [TestFixture] + public class ExpandoObjectConverterTests : TestFixtureBase { - public string Before { get; set; } - public ExpandoObject Expando { get; set; } - public string After { get; set; } - } - - [Test] - public void SerializeExpandoObject() - { - ExpandoContainer d = new ExpandoContainer + public class ExpandoContainer { - Before = "Before!", - Expando = new ExpandoObject(), - After = "After!" - }; + public string Before { get; set; } + public ExpandoObject Expando { get; set; } + public string After { get; set; } + } - dynamic o = d.Expando; - - o.String = "String!"; - o.Integer = 234; - o.Float = 1.23d; - o.List = new List {"First", "Second", "Third"}; - o.Object = new Dictionary + [Test] + public void SerializeExpandoObject() { - {"First", 1} - }; + ExpandoContainer d = new ExpandoContainer + { + Before = "Before!", + Expando = new ExpandoObject(), + After = "After!" + }; - string json = JsonConvert.SerializeObject(d, Formatting.Indented); + dynamic o = d.Expando; - Assert.AreEqual(@"{ + o.String = "String!"; + o.Integer = 234; + o.Float = 1.23d; + o.List = new List { "First", "Second", "Third" }; + o.Object = new Dictionary + { + { "First", 1 } + }; + + string json = JsonConvert.SerializeObject(d, Formatting.Indented); + + Assert.AreEqual(@"{ ""Before"": ""Before!"", ""Expando"": { ""String"": ""String!"", @@ -98,26 +98,26 @@ namespace Newtonsoft.Json.Tests.Converters }, ""After"": ""After!"" }", json); - } + } - [Test] - public void SerializeNullExpandoObject() - { - ExpandoContainer d = new ExpandoContainer(); + [Test] + public void SerializeNullExpandoObject() + { + ExpandoContainer d = new ExpandoContainer(); - string json = JsonConvert.SerializeObject(d, Formatting.Indented); + string json = JsonConvert.SerializeObject(d, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Before"": null, ""Expando"": null, ""After"": null }", json); - } + } - [Test] - public void DeserializeExpandoObject() - { - string json = @"{ + [Test] + public void DeserializeExpandoObject() + { + string json = @"{ ""Before"": ""Before!"", ""Expando"": { ""String"": ""String!"", @@ -135,56 +135,55 @@ namespace Newtonsoft.Json.Tests.Converters ""After"": ""After!"" }"; - ExpandoContainer o = JsonConvert.DeserializeObject(json); + ExpandoContainer o = JsonConvert.DeserializeObject(json); - Assert.AreEqual(o.Before, "Before!"); - Assert.AreEqual(o.After, "After!"); - Assert.IsNotNull(o.Expando); + Assert.AreEqual(o.Before, "Before!"); + Assert.AreEqual(o.After, "After!"); + Assert.IsNotNull(o.Expando); - dynamic d = o.Expando; - CustomAssert.IsInstanceOfType(typeof(ExpandoObject), d); + dynamic d = o.Expando; + CustomAssert.IsInstanceOfType(typeof(ExpandoObject), d); - Assert.AreEqual("String!", d.String); - CustomAssert.IsInstanceOfType(typeof(string), d.String); + Assert.AreEqual("String!", d.String); + CustomAssert.IsInstanceOfType(typeof(string), d.String); - Assert.AreEqual(234, d.Integer); - CustomAssert.IsInstanceOfType(typeof(long), d.Integer); + Assert.AreEqual(234, d.Integer); + CustomAssert.IsInstanceOfType(typeof(long), d.Integer); - Assert.AreEqual(1.23, d.Float); - CustomAssert.IsInstanceOfType(typeof(double), d.Float); + Assert.AreEqual(1.23, d.Float); + CustomAssert.IsInstanceOfType(typeof(double), d.Float); - Assert.IsNotNull(d.List); - Assert.AreEqual(3, d.List.Count); - CustomAssert.IsInstanceOfType(typeof(List), d.List); + Assert.IsNotNull(d.List); + Assert.AreEqual(3, d.List.Count); + CustomAssert.IsInstanceOfType(typeof(List), d.List); - Assert.AreEqual("First", d.List[0]); - CustomAssert.IsInstanceOfType(typeof(string), d.List[0]); + Assert.AreEqual("First", d.List[0]); + CustomAssert.IsInstanceOfType(typeof(string), d.List[0]); - Assert.AreEqual("Second", d.List[1]); - Assert.AreEqual("Third", d.List[2]); + Assert.AreEqual("Second", d.List[1]); + Assert.AreEqual("Third", d.List[2]); - Assert.IsNotNull(d.Object); - CustomAssert.IsInstanceOfType(typeof(ExpandoObject), d.Object); + Assert.IsNotNull(d.Object); + CustomAssert.IsInstanceOfType(typeof(ExpandoObject), d.Object); - Assert.AreEqual(1, d.Object.First); - CustomAssert.IsInstanceOfType(typeof(long), d.Object.First); - } + Assert.AreEqual(1, d.Object.First); + CustomAssert.IsInstanceOfType(typeof(long), d.Object.First); + } - [Test] - public void DeserializeNullExpandoObject() - { - string json = @"{ + [Test] + public void DeserializeNullExpandoObject() + { + string json = @"{ ""Before"": null, ""Expando"": null, ""After"": null }"; - ExpandoContainer c = JsonConvert.DeserializeObject(json); + ExpandoContainer c = JsonConvert.DeserializeObject(json); - Assert.AreEqual(null, c.Expando); + Assert.AreEqual(null, c.Expando); + } } - - } } #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Converters/IsoDateTimeConverterTests.cs b/Src/Newtonsoft.Json.Tests/Converters/IsoDateTimeConverterTests.cs index 48850f78..606aa8f2 100644 --- a/Src/Newtonsoft.Json.Tests/Converters/IsoDateTimeConverterTests.cs +++ b/Src/Newtonsoft.Json.Tests/Converters/IsoDateTimeConverterTests.cs @@ -38,242 +38,241 @@ using System.Globalization; namespace Newtonsoft.Json.Tests.Converters { - [TestFixture] - public class IsoDateTimeConverterTests : TestFixtureBase - { - [Test] - public void PropertiesShouldBeSet() + [TestFixture] + public class IsoDateTimeConverterTests : TestFixtureBase { - IsoDateTimeConverter converter = new IsoDateTimeConverter(); - Assert.AreEqual(CultureInfo.CurrentCulture, converter.Culture); - Assert.AreEqual(string.Empty, converter.DateTimeFormat); - Assert.AreEqual(DateTimeStyles.RoundtripKind, converter.DateTimeStyles); + [Test] + public void PropertiesShouldBeSet() + { + IsoDateTimeConverter converter = new IsoDateTimeConverter(); + Assert.AreEqual(CultureInfo.CurrentCulture, converter.Culture); + Assert.AreEqual(string.Empty, converter.DateTimeFormat); + Assert.AreEqual(DateTimeStyles.RoundtripKind, converter.DateTimeStyles); - converter = new IsoDateTimeConverter() - { - DateTimeFormat = "F", - Culture = CultureInfo.InvariantCulture, - DateTimeStyles = DateTimeStyles.None - }; + converter = new IsoDateTimeConverter() + { + DateTimeFormat = "F", + Culture = CultureInfo.InvariantCulture, + DateTimeStyles = DateTimeStyles.None + }; - Assert.AreEqual(CultureInfo.InvariantCulture, converter.Culture); - Assert.AreEqual("F", converter.DateTimeFormat); - Assert.AreEqual(DateTimeStyles.None, converter.DateTimeStyles); - } + Assert.AreEqual(CultureInfo.InvariantCulture, converter.Culture); + Assert.AreEqual("F", converter.DateTimeFormat); + Assert.AreEqual(DateTimeStyles.None, converter.DateTimeStyles); + } - public static string GetUtcOffsetText(DateTime d) - { - TimeSpan utcOffset = d.GetUtcOffset(); + public static string GetUtcOffsetText(DateTime d) + { + TimeSpan utcOffset = d.GetUtcOffset(); - return utcOffset.Hours.ToString("+00;-00", CultureInfo.InvariantCulture) + ":" + utcOffset.Minutes.ToString("00;00", CultureInfo.InvariantCulture); - } + return utcOffset.Hours.ToString("+00;-00", CultureInfo.InvariantCulture) + ":" + utcOffset.Minutes.ToString("00;00", CultureInfo.InvariantCulture); + } - [Test] - public void SerializeDateTime() - { - IsoDateTimeConverter converter = new IsoDateTimeConverter(); + [Test] + public void SerializeDateTime() + { + IsoDateTimeConverter converter = new IsoDateTimeConverter(); - DateTime d = new DateTime(2000, 12, 15, 22, 11, 3, 55, DateTimeKind.Utc); - string result; + DateTime d = new DateTime(2000, 12, 15, 22, 11, 3, 55, DateTimeKind.Utc); + string result; - result = JsonConvert.SerializeObject(d, converter); - Assert.AreEqual(@"""2000-12-15T22:11:03.055Z""", result); + result = JsonConvert.SerializeObject(d, converter); + Assert.AreEqual(@"""2000-12-15T22:11:03.055Z""", result); - Assert.AreEqual(d, JsonConvert.DeserializeObject(result, converter)); + Assert.AreEqual(d, JsonConvert.DeserializeObject(result, converter)); - d = new DateTime(2000, 12, 15, 22, 11, 3, 55, DateTimeKind.Local); - result = JsonConvert.SerializeObject(d, converter); - Assert.AreEqual(@"""2000-12-15T22:11:03.055" + GetUtcOffsetText(d) + @"""", result); - } + d = new DateTime(2000, 12, 15, 22, 11, 3, 55, DateTimeKind.Local); + result = JsonConvert.SerializeObject(d, converter); + Assert.AreEqual(@"""2000-12-15T22:11:03.055" + GetUtcOffsetText(d) + @"""", result); + } - [Test] - public void SerializeFormattedDateTimeInvariantCulture() - { - IsoDateTimeConverter converter = new IsoDateTimeConverter() { DateTimeFormat = "F", Culture = CultureInfo.InvariantCulture }; + [Test] + public void SerializeFormattedDateTimeInvariantCulture() + { + IsoDateTimeConverter converter = new IsoDateTimeConverter() { DateTimeFormat = "F", Culture = CultureInfo.InvariantCulture }; - DateTime d = new DateTime(2000, 12, 15, 22, 11, 3, 0, DateTimeKind.Utc); - string result; + DateTime d = new DateTime(2000, 12, 15, 22, 11, 3, 0, DateTimeKind.Utc); + string result; - result = JsonConvert.SerializeObject(d, converter); - Assert.AreEqual(@"""Friday, 15 December 2000 22:11:03""", result); + result = JsonConvert.SerializeObject(d, converter); + Assert.AreEqual(@"""Friday, 15 December 2000 22:11:03""", result); - Assert.AreEqual(d, JsonConvert.DeserializeObject(result, converter)); + Assert.AreEqual(d, JsonConvert.DeserializeObject(result, converter)); - d = new DateTime(2000, 12, 15, 22, 11, 3, 0, DateTimeKind.Local); - result = JsonConvert.SerializeObject(d, converter); - Assert.AreEqual(@"""Friday, 15 December 2000 22:11:03""", result); - } + d = new DateTime(2000, 12, 15, 22, 11, 3, 0, DateTimeKind.Local); + result = JsonConvert.SerializeObject(d, converter); + Assert.AreEqual(@"""Friday, 15 December 2000 22:11:03""", result); + } - [Test] - public void SerializeCustomFormattedDateTime() - { - IsoDateTimeConverter converter = new IsoDateTimeConverter - { - DateTimeFormat = "dd/MM/yyyy", - Culture = CultureInfo.InvariantCulture - }; + [Test] + public void SerializeCustomFormattedDateTime() + { + IsoDateTimeConverter converter = new IsoDateTimeConverter + { + DateTimeFormat = "dd/MM/yyyy", + Culture = CultureInfo.InvariantCulture + }; - string json = @"""09/12/2006"""; + string json = @"""09/12/2006"""; - DateTime d = JsonConvert.DeserializeObject(json, converter); + DateTime d = JsonConvert.DeserializeObject(json, converter); - Assert.AreEqual(9, d.Day); - Assert.AreEqual(12, d.Month); - Assert.AreEqual(2006, d.Year); - } + Assert.AreEqual(9, d.Day); + Assert.AreEqual(12, d.Month); + Assert.AreEqual(2006, d.Year); + } #if !SILVERLIGHT && !NETFX_CORE - [Test] - public void SerializeFormattedDateTimeNewZealandCulture() - { - IsoDateTimeConverter converter = new IsoDateTimeConverter() { DateTimeFormat = "F", Culture = CultureInfo.GetCultureInfo("en-NZ") }; + [Test] + public void SerializeFormattedDateTimeNewZealandCulture() + { + IsoDateTimeConverter converter = new IsoDateTimeConverter() { DateTimeFormat = "F", Culture = CultureInfo.GetCultureInfo("en-NZ") }; - DateTime d = new DateTime(2000, 12, 15, 22, 11, 3, 0, DateTimeKind.Utc); - string result; + DateTime d = new DateTime(2000, 12, 15, 22, 11, 3, 0, DateTimeKind.Utc); + string result; - result = JsonConvert.SerializeObject(d, converter); - Assert.AreEqual(@"""Friday, 15 December 2000 10:11:03 p.m.""", result); + result = JsonConvert.SerializeObject(d, converter); + Assert.AreEqual(@"""Friday, 15 December 2000 10:11:03 p.m.""", result); - Assert.AreEqual(d, JsonConvert.DeserializeObject(result, converter)); + Assert.AreEqual(d, JsonConvert.DeserializeObject(result, converter)); - d = new DateTime(2000, 12, 15, 22, 11, 3, 0, DateTimeKind.Local); - result = JsonConvert.SerializeObject(d, converter); - Assert.AreEqual(@"""Friday, 15 December 2000 10:11:03 p.m.""", result); - } + d = new DateTime(2000, 12, 15, 22, 11, 3, 0, DateTimeKind.Local); + result = JsonConvert.SerializeObject(d, converter); + Assert.AreEqual(@"""Friday, 15 December 2000 10:11:03 p.m.""", result); + } - [Test] - public void SerializeDateTimeCulture() - { - IsoDateTimeConverter converter = new IsoDateTimeConverter() { Culture = CultureInfo.GetCultureInfo("en-NZ") }; + [Test] + public void SerializeDateTimeCulture() + { + IsoDateTimeConverter converter = new IsoDateTimeConverter() { Culture = CultureInfo.GetCultureInfo("en-NZ") }; - string json = @"""09/12/2006"""; + string json = @"""09/12/2006"""; - DateTime d = JsonConvert.DeserializeObject(json, converter); + DateTime d = JsonConvert.DeserializeObject(json, converter); - Assert.AreEqual(9, d.Day); - Assert.AreEqual(12, d.Month); - Assert.AreEqual(2006, d.Year); - } + Assert.AreEqual(9, d.Day); + Assert.AreEqual(12, d.Month); + Assert.AreEqual(2006, d.Year); + } #endif #if !NET20 - [Test] - public void SerializeDateTimeOffset() - { - IsoDateTimeConverter converter = new IsoDateTimeConverter(); + [Test] + public void SerializeDateTimeOffset() + { + IsoDateTimeConverter converter = new IsoDateTimeConverter(); - DateTimeOffset d = new DateTimeOffset(2000, 12, 15, 22, 11, 3, 55, TimeSpan.Zero); - string result; + DateTimeOffset d = new DateTimeOffset(2000, 12, 15, 22, 11, 3, 55, TimeSpan.Zero); + string result; - result = JsonConvert.SerializeObject(d, converter); - Assert.AreEqual(@"""2000-12-15T22:11:03.055+00:00""", result); + result = JsonConvert.SerializeObject(d, converter); + Assert.AreEqual(@"""2000-12-15T22:11:03.055+00:00""", result); - Assert.AreEqual(d, JsonConvert.DeserializeObject(result, converter)); - } + Assert.AreEqual(d, JsonConvert.DeserializeObject(result, converter)); + } - [Test] - public void SerializeUTC() - { - DateTimeTestClass c = new DateTimeTestClass(); - c.DateTimeField = new DateTime(2008, 12, 12, 12, 12, 12, 0, DateTimeKind.Utc).ToLocalTime(); - c.DateTimeOffsetField = new DateTime(2008, 12, 12, 12, 12, 12, 0, DateTimeKind.Utc).ToLocalTime(); - c.PreField = "Pre"; - c.PostField = "Post"; - string json = JsonConvert.SerializeObject(c, new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal }); - Assert.AreEqual(@"{""PreField"":""Pre"",""DateTimeField"":""2008-12-12T12:12:12Z"",""DateTimeOffsetField"":""2008-12-12T12:12:12+00:00"",""PostField"":""Post""}", json); + [Test] + public void SerializeUTC() + { + DateTimeTestClass c = new DateTimeTestClass(); + c.DateTimeField = new DateTime(2008, 12, 12, 12, 12, 12, 0, DateTimeKind.Utc).ToLocalTime(); + c.DateTimeOffsetField = new DateTime(2008, 12, 12, 12, 12, 12, 0, DateTimeKind.Utc).ToLocalTime(); + c.PreField = "Pre"; + c.PostField = "Post"; + string json = JsonConvert.SerializeObject(c, new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal }); + Assert.AreEqual(@"{""PreField"":""Pre"",""DateTimeField"":""2008-12-12T12:12:12Z"",""DateTimeOffsetField"":""2008-12-12T12:12:12+00:00"",""PostField"":""Post""}", json); - //test the other edge case too - c.DateTimeField = new DateTime(2008, 1, 1, 1, 1, 1, 0, DateTimeKind.Utc).ToLocalTime(); - c.DateTimeOffsetField = new DateTime(2008, 1, 1, 1, 1, 1, 0, DateTimeKind.Utc).ToLocalTime(); - c.PreField = "Pre"; - c.PostField = "Post"; - json = JsonConvert.SerializeObject(c, new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal }); - Assert.AreEqual(@"{""PreField"":""Pre"",""DateTimeField"":""2008-01-01T01:01:01Z"",""DateTimeOffsetField"":""2008-01-01T01:01:01+00:00"",""PostField"":""Post""}", json); - } + //test the other edge case too + c.DateTimeField = new DateTime(2008, 1, 1, 1, 1, 1, 0, DateTimeKind.Utc).ToLocalTime(); + c.DateTimeOffsetField = new DateTime(2008, 1, 1, 1, 1, 1, 0, DateTimeKind.Utc).ToLocalTime(); + c.PreField = "Pre"; + c.PostField = "Post"; + json = JsonConvert.SerializeObject(c, new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal }); + Assert.AreEqual(@"{""PreField"":""Pre"",""DateTimeField"":""2008-01-01T01:01:01Z"",""DateTimeOffsetField"":""2008-01-01T01:01:01+00:00"",""PostField"":""Post""}", json); + } - [Test] - public void NullableSerializeUTC() - { - NullableDateTimeTestClass c = new NullableDateTimeTestClass(); - c.DateTimeField = new DateTime(2008, 12, 12, 12, 12, 12, 0, DateTimeKind.Utc).ToLocalTime(); - c.DateTimeOffsetField = new DateTime(2008, 12, 12, 12, 12, 12, 0, DateTimeKind.Utc).ToLocalTime(); - c.PreField = "Pre"; - c.PostField = "Post"; - string json = JsonConvert.SerializeObject(c, new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal }); - Assert.AreEqual(@"{""PreField"":""Pre"",""DateTimeField"":""2008-12-12T12:12:12Z"",""DateTimeOffsetField"":""2008-12-12T12:12:12+00:00"",""PostField"":""Post""}", json); + [Test] + public void NullableSerializeUTC() + { + NullableDateTimeTestClass c = new NullableDateTimeTestClass(); + c.DateTimeField = new DateTime(2008, 12, 12, 12, 12, 12, 0, DateTimeKind.Utc).ToLocalTime(); + c.DateTimeOffsetField = new DateTime(2008, 12, 12, 12, 12, 12, 0, DateTimeKind.Utc).ToLocalTime(); + c.PreField = "Pre"; + c.PostField = "Post"; + string json = JsonConvert.SerializeObject(c, new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal }); + Assert.AreEqual(@"{""PreField"":""Pre"",""DateTimeField"":""2008-12-12T12:12:12Z"",""DateTimeOffsetField"":""2008-12-12T12:12:12+00:00"",""PostField"":""Post""}", json); - //test the other edge case too - c.DateTimeField = null; - c.DateTimeOffsetField = null; - c.PreField = "Pre"; - c.PostField = "Post"; - json = JsonConvert.SerializeObject(c, new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal }); - Assert.AreEqual(@"{""PreField"":""Pre"",""DateTimeField"":null,""DateTimeOffsetField"":null,""PostField"":""Post""}", json); - } + //test the other edge case too + c.DateTimeField = null; + c.DateTimeOffsetField = null; + c.PreField = "Pre"; + c.PostField = "Post"; + json = JsonConvert.SerializeObject(c, new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal }); + Assert.AreEqual(@"{""PreField"":""Pre"",""DateTimeField"":null,""DateTimeOffsetField"":null,""PostField"":""Post""}", json); + } - [Test] - public void NullableDeserializeEmptyString() - { - string json = @"{""DateTimeField"":""""}"; + [Test] + public void NullableDeserializeEmptyString() + { + string json = @"{""DateTimeField"":""""}"; - NullableDateTimeTestClass c = JsonConvert.DeserializeObject(json, - new JsonSerializerSettings { Converters = new [] {new IsoDateTimeConverter()}}); - Assert.AreEqual(null, c.DateTimeField); - } + NullableDateTimeTestClass c = JsonConvert.DeserializeObject(json, + new JsonSerializerSettings { Converters = new[] { new IsoDateTimeConverter() } }); + Assert.AreEqual(null, c.DateTimeField); + } - [Test] - public void DeserializeNullToNonNullable() - { - ExceptionAssert.Throws("Cannot convert null value to System.DateTime. Path 'DateTimeField', line 1, position 38.", - () => - { - DateTimeTestClass c2 = - JsonConvert.DeserializeObject(@"{""PreField"":""Pre"",""DateTimeField"":null,""DateTimeOffsetField"":null,""PostField"":""Post""}", new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal }); - }); - } + [Test] + public void DeserializeNullToNonNullable() + { + ExceptionAssert.Throws("Cannot convert null value to System.DateTime. Path 'DateTimeField', line 1, position 38.", + () => + { + DateTimeTestClass c2 = + JsonConvert.DeserializeObject(@"{""PreField"":""Pre"",""DateTimeField"":null,""DateTimeOffsetField"":null,""PostField"":""Post""}", new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal }); + }); + } - [Test] - public void SerializeShouldChangeNonUTCDates() - { - DateTime localDateTime = new DateTime(2008, 1, 1, 1, 1, 1, 0, DateTimeKind.Local); + [Test] + public void SerializeShouldChangeNonUTCDates() + { + DateTime localDateTime = new DateTime(2008, 1, 1, 1, 1, 1, 0, DateTimeKind.Local); - DateTimeTestClass c = new DateTimeTestClass(); - c.DateTimeField = localDateTime; - c.PreField = "Pre"; - c.PostField = "Post"; - string json = JsonConvert.SerializeObject(c, new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal }); //note that this fails without the Utc converter... - c.DateTimeField = new DateTime(2008, 1, 1, 1, 1, 1, 0, DateTimeKind.Utc); - string json2 = JsonConvert.SerializeObject(c, new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal }); + DateTimeTestClass c = new DateTimeTestClass(); + c.DateTimeField = localDateTime; + c.PreField = "Pre"; + c.PostField = "Post"; + string json = JsonConvert.SerializeObject(c, new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal }); //note that this fails without the Utc converter... + c.DateTimeField = new DateTime(2008, 1, 1, 1, 1, 1, 0, DateTimeKind.Utc); + string json2 = JsonConvert.SerializeObject(c, new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal }); - TimeSpan offset = localDateTime.GetUtcOffset(); + TimeSpan offset = localDateTime.GetUtcOffset(); - // if the current timezone is utc then local already equals utc - if (offset == TimeSpan.Zero) - Assert.AreEqual(json, json2); - else - Assert.AreNotEqual(json, json2); - } + // if the current timezone is utc then local already equals utc + if (offset == TimeSpan.Zero) + Assert.AreEqual(json, json2); + else + Assert.AreNotEqual(json, json2); + } #endif - [Test] - public void BlogCodeSample() - { - Person p = new Person - { - Name = "Keith", - BirthDate = new DateTime(1980, 3, 8), - LastModified = new DateTime(2009, 4, 12, 20, 44, 55), - }; + [Test] + public void BlogCodeSample() + { + Person p = new Person + { + Name = "Keith", + BirthDate = new DateTime(1980, 3, 8), + LastModified = new DateTime(2009, 4, 12, 20, 44, 55), + }; - string jsonText = JsonConvert.SerializeObject(p, new IsoDateTimeConverter()); - // { - // "Name": "Keith", - // "BirthDate": "1980-03-08T00:00:00", - // "LastModified": "2009-04-12T20:44:55" - // } - - Console.WriteLine(jsonText); + string jsonText = JsonConvert.SerializeObject(p, new IsoDateTimeConverter()); + // { + // "Name": "Keith", + // "BirthDate": "1980-03-08T00:00:00", + // "LastModified": "2009-04-12T20:44:55" + // } + Console.WriteLine(jsonText); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Converters/JavaScriptDateTimeConverterTests.cs b/Src/Newtonsoft.Json.Tests/Converters/JavaScriptDateTimeConverterTests.cs index 493aefe1..9d1cd2ac 100644 --- a/Src/Newtonsoft.Json.Tests/Converters/JavaScriptDateTimeConverterTests.cs +++ b/Src/Newtonsoft.Json.Tests/Converters/JavaScriptDateTimeConverterTests.cs @@ -38,109 +38,109 @@ using Newtonsoft.Json.Tests.TestObjects; namespace Newtonsoft.Json.Tests.Converters { - [TestFixture] - public class JavaScriptDateTimeConverterTests : TestFixtureBase - { - [Test] - public void SerializeDateTime() + [TestFixture] + public class JavaScriptDateTimeConverterTests : TestFixtureBase { - JavaScriptDateTimeConverter converter = new JavaScriptDateTimeConverter(); + [Test] + public void SerializeDateTime() + { + JavaScriptDateTimeConverter converter = new JavaScriptDateTimeConverter(); - DateTime d = new DateTime(2000, 12, 15, 22, 11, 3, 55, DateTimeKind.Utc); - string result; + DateTime d = new DateTime(2000, 12, 15, 22, 11, 3, 55, DateTimeKind.Utc); + string result; - result = JsonConvert.SerializeObject(d, converter); - Assert.AreEqual("new Date(976918263055)", result); - } + result = JsonConvert.SerializeObject(d, converter); + Assert.AreEqual("new Date(976918263055)", result); + } #if !NET20 - [Test] - public void SerializeDateTimeOffset() - { - JavaScriptDateTimeConverter converter = new JavaScriptDateTimeConverter(); + [Test] + public void SerializeDateTimeOffset() + { + JavaScriptDateTimeConverter converter = new JavaScriptDateTimeConverter(); - DateTimeOffset now = new DateTimeOffset(2000, 12, 15, 22, 11, 3, 55, TimeSpan.Zero); - string result; + DateTimeOffset now = new DateTimeOffset(2000, 12, 15, 22, 11, 3, 55, TimeSpan.Zero); + string result; - result = JsonConvert.SerializeObject(now, converter); - Assert.AreEqual("new Date(976918263055)", result); - } + result = JsonConvert.SerializeObject(now, converter); + Assert.AreEqual("new Date(976918263055)", result); + } - [Test] - public void sdfs() - { - int i = Convert.ToInt32("+1"); - Console.WriteLine(i); - } + [Test] + public void sdfs() + { + int i = Convert.ToInt32("+1"); + Console.WriteLine(i); + } - [Test] - public void SerializeNullableDateTimeClass() - { - NullableDateTimeTestClass t = new NullableDateTimeTestClass() - { - DateTimeField = null, - DateTimeOffsetField = null - }; + [Test] + public void SerializeNullableDateTimeClass() + { + NullableDateTimeTestClass t = new NullableDateTimeTestClass() + { + DateTimeField = null, + DateTimeOffsetField = null + }; - JavaScriptDateTimeConverter converter = new JavaScriptDateTimeConverter(); + JavaScriptDateTimeConverter converter = new JavaScriptDateTimeConverter(); - string result; + string result; - result = JsonConvert.SerializeObject(t, converter); - Assert.AreEqual(@"{""PreField"":null,""DateTimeField"":null,""DateTimeOffsetField"":null,""PostField"":null}", result); + result = JsonConvert.SerializeObject(t, converter); + Assert.AreEqual(@"{""PreField"":null,""DateTimeField"":null,""DateTimeOffsetField"":null,""PostField"":null}", result); - t = new NullableDateTimeTestClass() - { - DateTimeField = new DateTime(2000, 12, 15, 22, 11, 3, 55, DateTimeKind.Utc), - DateTimeOffsetField = new DateTimeOffset(2000, 12, 15, 22, 11, 3, 55, TimeSpan.Zero) - }; + t = new NullableDateTimeTestClass() + { + DateTimeField = new DateTime(2000, 12, 15, 22, 11, 3, 55, DateTimeKind.Utc), + DateTimeOffsetField = new DateTimeOffset(2000, 12, 15, 22, 11, 3, 55, TimeSpan.Zero) + }; - result = JsonConvert.SerializeObject(t, converter); - Assert.AreEqual(@"{""PreField"":null,""DateTimeField"":new Date(976918263055),""DateTimeOffsetField"":new Date(976918263055),""PostField"":null}", result); - } + result = JsonConvert.SerializeObject(t, converter); + Assert.AreEqual(@"{""PreField"":null,""DateTimeField"":new Date(976918263055),""DateTimeOffsetField"":new Date(976918263055),""PostField"":null}", result); + } - [Test] - public void DeserializeNullToNonNullable() - { - ExceptionAssert.Throws("Cannot convert null value to System.DateTime. Path 'DateTimeField', line 1, position 38.", - () => - { - DateTimeTestClass c2 = - JsonConvert.DeserializeObject(@"{""PreField"":""Pre"",""DateTimeField"":null,""DateTimeOffsetField"":null,""PostField"":""Post""}", new JavaScriptDateTimeConverter()); - }); - } + [Test] + public void DeserializeNullToNonNullable() + { + ExceptionAssert.Throws("Cannot convert null value to System.DateTime. Path 'DateTimeField', line 1, position 38.", + () => + { + DateTimeTestClass c2 = + JsonConvert.DeserializeObject(@"{""PreField"":""Pre"",""DateTimeField"":null,""DateTimeOffsetField"":null,""PostField"":""Post""}", new JavaScriptDateTimeConverter()); + }); + } - [Test] - public void DeserializeDateTimeOffset() - { - JavaScriptDateTimeConverter converter = new JavaScriptDateTimeConverter(); - DateTimeOffset start = new DateTimeOffset(2000, 12, 15, 22, 11, 3, 55, TimeSpan.Zero); + [Test] + public void DeserializeDateTimeOffset() + { + JavaScriptDateTimeConverter converter = new JavaScriptDateTimeConverter(); + DateTimeOffset start = new DateTimeOffset(2000, 12, 15, 22, 11, 3, 55, TimeSpan.Zero); - string json = JsonConvert.SerializeObject(start, converter); + string json = JsonConvert.SerializeObject(start, converter); - DateTimeOffset result = JsonConvert.DeserializeObject(json, converter); - Assert.AreEqual(new DateTimeOffset(2000, 12, 15, 22, 11, 3, 55, TimeSpan.Zero), result); - } + DateTimeOffset result = JsonConvert.DeserializeObject(json, converter); + Assert.AreEqual(new DateTimeOffset(2000, 12, 15, 22, 11, 3, 55, TimeSpan.Zero), result); + } #endif - [Test] - public void DeserializeDateTime() - { - JavaScriptDateTimeConverter converter = new JavaScriptDateTimeConverter(); + [Test] + public void DeserializeDateTime() + { + JavaScriptDateTimeConverter converter = new JavaScriptDateTimeConverter(); - DateTime result = JsonConvert.DeserializeObject("new Date(976918263055)", converter); - Assert.AreEqual(new DateTime(2000, 12, 15, 22, 11, 3, 55, DateTimeKind.Utc), result); - } + DateTime result = JsonConvert.DeserializeObject("new Date(976918263055)", converter); + Assert.AreEqual(new DateTime(2000, 12, 15, 22, 11, 3, 55, DateTimeKind.Utc), result); + } - [Test] - public void ConverterList() - { - ConverterList l1 = new ConverterList(); - l1.Add(new DateTime(2000, 12, 12, 20, 10, 0, DateTimeKind.Utc)); - l1.Add(new DateTime(1983, 10, 9, 23, 10, 0, DateTimeKind.Utc)); + [Test] + public void ConverterList() + { + ConverterList l1 = new ConverterList(); + l1.Add(new DateTime(2000, 12, 12, 20, 10, 0, DateTimeKind.Utc)); + l1.Add(new DateTime(1983, 10, 9, 23, 10, 0, DateTimeKind.Utc)); - string json = JsonConvert.SerializeObject(l1, Formatting.Indented); - Assert.AreEqual(@"[ + string json = JsonConvert.SerializeObject(l1, Formatting.Indented); + Assert.AreEqual(@"[ new Date( 976651800000 ), @@ -149,22 +149,22 @@ namespace Newtonsoft.Json.Tests.Converters ) ]", json); - ConverterList l2 = JsonConvert.DeserializeObject>(json); - Assert.IsNotNull(l2); + ConverterList l2 = JsonConvert.DeserializeObject>(json); + Assert.IsNotNull(l2); - Assert.AreEqual(new DateTime(2000, 12, 12, 20, 10, 0, DateTimeKind.Utc), l2[0]); - Assert.AreEqual(new DateTime(1983, 10, 9, 23, 10, 0, DateTimeKind.Utc), l2[1]); - } + Assert.AreEqual(new DateTime(2000, 12, 12, 20, 10, 0, DateTimeKind.Utc), l2[0]); + Assert.AreEqual(new DateTime(1983, 10, 9, 23, 10, 0, DateTimeKind.Utc), l2[1]); + } - [Test] - public void ConverterDictionary() - { - ConverterDictionary l1 = new ConverterDictionary(); - l1.Add("First", new DateTime(2000, 12, 12, 20, 10, 0, DateTimeKind.Utc)); - l1.Add("Second", new DateTime(1983, 10, 9, 23, 10, 0, DateTimeKind.Utc)); + [Test] + public void ConverterDictionary() + { + ConverterDictionary l1 = new ConverterDictionary(); + l1.Add("First", new DateTime(2000, 12, 12, 20, 10, 0, DateTimeKind.Utc)); + l1.Add("Second", new DateTime(1983, 10, 9, 23, 10, 0, DateTimeKind.Utc)); - string json = JsonConvert.SerializeObject(l1, Formatting.Indented); - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(l1, Formatting.Indented); + Assert.AreEqual(@"{ ""First"": new Date( 976651800000 ), @@ -173,23 +173,23 @@ namespace Newtonsoft.Json.Tests.Converters ) }", json); - ConverterDictionary l2 = JsonConvert.DeserializeObject>(json); - Assert.IsNotNull(l2); + ConverterDictionary l2 = JsonConvert.DeserializeObject>(json); + Assert.IsNotNull(l2); - Assert.AreEqual(new DateTime(2000, 12, 12, 20, 10, 0, DateTimeKind.Utc), l2["First"]); - Assert.AreEqual(new DateTime(1983, 10, 9, 23, 10, 0, DateTimeKind.Utc), l2["Second"]); - } + Assert.AreEqual(new DateTime(2000, 12, 12, 20, 10, 0, DateTimeKind.Utc), l2["First"]); + Assert.AreEqual(new DateTime(1983, 10, 9, 23, 10, 0, DateTimeKind.Utc), l2["Second"]); + } - [Test] - public void ConverterObject() - { - ConverterObject l1 = new ConverterObject(); - l1.Object1 = new DateTime(2000, 12, 12, 20, 10, 0, DateTimeKind.Utc); - l1.Object2 = null; - l1.ObjectNotHandled = new DateTime(2000, 12, 12, 20, 10, 0, DateTimeKind.Utc); + [Test] + public void ConverterObject() + { + ConverterObject l1 = new ConverterObject(); + l1.Object1 = new DateTime(2000, 12, 12, 20, 10, 0, DateTimeKind.Utc); + l1.Object2 = null; + l1.ObjectNotHandled = new DateTime(2000, 12, 12, 20, 10, 0, DateTimeKind.Utc); - string json = JsonConvert.SerializeObject(l1, Formatting.Indented); - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(l1, Formatting.Indented); + Assert.AreEqual(@"{ ""Object1"": new Date( 976651800000 ), @@ -197,52 +197,53 @@ namespace Newtonsoft.Json.Tests.Converters ""ObjectNotHandled"": 631122486000000000 }", json); - ConverterObject l2 = JsonConvert.DeserializeObject(json); - Assert.IsNotNull(l2); + ConverterObject l2 = JsonConvert.DeserializeObject(json); + Assert.IsNotNull(l2); - //Assert.AreEqual(new DateTime(2000, 12, 12, 20, 10, 0, DateTimeKind.Utc), l2["First"]); - //Assert.AreEqual(new DateTime(1983, 10, 9, 23, 10, 0, DateTimeKind.Utc), l2["Second"]); + //Assert.AreEqual(new DateTime(2000, 12, 12, 20, 10, 0, DateTimeKind.Utc), l2["First"]); + //Assert.AreEqual(new DateTime(1983, 10, 9, 23, 10, 0, DateTimeKind.Utc), l2["Second"]); + } } - } - [JsonArray(ItemConverterType = typeof(JavaScriptDateTimeConverter))] - public class ConverterList : List - { - } - - [JsonDictionary(ItemConverterType = typeof(JavaScriptDateTimeConverter))] - public class ConverterDictionary : Dictionary - { - } - - [JsonObject(ItemConverterType = typeof(JavaScriptDateTimeConverter))] - public class ConverterObject - { - public object Object1 { get; set; } - public object Object2 { get; set; } - [JsonConverter(typeof(DateIntConverter))] - public object ObjectNotHandled { get; set; } - } - - public class DateIntConverter : JsonConverter - { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + [JsonArray(ItemConverterType = typeof(JavaScriptDateTimeConverter))] + public class ConverterList : List { - DateTime? d = (DateTime?) value; - if (d == null) - writer.WriteNull(); - else - writer.WriteValue(d.Value.Ticks); } - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + [JsonDictionary(ItemConverterType = typeof(JavaScriptDateTimeConverter))] + public class ConverterDictionary : Dictionary { - return new DateTime(Convert.ToInt64(reader.Value), DateTimeKind.Utc); } - public override bool CanConvert(Type objectType) + [JsonObject(ItemConverterType = typeof(JavaScriptDateTimeConverter))] + public class ConverterObject { - return objectType == typeof (DateTime) || objectType == typeof (DateTime?); + public object Object1 { get; set; } + public object Object2 { get; set; } + + [JsonConverter(typeof(DateIntConverter))] + public object ObjectNotHandled { get; set; } + } + + public class DateIntConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + DateTime? d = (DateTime?)value; + if (d == null) + writer.WriteNull(); + else + writer.WriteValue(d.Value.Ticks); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + return new DateTime(Convert.ToInt64(reader.Value), DateTimeKind.Utc); + } + + public override bool CanConvert(Type objectType) + { + return objectType == typeof(DateTime) || objectType == typeof(DateTime?); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Converters/JsonValueConverterTests.cs b/Src/Newtonsoft.Json.Tests/Converters/JsonValueConverterTests.cs index fee7dcd0..d8ed6a17 100644 --- a/Src/Newtonsoft.Json.Tests/Converters/JsonValueConverterTests.cs +++ b/Src/Newtonsoft.Json.Tests/Converters/JsonValueConverterTests.cs @@ -23,6 +23,7 @@ // OTHER DEALINGS IN THE SOFTWARE. #endregion + #if NETFX_CORE using System; using Newtonsoft.Json.Converters; diff --git a/Src/Newtonsoft.Json.Tests/Converters/ObjectIdConverterTests.cs b/Src/Newtonsoft.Json.Tests/Converters/ObjectIdConverterTests.cs index ded76aca..f7d4780a 100644 --- a/Src/Newtonsoft.Json.Tests/Converters/ObjectIdConverterTests.cs +++ b/Src/Newtonsoft.Json.Tests/Converters/ObjectIdConverterTests.cs @@ -28,6 +28,7 @@ using Newtonsoft.Json.Bson; using Newtonsoft.Json.Utilities; #if !NETFX_CORE using NUnit.Framework; + #else using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; @@ -36,50 +37,51 @@ using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAtt namespace Newtonsoft.Json.Tests.Converters { - [TestFixture] - public class ObjectIdConverterTests : TestFixtureBase - { - public class ObjectIdTestClass + [TestFixture] + public class ObjectIdConverterTests : TestFixtureBase { - [JsonProperty("_id")] - public BsonObjectId Id { get; set; } - [JsonProperty("test")] - public string Test { get; set; } + public class ObjectIdTestClass + { + [JsonProperty("_id")] + public BsonObjectId Id { get; set; } + + [JsonProperty("test")] + public string Test { get; set; } + } + + [Test] + public void Serialize() + { + ObjectIdTestClass c = new ObjectIdTestClass + { + Id = new BsonObjectId(HexToBytes("4ABBED9D1D8B0F0218000001")), + Test = "1234£56" + }; + + MemoryStream ms = new MemoryStream(); + JsonSerializer serializer = new JsonSerializer(); + + // serialize product to BSON + BsonWriter writer = new BsonWriter(ms); + serializer.Serialize(writer, c); + + byte[] expected = HexToBytes("29000000075F6964004ABBED9D1D8B0F02180000010274657374000900000031323334C2A335360000"); + + CollectionAssert.AreEquivalent(expected, ms.ToArray()); + } + + [Test] + public void Deserialize() + { + byte[] bson = HexToBytes("29000000075F6964004ABBED9D1D8B0F02180000010274657374000900000031323334C2A335360000"); + + JsonSerializer serializer = new JsonSerializer(); + + BsonReader reader = new BsonReader(new MemoryStream(bson)); + ObjectIdTestClass c = serializer.Deserialize(reader); + + CollectionAssert.AreEquivalent(c.Id.Value, HexToBytes("4ABBED9D1D8B0F0218000001")); + Assert.AreEqual(c.Test, "1234£56"); + } } - - [Test] - public void Serialize() - { - ObjectIdTestClass c = new ObjectIdTestClass - { - Id = new BsonObjectId(HexToBytes("4ABBED9D1D8B0F0218000001")), - Test = "1234£56" - }; - - MemoryStream ms = new MemoryStream(); - JsonSerializer serializer = new JsonSerializer(); - - // serialize product to BSON - BsonWriter writer = new BsonWriter(ms); - serializer.Serialize(writer, c); - - byte[] expected = HexToBytes("29000000075F6964004ABBED9D1D8B0F02180000010274657374000900000031323334C2A335360000"); - - CollectionAssert.AreEquivalent(expected, ms.ToArray()); - } - - [Test] - public void Deserialize() - { - byte[] bson = HexToBytes("29000000075F6964004ABBED9D1D8B0F02180000010274657374000900000031323334C2A335360000"); - - JsonSerializer serializer = new JsonSerializer(); - - BsonReader reader = new BsonReader(new MemoryStream(bson)); - ObjectIdTestClass c = serializer.Deserialize(reader); - - CollectionAssert.AreEquivalent(c.Id.Value, HexToBytes("4ABBED9D1D8B0F0218000001")); - Assert.AreEqual(c.Test, "1234£56"); - } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Converters/RegexConverterTests.cs b/Src/Newtonsoft.Json.Tests/Converters/RegexConverterTests.cs index e3fa643c..ec4682f3 100644 --- a/Src/Newtonsoft.Json.Tests/Converters/RegexConverterTests.cs +++ b/Src/Newtonsoft.Json.Tests/Converters/RegexConverterTests.cs @@ -48,65 +48,65 @@ using Newtonsoft.Json.Tests.TestObjects; namespace Newtonsoft.Json.Tests.Converters { - [TestFixture] - public class RegexConverterTests : TestFixtureBase - { - public class RegexTestClass + [TestFixture] + public class RegexConverterTests : TestFixtureBase { - public Regex Regex { get; set; } - } + public class RegexTestClass + { + public Regex Regex { get; set; } + } - [Test] - public void SerializeToText() - { - Regex regex = new Regex("abc", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); + [Test] + public void SerializeToText() + { + Regex regex = new Regex("abc", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); - string json = JsonConvert.SerializeObject(regex, Formatting.Indented, new RegexConverter()); + string json = JsonConvert.SerializeObject(regex, Formatting.Indented, new RegexConverter()); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Pattern"": ""abc"", ""Options"": 513 }", json); - } + } - [Test] - public void SerializeCamelCaseAndStringEnums() - { - Regex regex = new Regex("abc", RegexOptions.IgnoreCase); - - string json = JsonConvert.SerializeObject(regex, Formatting.Indented, new JsonSerializerSettings + [Test] + public void SerializeCamelCaseAndStringEnums() { - Converters = {new RegexConverter(),new StringEnumConverter() { CamelCaseText = true }}, - ContractResolver = new CamelCasePropertyNamesContractResolver() - }); + Regex regex = new Regex("abc", RegexOptions.IgnoreCase); - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(regex, Formatting.Indented, new JsonSerializerSettings + { + Converters = { new RegexConverter(), new StringEnumConverter() { CamelCaseText = true } }, + ContractResolver = new CamelCasePropertyNamesContractResolver() + }); + + Assert.AreEqual(@"{ ""pattern"": ""abc"", ""options"": ""ignoreCase"" }", json); - } + } - [Test] - public void DeserializeCamelCaseAndStringEnums() - { - string json = @"{ + [Test] + public void DeserializeCamelCaseAndStringEnums() + { + string json = @"{ ""pattern"": ""abc"", ""options"": ""ignoreCase"" }"; - - Regex regex = JsonConvert.DeserializeObject(json, new JsonSerializerSettings - { - Converters = { new RegexConverter() } - }); - Assert.AreEqual("abc", regex.ToString()); - Assert.AreEqual(RegexOptions.IgnoreCase, regex.Options); - } + Regex regex = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + Converters = { new RegexConverter() } + }); - [Test] - public void DeserializeISerializeRegexJson() - { - string json = @"{ + Assert.AreEqual("abc", regex.ToString()); + Assert.AreEqual(RegexOptions.IgnoreCase, regex.Options); + } + + [Test] + public void DeserializeISerializeRegexJson() + { + string json = @"{ ""Regex"": { ""pattern"": ""(hi)"", ""options"": 5, @@ -114,125 +114,125 @@ namespace Newtonsoft.Json.Tests.Converters } }"; - RegexTestClass r = JsonConvert.DeserializeObject(json); + RegexTestClass r = JsonConvert.DeserializeObject(json); - Assert.AreEqual("(hi)", r.Regex.ToString()); - Assert.AreEqual(RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture, r.Regex.Options); - } + Assert.AreEqual("(hi)", r.Regex.ToString()); + Assert.AreEqual(RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture, r.Regex.Options); + } - [Test] - public void SerializeToBson() - { - Regex regex = new Regex("abc", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); + [Test] + public void SerializeToBson() + { + Regex regex = new Regex("abc", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); - MemoryStream ms = new MemoryStream(); - BsonWriter writer = new BsonWriter(ms); - JsonSerializer serializer = new JsonSerializer(); - serializer.Converters.Add(new RegexConverter()); + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); + JsonSerializer serializer = new JsonSerializer(); + serializer.Converters.Add(new RegexConverter()); - serializer.Serialize(writer, new RegexTestClass { Regex = regex }); + serializer.Serialize(writer, new RegexTestClass { Regex = regex }); - string expected = "13-00-00-00-0B-52-65-67-65-78-00-61-62-63-00-69-75-00-00"; - string bson = BytesToHex(ms.ToArray()); + string expected = "13-00-00-00-0B-52-65-67-65-78-00-61-62-63-00-69-75-00-00"; + string bson = BytesToHex(ms.ToArray()); - Assert.AreEqual(expected, bson); - } + Assert.AreEqual(expected, bson); + } - [Test] - public void DeserializeFromText() - { - string json = @"{ + [Test] + public void DeserializeFromText() + { + string json = @"{ ""Pattern"": ""abc"", ""Options"": 513 }"; - Regex newRegex = JsonConvert.DeserializeObject(json, new RegexConverter()); - Assert.AreEqual("abc", newRegex.ToString()); - Assert.AreEqual(RegexOptions.IgnoreCase | RegexOptions.CultureInvariant, newRegex.Options); - } + Regex newRegex = JsonConvert.DeserializeObject(json, new RegexConverter()); + Assert.AreEqual("abc", newRegex.ToString()); + Assert.AreEqual(RegexOptions.IgnoreCase | RegexOptions.CultureInvariant, newRegex.Options); + } - [Test] - public void DeserializeFromBson() - { - MemoryStream ms = new MemoryStream(HexToBytes("13-00-00-00-0B-52-65-67-65-78-00-61-62-63-00-69-75-00-00")); - BsonReader reader = new BsonReader(ms); - JsonSerializer serializer = new JsonSerializer(); - serializer.Converters.Add(new RegexConverter()); + [Test] + public void DeserializeFromBson() + { + MemoryStream ms = new MemoryStream(HexToBytes("13-00-00-00-0B-52-65-67-65-78-00-61-62-63-00-69-75-00-00")); + BsonReader reader = new BsonReader(ms); + JsonSerializer serializer = new JsonSerializer(); + serializer.Converters.Add(new RegexConverter()); - RegexTestClass c = serializer.Deserialize(reader); + RegexTestClass c = serializer.Deserialize(reader); - Assert.AreEqual("abc", c.Regex.ToString()); - Assert.AreEqual(RegexOptions.IgnoreCase, c.Regex.Options); - } + Assert.AreEqual("abc", c.Regex.ToString()); + Assert.AreEqual(RegexOptions.IgnoreCase, c.Regex.Options); + } - [Test] - public void ConvertEmptyRegexBson() - { - Regex regex = new Regex(string.Empty); + [Test] + public void ConvertEmptyRegexBson() + { + Regex regex = new Regex(string.Empty); - MemoryStream ms = new MemoryStream(); - BsonWriter writer = new BsonWriter(ms); - JsonSerializer serializer = new JsonSerializer(); - serializer.Converters.Add(new RegexConverter()); + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); + JsonSerializer serializer = new JsonSerializer(); + serializer.Converters.Add(new RegexConverter()); - serializer.Serialize(writer, new RegexTestClass { Regex = regex }); + serializer.Serialize(writer, new RegexTestClass { Regex = regex }); - ms.Seek(0, SeekOrigin.Begin); - BsonReader reader = new BsonReader(ms); - serializer.Converters.Add(new RegexConverter()); + ms.Seek(0, SeekOrigin.Begin); + BsonReader reader = new BsonReader(ms); + serializer.Converters.Add(new RegexConverter()); - RegexTestClass c = serializer.Deserialize(reader); + RegexTestClass c = serializer.Deserialize(reader); - Assert.AreEqual("", c.Regex.ToString()); - Assert.AreEqual(RegexOptions.None, c.Regex.Options); - } + Assert.AreEqual("", c.Regex.ToString()); + Assert.AreEqual(RegexOptions.None, c.Regex.Options); + } - [Test] - public void ConvertRegexWithAllOptionsBson() - { - Regex regex = new Regex( - "/", - RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Multiline | RegexOptions.ExplicitCapture); + [Test] + public void ConvertRegexWithAllOptionsBson() + { + Regex regex = new Regex( + "/", + RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Multiline | RegexOptions.ExplicitCapture); - MemoryStream ms = new MemoryStream(); - BsonWriter writer = new BsonWriter(ms); - JsonSerializer serializer = new JsonSerializer(); - serializer.Converters.Add(new RegexConverter()); + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); + JsonSerializer serializer = new JsonSerializer(); + serializer.Converters.Add(new RegexConverter()); - serializer.Serialize(writer, new RegexTestClass { Regex = regex }); + serializer.Serialize(writer, new RegexTestClass { Regex = regex }); - string expected = "14-00-00-00-0B-52-65-67-65-78-00-2F-00-69-6D-73-75-78-00-00"; - string bson = BytesToHex(ms.ToArray()); + string expected = "14-00-00-00-0B-52-65-67-65-78-00-2F-00-69-6D-73-75-78-00-00"; + string bson = BytesToHex(ms.ToArray()); - Assert.AreEqual(expected, bson); + Assert.AreEqual(expected, bson); - ms.Seek(0, SeekOrigin.Begin); - BsonReader reader = new BsonReader(ms); - serializer.Converters.Add(new RegexConverter()); + ms.Seek(0, SeekOrigin.Begin); + BsonReader reader = new BsonReader(ms); + serializer.Converters.Add(new RegexConverter()); - RegexTestClass c = serializer.Deserialize(reader); + RegexTestClass c = serializer.Deserialize(reader); - Assert.AreEqual("/", c.Regex.ToString()); - Assert.AreEqual(RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Multiline | RegexOptions.ExplicitCapture, c.Regex.Options); - } + Assert.AreEqual("/", c.Regex.ToString()); + Assert.AreEqual(RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Multiline | RegexOptions.ExplicitCapture, c.Regex.Options); + } - [Test] - public void ConvertEmptyRegexJson() - { - Regex regex = new Regex(""); + [Test] + public void ConvertEmptyRegexJson() + { + Regex regex = new Regex(""); - string json = JsonConvert.SerializeObject(new RegexTestClass { Regex = regex }, Formatting.Indented, new RegexConverter()); + string json = JsonConvert.SerializeObject(new RegexTestClass { Regex = regex }, Formatting.Indented, new RegexConverter()); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Regex"": { ""Pattern"": """", ""Options"": 0 } }", json); - RegexTestClass newRegex = JsonConvert.DeserializeObject(json, new RegexConverter()); - Assert.AreEqual("", newRegex.Regex.ToString()); - Assert.AreEqual(RegexOptions.None, newRegex.Regex.Options); + RegexTestClass newRegex = JsonConvert.DeserializeObject(json, new RegexConverter()); + Assert.AreEqual("", newRegex.Regex.ToString()); + Assert.AreEqual(RegexOptions.None, newRegex.Regex.Options); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Converters/StringEnumConverterTests.cs b/Src/Newtonsoft.Json.Tests/Converters/StringEnumConverterTests.cs index 1ed30fbf..feff2573 100644 --- a/Src/Newtonsoft.Json.Tests/Converters/StringEnumConverterTests.cs +++ b/Src/Newtonsoft.Json.Tests/Converters/StringEnumConverterTests.cs @@ -42,350 +42,350 @@ using Newtonsoft.Json.Tests.TestObjects; namespace Newtonsoft.Json.Tests.Converters { - [TestFixture] - public class StringEnumConverterTests : TestFixtureBase - { - public class EnumClass + [TestFixture] + public class StringEnumConverterTests : TestFixtureBase { - public StoreColor StoreColor { get; set; } - public StoreColor? NullableStoreColor1 { get; set; } - public StoreColor? NullableStoreColor2 { get; set; } - } + public class EnumClass + { + public StoreColor StoreColor { get; set; } + public StoreColor? NullableStoreColor1 { get; set; } + public StoreColor? NullableStoreColor2 { get; set; } + } - public class EnumContainer - { - public T Enum { get; set; } - } + public class EnumContainer + { + public T Enum { get; set; } + } - [Flags] - public enum FlagsTestEnum - { - Default = 0, - First = 1, - Second = 2 - } + [Flags] + public enum FlagsTestEnum + { + Default = 0, + First = 1, + Second = 2 + } - public enum NegativeEnum - { - Negative = -1, - Zero = 0, - Positive = 1 - } + public enum NegativeEnum + { + Negative = -1, + Zero = 0, + Positive = 1 + } #if !NET20 - public enum NamedEnum - { - [EnumMember(Value = "@first")] - First, + public enum NamedEnum + { + [EnumMember(Value = "@first")] + First, - [EnumMember(Value = "@second")] - Second, - Third - } + [EnumMember(Value = "@second")] + Second, + Third + } - public enum NamedEnumDuplicate - { - [EnumMember(Value = "Third")] - First, + public enum NamedEnumDuplicate + { + [EnumMember(Value = "Third")] + First, - [EnumMember(Value = "@second")] - Second, - Third - } + [EnumMember(Value = "@second")] + Second, + Third + } #endif - public class NegativeEnumClass - { - public NegativeEnum Value1 { get; set; } - public NegativeEnum Value2 { get; set; } - } + public class NegativeEnumClass + { + public NegativeEnum Value1 { get; set; } + public NegativeEnum Value2 { get; set; } + } #if !NET20 - [Test] - public void NamedEnumDuplicateTest() - { - ExceptionAssert.Throws("Enum name 'Third' already exists on enum 'NamedEnumDuplicate'.", - () => - { - EnumContainer c = new EnumContainer - { - Enum = NamedEnumDuplicate.First - }; + [Test] + public void NamedEnumDuplicateTest() + { + ExceptionAssert.Throws("Enum name 'Third' already exists on enum 'NamedEnumDuplicate'.", + () => + { + EnumContainer c = new EnumContainer + { + Enum = NamedEnumDuplicate.First + }; - JsonConvert.SerializeObject(c, Formatting.Indented, new StringEnumConverter()); - }); - } + JsonConvert.SerializeObject(c, Formatting.Indented, new StringEnumConverter()); + }); + } - [Test] - public void SerializeNameEnumTest() - { - EnumContainer c = new EnumContainer - { - Enum = NamedEnum.First - }; - - string json = JsonConvert.SerializeObject(c, Formatting.Indented, new StringEnumConverter()); - Assert.AreEqual(@"{ - ""Enum"": ""@first"" -}", json); - - c = new EnumContainer + [Test] + public void SerializeNameEnumTest() + { + EnumContainer c = new EnumContainer { - Enum = NamedEnum.Third + Enum = NamedEnum.First }; - json = JsonConvert.SerializeObject(c, Formatting.Indented, new StringEnumConverter()); - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(c, Formatting.Indented, new StringEnumConverter()); + Assert.AreEqual(@"{ + ""Enum"": ""@first"" +}", json); + + c = new EnumContainer + { + Enum = NamedEnum.Third + }; + + json = JsonConvert.SerializeObject(c, Formatting.Indented, new StringEnumConverter()); + Assert.AreEqual(@"{ ""Enum"": ""Third"" }", json); - } + } - [Test] - public void DeserializeNameEnumTest() - { - string json = @"{ + [Test] + public void DeserializeNameEnumTest() + { + string json = @"{ ""Enum"": ""@first"" }"; - EnumContainer c = JsonConvert.DeserializeObject>(json, new StringEnumConverter()); - Assert.AreEqual(NamedEnum.First, c.Enum); + EnumContainer c = JsonConvert.DeserializeObject>(json, new StringEnumConverter()); + Assert.AreEqual(NamedEnum.First, c.Enum); - json = @"{ + json = @"{ ""Enum"": ""Third"" }"; - c = JsonConvert.DeserializeObject>(json, new StringEnumConverter()); - Assert.AreEqual(NamedEnum.Third, c.Enum); - } + c = JsonConvert.DeserializeObject>(json, new StringEnumConverter()); + Assert.AreEqual(NamedEnum.Third, c.Enum); + } #endif - [Test] - public void SerializeEnumClass() - { - EnumClass enumClass = new EnumClass(); - enumClass.StoreColor = StoreColor.Red; - enumClass.NullableStoreColor1 = StoreColor.White; - enumClass.NullableStoreColor2 = null; + [Test] + public void SerializeEnumClass() + { + EnumClass enumClass = new EnumClass(); + enumClass.StoreColor = StoreColor.Red; + enumClass.NullableStoreColor1 = StoreColor.White; + enumClass.NullableStoreColor2 = null; - string json = JsonConvert.SerializeObject(enumClass, Formatting.Indented, new StringEnumConverter()); + string json = JsonConvert.SerializeObject(enumClass, Formatting.Indented, new StringEnumConverter()); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""StoreColor"": ""Red"", ""NullableStoreColor1"": ""White"", ""NullableStoreColor2"": null }", json); - } + } - [Test] - public void SerializeEnumClassWithCamelCase() - { - EnumClass enumClass = new EnumClass(); - enumClass.StoreColor = StoreColor.Red; - enumClass.NullableStoreColor1 = StoreColor.DarkGoldenrod; - enumClass.NullableStoreColor2 = null; + [Test] + public void SerializeEnumClassWithCamelCase() + { + EnumClass enumClass = new EnumClass(); + enumClass.StoreColor = StoreColor.Red; + enumClass.NullableStoreColor1 = StoreColor.DarkGoldenrod; + enumClass.NullableStoreColor2 = null; - string json = JsonConvert.SerializeObject(enumClass, Formatting.Indented, new StringEnumConverter {CamelCaseText = true}); + string json = JsonConvert.SerializeObject(enumClass, Formatting.Indented, new StringEnumConverter { CamelCaseText = true }); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""StoreColor"": ""red"", ""NullableStoreColor1"": ""darkGoldenrod"", ""NullableStoreColor2"": null }", json); - } + } - [Test] - public void SerializeEnumClassUndefined() - { - EnumClass enumClass = new EnumClass(); - enumClass.StoreColor = (StoreColor) 1000; - enumClass.NullableStoreColor1 = (StoreColor) 1000; - enumClass.NullableStoreColor2 = null; + [Test] + public void SerializeEnumClassUndefined() + { + EnumClass enumClass = new EnumClass(); + enumClass.StoreColor = (StoreColor)1000; + enumClass.NullableStoreColor1 = (StoreColor)1000; + enumClass.NullableStoreColor2 = null; - string json = JsonConvert.SerializeObject(enumClass, Formatting.Indented, new StringEnumConverter()); + string json = JsonConvert.SerializeObject(enumClass, Formatting.Indented, new StringEnumConverter()); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""StoreColor"": 1000, ""NullableStoreColor1"": 1000, ""NullableStoreColor2"": null }", json); - } + } - [Test] - public void SerializeFlagEnum() - { - EnumClass enumClass = new EnumClass(); - enumClass.StoreColor = StoreColor.Red | StoreColor.White; - enumClass.NullableStoreColor1 = StoreColor.White & StoreColor.Yellow; - enumClass.NullableStoreColor2 = StoreColor.Red | StoreColor.White | StoreColor.Black; + [Test] + public void SerializeFlagEnum() + { + EnumClass enumClass = new EnumClass(); + enumClass.StoreColor = StoreColor.Red | StoreColor.White; + enumClass.NullableStoreColor1 = StoreColor.White & StoreColor.Yellow; + enumClass.NullableStoreColor2 = StoreColor.Red | StoreColor.White | StoreColor.Black; - string json = JsonConvert.SerializeObject(enumClass, Formatting.Indented, new StringEnumConverter()); + string json = JsonConvert.SerializeObject(enumClass, Formatting.Indented, new StringEnumConverter()); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""StoreColor"": ""Red, White"", ""NullableStoreColor1"": 0, ""NullableStoreColor2"": ""Black, Red, White"" }", json); - } + } - [Test] - public void SerializeNegativeEnum() - { - NegativeEnumClass negativeEnumClass = new NegativeEnumClass(); - negativeEnumClass.Value1 = NegativeEnum.Negative; - negativeEnumClass.Value2 = (NegativeEnum) int.MinValue; + [Test] + public void SerializeNegativeEnum() + { + NegativeEnumClass negativeEnumClass = new NegativeEnumClass(); + negativeEnumClass.Value1 = NegativeEnum.Negative; + negativeEnumClass.Value2 = (NegativeEnum)int.MinValue; - string json = JsonConvert.SerializeObject(negativeEnumClass, Formatting.Indented, new StringEnumConverter()); + string json = JsonConvert.SerializeObject(negativeEnumClass, Formatting.Indented, new StringEnumConverter()); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Value1"": ""Negative"", ""Value2"": -2147483648 }", json); - } + } - [Test] - public void DeserializeNegativeEnum() - { - string json = @"{ + [Test] + public void DeserializeNegativeEnum() + { + string json = @"{ ""Value1"": ""Negative"", ""Value2"": -2147483648 }"; - NegativeEnumClass negativeEnumClass = JsonConvert.DeserializeObject(json, new StringEnumConverter()); + NegativeEnumClass negativeEnumClass = JsonConvert.DeserializeObject(json, new StringEnumConverter()); - Assert.AreEqual(NegativeEnum.Negative, negativeEnumClass.Value1); - Assert.AreEqual((NegativeEnum) int.MinValue, negativeEnumClass.Value2); - } + Assert.AreEqual(NegativeEnum.Negative, negativeEnumClass.Value1); + Assert.AreEqual((NegativeEnum)int.MinValue, negativeEnumClass.Value2); + } - [Test] - public void DeserializeFlagEnum() - { - string json = @"{ + [Test] + public void DeserializeFlagEnum() + { + string json = @"{ ""StoreColor"": ""Red, White"", ""NullableStoreColor1"": 0, ""NullableStoreColor2"": ""black, Red, White"" }"; - EnumClass enumClass = JsonConvert.DeserializeObject(json, new StringEnumConverter()); + EnumClass enumClass = JsonConvert.DeserializeObject(json, new StringEnumConverter()); - Assert.AreEqual(StoreColor.Red | StoreColor.White, enumClass.StoreColor); - Assert.AreEqual((StoreColor) 0, enumClass.NullableStoreColor1); - Assert.AreEqual(StoreColor.Red | StoreColor.White | StoreColor.Black, enumClass.NullableStoreColor2); - } + Assert.AreEqual(StoreColor.Red | StoreColor.White, enumClass.StoreColor); + Assert.AreEqual((StoreColor)0, enumClass.NullableStoreColor1); + Assert.AreEqual(StoreColor.Red | StoreColor.White | StoreColor.Black, enumClass.NullableStoreColor2); + } - [Test] - public void DeserializeEnumClass() - { - string json = @"{ + [Test] + public void DeserializeEnumClass() + { + string json = @"{ ""StoreColor"": ""Red"", ""NullableStoreColor1"": ""White"", ""NullableStoreColor2"": null }"; - EnumClass enumClass = JsonConvert.DeserializeObject(json, new StringEnumConverter()); + EnumClass enumClass = JsonConvert.DeserializeObject(json, new StringEnumConverter()); - Assert.AreEqual(StoreColor.Red, enumClass.StoreColor); - Assert.AreEqual(StoreColor.White, enumClass.NullableStoreColor1); - Assert.AreEqual(null, enumClass.NullableStoreColor2); - } + Assert.AreEqual(StoreColor.Red, enumClass.StoreColor); + Assert.AreEqual(StoreColor.White, enumClass.NullableStoreColor1); + Assert.AreEqual(null, enumClass.NullableStoreColor2); + } - [Test] - public void DeserializeEnumClassUndefined() - { - string json = @"{ + [Test] + public void DeserializeEnumClassUndefined() + { + string json = @"{ ""StoreColor"": 1000, ""NullableStoreColor1"": 1000, ""NullableStoreColor2"": null }"; - EnumClass enumClass = JsonConvert.DeserializeObject(json, new StringEnumConverter()); + EnumClass enumClass = JsonConvert.DeserializeObject(json, new StringEnumConverter()); - Assert.AreEqual((StoreColor) 1000, enumClass.StoreColor); - Assert.AreEqual((StoreColor) 1000, enumClass.NullableStoreColor1); - Assert.AreEqual(null, enumClass.NullableStoreColor2); - } + Assert.AreEqual((StoreColor)1000, enumClass.StoreColor); + Assert.AreEqual((StoreColor)1000, enumClass.NullableStoreColor1); + Assert.AreEqual(null, enumClass.NullableStoreColor2); + } - [Test] - public void CamelCaseTextFlagEnumSerialization() - { - EnumContainer c = new EnumContainer - { - Enum = FlagsTestEnum.First | FlagsTestEnum.Second - }; + [Test] + public void CamelCaseTextFlagEnumSerialization() + { + EnumContainer c = new EnumContainer + { + Enum = FlagsTestEnum.First | FlagsTestEnum.Second + }; - string json = JsonConvert.SerializeObject(c, Formatting.Indented, new StringEnumConverter {CamelCaseText = true}); - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(c, Formatting.Indented, new StringEnumConverter { CamelCaseText = true }); + Assert.AreEqual(@"{ ""Enum"": ""first, second"" }", json); - } + } - [Test] - public void CamelCaseTextFlagEnumDeserialization() - { - string json = @"{ + [Test] + public void CamelCaseTextFlagEnumDeserialization() + { + string json = @"{ ""Enum"": ""first, second"" }"; - EnumContainer c = JsonConvert.DeserializeObject>(json, new StringEnumConverter {CamelCaseText = true}); - Assert.AreEqual(FlagsTestEnum.First | FlagsTestEnum.Second, c.Enum); - } + EnumContainer c = JsonConvert.DeserializeObject>(json, new StringEnumConverter { CamelCaseText = true }); + Assert.AreEqual(FlagsTestEnum.First | FlagsTestEnum.Second, c.Enum); + } - [Test] - public void DeserializeEmptyStringIntoNullable() - { - string json = @"{ + [Test] + public void DeserializeEmptyStringIntoNullable() + { + string json = @"{ ""StoreColor"": ""Red"", ""NullableStoreColor1"": ""White"", ""NullableStoreColor2"": """" }"; - EnumClass c = JsonConvert.DeserializeObject(json, new StringEnumConverter()); - Assert.IsNull(c.NullableStoreColor2); - } + EnumClass c = JsonConvert.DeserializeObject(json, new StringEnumConverter()); + Assert.IsNull(c.NullableStoreColor2); + } - [Test] - public void DeserializeInvalidString() - { - string json = "{ \"Value\" : \"Three\" }"; + [Test] + public void DeserializeInvalidString() + { + string json = "{ \"Value\" : \"Three\" }"; - ExceptionAssert.Throws( - @"Error converting value ""Three"" to type 'Newtonsoft.Json.Tests.Converters.StringEnumConverterTests+MyEnum'. Path 'Value', line 1, position 19.", - () => - { - var serializer = new JsonSerializer(); - serializer.Converters.Add(new StringEnumConverter()); - serializer.Deserialize(new JsonTextReader(new StringReader(json))); - }); - } + ExceptionAssert.Throws( + @"Error converting value ""Three"" to type 'Newtonsoft.Json.Tests.Converters.StringEnumConverterTests+MyEnum'. Path 'Value', line 1, position 19.", + () => + { + var serializer = new JsonSerializer(); + serializer.Converters.Add(new StringEnumConverter()); + serializer.Deserialize(new JsonTextReader(new StringReader(json))); + }); + } - public class Bucket - { - public MyEnum Value; - } + public class Bucket + { + public MyEnum Value; + } - public enum MyEnum - { - Alpha, - Beta, - } + public enum MyEnum + { + Alpha, + Beta, + } #if !NET20 - [Test] - public void EnumMemberPlusFlags() - { - List lfoo = - new List - { - Foo.Bat | Foo.SerializeAsBaz, - Foo.FooBar, - Foo.Bat, - Foo.SerializeAsBaz, - Foo.FooBar | Foo.SerializeAsBaz, - (Foo) int.MaxValue - }; + [Test] + public void EnumMemberPlusFlags() + { + List lfoo = + new List + { + Foo.Bat | Foo.SerializeAsBaz, + Foo.FooBar, + Foo.Bat, + Foo.SerializeAsBaz, + Foo.FooBar | Foo.SerializeAsBaz, + (Foo)int.MaxValue + }; - string json1 = JsonConvert.SerializeObject(lfoo, Formatting.Indented, new StringEnumConverter {CamelCaseText = true}); + string json1 = JsonConvert.SerializeObject(lfoo, Formatting.Indented, new StringEnumConverter { CamelCaseText = true }); - Assert.AreEqual(@"[ + Assert.AreEqual(@"[ ""Bat, baz"", ""foo_bar"", ""Bat"", @@ -394,57 +394,57 @@ namespace Newtonsoft.Json.Tests.Converters 2147483647 ]", json1); - IList foos = JsonConvert.DeserializeObject>(json1); + IList foos = JsonConvert.DeserializeObject>(json1); - Assert.AreEqual(6, foos.Count); - Assert.AreEqual(Foo.Bat | Foo.SerializeAsBaz, foos[0]); - Assert.AreEqual(Foo.FooBar, foos[1]); - Assert.AreEqual(Foo.Bat, foos[2]); - Assert.AreEqual(Foo.SerializeAsBaz, foos[3]); - Assert.AreEqual(Foo.FooBar | Foo.SerializeAsBaz, foos[4]); - Assert.AreEqual((Foo) int.MaxValue, foos[5]); + Assert.AreEqual(6, foos.Count); + Assert.AreEqual(Foo.Bat | Foo.SerializeAsBaz, foos[0]); + Assert.AreEqual(Foo.FooBar, foos[1]); + Assert.AreEqual(Foo.Bat, foos[2]); + Assert.AreEqual(Foo.SerializeAsBaz, foos[3]); + Assert.AreEqual(Foo.FooBar | Foo.SerializeAsBaz, foos[4]); + Assert.AreEqual((Foo)int.MaxValue, foos[5]); - List lbar = new List() {Bar.FooBar, Bar.Bat, Bar.SerializeAsBaz}; + List lbar = new List() { Bar.FooBar, Bar.Bat, Bar.SerializeAsBaz }; - string json2 = JsonConvert.SerializeObject(lbar, Formatting.Indented, new StringEnumConverter {CamelCaseText = true}); + string json2 = JsonConvert.SerializeObject(lbar, Formatting.Indented, new StringEnumConverter { CamelCaseText = true }); - Assert.AreEqual(@"[ + Assert.AreEqual(@"[ ""foo_bar"", ""Bat"", ""baz"" ]", json2); - IList bars = JsonConvert.DeserializeObject>(json2); + IList bars = JsonConvert.DeserializeObject>(json2); - Assert.AreEqual(3, bars.Count); - Assert.AreEqual(Bar.FooBar, bars[0]); - Assert.AreEqual(Bar.Bat, bars[1]); - Assert.AreEqual(Bar.SerializeAsBaz, bars[2]); - } + Assert.AreEqual(3, bars.Count); + Assert.AreEqual(Bar.FooBar, bars[0]); + Assert.AreEqual(Bar.Bat, bars[1]); + Assert.AreEqual(Bar.SerializeAsBaz, bars[2]); + } - // Define other methods and classes here - [Flags] - [JsonConverter(typeof (StringEnumConverter))] - private enum Foo - { - [EnumMember(Value = "foo_bar")] - FooBar = 0x01, - Bat = 0x02, + // Define other methods and classes here + [Flags] + [JsonConverter(typeof(StringEnumConverter))] + private enum Foo + { + [EnumMember(Value = "foo_bar")] + FooBar = 0x01, + Bat = 0x02, - [EnumMember(Value = "baz")] - SerializeAsBaz = 0x4, - }; + [EnumMember(Value = "baz")] + SerializeAsBaz = 0x4, + }; - [JsonConverter(typeof (StringEnumConverter))] - private enum Bar - { - [EnumMember(Value = "foo_bar")] - FooBar, - Bat, + [JsonConverter(typeof(StringEnumConverter))] + private enum Bar + { + [EnumMember(Value = "foo_bar")] + FooBar, + Bat, - [EnumMember(Value = "baz")] - SerializeAsBaz - }; + [EnumMember(Value = "baz")] + SerializeAsBaz + }; #endif - } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Converters/VersionConverterTests.cs b/Src/Newtonsoft.Json.Tests/Converters/VersionConverterTests.cs index 8d445d9c..0bfe6603 100644 --- a/Src/Newtonsoft.Json.Tests/Converters/VersionConverterTests.cs +++ b/Src/Newtonsoft.Json.Tests/Converters/VersionConverterTests.cs @@ -27,6 +27,7 @@ using System; using Newtonsoft.Json.Converters; #if !NETFX_CORE using NUnit.Framework; + #else using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; @@ -35,96 +36,96 @@ using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAtt namespace Newtonsoft.Json.Tests.Converters { - public class VersionClass - { - public VersionClass(string version1, string version2) + public class VersionClass { - this.StringProperty1 = "StringProperty1"; - this.Version1 = new Version(version1); - this.Version2 = new Version(version2); - this.StringProperty2 = "StringProperty2"; + public VersionClass(string version1, string version2) + { + StringProperty1 = "StringProperty1"; + Version1 = new Version(version1); + Version2 = new Version(version2); + StringProperty2 = "StringProperty2"; + } + + public VersionClass() + { + } + + public string StringProperty1 { get; set; } + public Version Version1 { get; set; } + public Version Version2 { get; set; } + public string StringProperty2 { get; set; } } - public VersionClass() + [TestFixture] + public class VersionConverterTests : TestFixtureBase { - } + private void SerializeVersionClass(string version1, string version2) + { + VersionClass versionClass = new VersionClass(version1, version2); - public string StringProperty1 { get; set; } - public Version Version1 { get; set; } - public Version Version2 { get; set; } - public string StringProperty2 { get; set; } - } + string json = JsonConvert.SerializeObject(versionClass, Formatting.Indented, new VersionConverter()); - [TestFixture] - public class VersionConverterTests : TestFixtureBase - { - private void SerializeVersionClass(string version1, string version2) - { - VersionClass versionClass = new VersionClass(version1, version2); - - string json = JsonConvert.SerializeObject(versionClass, Formatting.Indented, new VersionConverter()); - - string expectedJson = string.Format(@"{{ + string expectedJson = string.Format(@"{{ ""StringProperty1"": ""StringProperty1"", ""Version1"": ""{0}"", ""Version2"": ""{1}"", ""StringProperty2"": ""StringProperty2"" }}", version1, version2); - Assert.AreEqual(expectedJson, json); + Assert.AreEqual(expectedJson, json); + } + + [Test] + public void SerializeVersionClass() + { + SerializeVersionClass("1.0.0.0", "2.0.0.0"); + SerializeVersionClass("1.2.0.0", "2.3.0.0"); + SerializeVersionClass("1.2.3.0", "2.3.4.0"); + SerializeVersionClass("1.2.3.4", "2.3.4.5"); + + SerializeVersionClass("1.2", "2.3"); + SerializeVersionClass("1.2.3", "2.3.4"); + SerializeVersionClass("1.2.3.4", "2.3.4.5"); + } + + private void DeserializeVersionClass(string version1, string version2) + { + string json = string.Format(@"{{""StringProperty1"": ""StringProperty1"", ""Version1"": ""{0}"", ""Version2"": ""{1}"", ""StringProperty2"": ""StringProperty2""}}", version1, version2); + Version expectedVersion1 = new Version(version1); + Version expectedVersion2 = new Version(version2); + + VersionClass versionClass = JsonConvert.DeserializeObject(json, new VersionConverter()); + + Assert.AreEqual("StringProperty1", versionClass.StringProperty1); + Assert.AreEqual(expectedVersion1, versionClass.Version1); + Assert.AreEqual(expectedVersion2, versionClass.Version2); + Assert.AreEqual("StringProperty2", versionClass.StringProperty2); + } + + [Test] + public void DeserializeVersionClass() + { + DeserializeVersionClass("1.0.0.0", "2.0.0.0"); + DeserializeVersionClass("1.2.0.0", "2.3.0.0"); + DeserializeVersionClass("1.2.3.0", "2.3.4.0"); + DeserializeVersionClass("1.2.3.4", "2.3.4.5"); + + DeserializeVersionClass("1.2", "2.3"); + DeserializeVersionClass("1.2.3", "2.3.4"); + DeserializeVersionClass("1.2.3.4", "2.3.4.5"); + } + + [Test] + public void RoundtripImplicitConverter() + { + var version = new Version(1, 0, 0, 0); + string reportJSON = JsonConvert.SerializeObject(version); + + //Test + Version report2 = JsonConvert.DeserializeObject(reportJSON); + string reportJSON2 = JsonConvert.SerializeObject(report2); + + Assert.AreEqual(reportJSON, reportJSON2); + } } - - [Test] - public void SerializeVersionClass() - { - SerializeVersionClass("1.0.0.0", "2.0.0.0"); - SerializeVersionClass("1.2.0.0", "2.3.0.0"); - SerializeVersionClass("1.2.3.0", "2.3.4.0"); - SerializeVersionClass("1.2.3.4", "2.3.4.5"); - - SerializeVersionClass("1.2", "2.3"); - SerializeVersionClass("1.2.3", "2.3.4"); - SerializeVersionClass("1.2.3.4", "2.3.4.5"); - } - - private void DeserializeVersionClass(string version1, string version2) - { - string json = string.Format(@"{{""StringProperty1"": ""StringProperty1"", ""Version1"": ""{0}"", ""Version2"": ""{1}"", ""StringProperty2"": ""StringProperty2""}}", version1, version2); - Version expectedVersion1 = new Version(version1); - Version expectedVersion2 = new Version(version2); - - VersionClass versionClass = JsonConvert.DeserializeObject(json, new VersionConverter()); - - Assert.AreEqual("StringProperty1", versionClass.StringProperty1); - Assert.AreEqual(expectedVersion1, versionClass.Version1); - Assert.AreEqual(expectedVersion2, versionClass.Version2); - Assert.AreEqual("StringProperty2", versionClass.StringProperty2); - } - - [Test] - public void DeserializeVersionClass() - { - DeserializeVersionClass("1.0.0.0", "2.0.0.0"); - DeserializeVersionClass("1.2.0.0", "2.3.0.0"); - DeserializeVersionClass("1.2.3.0", "2.3.4.0"); - DeserializeVersionClass("1.2.3.4", "2.3.4.5"); - - DeserializeVersionClass("1.2", "2.3"); - DeserializeVersionClass("1.2.3", "2.3.4"); - DeserializeVersionClass("1.2.3.4", "2.3.4.5"); - } - - [Test] - public void RoundtripImplicitConverter() - { - var version = new Version(1, 0, 0, 0); - string reportJSON = JsonConvert.SerializeObject(version); - - //Test - Version report2 = JsonConvert.DeserializeObject(reportJSON); - string reportJSON2 = JsonConvert.SerializeObject(report2); - - Assert.AreEqual(reportJSON, reportJSON2); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs b/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs index c6278a2f..614e444d 100644 --- a/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs +++ b/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs @@ -43,110 +43,111 @@ using Newtonsoft.Json.Utilities; using Newtonsoft.Json.Linq; #if !NET20 using System.Xml.Linq; + #endif namespace Newtonsoft.Json.Tests.Converters { - [TestFixture] - public class XmlNodeConverterTest : TestFixtureBase - { - private string SerializeXmlNode(XmlNode node) + [TestFixture] + public class XmlNodeConverterTest : TestFixtureBase { - string json = JsonConvert.SerializeXmlNode(node, Formatting.Indented); - XmlNodeReader reader = new XmlNodeReader(node); + private string SerializeXmlNode(XmlNode node) + { + string json = JsonConvert.SerializeXmlNode(node, Formatting.Indented); + XmlNodeReader reader = new XmlNodeReader(node); #if !NET20 - XObject xNode; - if (node is XmlDocument) - { - xNode = XDocument.Load(reader); - } - else if (node is XmlAttribute) - { - XmlAttribute attribute = (XmlAttribute) node; - xNode = new XAttribute(XName.Get(attribute.LocalName, attribute.NamespaceURI), attribute.Value); - } - else - { - reader.MoveToContent(); - xNode = XNode.ReadFrom(reader); - } + XObject xNode; + if (node is XmlDocument) + { + xNode = XDocument.Load(reader); + } + else if (node is XmlAttribute) + { + XmlAttribute attribute = (XmlAttribute)node; + xNode = new XAttribute(XName.Get(attribute.LocalName, attribute.NamespaceURI), attribute.Value); + } + else + { + reader.MoveToContent(); + xNode = XNode.ReadFrom(reader); + } - string linqJson = JsonConvert.SerializeXNode(xNode, Formatting.Indented); + string linqJson = JsonConvert.SerializeXNode(xNode, Formatting.Indented); - Assert.AreEqual(json, linqJson); + Assert.AreEqual(json, linqJson); #endif - return json; - } + return json; + } - private XmlNode DeserializeXmlNode(string json) - { - return DeserializeXmlNode(json, null); - } + private XmlNode DeserializeXmlNode(string json) + { + return DeserializeXmlNode(json, null); + } - private XmlNode DeserializeXmlNode(string json, string deserializeRootElementName) - { - JsonTextReader reader; + private XmlNode DeserializeXmlNode(string json, string deserializeRootElementName) + { + JsonTextReader reader; - reader = new JsonTextReader(new StringReader(json)); - reader.Read(); - XmlNodeConverter converter = new XmlNodeConverter(); - if (deserializeRootElementName != null) - converter.DeserializeRootElementName = deserializeRootElementName; + reader = new JsonTextReader(new StringReader(json)); + reader.Read(); + XmlNodeConverter converter = new XmlNodeConverter(); + if (deserializeRootElementName != null) + converter.DeserializeRootElementName = deserializeRootElementName; - XmlNode node = (XmlNode)converter.ReadJson(reader, typeof (XmlDocument), null, new JsonSerializer()); + XmlNode node = (XmlNode)converter.ReadJson(reader, typeof(XmlDocument), null, new JsonSerializer()); #if !NET20 - string xmlText = node.OuterXml; + string xmlText = node.OuterXml; - reader = new JsonTextReader(new StringReader(json)); - reader.Read(); - XDocument d = (XDocument) converter.ReadJson(reader, typeof (XDocument), null, new JsonSerializer()); + reader = new JsonTextReader(new StringReader(json)); + reader.Read(); + XDocument d = (XDocument)converter.ReadJson(reader, typeof(XDocument), null, new JsonSerializer()); - string linqXmlText = d.ToString(SaveOptions.DisableFormatting); - if (d.Declaration != null) - linqXmlText = d.Declaration + linqXmlText; + string linqXmlText = d.ToString(SaveOptions.DisableFormatting); + if (d.Declaration != null) + linqXmlText = d.Declaration + linqXmlText; - Assert.AreEqual(xmlText, linqXmlText); + Assert.AreEqual(xmlText, linqXmlText); #endif - return node; - } + return node; + } #if !NET20 - [Test] - public void SerializeEmptyDocument() - { - XmlDocument doc = new XmlDocument(); - doc.LoadXml(""); + [Test] + public void SerializeEmptyDocument() + { + XmlDocument doc = new XmlDocument(); + doc.LoadXml(""); - string json = JsonConvert.SerializeXmlNode(doc, Formatting.Indented, true); - Assert.AreEqual("null", json); + string json = JsonConvert.SerializeXmlNode(doc, Formatting.Indented, true); + Assert.AreEqual("null", json); - doc = new XmlDocument(); - doc.LoadXml(""); + doc = new XmlDocument(); + doc.LoadXml(""); - json = JsonConvert.SerializeXmlNode(doc, Formatting.Indented, true); - Assert.AreEqual("null", json); + json = JsonConvert.SerializeXmlNode(doc, Formatting.Indented, true); + Assert.AreEqual("null", json); - XDocument doc1 = XDocument.Parse(""); + XDocument doc1 = XDocument.Parse(""); - json = JsonConvert.SerializeXNode(doc1, Formatting.Indented, true); - Assert.AreEqual("null", json); + json = JsonConvert.SerializeXNode(doc1, Formatting.Indented, true); + Assert.AreEqual("null", json); - doc1 = XDocument.Parse(""); + doc1 = XDocument.Parse(""); - json = JsonConvert.SerializeXNode(doc1, Formatting.Indented, true); - Assert.AreEqual("null", json); - } + json = JsonConvert.SerializeXNode(doc1, Formatting.Indented, true); + Assert.AreEqual("null", json); + } #endif - [Test] - public void DocumentSerializeIndented() - { - string xml = @" + [Test] + public void DocumentSerializeIndented() + { + string xml = @" @@ -156,11 +157,11 @@ namespace Newtonsoft.Json.Tests.Converters Argent Hotel, San Francisco, CA "; - XmlDocument doc = new XmlDocument(); - doc.LoadXml(xml); + XmlDocument doc = new XmlDocument(); + doc.LoadXml(xml); - string jsonText = SerializeXmlNode(doc); - string expected = @"{ + string jsonText = SerializeXmlNode(doc); + string expected = @"{ ""?xml"": { ""@version"": ""1.0"", ""@standalone"": ""no"" @@ -198,22 +199,22 @@ namespace Newtonsoft.Json.Tests.Converters } }"; - Assert.AreEqual(expected, jsonText); + Assert.AreEqual(expected, jsonText); - Console.WriteLine("DocumentSerializeIndented"); - Console.WriteLine(jsonText); - Console.WriteLine(); - } + Console.WriteLine("DocumentSerializeIndented"); + Console.WriteLine(jsonText); + Console.WriteLine(); + } - [Test] - public void SerializeNodeTypes() - { - XmlDocument doc = new XmlDocument(); - string jsonText; + [Test] + public void SerializeNodeTypes() + { + XmlDocument doc = new XmlDocument(); + string jsonText; - Console.WriteLine("SerializeNodeTypes"); + Console.WriteLine("SerializeNodeTypes"); - string xml = @" + string xml = @" "; - XmlDocument document = new XmlDocument(); - document.LoadXml(xml); + XmlDocument document = new XmlDocument(); + document.LoadXml(xml); - // XmlAttribute - XmlAttribute attribute = document.DocumentElement.ChildNodes[0].Attributes["IsDataSet", "urn:schemas-microsoft-com:xml-msdata"]; - attribute.Value = "true"; + // XmlAttribute + XmlAttribute attribute = document.DocumentElement.ChildNodes[0].Attributes["IsDataSet", "urn:schemas-microsoft-com:xml-msdata"]; + attribute.Value = "true"; - jsonText = JsonConvert.SerializeXmlNode(attribute); + jsonText = JsonConvert.SerializeXmlNode(attribute); - Console.WriteLine(jsonText); - Assert.AreEqual(@"{""@msdata:IsDataSet"":""true""}", jsonText); + Console.WriteLine(jsonText); + Assert.AreEqual(@"{""@msdata:IsDataSet"":""true""}", jsonText); #if !NET20 - XDocument d = XDocument.Parse(xml); - XAttribute a = d.Root.Element("{http://www.w3.org/2001/XMLSchema}element").Attribute("{urn:schemas-microsoft-com:xml-msdata}IsDataSet"); + XDocument d = XDocument.Parse(xml); + XAttribute a = d.Root.Element("{http://www.w3.org/2001/XMLSchema}element").Attribute("{urn:schemas-microsoft-com:xml-msdata}IsDataSet"); - jsonText = JsonConvert.SerializeXNode(a); + jsonText = JsonConvert.SerializeXNode(a); - Assert.AreEqual(@"{""@msdata:IsDataSet"":""true""}", jsonText); + Assert.AreEqual(@"{""@msdata:IsDataSet"":""true""}", jsonText); #endif - // XmlProcessingInstruction - XmlProcessingInstruction instruction = doc.CreateProcessingInstruction("xml-stylesheet", @"href=""classic.xsl"" type=""text/xml"""); + // XmlProcessingInstruction + XmlProcessingInstruction instruction = doc.CreateProcessingInstruction("xml-stylesheet", @"href=""classic.xsl"" type=""text/xml"""); - jsonText = JsonConvert.SerializeXmlNode(instruction); + jsonText = JsonConvert.SerializeXmlNode(instruction); - Console.WriteLine(jsonText); - Assert.AreEqual(@"{""?xml-stylesheet"":""href=\""classic.xsl\"" type=\""text/xml\""""}", jsonText); + Console.WriteLine(jsonText); + Assert.AreEqual(@"{""?xml-stylesheet"":""href=\""classic.xsl\"" type=\""text/xml\""""}", jsonText); - // XmlProcessingInstruction - XmlCDataSection cDataSection = doc.CreateCDataSection("true"); + // XmlProcessingInstruction + XmlCDataSection cDataSection = doc.CreateCDataSection("true"); - jsonText = JsonConvert.SerializeXmlNode(cDataSection); + jsonText = JsonConvert.SerializeXmlNode(cDataSection); - Console.WriteLine(jsonText); - Assert.AreEqual(@"{""#cdata-section"":""true""}", jsonText); + Console.WriteLine(jsonText); + Assert.AreEqual(@"{""#cdata-section"":""true""}", jsonText); - // XmlElement - XmlElement element = doc.CreateElement("xs", "Choice", "http://www.w3.org/2001/XMLSchema"); - element.SetAttributeNode(doc.CreateAttribute("msdata", "IsDataSet", "urn:schemas-microsoft-com:xml-msdata")); + // XmlElement + XmlElement element = doc.CreateElement("xs", "Choice", "http://www.w3.org/2001/XMLSchema"); + element.SetAttributeNode(doc.CreateAttribute("msdata", "IsDataSet", "urn:schemas-microsoft-com:xml-msdata")); - XmlAttribute aa = doc.CreateAttribute(@"xmlns", "xs", "http://www.w3.org/2000/xmlns/"); - aa.Value = "http://www.w3.org/2001/XMLSchema"; - element.SetAttributeNode(aa); + XmlAttribute aa = doc.CreateAttribute(@"xmlns", "xs", "http://www.w3.org/2000/xmlns/"); + aa.Value = "http://www.w3.org/2001/XMLSchema"; + element.SetAttributeNode(aa); - aa = doc.CreateAttribute(@"xmlns", "msdata", "http://www.w3.org/2000/xmlns/"); - aa.Value = "urn:schemas-microsoft-com:xml-msdata"; - element.SetAttributeNode(aa); + aa = doc.CreateAttribute(@"xmlns", "msdata", "http://www.w3.org/2000/xmlns/"); + aa.Value = "urn:schemas-microsoft-com:xml-msdata"; + element.SetAttributeNode(aa); - element.AppendChild(instruction); - element.AppendChild(cDataSection); + element.AppendChild(instruction); + element.AppendChild(cDataSection); - doc.AppendChild(element); + doc.AppendChild(element); - jsonText = JsonConvert.SerializeXmlNode(element, Formatting.Indented); + jsonText = JsonConvert.SerializeXmlNode(element, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""xs:Choice"": { ""@msdata:IsDataSet"": """", ""@xmlns:xs"": ""http://www.w3.org/2001/XMLSchema"", @@ -289,32 +290,32 @@ namespace Newtonsoft.Json.Tests.Converters ""#cdata-section"": ""true"" } }", jsonText); - } + } - [Test] - public void DocumentFragmentSerialize() - { - XmlDocument doc = new XmlDocument(); + [Test] + public void DocumentFragmentSerialize() + { + XmlDocument doc = new XmlDocument(); - XmlDocumentFragment fragement = doc.CreateDocumentFragment(); + XmlDocumentFragment fragement = doc.CreateDocumentFragment(); - fragement.InnerXml = "widgetwidget"; + fragement.InnerXml = "widgetwidget"; - string jsonText = JsonConvert.SerializeXmlNode(fragement); + string jsonText = JsonConvert.SerializeXmlNode(fragement); - string expected = @"{""Item"":[""widget"",""widget""]}"; + string expected = @"{""Item"":[""widget"",""widget""]}"; - Assert.AreEqual(expected, jsonText); + Assert.AreEqual(expected, jsonText); - Console.WriteLine("DocumentFragmentSerialize"); - Console.WriteLine(jsonText); - Console.WriteLine(); - } + Console.WriteLine("DocumentFragmentSerialize"); + Console.WriteLine(jsonText); + Console.WriteLine(); + } - [Test] - public void NamespaceSerializeDeserialize() - { - string xml = @" + [Test] + public void NamespaceSerializeDeserialize() + { + string xml = @" "; - XmlDocument doc = new XmlDocument(); - doc.LoadXml(xml); + XmlDocument doc = new XmlDocument(); + doc.LoadXml(xml); - string jsonText = SerializeXmlNode(doc); + string jsonText = SerializeXmlNode(doc); - string expected = @"{ + string expected = @"{ ""?xml"": { ""@version"": ""1.0"", ""@encoding"": ""utf-8"" @@ -388,22 +389,22 @@ namespace Newtonsoft.Json.Tests.Converters } }"; - Assert.AreEqual(expected, jsonText); + Assert.AreEqual(expected, jsonText); - XmlDocument deserializedDoc = (XmlDocument)DeserializeXmlNode(jsonText); + XmlDocument deserializedDoc = (XmlDocument)DeserializeXmlNode(jsonText); - Assert.AreEqual(doc.InnerXml, deserializedDoc.InnerXml); + Assert.AreEqual(doc.InnerXml, deserializedDoc.InnerXml); - Console.WriteLine("NamespaceSerializeDeserialize"); - Console.WriteLine(jsonText); - Console.WriteLine(deserializedDoc.InnerXml); - Console.WriteLine(); - } + Console.WriteLine("NamespaceSerializeDeserialize"); + Console.WriteLine(jsonText); + Console.WriteLine(deserializedDoc.InnerXml); + Console.WriteLine(); + } - [Test] - public void DocumentDeserialize() - { - string jsonText = @"{ + [Test] + public void DocumentDeserialize() + { + string jsonText = @"{ ""?xml"": { ""@version"": ""1.0"", ""@standalone"": ""no"" @@ -422,43 +423,43 @@ namespace Newtonsoft.Json.Tests.Converters } }"; - XmlDocument doc = (XmlDocument)DeserializeXmlNode(jsonText); + XmlDocument doc = (XmlDocument)DeserializeXmlNode(jsonText); - string expected = @" + string expected = @" Web 2.0 Conference "; - string formattedXml = GetIndentedInnerXml(doc); + string formattedXml = GetIndentedInnerXml(doc); - Console.WriteLine("DocumentDeserialize"); - Console.WriteLine(formattedXml); - Console.WriteLine(); + Console.WriteLine("DocumentDeserialize"); + Console.WriteLine(formattedXml); + Console.WriteLine(); - Assert.AreEqual(expected, formattedXml); - } + Assert.AreEqual(expected, formattedXml); + } - private string GetIndentedInnerXml(XmlNode node) - { - XmlWriterSettings settings = new XmlWriterSettings(); - settings.Indent = true; + private string GetIndentedInnerXml(XmlNode node) + { + XmlWriterSettings settings = new XmlWriterSettings(); + settings.Indent = true; - StringWriter sw = new StringWriter(); + StringWriter sw = new StringWriter(); - using (XmlWriter writer = XmlWriter.Create(sw, settings)) - { - node.WriteTo(writer); - } + using (XmlWriter writer = XmlWriter.Create(sw, settings)) + { + node.WriteTo(writer); + } - return sw.ToString(); - } + return sw.ToString(); + } - [Test] - public void SingleTextNode() - { - string xml = @" + [Test] + public void SingleTextNode() + { + string xml = @" Alan @@ -470,20 +471,20 @@ namespace Newtonsoft.Json.Tests.Converters "; - XmlDocument doc = new XmlDocument(); - doc.LoadXml(xml); + XmlDocument doc = new XmlDocument(); + doc.LoadXml(xml); - string jsonText = SerializeXmlNode(doc); + string jsonText = SerializeXmlNode(doc); - XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText); + XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText); - Assert.AreEqual(doc.InnerXml, newDoc.InnerXml); - } + Assert.AreEqual(doc.InnerXml, newDoc.InnerXml); + } - [Test] - public void EmptyNode() - { - string xml = @" + [Test] + public void EmptyNode() + { + string xml = @" Alan @@ -495,65 +496,59 @@ namespace Newtonsoft.Json.Tests.Converters "; - XmlDocument doc = new XmlDocument(); - doc.LoadXml(xml); + XmlDocument doc = new XmlDocument(); + doc.LoadXml(xml); - string jsonText = SerializeXmlNode(doc); + string jsonText = SerializeXmlNode(doc); - Console.WriteLine(jsonText); + Console.WriteLine(jsonText); - XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText); + XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText); - Assert.AreEqual(doc.InnerXml, newDoc.InnerXml); - } + Assert.AreEqual(doc.InnerXml, newDoc.InnerXml); + } - [Test] - public void OtherElementDataTypes() - { - string jsonText = @"{""?xml"":{""@version"":""1.0"",""@standalone"":""no""},""root"":{""person"":[{""@id"":""1"",""Float"":2.5,""Integer"":99},{""Boolean"":true,""@id"":""2"",""date"":""\/Date(954374400000)\/""}]}}"; - - XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText); - - string expected = @"2.599true2000-03-30T00:00:00Z"; - - Assert.AreEqual(expected, newDoc.InnerXml); - } - - [Test] - public void NoRootObject() - { - ExceptionAssert.Throws( - "XmlNodeConverter can only convert JSON that begins with an object.", - () => - { - XmlDocument newDoc = (XmlDocument)JsonConvert.DeserializeXmlNode(@"[1]"); - }); - } - - [Test] - public void RootObjectMultipleProperties() - { - ExceptionAssert.Throws( - "JSON root object has multiple properties. The root object must have a single property in order to create a valid XML document. Consider specifing a DeserializeRootElementName.", - () => + [Test] + public void OtherElementDataTypes() { - XmlDocument newDoc = (XmlDocument)JsonConvert.DeserializeXmlNode(@"{Prop1:1,Prop2:2}"); - }); - } + string jsonText = @"{""?xml"":{""@version"":""1.0"",""@standalone"":""no""},""root"":{""person"":[{""@id"":""1"",""Float"":2.5,""Integer"":99},{""Boolean"":true,""@id"":""2"",""date"":""\/Date(954374400000)\/""}]}}"; - [Test] - public void JavaScriptConstructor() - { - string jsonText = @"{root:{r:new Date(34343, 55)}}"; + XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText); - XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText); + string expected = @"2.599true2000-03-30T00:00:00Z"; - string expected = @"3434355"; + Assert.AreEqual(expected, newDoc.InnerXml); + } - Assert.AreEqual(expected, newDoc.InnerXml); + [Test] + public void NoRootObject() + { + ExceptionAssert.Throws( + "XmlNodeConverter can only convert JSON that begins with an object.", + () => { XmlDocument newDoc = (XmlDocument)JsonConvert.DeserializeXmlNode(@"[1]"); }); + } - string json = SerializeXmlNode(newDoc); - expected = @"{ + [Test] + public void RootObjectMultipleProperties() + { + ExceptionAssert.Throws( + "JSON root object has multiple properties. The root object must have a single property in order to create a valid XML document. Consider specifing a DeserializeRootElementName.", + () => { XmlDocument newDoc = (XmlDocument)JsonConvert.DeserializeXmlNode(@"{Prop1:1,Prop2:2}"); }); + } + + [Test] + public void JavaScriptConstructor() + { + string jsonText = @"{root:{r:new Date(34343, 55)}}"; + + XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText); + + string expected = @"3434355"; + + Assert.AreEqual(expected, newDoc.InnerXml); + + string json = SerializeXmlNode(newDoc); + expected = @"{ ""root"": { ""r"": { ""Date"": [ @@ -564,13 +559,13 @@ namespace Newtonsoft.Json.Tests.Converters } }"; - Assert.AreEqual(expected, json); - } + Assert.AreEqual(expected, json); + } - [Test] - public void ForceJsonArray() - { - string arrayXml = @" + [Test] + public void ForceJsonArray() + { + string arrayXml = @" Alan http://www.google.com @@ -578,11 +573,11 @@ namespace Newtonsoft.Json.Tests.Converters "; - XmlDocument arrayDoc = new XmlDocument(); - arrayDoc.LoadXml(arrayXml); + XmlDocument arrayDoc = new XmlDocument(); + arrayDoc.LoadXml(arrayXml); - string arrayJsonText = SerializeXmlNode(arrayDoc); - string expected = @"{ + string arrayJsonText = SerializeXmlNode(arrayDoc); + string expected = @"{ ""root"": { ""person"": { ""@id"": ""1"", @@ -594,9 +589,9 @@ namespace Newtonsoft.Json.Tests.Converters } } }"; - Assert.AreEqual(expected, arrayJsonText); + Assert.AreEqual(expected, arrayJsonText); - arrayXml = @" + arrayXml = @" Alan http://www.google.com @@ -605,11 +600,11 @@ namespace Newtonsoft.Json.Tests.Converters "; - arrayDoc = new XmlDocument(); - arrayDoc.LoadXml(arrayXml); + arrayDoc = new XmlDocument(); + arrayDoc.LoadXml(arrayXml); - arrayJsonText = SerializeXmlNode(arrayDoc); - expected = @"{ + arrayJsonText = SerializeXmlNode(arrayDoc); + expected = @"{ ""root"": { ""person"": { ""@id"": ""1"", @@ -622,9 +617,9 @@ namespace Newtonsoft.Json.Tests.Converters } } }"; - Assert.AreEqual(expected, arrayJsonText); + Assert.AreEqual(expected, arrayJsonText); - arrayXml = @" + arrayXml = @" Alan http://www.google.com @@ -632,11 +627,11 @@ namespace Newtonsoft.Json.Tests.Converters "; - arrayDoc = new XmlDocument(); - arrayDoc.LoadXml(arrayXml); + arrayDoc = new XmlDocument(); + arrayDoc.LoadXml(arrayXml); - arrayJsonText = SerializeXmlNode(arrayDoc); - expected = @"{ + arrayJsonText = SerializeXmlNode(arrayDoc); + expected = @"{ ""root"": { ""person"": { ""@id"": ""1"", @@ -646,57 +641,51 @@ namespace Newtonsoft.Json.Tests.Converters } } }"; - Assert.AreEqual(expected, arrayJsonText); - } + Assert.AreEqual(expected, arrayJsonText); + } - [Test] - public void MultipleRootPropertiesXmlDocument() - { - string json = @"{""count"": 773840,""photos"": null}"; - - ExceptionAssert.Throws( - "JSON root object has multiple properties. The root object must have a single property in order to create a valid XML document. Consider specifing a DeserializeRootElementName.", - () => + [Test] + public void MultipleRootPropertiesXmlDocument() { - JsonConvert.DeserializeXmlNode(json); - }); - } + string json = @"{""count"": 773840,""photos"": null}"; + + ExceptionAssert.Throws( + "JSON root object has multiple properties. The root object must have a single property in order to create a valid XML document. Consider specifing a DeserializeRootElementName.", + () => { JsonConvert.DeserializeXmlNode(json); }); + } #if !NET20 - [Test] - public void MultipleRootPropertiesXDocument() - { - string json = @"{""count"": 773840,""photos"": null}"; - - ExceptionAssert.Throws( - "JSON root object has multiple properties. The root object must have a single property in order to create a valid XML document. Consider specifing a DeserializeRootElementName.", - () => + [Test] + public void MultipleRootPropertiesXDocument() { - JsonConvert.DeserializeXNode(json); - }); - } + string json = @"{""count"": 773840,""photos"": null}"; + + ExceptionAssert.Throws( + "JSON root object has multiple properties. The root object must have a single property in order to create a valid XML document. Consider specifing a DeserializeRootElementName.", + () => { JsonConvert.DeserializeXNode(json); }); + } #endif - [Test] - public void MultipleRootPropertiesAddRootElement() - { - string json = @"{""count"": 773840,""photos"": 773840}"; + [Test] + public void MultipleRootPropertiesAddRootElement() + { + string json = @"{""count"": 773840,""photos"": 773840}"; - XmlDocument newDoc = JsonConvert.DeserializeXmlNode(json, "myRoot"); + XmlDocument newDoc = JsonConvert.DeserializeXmlNode(json, "myRoot"); - Assert.AreEqual(@"773840773840", newDoc.InnerXml); + Assert.AreEqual(@"773840773840", newDoc.InnerXml); #if !NET20 - XDocument newXDoc = JsonConvert.DeserializeXNode(json, "myRoot"); + XDocument newXDoc = JsonConvert.DeserializeXNode(json, "myRoot"); - Assert.AreEqual(@"773840773840", newXDoc.ToString(SaveOptions.DisableFormatting)); + Assert.AreEqual(@"773840773840", newXDoc.ToString(SaveOptions.DisableFormatting)); #endif - } + } - [Test] - public void NestedArrays() - { - string json = @"{ + [Test] + public void NestedArrays() + { + string json = @"{ ""available_sizes"": [ [ ""assets/images/resized/0001/1070/11070v1-max-150x150.jpg"", @@ -712,11 +701,11 @@ namespace Newtonsoft.Json.Tests.Converters ] }"; - XmlDocument newDoc = JsonConvert.DeserializeXmlNode(json, "myRoot"); + XmlDocument newDoc = JsonConvert.DeserializeXmlNode(json, "myRoot"); - string xml = IndentXml(newDoc.InnerXml); + string xml = IndentXml(newDoc.InnerXml); - Assert.AreEqual(@" + Assert.AreEqual(@" assets/images/resized/0001/1070/11070v1-max-150x150.jpg assets/images/resized/0001/1070/11070v1-max-150x150.jpg @@ -731,9 +720,9 @@ namespace Newtonsoft.Json.Tests.Converters ", IndentXml(newDoc.InnerXml)); #if !NET20 - XDocument newXDoc = JsonConvert.DeserializeXNode(json, "myRoot"); + XDocument newXDoc = JsonConvert.DeserializeXNode(json, "myRoot"); - Assert.AreEqual(@" + Assert.AreEqual(@" assets/images/resized/0001/1070/11070v1-max-150x150.jpg assets/images/resized/0001/1070/11070v1-max-150x150.jpg @@ -748,14 +737,14 @@ namespace Newtonsoft.Json.Tests.Converters ", IndentXml(newXDoc.ToString(SaveOptions.DisableFormatting))); #endif - string newJson = JsonConvert.SerializeXmlNode(newDoc, Formatting.Indented); - Console.WriteLine(newJson); - } + string newJson = JsonConvert.SerializeXmlNode(newDoc, Formatting.Indented); + Console.WriteLine(newJson); + } - [Test] - public void RoundTripNestedArrays() - { - string json = @"{ + [Test] + public void RoundTripNestedArrays() + { + string json = @"{ ""available_sizes"": [ [ ""assets/images/resized/0001/1070/11070v1-max-150x150.jpg"", @@ -771,9 +760,9 @@ namespace Newtonsoft.Json.Tests.Converters ] }"; - XmlDocument newDoc = JsonConvert.DeserializeXmlNode(json, "myRoot", true); + XmlDocument newDoc = JsonConvert.DeserializeXmlNode(json, "myRoot", true); - Assert.AreEqual(@" + Assert.AreEqual(@" assets/images/resized/0001/1070/11070v1-max-150x150.jpg assets/images/resized/0001/1070/11070v1-max-150x150.jpg @@ -788,11 +777,11 @@ namespace Newtonsoft.Json.Tests.Converters ", IndentXml(newDoc.InnerXml)); #if !NET20 - XDocument newXDoc = JsonConvert.DeserializeXNode(json, "myRoot", true); + XDocument newXDoc = JsonConvert.DeserializeXNode(json, "myRoot", true); - Console.WriteLine(IndentXml(newXDoc.ToString(SaveOptions.DisableFormatting))); + Console.WriteLine(IndentXml(newXDoc.ToString(SaveOptions.DisableFormatting))); - Assert.AreEqual(@" + Assert.AreEqual(@" assets/images/resized/0001/1070/11070v1-max-150x150.jpg assets/images/resized/0001/1070/11070v1-max-150x150.jpg @@ -807,14 +796,14 @@ namespace Newtonsoft.Json.Tests.Converters ", IndentXml(newXDoc.ToString(SaveOptions.DisableFormatting))); #endif - string newJson = JsonConvert.SerializeXmlNode(newDoc, Formatting.Indented, true); - Assert.AreEqual(json, newJson); - } + string newJson = JsonConvert.SerializeXmlNode(newDoc, Formatting.Indented, true); + Assert.AreEqual(json, newJson); + } - [Test] - public void MultipleNestedArraysToXml() - { - string json = @"{ + [Test] + public void MultipleNestedArraysToXml() + { + string json = @"{ ""available_sizes"": [ [ [113, 150], @@ -831,42 +820,42 @@ namespace Newtonsoft.Json.Tests.Converters ] }"; - XmlDocument newDoc = JsonConvert.DeserializeXmlNode(json, "myRoot"); + XmlDocument newDoc = JsonConvert.DeserializeXmlNode(json, "myRoot"); - Assert.AreEqual(@"113150assets/images/resized/0001/1070/11070v1-max-150x150.jpg189250assets/images/resized/0001/1070/11070v1-max-250x250.jpg341450assets/images/resized/0001/1070/11070v1-max-450x450.jpg", newDoc.InnerXml); + Assert.AreEqual(@"113150assets/images/resized/0001/1070/11070v1-max-150x150.jpg189250assets/images/resized/0001/1070/11070v1-max-250x250.jpg341450assets/images/resized/0001/1070/11070v1-max-450x450.jpg", newDoc.InnerXml); #if !NET20 - XDocument newXDoc = JsonConvert.DeserializeXNode(json, "myRoot"); + XDocument newXDoc = JsonConvert.DeserializeXNode(json, "myRoot"); - Assert.AreEqual(@"113150assets/images/resized/0001/1070/11070v1-max-150x150.jpg189250assets/images/resized/0001/1070/11070v1-max-250x250.jpg341450assets/images/resized/0001/1070/11070v1-max-450x450.jpg", newXDoc.ToString(SaveOptions.DisableFormatting)); + Assert.AreEqual(@"113150assets/images/resized/0001/1070/11070v1-max-150x150.jpg189250assets/images/resized/0001/1070/11070v1-max-250x250.jpg341450assets/images/resized/0001/1070/11070v1-max-450x450.jpg", newXDoc.ToString(SaveOptions.DisableFormatting)); #endif - } + } - [Test] - public void Encoding() - { - XmlDocument doc = new XmlDocument(); + [Test] + public void Encoding() + { + XmlDocument doc = new XmlDocument(); - doc.LoadXml(@"O""Connor"); // i use "" so it will be easier to see the problem + doc.LoadXml(@"O""Connor"); // i use "" so it will be easier to see the problem - string json = SerializeXmlNode(doc); - Assert.AreEqual(@"{ + string json = SerializeXmlNode(doc); + Assert.AreEqual(@"{ ""name"": ""O\""Connor"" }", json); - } + } - [Test] - public void SerializeComment() - { - string xml = @" + [Test] + public void SerializeComment() + { + string xml = @" Text "; - XmlDocument doc = new XmlDocument(); - doc.LoadXml(xml); + XmlDocument doc = new XmlDocument(); + doc.LoadXml(xml); - string jsonText = SerializeXmlNode(doc); + string jsonText = SerializeXmlNode(doc); - string expected = @"{ + string expected = @"{ ""span"": { ""@class"": ""vevent"", ""a"": { @@ -877,16 +866,16 @@ namespace Newtonsoft.Json.Tests.Converters } }"; - Assert.AreEqual(expected, jsonText); + Assert.AreEqual(expected, jsonText); - XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText); - Assert.AreEqual(@"Text", newDoc.InnerXml); - } + XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText); + Assert.AreEqual(@"Text", newDoc.InnerXml); + } - [Test] - public void SerializeExample() - { - string xml = @" + [Test] + public void SerializeExample() + { + string xml = @" Alan @@ -898,35 +887,35 @@ namespace Newtonsoft.Json.Tests.Converters "; - XmlDocument doc = new XmlDocument(); - doc.LoadXml(xml); + XmlDocument doc = new XmlDocument(); + doc.LoadXml(xml); - string jsonText = SerializeXmlNode(doc); - // { - // "?xml": { - // "@version": "1.0", - // "@standalone": "no" - // }, - // "root": { - // "person": [ - // { - // "@id": "1", - // "name": "Alan", - // "url": "http://www.google.com" - // }, - // { - // "@id": "2", - // "name": "Louis", - // "url": "http://www.yahoo.com" - // } - // ] - // } - // } + string jsonText = SerializeXmlNode(doc); + // { + // "?xml": { + // "@version": "1.0", + // "@standalone": "no" + // }, + // "root": { + // "person": [ + // { + // "@id": "1", + // "name": "Alan", + // "url": "http://www.google.com" + // }, + // { + // "@id": "2", + // "name": "Louis", + // "url": "http://www.yahoo.com" + // } + // ] + // } + // } - // format - jsonText = JObject.Parse(jsonText).ToString(); + // format + jsonText = JObject.Parse(jsonText).ToString(); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""?xml"": { ""@version"": ""1.0"", ""@standalone"": ""no"" @@ -947,15 +936,15 @@ namespace Newtonsoft.Json.Tests.Converters } }", jsonText); - XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText); + XmlDocument newDoc = (XmlDocument)DeserializeXmlNode(jsonText); - Assert.AreEqual(doc.InnerXml, newDoc.InnerXml); - } + Assert.AreEqual(doc.InnerXml, newDoc.InnerXml); + } - [Test] - public void DeserializeExample() - { - string json = @"{ + [Test] + public void DeserializeExample() + { + string json = @"{ ""?xml"": { ""@version"": ""1.0"", ""@standalone"": ""no"" @@ -976,20 +965,20 @@ namespace Newtonsoft.Json.Tests.Converters } }"; - XmlDocument doc = (XmlDocument)DeserializeXmlNode(json); - // - // - // - // Alan - // http://www.google.com - // - // - // Louis - // http://www.yahoo.com - // - // + XmlDocument doc = (XmlDocument)DeserializeXmlNode(json); + // + // + // + // Alan + // http://www.google.com + // + // + // Louis + // http://www.yahoo.com + // + // - Assert.AreEqual(@" + Assert.AreEqual(@" Alan @@ -1000,19 +989,19 @@ namespace Newtonsoft.Json.Tests.Converters http://www.yahoo.com ".Replace(Environment.NewLine, string.Empty), doc.InnerXml); - } + } - [Test] - public void SerializeDeserializeSpecialProperties() - { - PreserveReferencesHandlingTests.CircularDictionary circularDictionary = new PreserveReferencesHandlingTests.CircularDictionary(); - circularDictionary.Add("other", new PreserveReferencesHandlingTests.CircularDictionary { { "blah", null } }); - circularDictionary.Add("self", circularDictionary); + [Test] + public void SerializeDeserializeSpecialProperties() + { + PreserveReferencesHandlingTests.CircularDictionary circularDictionary = new PreserveReferencesHandlingTests.CircularDictionary(); + circularDictionary.Add("other", new PreserveReferencesHandlingTests.CircularDictionary { { "blah", null } }); + circularDictionary.Add("self", circularDictionary); - string json = JsonConvert.SerializeObject(circularDictionary, Formatting.Indented, - new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.All }); + string json = JsonConvert.SerializeObject(circularDictionary, Formatting.Indented, + new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.All }); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""$id"": ""1"", ""other"": { ""$id"": ""2"", @@ -1023,9 +1012,9 @@ namespace Newtonsoft.Json.Tests.Converters } }", json); - XmlNode node = DeserializeXmlNode(json, "root"); - string xml = GetIndentedInnerXml(node); - string expected = @" + XmlNode node = DeserializeXmlNode(json, "root"); + string xml = GetIndentedInnerXml(node); + string expected = @" @@ -1033,10 +1022,10 @@ namespace Newtonsoft.Json.Tests.Converters "; - Assert.AreEqual(expected, xml); + Assert.AreEqual(expected, xml); - string xmlJson = SerializeXmlNode(node); - string expectedXmlJson = @"{ + string xmlJson = SerializeXmlNode(node); + string expectedXmlJson = @"{ ""root"": { ""$id"": ""1"", ""other"": { @@ -1049,13 +1038,13 @@ namespace Newtonsoft.Json.Tests.Converters } }"; - Assert.AreEqual(expectedXmlJson, xmlJson); - } + Assert.AreEqual(expectedXmlJson, xmlJson); + } - [Test] - public void EmptyPropertyName() - { - string json = @"{ + [Test] + public void EmptyPropertyName() + { + string json = @"{ ""8452309520V2"": { """": { ""CLIENT"": { @@ -1134,38 +1123,35 @@ namespace Newtonsoft.Json.Tests.Converters } }"; - ExceptionAssert.Throws( - "XmlNodeConverter cannot convert JSON with an empty property name to XML.", - () => + ExceptionAssert.Throws( + "XmlNodeConverter cannot convert JSON with an empty property name to XML.", + () => { DeserializeXmlNode(json); }); + } + + [Test] + public void SingleItemArrayPropertySerialization() { - DeserializeXmlNode(json); - }); - } + Product product = new Product(); - [Test] - public void SingleItemArrayPropertySerialization() - { - Product product = new Product(); + product.Name = "Apple"; + product.ExpiryDate = new DateTime(2008, 12, 28, 0, 0, 0, DateTimeKind.Utc); + product.Price = 3.99M; + product.Sizes = new string[] { "Small" }; - product.Name = "Apple"; - product.ExpiryDate = new DateTime(2008, 12, 28, 0, 0, 0, DateTimeKind.Utc); - product.Price = 3.99M; - product.Sizes = new string[] { "Small" }; + string output = JsonConvert.SerializeObject(product, new IsoDateTimeConverter()); - string output = JsonConvert.SerializeObject(product, new IsoDateTimeConverter()); + XmlDocument xmlProduct = JsonConvert.DeserializeXmlNode(output, "product", true); - XmlDocument xmlProduct = JsonConvert.DeserializeXmlNode(output, "product", true); - - Assert.AreEqual(@" + Assert.AreEqual(@" Apple 2008-12-28T00:00:00Z 3.99 Small ", IndentXml(xmlProduct.InnerXml)); - string output2 = JsonConvert.SerializeXmlNode(xmlProduct.DocumentElement, Formatting.Indented); + string output2 = JsonConvert.SerializeXmlNode(xmlProduct.DocumentElement, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""product"": { ""Name"": ""Apple"", ""ExpiryDate"": ""2008-12-28T00:00:00Z"", @@ -1175,31 +1161,31 @@ namespace Newtonsoft.Json.Tests.Converters ] } }", output2); - } + } - public class TestComplexArrayClass - { - public string Name { get; set; } - public IList Products { get; set; } - } - - [Test] - public void ComplexSingleItemArrayPropertySerialization() - { - TestComplexArrayClass o = new TestComplexArrayClass + public class TestComplexArrayClass { - Name = "Hi", - Products = new List + public string Name { get; set; } + public IList Products { get; set; } + } + + [Test] + public void ComplexSingleItemArrayPropertySerialization() + { + TestComplexArrayClass o = new TestComplexArrayClass { - new Product { Name = "First" } - } - }; + Name = "Hi", + Products = new List + { + new Product { Name = "First" } + } + }; - string output = JsonConvert.SerializeObject(o, new IsoDateTimeConverter()); + string output = JsonConvert.SerializeObject(o, new IsoDateTimeConverter()); - XmlDocument xmlProduct = JsonConvert.DeserializeXmlNode(output, "test", true); + XmlDocument xmlProduct = JsonConvert.DeserializeXmlNode(output, "test", true); - Assert.AreEqual(@" + Assert.AreEqual(@" Hi First @@ -1209,9 +1195,9 @@ namespace Newtonsoft.Json.Tests.Converters ", IndentXml(xmlProduct.InnerXml)); - string output2 = JsonConvert.SerializeXmlNode(xmlProduct.DocumentElement, Formatting.Indented, true); + string output2 = JsonConvert.SerializeXmlNode(xmlProduct.DocumentElement, Formatting.Indented, true); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Name"": ""Hi"", ""Products"": [ { @@ -1222,29 +1208,29 @@ namespace Newtonsoft.Json.Tests.Converters } ] }", output2); - } + } - private string IndentXml(string xml) - { - XmlReader reader = XmlReader.Create(new StringReader(xml)); + private string IndentXml(string xml) + { + XmlReader reader = XmlReader.Create(new StringReader(xml)); - StringWriter sw = new StringWriter(); - XmlWriter writer = XmlWriter.Create(sw, new XmlWriterSettings { Indent = true, OmitXmlDeclaration = true }); + StringWriter sw = new StringWriter(); + XmlWriter writer = XmlWriter.Create(sw, new XmlWriterSettings { Indent = true, OmitXmlDeclaration = true }); - while (reader.Read()) - { - writer.WriteNode(reader, false); - } + while (reader.Read()) + { + writer.WriteNode(reader, false); + } - writer.Flush(); + writer.Flush(); - return sw.ToString(); - } + return sw.ToString(); + } - [Test] - public void OmitRootObject() - { - string xml = @" + [Test] + public void OmitRootObject() + { + string xml = @" Hi Hi @@ -1255,12 +1241,12 @@ namespace Newtonsoft.Json.Tests.Converters "; - XmlDocument d = new XmlDocument(); - d.LoadXml(xml); + XmlDocument d = new XmlDocument(); + d.LoadXml(xml); - string output = JsonConvert.SerializeXmlNode(d, Formatting.Indented, true); + string output = JsonConvert.SerializeXmlNode(d, Formatting.Indented, true); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Name"": [ ""Hi"", ""Hi"" @@ -1274,12 +1260,12 @@ namespace Newtonsoft.Json.Tests.Converters } ] }", output); - } + } - [Test] - public void EmtpyElementWithArrayAttributeShouldWriteAttributes() - { - string xml = @" + [Test] + public void EmtpyElementWithArrayAttributeShouldWriteAttributes() + { + string xml = @" @@ -1288,12 +1274,12 @@ namespace Newtonsoft.Json.Tests.Converters "; - XmlDocument d = new XmlDocument(); - d.LoadXml(xml); + XmlDocument d = new XmlDocument(); + d.LoadXml(xml); - string json = JsonConvert.SerializeXmlNode(d, Formatting.Indented); + string json = JsonConvert.SerializeXmlNode(d, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""?xml"": { ""@version"": ""1.0"", ""@encoding"": ""utf-8"" @@ -1312,78 +1298,78 @@ namespace Newtonsoft.Json.Tests.Converters } } }", json); - } + } - [Test] - public void EmtpyElementWithArrayAttributeShouldWriteElement() - { - string xml = @" + [Test] + public void EmtpyElementWithArrayAttributeShouldWriteElement() + { + string xml = @" "; - XmlDocument d = new XmlDocument(); - d.LoadXml(xml); + XmlDocument d = new XmlDocument(); + d.LoadXml(xml); - string json = JsonConvert.SerializeXmlNode(d, Formatting.Indented); + string json = JsonConvert.SerializeXmlNode(d, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""root"": { ""Reports"": [ {} ] } }", json); - } - - [Test] - public void DeserializeNonInt64IntegerValues() - { - var dict = new Dictionary { { "Int16", (short)1 }, { "Float", 2f }, { "Int32", 3 } }; - var obj = JObject.FromObject(dict); - var serializer = JsonSerializer.Create(new JsonSerializerSettings { Converters = { new XmlNodeConverter() { DeserializeRootElementName = "root" } } }); - using (var reader = obj.CreateReader()) - { - var value = (XmlDocument)serializer.Deserialize(reader, typeof(XmlDocument)); - - Assert.AreEqual(@"123", value.InnerXml); - } - } - - [Test] - public void DeserializingBooleanValues() - { - MemoryStream ms = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(@"{root:{""@booleanType"":true}}")); - MemoryStream xml = new MemoryStream(); - - JsonBodyToSoapXml(ms, xml); - - string xmlString = System.Text.Encoding.UTF8.GetString(xml.ToArray()); - - Assert.AreEqual(@"", xmlString); - } - - private static void JsonBodyToSoapXml(Stream json, Stream xml) - { - Newtonsoft.Json.JsonSerializerSettings settings = new Newtonsoft.Json.JsonSerializerSettings(); - settings.Converters.Add(new Newtonsoft.Json.Converters.XmlNodeConverter()); - Newtonsoft.Json.JsonSerializer serializer = Newtonsoft.Json.JsonSerializer.Create(settings); - using (Newtonsoft.Json.JsonTextReader reader = new Newtonsoft.Json.JsonTextReader(new System.IO.StreamReader(json))) - { - XmlDocument doc = (XmlDocument)serializer.Deserialize(reader, typeof(XmlDocument)); - if (reader.Read() && reader.TokenType != JsonToken.Comment) - throw new JsonSerializationException("Additional text found in JSON string after finishing deserializing object."); - using (XmlWriter writer = XmlWriter.Create(xml)) - { - doc.Save(writer); } - } - } + + [Test] + public void DeserializeNonInt64IntegerValues() + { + var dict = new Dictionary { { "Int16", (short)1 }, { "Float", 2f }, { "Int32", 3 } }; + var obj = JObject.FromObject(dict); + var serializer = JsonSerializer.Create(new JsonSerializerSettings { Converters = { new XmlNodeConverter() { DeserializeRootElementName = "root" } } }); + using (var reader = obj.CreateReader()) + { + var value = (XmlDocument)serializer.Deserialize(reader, typeof(XmlDocument)); + + Assert.AreEqual(@"123", value.InnerXml); + } + } + + [Test] + public void DeserializingBooleanValues() + { + MemoryStream ms = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(@"{root:{""@booleanType"":true}}")); + MemoryStream xml = new MemoryStream(); + + JsonBodyToSoapXml(ms, xml); + + string xmlString = System.Text.Encoding.UTF8.GetString(xml.ToArray()); + + Assert.AreEqual(@"", xmlString); + } + + private static void JsonBodyToSoapXml(Stream json, Stream xml) + { + Newtonsoft.Json.JsonSerializerSettings settings = new Newtonsoft.Json.JsonSerializerSettings(); + settings.Converters.Add(new Newtonsoft.Json.Converters.XmlNodeConverter()); + Newtonsoft.Json.JsonSerializer serializer = Newtonsoft.Json.JsonSerializer.Create(settings); + using (Newtonsoft.Json.JsonTextReader reader = new Newtonsoft.Json.JsonTextReader(new System.IO.StreamReader(json))) + { + XmlDocument doc = (XmlDocument)serializer.Deserialize(reader, typeof(XmlDocument)); + if (reader.Read() && reader.TokenType != JsonToken.Comment) + throw new JsonSerializationException("Additional text found in JSON string after finishing deserializing object."); + using (XmlWriter writer = XmlWriter.Create(xml)) + { + doc.Save(writer); + } + } + } #if !NET20 - [Test] - public void DeserializeXNodeDefaultNamespace() - { - string xaml = @" + [Test] + public void DeserializeXNodeDefaultNamespace() + { + string xaml = @" @@ -1416,9 +1402,9 @@ namespace Newtonsoft.Json.Tests.Converters "; - string json = JsonConvert.SerializeXNode(XDocument.Parse(xaml), Formatting.Indented); + string json = JsonConvert.SerializeXNode(XDocument.Parse(xaml), Formatting.Indented); - string expectedJson = @"{ + string expectedJson = @"{ ""Grid"": { ""@xmlns"": ""http://schemas.microsoft.com/winfx/2006/xaml/presentation"", ""@xmlns:x"": ""http://schemas.microsoft.com/winfx/2006/xaml"", @@ -1575,13 +1561,13 @@ namespace Newtonsoft.Json.Tests.Converters } }"; - Assert.AreEqual(expectedJson, json); + Assert.AreEqual(expectedJson, json); - XNode node = JsonConvert.DeserializeXNode(json); + XNode node = JsonConvert.DeserializeXNode(json); - string xaml2 = node.ToString(); + string xaml2 = node.ToString(); - string expectedXaml = @" + string expectedXaml = @" @@ -1614,14 +1600,14 @@ namespace Newtonsoft.Json.Tests.Converters "; - Assert.AreEqual(expectedXaml, xaml2); - } + Assert.AreEqual(expectedXaml, xaml2); + } #endif - [Test] - public void DeserializeXmlNodeDefaultNamespace() - { - string xaml = @" + [Test] + public void DeserializeXmlNodeDefaultNamespace() + { + string xaml = @" @@ -1654,12 +1640,12 @@ namespace Newtonsoft.Json.Tests.Converters "; - XmlDocument document = new XmlDocument(); - document.LoadXml(xaml); + XmlDocument document = new XmlDocument(); + document.LoadXml(xaml); - string json = JsonConvert.SerializeXmlNode(document, Formatting.Indented); + string json = JsonConvert.SerializeXmlNode(document, Formatting.Indented); - string expectedJson = @"{ + string expectedJson = @"{ ""Grid"": { ""@xmlns"": ""http://schemas.microsoft.com/winfx/2006/xaml/presentation"", ""@xmlns:x"": ""http://schemas.microsoft.com/winfx/2006/xaml"", @@ -1816,22 +1802,22 @@ namespace Newtonsoft.Json.Tests.Converters } }"; - Assert.AreEqual(expectedJson, json); + Assert.AreEqual(expectedJson, json); - XmlNode node = JsonConvert.DeserializeXmlNode(json); + XmlNode node = JsonConvert.DeserializeXmlNode(json); - StringWriter sw = new StringWriter(); - XmlWriter writer = XmlWriter.Create(sw, new XmlWriterSettings - { - Indent = true, - OmitXmlDeclaration = true - }); - node.WriteTo(writer); - writer.Flush(); + StringWriter sw = new StringWriter(); + XmlWriter writer = XmlWriter.Create(sw, new XmlWriterSettings + { + Indent = true, + OmitXmlDeclaration = true + }); + node.WriteTo(writer); + writer.Flush(); - string xaml2 = sw.ToString(); + string xaml2 = sw.ToString(); - string expectedXaml = @" + string expectedXaml = @" @@ -1864,65 +1850,66 @@ namespace Newtonsoft.Json.Tests.Converters "; - Assert.AreEqual(expectedXaml, xaml2); - } + Assert.AreEqual(expectedXaml, xaml2); + } - [Test] - public void DeserializeAttributePropertyNotAtStart() - { - string json = @"{""item"": {""@action"": ""update"", ""@itemid"": ""1"", ""elements"": [{""@action"": ""none"", ""@id"": ""2""},{""@action"": ""none"", ""@id"": ""3""}],""@description"": ""temp""}}"; + [Test] + public void DeserializeAttributePropertyNotAtStart() + { + string json = @"{""item"": {""@action"": ""update"", ""@itemid"": ""1"", ""elements"": [{""@action"": ""none"", ""@id"": ""2""},{""@action"": ""none"", ""@id"": ""3""}],""@description"": ""temp""}}"; - XmlDocument xmldoc = JsonConvert.DeserializeXmlNode(json); + XmlDocument xmldoc = JsonConvert.DeserializeXmlNode(json); - Assert.AreEqual(@"", xmldoc.InnerXml); - } + Assert.AreEqual(@"", xmldoc.InnerXml); + } - [Test] - public void SerializingXmlNamespaceScope() - { - var xmlString = @" + [Test] + public void SerializingXmlNamespaceScope() + { + var xmlString = @" "; #if !NET20 - var xml = XElement.Parse(xmlString); + var xml = XElement.Parse(xmlString); - var json1 = JsonConvert.SerializeObject(xml); + var json1 = JsonConvert.SerializeObject(xml); - Assert.AreEqual(@"{""root"":{""@xmlns"":""http://www.example.com/ns"",""a"":null,""bns:b"":{""@xmlns:bns"":""http://www.example.com/ns""},""c"":null}}", json1); + Assert.AreEqual(@"{""root"":{""@xmlns"":""http://www.example.com/ns"",""a"":null,""bns:b"":{""@xmlns:bns"":""http://www.example.com/ns""},""c"":null}}", json1); #endif #if !(SILVERLIGHT || NETFX_CORE) - var xml1 = new XmlDocument(); - xml1.LoadXml(xmlString); + var xml1 = new XmlDocument(); + xml1.LoadXml(xmlString); - var json2 = JsonConvert.SerializeObject(xml1); + var json2 = JsonConvert.SerializeObject(xml1); - Assert.AreEqual(@"{""root"":{""@xmlns"":""http://www.example.com/ns"",""a"":null,""bns:b"":{""@xmlns:bns"":""http://www.example.com/ns""},""c"":null}}", json2); + Assert.AreEqual(@"{""root"":{""@xmlns"":""http://www.example.com/ns"",""a"":null,""bns:b"":{""@xmlns:bns"":""http://www.example.com/ns""},""c"":null}}", json2); #endif - } + } #if !NET20 - public class NullableXml - { - public string Name; - public XElement notNull; - public XElement isNull; - } + public class NullableXml + { + public string Name; + public XElement notNull; + public XElement isNull; + } - [Test] - public void SerializeAndDeserializeNullableXml() - { - var xml = new NullableXml { Name = "test", notNull = XElement.Parse("test") }; - var json = JsonConvert.SerializeObject(xml); + [Test] + public void SerializeAndDeserializeNullableXml() + { + var xml = new NullableXml { Name = "test", notNull = XElement.Parse("test") }; + var json = JsonConvert.SerializeObject(xml); - var w2 = JsonConvert.DeserializeObject(json); - Assert.AreEqual(xml.Name, w2.Name); - Assert.AreEqual(xml.isNull, w2.isNull); - Assert.AreEqual(xml.notNull.ToString(), w2.notNull.ToString()); - } + var w2 = JsonConvert.DeserializeObject(json); + Assert.AreEqual(xml.Name, w2.Name); + Assert.AreEqual(xml.isNull, w2.isNull); + Assert.AreEqual(xml.notNull.ToString(), w2.notNull.ToString()); + } #endif - } + } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/ConditionalPropertiesTests.cs b/Src/Newtonsoft.Json.Tests/Documentation/ConditionalPropertiesTests.cs index 7ae89735..b1f5c4e6 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/ConditionalPropertiesTests.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/ConditionalPropertiesTests.cs @@ -51,83 +51,83 @@ using System.Globalization; namespace Newtonsoft.Json.Tests.Documentation { - public class Employee - { - public string Name { get; set; } - public Employee Manager { get; set; } - } - - #region ShouldSerializeContractResolver - public class ShouldSerializeContractResolver : DefaultContractResolver - { - public new static readonly ShouldSerializeContractResolver Instance = new ShouldSerializeContractResolver(); - - protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) - { - JsonProperty property = base.CreateProperty(member, memberSerialization); - - if (property.DeclaringType == typeof(Employee) && property.PropertyName == "Manager") - { - property.ShouldSerialize = - instance => - { - Employee e = (Employee) instance; - return e.Manager != e; - }; - } - - return property; - } - } - #endregion - - [TestFixture] - public class ConditionalPropertiesTests : TestFixtureBase - { - #region EmployeeShouldSerializeExample public class Employee { - public string Name { get; set; } - public Employee Manager { get; set; } + public string Name { get; set; } + public Employee Manager { get; set; } + } - public bool ShouldSerializeManager() - { - // don't serialize the Manager property if an employee is their own manager - return (Manager != this); - } + #region ShouldSerializeContractResolver + public class ShouldSerializeContractResolver : DefaultContractResolver + { + public new static readonly ShouldSerializeContractResolver Instance = new ShouldSerializeContractResolver(); + + protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) + { + JsonProperty property = base.CreateProperty(member, memberSerialization); + + if (property.DeclaringType == typeof(Employee) && property.PropertyName == "Manager") + { + property.ShouldSerialize = + instance => + { + Employee e = (Employee)instance; + return e.Manager != e; + }; + } + + return property; + } } #endregion - [Test] - public void ShouldSerializeClassTest() + [TestFixture] + public class ConditionalPropertiesTests : TestFixtureBase { - #region ShouldSerializeClassTest - Employee joe = new Employee(); - joe.Name = "Joe Employee"; - Employee mike = new Employee(); - mike.Name = "Mike Manager"; + #region EmployeeShouldSerializeExample + public class Employee + { + public string Name { get; set; } + public Employee Manager { get; set; } - joe.Manager = mike; + public bool ShouldSerializeManager() + { + // don't serialize the Manager property if an employee is their own manager + return (Manager != this); + } + } + #endregion - // mike is his own manager - // ShouldSerialize will skip this property - mike.Manager = mike; + [Test] + public void ShouldSerializeClassTest() + { + #region ShouldSerializeClassTest + Employee joe = new Employee(); + joe.Name = "Joe Employee"; + Employee mike = new Employee(); + mike.Name = "Mike Manager"; - string json = JsonConvert.SerializeObject(new[] { joe, mike }, Formatting.Indented); - // [ - // { - // "Name": "Joe Employee", - // "Manager": { - // "Name": "Mike Manager" - // } - // }, - // { - // "Name": "Mike Manager" - // } - // ] - #endregion + joe.Manager = mike; - Assert.AreEqual(@"[ + // mike is his own manager + // ShouldSerialize will skip this property + mike.Manager = mike; + + string json = JsonConvert.SerializeObject(new[] { joe, mike }, Formatting.Indented); + // [ + // { + // "Name": "Joe Employee", + // "Manager": { + // "Name": "Mike Manager" + // } + // }, + // { + // "Name": "Mike Manager" + // } + // ] + #endregion + + Assert.AreEqual(@"[ { ""Name"": ""Joe Employee"", ""Manager"": { @@ -138,28 +138,28 @@ namespace Newtonsoft.Json.Tests.Documentation ""Name"": ""Mike Manager"" } ]", json); - } + } - [Test] - public void ShouldSerializeContractResolverTest() - { - Newtonsoft.Json.Tests.Documentation.Employee joe = new Newtonsoft.Json.Tests.Documentation.Employee(); - joe.Name = "Joe Employee"; - Newtonsoft.Json.Tests.Documentation.Employee mike = new Newtonsoft.Json.Tests.Documentation.Employee(); - mike.Name = "Mike Manager"; + [Test] + public void ShouldSerializeContractResolverTest() + { + Newtonsoft.Json.Tests.Documentation.Employee joe = new Newtonsoft.Json.Tests.Documentation.Employee(); + joe.Name = "Joe Employee"; + Newtonsoft.Json.Tests.Documentation.Employee mike = new Newtonsoft.Json.Tests.Documentation.Employee(); + mike.Name = "Mike Manager"; - joe.Manager = mike; - mike.Manager = mike; + joe.Manager = mike; + mike.Manager = mike; - string json = JsonConvert.SerializeObject( - new[] {joe, mike}, - Formatting.Indented, - new JsonSerializerSettings - { - ContractResolver = ShouldSerializeContractResolver.Instance - }); + string json = JsonConvert.SerializeObject( + new[] { joe, mike }, + Formatting.Indented, + new JsonSerializerSettings + { + ContractResolver = ShouldSerializeContractResolver.Instance + }); - Assert.AreEqual(@"[ + Assert.AreEqual(@"[ { ""Name"": ""Joe Employee"", ""Manager"": { @@ -170,8 +170,8 @@ namespace Newtonsoft.Json.Tests.Documentation ""Name"": ""Mike Manager"" } ]", json); - + } } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/ConvertingJsonAndXmlTests.cs b/Src/Newtonsoft.Json.Tests/Documentation/ConvertingJsonAndXmlTests.cs index 3cb45ab9..9104cb3d 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/ConvertingJsonAndXmlTests.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/ConvertingJsonAndXmlTests.cs @@ -50,12 +50,12 @@ using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs; namespace Newtonsoft.Json.Tests.Documentation { - public class ConvertingJsonAndXmlTests - { - public void SerializeXmlNode() + public class ConvertingJsonAndXmlTests { - #region SerializeXmlNode - string xml = @" + public void SerializeXmlNode() + { + #region SerializeXmlNode + string xml = @" Alan @@ -67,37 +67,37 @@ namespace Newtonsoft.Json.Tests.Documentation "; - XmlDocument doc = new XmlDocument(); - doc.LoadXml(xml); + XmlDocument doc = new XmlDocument(); + doc.LoadXml(xml); - string jsonText = JsonConvert.SerializeXmlNode(doc); - //{ - // "?xml": { - // "@version": "1.0", - // "@standalone": "no" - // }, - // "root": { - // "person": [ - // { - // "@id": "1", - // "name": "Alan", - // "url": "http://www.google.com" - // }, - // { - // "@id": "2", - // "name": "Louis", - // "url": "http://www.yahoo.com" - // } - // ] - // } - //} - #endregion - } + string jsonText = JsonConvert.SerializeXmlNode(doc); + //{ + // "?xml": { + // "@version": "1.0", + // "@standalone": "no" + // }, + // "root": { + // "person": [ + // { + // "@id": "1", + // "name": "Alan", + // "url": "http://www.google.com" + // }, + // { + // "@id": "2", + // "name": "Louis", + // "url": "http://www.yahoo.com" + // } + // ] + // } + //} + #endregion + } - public void DeserializeXmlNode() - { - #region DeserializeXmlNode - string json = @"{ + public void DeserializeXmlNode() + { + #region DeserializeXmlNode + string json = @"{ '?xml': { '@version': '1.0', '@standalone': 'no' @@ -118,66 +118,66 @@ namespace Newtonsoft.Json.Tests.Documentation } }"; - XmlDocument doc = (XmlDocument)JsonConvert.DeserializeXmlNode(json); - // - // - // - // Alan - // http://www.google.com - // - // - // Louis - // http://www.yahoo.com - // - // - #endregion - } + XmlDocument doc = (XmlDocument)JsonConvert.DeserializeXmlNode(json); + // + // + // + // Alan + // http://www.google.com + // + // + // Louis + // http://www.yahoo.com + // + // + #endregion + } - public void ForceJsonArray() - { - #region ForceJsonArray - string xml = @" + public void ForceJsonArray() + { + #region ForceJsonArray + string xml = @" Alan http://www.google.com Admin1 "; - XmlDocument doc = new XmlDocument(); - doc.LoadXml(xml); + XmlDocument doc = new XmlDocument(); + doc.LoadXml(xml); - string json = JsonConvert.SerializeXmlNode(doc); - //{ - // "person": { - // "@id": "1", - // "name": "Alan", - // "url": "http://www.google.com", - // "role": "Admin1" - // } - //} + string json = JsonConvert.SerializeXmlNode(doc); + //{ + // "person": { + // "@id": "1", + // "name": "Alan", + // "url": "http://www.google.com", + // "role": "Admin1" + // } + //} - xml = @" + xml = @" Alan http://www.google.com Admin "; - doc = new XmlDocument(); - doc.LoadXml(xml); + doc = new XmlDocument(); + doc.LoadXml(xml); - json = JsonConvert.SerializeXmlNode(doc); - //{ - // "person": { - // "@id": "1", - // "name": "Alan", - // "url": "http://www.google.com", - // "role": [ - // "Admin" - // ] - // } - //} - #endregion + json = JsonConvert.SerializeXmlNode(doc); + //{ + // "person": { + // "@id": "1", + // "name": "Alan", + // "url": "http://www.google.com", + // "role": [ + // "Admin" + // ] + // } + //} + #endregion + } } - - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/JsonNetVsWindowsDataJsonTests.cs b/Src/Newtonsoft.Json.Tests/Documentation/JsonNetVsWindowsDataJsonTests.cs index fa36538d..eb70e0e9 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/JsonNetVsWindowsDataJsonTests.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/JsonNetVsWindowsDataJsonTests.cs @@ -6,10 +6,10 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Documentation { - public class JsonNetVsWindowsDataJsonTests - { - public void CreatingJson() + public class JsonNetVsWindowsDataJsonTests { + public void CreatingJson() + { #if NETFX_CORE #region CreatingJSON // Windows.Data.Json @@ -43,10 +43,10 @@ namespace Newtonsoft.Json.Tests.Documentation string json2 = jObject.ToString(); #endregion #endif - } + } - public void QueryingJson() - { + public void QueryingJson() + { #if NETFX_CORE #region QueryingJSON string json = @"{ @@ -79,10 +79,10 @@ namespace Newtonsoft.Json.Tests.Documentation string itemTitle2 = (string)jObject["channel"]["item"][0]["title"]; #endregion #endif - } + } - public void Converting() - { + public void Converting() + { #if NETFX_CORE #region Converting JsonObject jsonObject = new JsonObject @@ -103,6 +103,6 @@ namespace Newtonsoft.Json.Tests.Documentation JsonArray jsonArray = a.ToObject(); #endregion #endif + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/JsonSchemaTests.cs b/Src/Newtonsoft.Json.Tests/Documentation/JsonSchemaTests.cs index 09baeb2d..29b50e6c 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/JsonSchemaTests.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/JsonSchemaTests.cs @@ -51,12 +51,12 @@ using File = System.IO.File; namespace Newtonsoft.Json.Tests.Documentation { - public class JsonSchemaTests - { - public void IsValidBasic() + public class JsonSchemaTests { - #region IsValidBasic - string schemaJson = @"{ + public void IsValidBasic() + { + #region IsValidBasic + string schemaJson = @"{ 'description': 'A person', 'type': 'object', 'properties': @@ -69,21 +69,21 @@ namespace Newtonsoft.Json.Tests.Documentation } }"; - JsonSchema schema = JsonSchema.Parse(schemaJson); + JsonSchema schema = JsonSchema.Parse(schemaJson); - JObject person = JObject.Parse(@"{ + JObject person = JObject.Parse(@"{ 'name': 'James', 'hobbies': ['.NET', 'Blogging', 'Reading', 'Xbox', 'LOLCATS'] }"); - bool valid = person.IsValid(schema); - // true - #endregion - } + bool valid = person.IsValid(schema); + // true + #endregion + } - public void IsValidMessages() - { - string schemaJson = @"{ + public void IsValidMessages() + { + string schemaJson = @"{ 'description': 'A person', 'type': 'object', 'properties': @@ -96,89 +96,90 @@ namespace Newtonsoft.Json.Tests.Documentation } }"; - #region IsValidMessages - JsonSchema schema = JsonSchema.Parse(schemaJson); + #region IsValidMessages + JsonSchema schema = JsonSchema.Parse(schemaJson); - JObject person = JObject.Parse(@"{ + JObject person = JObject.Parse(@"{ 'name': null, 'hobbies': ['Invalid content', 0.123456789] }"); - IList messages; - bool valid = person.IsValid(schema, out messages); - // false - // Invalid type. Expected String but got Null. Line 2, position 21. - // Invalid type. Expected String but got Float. Line 3, position 51. - #endregion - } + IList messages; + bool valid = person.IsValid(schema, out messages); + // false + // Invalid type. Expected String but got Null. Line 2, position 21. + // Invalid type. Expected String but got Float. Line 3, position 51. + #endregion + } - public void JsonValidatingReader() - { - string schemaJson = "{}"; + public void JsonValidatingReader() + { + string schemaJson = "{}"; - #region JsonValidatingReader - string json = @"{ + #region JsonValidatingReader + string json = @"{ 'name': 'James', 'hobbies': ['.NET', 'Blogging', 'Reading', 'Xbox', 'LOLCATS'] }"; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); + JsonTextReader reader = new JsonTextReader(new StringReader(json)); - JsonValidatingReader validatingReader = new JsonValidatingReader(reader); - validatingReader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader validatingReader = new JsonValidatingReader(reader); + validatingReader.Schema = JsonSchema.Parse(schemaJson); - IList messages = new List(); - validatingReader.ValidationEventHandler += (o, a) => messages.Add(a.Message); + IList messages = new List(); + validatingReader.ValidationEventHandler += (o, a) => messages.Add(a.Message); - JsonSerializer serializer = new JsonSerializer(); - Person p = serializer.Deserialize(validatingReader); - #endregion - } + JsonSerializer serializer = new JsonSerializer(); + Person p = serializer.Deserialize(validatingReader); + #endregion + } - public void LoadJsonSchema() - { - #region LoadJsonSchema - // load from a string - JsonSchema schema1 = JsonSchema.Parse(@"{'type':'object'}"); - - // load from a file - using (TextReader reader = File.OpenText(@"c:\schema\Person.json")) - { - JsonSchema schema2 = JsonSchema.Read(new JsonTextReader(reader)); - - // do stuff - } - #endregion - } - - public void ManuallyCreateJsonSchema() - { - #region ManuallyCreateJsonSchema - JsonSchema schema = new JsonSchema(); - schema.Type = JsonSchemaType.Object; - schema.Properties = new Dictionary + public void LoadJsonSchema() { - {"name", new JsonSchema {Type = JsonSchemaType.String}}, - { - "hobbies", new JsonSchema - { - Type = JsonSchemaType.Array, - Items = new List { new JsonSchema {Type = JsonSchemaType.String} } - } - }, - }; + #region LoadJsonSchema + // load from a string + JsonSchema schema1 = JsonSchema.Parse(@"{'type':'object'}"); - JObject person = JObject.Parse(@"{ + // load from a file + using (TextReader reader = File.OpenText(@"c:\schema\Person.json")) + { + JsonSchema schema2 = JsonSchema.Read(new JsonTextReader(reader)); + + // do stuff + } + #endregion + } + + public void ManuallyCreateJsonSchema() + { + #region ManuallyCreateJsonSchema + JsonSchema schema = new JsonSchema(); + schema.Type = JsonSchemaType.Object; + schema.Properties = new Dictionary + { + { "name", new JsonSchema { Type = JsonSchemaType.String } }, + { + "hobbies", new JsonSchema + { + Type = JsonSchemaType.Array, + Items = new List { new JsonSchema { Type = JsonSchemaType.String } } + } + }, + }; + + JObject person = JObject.Parse(@"{ 'name': 'James', 'hobbies': ['.NET', 'Blogging', 'Reading', 'Xbox', 'LOLCATS'] }"); - bool valid = person.IsValid(schema); - // true - #endregion + bool valid = person.IsValid(schema); + // true + #endregion - Assert.IsTrue(valid); + Assert.IsTrue(valid); + } } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/LinqToJsonTests.cs b/Src/Newtonsoft.Json.Tests/Documentation/LinqToJsonTests.cs index 3682b981..ce4926ba 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/LinqToJsonTests.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/LinqToJsonTests.cs @@ -50,35 +50,35 @@ using File = System.IO.File; namespace Newtonsoft.Json.Tests.Documentation { - public static class File - { - public static StreamReader OpenText(string path) + public static class File { - return null; + public static StreamReader OpenText(string path) + { + return null; + } + + public static StreamWriter CreateText(string path) + { + return null; + } + + public static void WriteAllText(string path, string contents) + { + Console.WriteLine(contents); + } + + public static string ReadAllText(string path) + { + return null; + } } - public static StreamWriter CreateText(string path) + public class LinqToJsonTests { - return null; - } - - public static void WriteAllText(string path, string contents) - { - Console.WriteLine(contents); - } - - public static string ReadAllText(string path) - { - return null; - } - } - - public class LinqToJsonTests - { - public void LinqToJsonBasic() - { - #region LinqToJsonBasic - JObject o = JObject.Parse(@"{ + public void LinqToJsonBasic() + { + #region LinqToJsonBasic + JObject o = JObject.Parse(@"{ 'CPU': 'Intel', 'Drives': [ 'DVD read/writer', @@ -86,137 +86,137 @@ namespace Newtonsoft.Json.Tests.Documentation ] }"); - string cpu = (string)o["CPU"]; - // Intel + string cpu = (string)o["CPU"]; + // Intel - string firstDrive = (string)o["Drives"][0]; - // DVD read/writer + string firstDrive = (string)o["Drives"][0]; + // DVD read/writer - IList allDrives = o["Drives"].Select(t => (string)t).ToList(); - // DVD read/writer - // 500 gigabyte hard drive - #endregion - } - - public void LinqToJsonCreateNormal() - { - #region LinqToJsonCreateNormal - JArray array = new JArray(); - JValue text = new JValue("Manual text"); - JValue date = new JValue(new DateTime(2000, 5, 23)); - - array.Add(text); - array.Add(date); - - string json = array.ToString(); - // [ - // "Manual text", - // "2000-05-23T00:00:00" - // ] - #endregion - } - - public class Post - { - public string Title { get; set; } - public string Description { get; set; } - public string Link { get; set; } - public IList Categories { get; set; } - } - - private List GetPosts() - { - return null; - } - - public void LinqToJsonCreateDeclaratively() - { - #region LinqToJsonCreateDeclaratively - List posts = GetPosts(); - - JObject rss = - new JObject( - new JProperty("channel", - new JObject( - new JProperty("title", "James Newton-King"), - new JProperty("link", "http://james.newtonking.com"), - new JProperty("description", "James Newton-King's blog."), - new JProperty("item", - new JArray( - from p in posts - orderby p.Title - select new JObject( - new JProperty("title", p.Title), - new JProperty("description", p.Description), - new JProperty("link", p.Link), - new JProperty("category", - new JArray( - from c in p.Categories - select new JValue(c))))))))); - - Console.WriteLine(rss.ToString()); - - //{ - // "channel": { - // "title": "James Newton-King", - // "link": "http://james.newtonking.com", - // "description": "James Newton-King's blog.", - // "item": [ - // { - // "title": "Json.NET 1.3 + New license + Now on CodePlex", - // "description": "Annoucing the release of Json.NET 1.3, the MIT license and being available on CodePlex", - // "link": "http://james.newtonking.com/projects/json-net.aspx", - // "category": [ - // "Json.NET", - // "CodePlex" - // ] - // }, - // { - // "title": "LINQ to JSON beta", - // "description": "Annoucing LINQ to JSON", - // "link": "http://james.newtonking.com/projects/json-net.aspx", - // "category": [ - // "Json.NET", - // "LINQ" - // ] - // } - // ] - // } - //} - #endregion - } - - public void LinqToJsonCreateFromObject() - { - List posts = null; - - #region LinqToJsonCreateFromObject - JObject o = JObject.FromObject(new - { - channel = new - { - title = "James Newton-King", - link = "http://james.newtonking.com", - description = "James Newton-King's blog.", - item = - from p in posts - orderby p.Title - select new - { - title = p.Title, - description = p.Description, - link = p.Link, - category = p.Categories - } + IList allDrives = o["Drives"].Select(t => (string)t).ToList(); + // DVD read/writer + // 500 gigabyte hard drive + #endregion } - }); - #endregion - } - public void LinqToJsonCreateParse() - { - #region LinqToJsonCreateParse - string json = @"{ + public void LinqToJsonCreateNormal() + { + #region LinqToJsonCreateNormal + JArray array = new JArray(); + JValue text = new JValue("Manual text"); + JValue date = new JValue(new DateTime(2000, 5, 23)); + + array.Add(text); + array.Add(date); + + string json = array.ToString(); + // [ + // "Manual text", + // "2000-05-23T00:00:00" + // ] + #endregion + } + + public class Post + { + public string Title { get; set; } + public string Description { get; set; } + public string Link { get; set; } + public IList Categories { get; set; } + } + + private List GetPosts() + { + return null; + } + + public void LinqToJsonCreateDeclaratively() + { + #region LinqToJsonCreateDeclaratively + List posts = GetPosts(); + + JObject rss = + new JObject( + new JProperty("channel", + new JObject( + new JProperty("title", "James Newton-King"), + new JProperty("link", "http://james.newtonking.com"), + new JProperty("description", "James Newton-King's blog."), + new JProperty("item", + new JArray( + from p in posts + orderby p.Title + select new JObject( + new JProperty("title", p.Title), + new JProperty("description", p.Description), + new JProperty("link", p.Link), + new JProperty("category", + new JArray( + from c in p.Categories + select new JValue(c))))))))); + + Console.WriteLine(rss.ToString()); + + //{ + // "channel": { + // "title": "James Newton-King", + // "link": "http://james.newtonking.com", + // "description": "James Newton-King's blog.", + // "item": [ + // { + // "title": "Json.NET 1.3 + New license + Now on CodePlex", + // "description": "Annoucing the release of Json.NET 1.3, the MIT license and being available on CodePlex", + // "link": "http://james.newtonking.com/projects/json-net.aspx", + // "category": [ + // "Json.NET", + // "CodePlex" + // ] + // }, + // { + // "title": "LINQ to JSON beta", + // "description": "Annoucing LINQ to JSON", + // "link": "http://james.newtonking.com/projects/json-net.aspx", + // "category": [ + // "Json.NET", + // "LINQ" + // ] + // } + // ] + // } + //} + #endregion + } + + public void LinqToJsonCreateFromObject() + { + List posts = null; + + #region LinqToJsonCreateFromObject + JObject o = JObject.FromObject(new + { + channel = new + { + title = "James Newton-King", + link = "http://james.newtonking.com", + description = "James Newton-King's blog.", + item = + from p in posts + orderby p.Title + select new + { + title = p.Title, + description = p.Description, + link = p.Link, + category = p.Categories + } + } + }); + #endregion + } + + public void LinqToJsonCreateParse() + { + #region LinqToJsonCreateParse + string json = @"{ CPU: 'Intel', Drives: [ 'DVD read/writer', @@ -224,38 +224,38 @@ namespace Newtonsoft.Json.Tests.Documentation ] }"; - JObject o = JObject.Parse(json); - #endregion - } + JObject o = JObject.Parse(json); + #endregion + } - public void LinqToJsonCreateParseArray() - { - #region LinqToJsonCreateParseArray - string json = @"[ + public void LinqToJsonCreateParseArray() + { + #region LinqToJsonCreateParseArray + string json = @"[ 'Small', 'Medium', 'Large' ]"; - JArray a = JArray.Parse(json); - #endregion - } + JArray a = JArray.Parse(json); + #endregion + } - public void LinqToJsonReadObject() - { - #region LinqToJsonReadObject - using (StreamReader reader = File.OpenText(@"c:\person.json")) - { - JObject o = (JObject)JToken.ReadFrom(new JsonTextReader(reader)); - // do stuff - } - #endregion - } + public void LinqToJsonReadObject() + { + #region LinqToJsonReadObject + using (StreamReader reader = File.OpenText(@"c:\person.json")) + { + JObject o = (JObject)JToken.ReadFrom(new JsonTextReader(reader)); + // do stuff + } + #endregion + } - public void LinqToJsonSimpleQuerying() - { - #region LinqToJsonSimpleQuerying - string json = @"{ + public void LinqToJsonSimpleQuerying() + { + #region LinqToJsonSimpleQuerying + string json = @"{ 'channel': { 'title': 'James Newton-King', 'link': 'http://james.newtonking.com', @@ -283,120 +283,121 @@ namespace Newtonsoft.Json.Tests.Documentation } }"; - JObject rss = JObject.Parse(json); + JObject rss = JObject.Parse(json); - string rssTitle = (string)rss["channel"]["title"]; - // James Newton-King + string rssTitle = (string)rss["channel"]["title"]; + // James Newton-King - string itemTitle = (string)rss["channel"]["item"][0]["title"]; - // Json.NET 1.3 + New license + Now on CodePlex + string itemTitle = (string)rss["channel"]["item"][0]["title"]; + // Json.NET 1.3 + New license + Now on CodePlex - JArray categories = (JArray)rss["channel"]["item"][0]["categories"]; - // ["Json.NET", "CodePlex"] + JArray categories = (JArray)rss["channel"]["item"][0]["categories"]; + // ["Json.NET", "CodePlex"] - IList categoriesText = categories.Select(c => (string)c).ToList(); - // Json.NET - // CodePlex - #endregion - } - - public void LinqToJsonQuerying() - { - JObject rss = new JObject(); - - #region LinqToJsonQuerying - var postTitles = - from p in rss["channel"]["item"] - select (string)p["title"]; - - foreach (var item in postTitles) - { - Console.WriteLine(item); - } - - //LINQ to JSON beta - //Json.NET 1.3 + New license + Now on CodePlex - - var categories = - from c in rss["channel"]["item"].Children()["category"].Values() - group c by c into g - orderby g.Count() descending - select new { Category = g.Key, Count = g.Count() }; - - foreach (var c in categories) - { - Console.WriteLine(c.Category + " - Count: " + c.Count); - } - - //Json.NET - Count: 2 - //LINQ - Count: 1 - //CodePlex - Count: 1 - #endregion - } - - #region LinqToJsonDeserializeObject - public class Shortie - { - public string Original { get; set; } - public string Shortened { get; set; } - public string Short { get; set; } - public ShortieException Error { get; set; } - } - - public class ShortieException - { - public int Code { get; set; } - public string ErrorMessage { get; set; } - } - #endregion - - public void LinqToJsonDeserializeExample() - { - #region LinqToJsonDeserializeExample - string jsonText = @"{ - 'short': { - 'original': 'http://www.foo.com/', - 'short': 'krehqk', - 'error': { - 'code':0, - 'msg':'No action taken' - } - }"; - - JObject json = JObject.Parse(jsonText); - - Shortie shortie = new Shortie - { - Original = (string)json["short"]["original"], - Short = (string)json["short"]["short"], - Error = new ShortieException - { - Code = (int)json["short"]["error"]["code"], - ErrorMessage = (string)json["short"]["error"]["msg"] + IList categoriesText = categories.Select(c => (string)c).ToList(); + // Json.NET + // CodePlex + #endregion } - }; - Console.WriteLine(shortie.Original); - // http://www.foo.com/ + public void LinqToJsonQuerying() + { + JObject rss = new JObject(); - Console.WriteLine(shortie.Error.ErrorMessage); - // No action taken - #endregion - } + #region LinqToJsonQuerying + var postTitles = + from p in rss["channel"]["item"] + select (string)p["title"]; - public void SelectTokenSimple() - { - JObject o = new JObject(); + foreach (var item in postTitles) + { + Console.WriteLine(item); + } - #region SelectTokenSimple - string name = (string)o.SelectToken("Manufacturers[0].Name"); - #endregion - } + //LINQ to JSON beta + //Json.NET 1.3 + New license + Now on CodePlex - public void SelectTokenComplex() - { - #region SelectTokenComplex - JObject o = JObject.Parse(@"{ + var categories = + from c in rss["channel"]["item"].Children()["category"].Values() + group c by c + into g + orderby g.Count() descending + select new { Category = g.Key, Count = g.Count() }; + + foreach (var c in categories) + { + Console.WriteLine(c.Category + " - Count: " + c.Count); + } + + //Json.NET - Count: 2 + //LINQ - Count: 1 + //CodePlex - Count: 1 + #endregion + } + + #region LinqToJsonDeserializeObject + public class Shortie + { + public string Original { get; set; } + public string Shortened { get; set; } + public string Short { get; set; } + public ShortieException Error { get; set; } + } + + public class ShortieException + { + public int Code { get; set; } + public string ErrorMessage { get; set; } + } + #endregion + + public void LinqToJsonDeserializeExample() + { + #region LinqToJsonDeserializeExample + string jsonText = @"{ + 'short': { + 'original': 'http://www.foo.com/', + 'short': 'krehqk', + 'error': { + 'code':0, + 'msg':'No action taken' + } + }"; + + JObject json = JObject.Parse(jsonText); + + Shortie shortie = new Shortie + { + Original = (string)json["short"]["original"], + Short = (string)json["short"]["short"], + Error = new ShortieException + { + Code = (int)json["short"]["error"]["code"], + ErrorMessage = (string)json["short"]["error"]["msg"] + } + }; + + Console.WriteLine(shortie.Original); + // http://www.foo.com/ + + Console.WriteLine(shortie.Error.ErrorMessage); + // No action taken + #endregion + } + + public void SelectTokenSimple() + { + JObject o = new JObject(); + + #region SelectTokenSimple + string name = (string)o.SelectToken("Manufacturers[0].Name"); + #endregion + } + + public void SelectTokenComplex() + { + #region SelectTokenComplex + JObject o = JObject.Parse(@"{ 'Stores': [ 'Lambton Quay', 'Willis Street' @@ -427,34 +428,35 @@ namespace Newtonsoft.Json.Tests.Documentation ] }"); - string name = (string)o.SelectToken("Manufacturers[0].Name"); - // Acme Co + string name = (string)o.SelectToken("Manufacturers[0].Name"); + // Acme Co - decimal productPrice = (decimal)o.SelectToken("Manufacturers[0].Products[0].Price"); - // 50 + decimal productPrice = (decimal)o.SelectToken("Manufacturers[0].Products[0].Price"); + // 50 - string productName = (string)o.SelectToken("Manufacturers[1].Products[0].Name"); - // Elbow Grease - #endregion + string productName = (string)o.SelectToken("Manufacturers[1].Products[0].Name"); + // Elbow Grease + #endregion + } + + public void SelectTokenLinq() + { + JObject o = new JObject(); + + #region SelectTokenLinq + IList storeNames = o.SelectToken("Stores").Select(s => (string)s).ToList(); + // Lambton Quay + // Willis Street + + IList firstProductNames = o["Manufacturers"].Select(m => (string)m.SelectToken("Products[1].Name")).ToList(); + // null + // Headlight Fluid + + decimal totalPrice = o["Manufacturers"].Sum(m => (decimal)m.SelectToken("Products[0].Price")); + // 149.95 + #endregion + } } - - public void SelectTokenLinq() - { - JObject o = new JObject(); - - #region SelectTokenLinq - IList storeNames = o.SelectToken("Stores").Select(s => (string)s).ToList(); - // Lambton Quay - // Willis Street - - IList firstProductNames = o["Manufacturers"].Select(m => (string)m.SelectToken("Products[1].Name")).ToList(); - // null - // Headlight Fluid - - decimal totalPrice = o["Manufacturers"].Sum(m => (decimal)m.SelectToken("Products[0].Price")); - // 149.95 - #endregion - } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/PerformanceTests.cs b/Src/Newtonsoft.Json.Tests/Documentation/PerformanceTests.cs index eafc15eb..e8a31673 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/PerformanceTests.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/PerformanceTests.cs @@ -50,172 +50,173 @@ using System.Globalization; namespace Newtonsoft.Json.Tests.Documentation { - public class HttpClient - { - public Task GetStringAsync(string requestUri) + public class HttpClient { - return null; - } - - public Task GetStreamAsync(string requestUri) - { - return null; - } - } - - #region JsonConverterAttribute - [JsonConverter(typeof(PersonConverter))] - public class Person - { - public Person() - { - Likes = new List(); - } - - public string Name { get; set; } - public IList Likes { get; private set; } - } - #endregion - - #region JsonConverterContractResolver - public class ConverterContractResolver : DefaultContractResolver - { - public new static readonly ConverterContractResolver Instance = new ConverterContractResolver(); - - protected override JsonContract CreateContract(Type objectType) - { - JsonContract contract = base.CreateContract(objectType); - - // this will only be called once and then cached - if (objectType == typeof(DateTime) || objectType == typeof(DateTimeOffset)) - contract.Converter = new JavaScriptDateTimeConverter(); - - return contract; - } - } - #endregion - - public class PersonConverter : JsonConverter - { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - return null; - } - - public override bool CanConvert(Type objectType) - { - return (objectType == typeof(Person)); - } - } - - [TestFixture] - public class PerformanceTests : TestFixtureBase - { - [Test] - public void ConverterContractResolverTest() - { - string json = JsonConvert.SerializeObject(new DateTime(2000, 10, 10, 10, 10, 10, DateTimeKind.Utc), new JsonSerializerSettings + public Task GetStringAsync(string requestUri) { - ContractResolver = ConverterContractResolver.Instance - }); + return null; + } - Console.WriteLine(json); + public Task GetStreamAsync(string requestUri) + { + return null; + } } - public void DeserializeString() + #region JsonConverterAttribute + [JsonConverter(typeof(PersonConverter))] + public class Person { - #region DeserializeString - HttpClient client = new HttpClient(); + public Person() + { + Likes = new List(); + } - // read the json into a string - // string could potentially be very large and cause memory problems - string json = client.GetStringAsync("http://www.test.com/large.json").Result; - - Person p = JsonConvert.DeserializeObject(json); - #endregion - } - - public void DeserializeStream() - { - #region DeserializeStream - HttpClient client = new HttpClient(); - - using (Stream s = client.GetStreamAsync("http://www.test.com/large.json").Result) - using (StreamReader sr = new StreamReader(s)) - using (JsonReader reader = new JsonTextReader(sr)) - { - JsonSerializer serializer = new JsonSerializer(); - - // read the json from a stream - // json size doesn't matter because only a small piece is read at a time from the HTTP request - Person p = serializer.Deserialize(reader); - } - #endregion - } - } - - public static class PersonWriter - { - #region ReaderWriter - public static string ToJson(this Person p) - { - StringWriter sw = new StringWriter(); - JsonTextWriter writer = new JsonTextWriter(sw); - - // { - writer.WriteStartObject(); - - // "name" : "Jerry" - writer.WritePropertyName("name"); - writer.WriteValue(p.Name); - - // "likes": ["Comedy", "Superman"] - writer.WritePropertyName("likes"); - writer.WriteStartArray(); - foreach (string like in p.Likes) - { - writer.WriteValue(like); - } - writer.WriteEndArray(); - - // } - writer.WriteEndObject(); - - return sw.ToString(); + public string Name { get; set; } + public IList Likes { get; private set; } } #endregion - public static Person ToPerson(this string s) + #region JsonConverterContractResolver + public class ConverterContractResolver : DefaultContractResolver { - StringReader sr = new StringReader(s); - JsonTextReader reader = new JsonTextReader(sr); + public new static readonly ConverterContractResolver Instance = new ConverterContractResolver(); - Person p = new Person(); - - // { - reader.Read(); - // "name" - reader.Read(); - // "Jerry" - p.Name = reader.ReadAsString(); - // "likes" - reader.Read(); - // [ - reader.Read(); - // "Comedy", "Superman", ] - while (reader.Read() && reader.TokenType != JsonToken.EndArray) - { - p.Likes.Add((string)reader.Value); - } - // } - reader.Read(); + protected override JsonContract CreateContract(Type objectType) + { + JsonContract contract = base.CreateContract(objectType); - return p; + // this will only be called once and then cached + if (objectType == typeof(DateTime) || objectType == typeof(DateTimeOffset)) + contract.Converter = new JavaScriptDateTimeConverter(); + + return contract; + } + } + #endregion + + public class PersonConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + return null; + } + + public override bool CanConvert(Type objectType) + { + return (objectType == typeof(Person)); + } + } + + [TestFixture] + public class PerformanceTests : TestFixtureBase + { + [Test] + public void ConverterContractResolverTest() + { + string json = JsonConvert.SerializeObject(new DateTime(2000, 10, 10, 10, 10, 10, DateTimeKind.Utc), new JsonSerializerSettings + { + ContractResolver = ConverterContractResolver.Instance + }); + + Console.WriteLine(json); + } + + public void DeserializeString() + { + #region DeserializeString + HttpClient client = new HttpClient(); + + // read the json into a string + // string could potentially be very large and cause memory problems + string json = client.GetStringAsync("http://www.test.com/large.json").Result; + + Person p = JsonConvert.DeserializeObject(json); + #endregion + } + + public void DeserializeStream() + { + #region DeserializeStream + HttpClient client = new HttpClient(); + + using (Stream s = client.GetStreamAsync("http://www.test.com/large.json").Result) + using (StreamReader sr = new StreamReader(s)) + using (JsonReader reader = new JsonTextReader(sr)) + { + JsonSerializer serializer = new JsonSerializer(); + + // read the json from a stream + // json size doesn't matter because only a small piece is read at a time from the HTTP request + Person p = serializer.Deserialize(reader); + } + #endregion + } + } + + public static class PersonWriter + { + #region ReaderWriter + public static string ToJson(this Person p) + { + StringWriter sw = new StringWriter(); + JsonTextWriter writer = new JsonTextWriter(sw); + + // { + writer.WriteStartObject(); + + // "name" : "Jerry" + writer.WritePropertyName("name"); + writer.WriteValue(p.Name); + + // "likes": ["Comedy", "Superman"] + writer.WritePropertyName("likes"); + writer.WriteStartArray(); + foreach (string like in p.Likes) + { + writer.WriteValue(like); + } + writer.WriteEndArray(); + + // } + writer.WriteEndObject(); + + return sw.ToString(); + } + #endregion + + public static Person ToPerson(this string s) + { + StringReader sr = new StringReader(s); + JsonTextReader reader = new JsonTextReader(sr); + + Person p = new Person(); + + // { + reader.Read(); + // "name" + reader.Read(); + // "Jerry" + p.Name = reader.ReadAsString(); + // "likes" + reader.Read(); + // [ + reader.Read(); + // "Comedy", "Superman", ] + while (reader.Read() && reader.TokenType != JsonToken.EndArray) + { + p.Likes.Add((string)reader.Value); + } + // } + reader.Read(); + + return p; + } } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/ReadingAndWritingJsonTests.cs b/Src/Newtonsoft.Json.Tests/Documentation/ReadingAndWritingJsonTests.cs index 3de4f2e9..acda4b68 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/ReadingAndWritingJsonTests.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/ReadingAndWritingJsonTests.cs @@ -49,52 +49,52 @@ using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs; namespace Newtonsoft.Json.Tests.Documentation { - [TestFixture] - public class ReadingAndWritingJsonTests : TestFixtureBase - { - public void ReadingAndWritingJsonText() + [TestFixture] + public class ReadingAndWritingJsonTests : TestFixtureBase { - #region ReadingAndWritingJsonText - StringBuilder sb = new StringBuilder(); - StringWriter sw = new StringWriter(sb); + public void ReadingAndWritingJsonText() + { + #region ReadingAndWritingJsonText + StringBuilder sb = new StringBuilder(); + StringWriter sw = new StringWriter(sb); - using (JsonWriter writer = new JsonTextWriter(sw)) - { - writer.Formatting = Formatting.Indented; + using (JsonWriter writer = new JsonTextWriter(sw)) + { + writer.Formatting = Formatting.Indented; - writer.WriteStartObject(); - writer.WritePropertyName("CPU"); - writer.WriteValue("Intel"); - writer.WritePropertyName("PSU"); - writer.WriteValue("500W"); - writer.WritePropertyName("Drives"); - writer.WriteStartArray(); - writer.WriteValue("DVD read/writer"); - writer.WriteComment("(broken)"); - writer.WriteValue("500 gigabyte hard drive"); - writer.WriteValue("200 gigabype hard drive"); - writer.WriteEnd(); - writer.WriteEndObject(); - } + writer.WriteStartObject(); + writer.WritePropertyName("CPU"); + writer.WriteValue("Intel"); + writer.WritePropertyName("PSU"); + writer.WriteValue("500W"); + writer.WritePropertyName("Drives"); + writer.WriteStartArray(); + writer.WriteValue("DVD read/writer"); + writer.WriteComment("(broken)"); + writer.WriteValue("500 gigabyte hard drive"); + writer.WriteValue("200 gigabype hard drive"); + writer.WriteEnd(); + writer.WriteEndObject(); + } - // { - // "CPU": "Intel", - // "PSU": "500W", - // "Drives": [ - // "DVD read/writer" - // /*(broken)*/, - // "500 gigabyte hard drive", - // "200 gigabype hard drive" - // ] - // } - #endregion - } + // { + // "CPU": "Intel", + // "PSU": "500W", + // "Drives": [ + // "DVD read/writer" + // /*(broken)*/, + // "500 gigabyte hard drive", + // "200 gigabype hard drive" + // ] + // } + #endregion + } - [Test] - public void ReadingJsonText() - { - #region ReadingJsonText - string json = @"{ + [Test] + public void ReadingJsonText() + { + #region ReadingJsonText + string json = @"{ 'CPU': 'Intel', 'PSU': '500W', 'Drives': [ @@ -105,46 +105,47 @@ namespace Newtonsoft.Json.Tests.Documentation ] }"; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - while (reader.Read()) - { - if (reader.Value != null) - Console.WriteLine("Token: {0}, Value: {1}", reader.TokenType, reader.Value); - else - Console.WriteLine("Token: {0}", reader.TokenType); - } + JsonTextReader reader = new JsonTextReader(new StringReader(json)); + while (reader.Read()) + { + if (reader.Value != null) + Console.WriteLine("Token: {0}, Value: {1}", reader.TokenType, reader.Value); + else + Console.WriteLine("Token: {0}", reader.TokenType); + } - // Token: StartObject - // Token: PropertyName, Value: CPU - // Token: String, Value: Intel - // Token: PropertyName, Value: PSU - // Token: String, Value: 500W - // Token: PropertyName, Value: Drives - // Token: StartArray - // Token: String, Value: DVD read/writer - // Token: Comment, Value: (broken) - // Token: String, Value: 500 gigabyte hard drive - // Token: String, Value: 200 gigabype hard drive - // Token: EndArray - // Token: EndObject - #endregion + // Token: StartObject + // Token: PropertyName, Value: CPU + // Token: String, Value: Intel + // Token: PropertyName, Value: PSU + // Token: String, Value: 500W + // Token: PropertyName, Value: Drives + // Token: StartArray + // Token: String, Value: DVD read/writer + // Token: Comment, Value: (broken) + // Token: String, Value: 500 gigabyte hard drive + // Token: String, Value: 200 gigabype hard drive + // Token: EndArray + // Token: EndObject + #endregion + } + + public void ReadingAndWritingJsonLinq() + { + #region ReadingAndWritingJsonLinq + JObject o = new JObject( + new JProperty("Name", "John Smith"), + new JProperty("BirthDate", new DateTime(1983, 3, 20)) + ); + + JsonSerializer serializer = new JsonSerializer(); + Person p = (Person)serializer.Deserialize(new JTokenReader(o), typeof(Person)); + + Console.WriteLine(p.Name); + // John Smith + #endregion + } } - - public void ReadingAndWritingJsonLinq() - { - #region ReadingAndWritingJsonLinq - JObject o = new JObject( - new JProperty("Name", "John Smith"), - new JProperty("BirthDate", new DateTime(1983, 3, 20)) - ); - - JsonSerializer serializer = new JsonSerializer(); - Person p = (Person)serializer.Deserialize(new JTokenReader(o), typeof(Person)); - - Console.WriteLine(p.Name); - // John Smith - #endregion - } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Bson/DeserializeFromBson.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Bson/DeserializeFromBson.cs index 5d74c457..e156e48a 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Bson/DeserializeFromBson.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Bson/DeserializeFromBson.cs @@ -7,32 +7,32 @@ using Newtonsoft.Json.Bson; namespace Newtonsoft.Json.Tests.Documentation.Samples.Bson { - public class DeserializeFromBson - { - #region Types - public class Event + public class DeserializeFromBson { - public string Name { get; set; } - public DateTime StartDate { get; set; } + #region Types + public class Event + { + public string Name { get; set; } + public DateTime StartDate { get; set; } + } + #endregion + + public void Example() + { + #region Usage + byte[] data = Convert.FromBase64String("MQAAAAJOYW1lAA8AAABNb3ZpZSBQcmVtaWVyZQAJU3RhcnREYXRlAMDgKWE8AQAAAA=="); + + MemoryStream ms = new MemoryStream(data); + using (BsonReader reader = new BsonReader(ms)) + { + JsonSerializer serializer = new JsonSerializer(); + + Event e = serializer.Deserialize(reader); + + Console.WriteLine(e.Name); + // Movie Premiere + } + #endregion + } } - #endregion - - public void Example() - { - #region Usage - byte[] data = Convert.FromBase64String("MQAAAAJOYW1lAA8AAABNb3ZpZSBQcmVtaWVyZQAJU3RhcnREYXRlAMDgKWE8AQAAAA=="); - - MemoryStream ms = new MemoryStream(data); - using (BsonReader reader = new BsonReader(ms)) - { - JsonSerializer serializer = new JsonSerializer(); - - Event e = serializer.Deserialize(reader); - - Console.WriteLine(e.Name); - // Movie Premiere - } - #endregion - } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Bson/DeserializeFromBsonCollection.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Bson/DeserializeFromBsonCollection.cs index 53fd8abe..71bcf622 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Bson/DeserializeFromBsonCollection.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Bson/DeserializeFromBsonCollection.cs @@ -7,53 +7,53 @@ using Newtonsoft.Json.Bson; namespace Newtonsoft.Json.Tests.Documentation.Samples.Bson { - public class DeserializeFromBsonCollection - { - #region Types - public class Event + public class DeserializeFromBsonCollection { - public string Name { get; set; } - public DateTime StartDate { get; set; } + #region Types + public class Event + { + public string Name { get; set; } + public DateTime StartDate { get; set; } + } + #endregion + + public void Example() + { + //IList e = new List + // { + // new Event {StartDate = new DateTime(2013, 3, 31), Name = "Easter"} + // }; + //MemoryStream ms1 = new MemoryStream(); + //using (BsonWriter writer = new BsonWriter(ms1)) + //{ + // JsonSerializer serializer = new JsonSerializer(); + + // serializer.Serialize(writer, e); + //} + + //string ss = Convert.ToBase64String(ms1.ToArray()); + //Console.WriteLine(ss); + + #region Usage + string s = "MQAAAAMwACkAAAACTmFtZQAHAAAARWFzdGVyAAlTdGFydERhdGUAgDf0uj0BAAAAAA=="; + byte[] data = Convert.FromBase64String(s); + + MemoryStream ms = new MemoryStream(data); + using (BsonReader reader = new BsonReader(ms)) + { + reader.ReadRootValueAsArray = true; + + JsonSerializer serializer = new JsonSerializer(); + + IList events = serializer.Deserialize>(reader); + + Console.WriteLine(events.Count); + // 1 + + Console.WriteLine(events[0].Name); + // Easter + } + #endregion + } } - #endregion - - public void Example() - { - //IList e = new List - // { - // new Event {StartDate = new DateTime(2013, 3, 31), Name = "Easter"} - // }; - //MemoryStream ms1 = new MemoryStream(); - //using (BsonWriter writer = new BsonWriter(ms1)) - //{ - // JsonSerializer serializer = new JsonSerializer(); - - // serializer.Serialize(writer, e); - //} - - //string ss = Convert.ToBase64String(ms1.ToArray()); - //Console.WriteLine(ss); - - #region Usage - string s = "MQAAAAMwACkAAAACTmFtZQAHAAAARWFzdGVyAAlTdGFydERhdGUAgDf0uj0BAAAAAA=="; - byte[] data = Convert.FromBase64String(s); - - MemoryStream ms = new MemoryStream(data); - using (BsonReader reader = new BsonReader(ms)) - { - reader.ReadRootValueAsArray = true; - - JsonSerializer serializer = new JsonSerializer(); - - IList events = serializer.Deserialize>(reader); - - Console.WriteLine(events.Count); - // 1 - - Console.WriteLine(events[0].Name); - // Easter - } - #endregion - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Bson/SerializeToBson.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Bson/SerializeToBson.cs index 59e8b680..23727626 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Bson/SerializeToBson.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Bson/SerializeToBson.cs @@ -8,37 +8,37 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Documentation.Samples.Bson { - public class SerializeToBson - { - #region Types - public class Event + public class SerializeToBson { - public string Name { get; set; } - public DateTime StartDate { get; set; } - } - #endregion - - public void Example() - { - #region Usage - Event e = new Event + #region Types + public class Event { - Name = "Movie Premiere", - StartDate = new DateTime(2013, 1, 22, 20, 30, 0) - }; + public string Name { get; set; } + public DateTime StartDate { get; set; } + } + #endregion - MemoryStream ms = new MemoryStream(); - using (BsonWriter writer = new BsonWriter(ms)) - { - JsonSerializer serializer = new JsonSerializer(); - serializer.Serialize(writer, e); - } + public void Example() + { + #region Usage + Event e = new Event + { + Name = "Movie Premiere", + StartDate = new DateTime(2013, 1, 22, 20, 30, 0) + }; - string data = Convert.ToBase64String(ms.ToArray()); - - Console.WriteLine(data); - // MQAAAAJOYW1lAA8AAABNb3ZpZSBQcmVtaWVyZQAJU3RhcnREYXRlAMDgKWE8AQAAAA== - #endregion + MemoryStream ms = new MemoryStream(); + using (BsonWriter writer = new BsonWriter(ms)) + { + JsonSerializer serializer = new JsonSerializer(); + serializer.Serialize(writer, e); + } + + string data = Convert.ToBase64String(ms.ToArray()); + + Console.WriteLine(data); + // MQAAAAJOYW1lAA8AAABNb3ZpZSBQcmVtaWVyZQAJU3RhcnREYXRlAMDgKWE8AQAAAA== + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Json/ReadJsonWithJsonTextReader.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Json/ReadJsonWithJsonTextReader.cs index 1da2258e..d876b233 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Json/ReadJsonWithJsonTextReader.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Json/ReadJsonWithJsonTextReader.cs @@ -6,45 +6,45 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Json { - public class ReadJsonWithJsonTextReader - { - public void Example() + public class ReadJsonWithJsonTextReader { - #region Usage - string json = @"{ - 'CPU': 'Intel', - 'PSU': '500W', - 'Drives': [ - 'DVD read/writer' - /*(broken)*/, - '500 gigabyte hard drive', - '200 gigabype hard drive' - ] - }"; + public void Example() + { + #region Usage + string json = @"{ + 'CPU': 'Intel', + 'PSU': '500W', + 'Drives': [ + 'DVD read/writer' + /*(broken)*/, + '500 gigabyte hard drive', + '200 gigabype hard drive' + ] + }"; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - while (reader.Read()) - { - if (reader.Value != null) - Console.WriteLine("Token: {0}, Value: {1}", reader.TokenType, reader.Value); - else - Console.WriteLine("Token: {0}", reader.TokenType); - } + JsonTextReader reader = new JsonTextReader(new StringReader(json)); + while (reader.Read()) + { + if (reader.Value != null) + Console.WriteLine("Token: {0}, Value: {1}", reader.TokenType, reader.Value); + else + Console.WriteLine("Token: {0}", reader.TokenType); + } - // Token: StartObject - // Token: PropertyName, Value: CPU - // Token: String, Value: Intel - // Token: PropertyName, Value: PSU - // Token: String, Value: 500W - // Token: PropertyName, Value: Drives - // Token: StartArray - // Token: String, Value: DVD read/writer - // Token: Comment, Value: (broken) - // Token: String, Value: 500 gigabyte hard drive - // Token: String, Value: 200 gigabype hard drive - // Token: EndArray - // Token: EndObject - #endregion + // Token: StartObject + // Token: PropertyName, Value: CPU + // Token: String, Value: Intel + // Token: PropertyName, Value: PSU + // Token: String, Value: 500W + // Token: PropertyName, Value: Drives + // Token: StartArray + // Token: String, Value: DVD read/writer + // Token: Comment, Value: (broken) + // Token: String, Value: 500 gigabyte hard drive + // Token: String, Value: 200 gigabype hard drive + // Token: EndArray + // Token: EndObject + #endregion + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Json/WriteJsonWithJsonTextWriter.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Json/WriteJsonWithJsonTextWriter.cs index fb8ebe63..a558726f 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Json/WriteJsonWithJsonTextWriter.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Json/WriteJsonWithJsonTextWriter.cs @@ -6,45 +6,45 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Json { - public class WriteJsonWithJsonTextWriter - { - public void Example() + public class WriteJsonWithJsonTextWriter { - #region Usage - StringBuilder sb = new StringBuilder(); - StringWriter sw = new StringWriter(sb); + public void Example() + { + #region Usage + StringBuilder sb = new StringBuilder(); + StringWriter sw = new StringWriter(sb); - using (JsonWriter writer = new JsonTextWriter(sw)) - { - writer.Formatting = Formatting.Indented; + using (JsonWriter writer = new JsonTextWriter(sw)) + { + writer.Formatting = Formatting.Indented; - writer.WriteStartObject(); - writer.WritePropertyName("CPU"); - writer.WriteValue("Intel"); - writer.WritePropertyName("PSU"); - writer.WriteValue("500W"); - writer.WritePropertyName("Drives"); - writer.WriteStartArray(); - writer.WriteValue("DVD read/writer"); - writer.WriteComment("(broken)"); - writer.WriteValue("500 gigabyte hard drive"); - writer.WriteValue("200 gigabype hard drive"); - writer.WriteEnd(); - writer.WriteEndObject(); - } + writer.WriteStartObject(); + writer.WritePropertyName("CPU"); + writer.WriteValue("Intel"); + writer.WritePropertyName("PSU"); + writer.WriteValue("500W"); + writer.WritePropertyName("Drives"); + writer.WriteStartArray(); + writer.WriteValue("DVD read/writer"); + writer.WriteComment("(broken)"); + writer.WriteValue("500 gigabyte hard drive"); + writer.WriteValue("200 gigabype hard drive"); + writer.WriteEnd(); + writer.WriteEndObject(); + } - Console.WriteLine(sb.ToString()); - // { - // "CPU": "Intel", - // "PSU": "500W", - // "Drives": [ - // "DVD read/writer" - // /*(broken)*/, - // "500 gigabyte hard drive", - // "200 gigabype hard drive" - // ] - // } - #endregion + Console.WriteLine(sb.ToString()); + // { + // "CPU": "Intel", + // "PSU": "500W", + // "Drives": [ + // "DVD read/writer" + // /*(broken)*/, + // "500 gigabyte hard drive", + // "200 gigabype hard drive" + // ] + // } + #endregion + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/Clone.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/Clone.cs index b363e290..aae8febd 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/Clone.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/Clone.cs @@ -6,43 +6,43 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class Clone - { - public void Example() + public class Clone { - #region Usage - JObject o1 = new JObject + public void Example() { - {"String", "A string!"}, - {"Items", new JArray(1, 2)} - }; + #region Usage + JObject o1 = new JObject + { + { "String", "A string!" }, + { "Items", new JArray(1, 2) } + }; - Console.WriteLine(o1.ToString()); - // { - // "String": "A string!", - // "Items": [ - // 1, - // 2 - // ] - // } + Console.WriteLine(o1.ToString()); + // { + // "String": "A string!", + // "Items": [ + // 1, + // 2 + // ] + // } - JObject o2 = (JObject) o1.DeepClone(); + JObject o2 = (JObject)o1.DeepClone(); - Console.WriteLine(o2.ToString()); - // { - // "String": "A string!", - // "Items": [ - // 1, - // 2 - // ] - // } + Console.WriteLine(o2.ToString()); + // { + // "String": "A string!", + // "Items": [ + // 1, + // 2 + // ] + // } - Console.WriteLine(JToken.DeepEquals(o1, o2)); - // true + Console.WriteLine(JToken.DeepEquals(o1, o2)); + // true - Console.WriteLine(Object.ReferenceEquals(o1, o2)); - // false - #endregion + Console.WriteLine(Object.ReferenceEquals(o1, o2)); + // false + #endregion + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateJsonAnonymousObject.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateJsonAnonymousObject.cs index badd761b..5f8f9e79 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateJsonAnonymousObject.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateJsonAnonymousObject.cs @@ -6,76 +6,76 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class CreateJsonAnonymousObject - { - #region Types - public class Post + public class CreateJsonAnonymousObject { - public string Title { get; set; } - public string Description { get; set; } - public string Link { get; set; } - public IList Categories { get; set; } - } - #endregion - - public void Example() - { - #region Usage - List posts = new List + #region Types + public class Post { - new Post + public string Title { get; set; } + public string Description { get; set; } + public string Link { get; set; } + public IList Categories { get; set; } + } + #endregion + + public void Example() + { + #region Usage + List posts = new List { - Title = "Episode VII", - Description = "Episode VII production", - Categories = new List + new Post { - "episode-vii", - "movie" - }, - Link = "episode-vii-production.aspx" - } - }; + Title = "Episode VII", + Description = "Episode VII production", + Categories = new List + { + "episode-vii", + "movie" + }, + Link = "episode-vii-production.aspx" + } + }; - JObject o = JObject.FromObject(new - { - channel = new + JObject o = JObject.FromObject(new { - title = "Star Wars", - link = "http://www.starwars.com", - description = "Star Wars blog.", - item = - from p in posts - orderby p.Title - select new - { - title = p.Title, - description = p.Description, - link = p.Link, - category = p.Categories - } - } - }); + channel = new + { + title = "Star Wars", + link = "http://www.starwars.com", + description = "Star Wars blog.", + item = + from p in posts + orderby p.Title + select new + { + title = p.Title, + description = p.Description, + link = p.Link, + category = p.Categories + } + } + }); - Console.WriteLine(o.ToString()); - // { - // "channel": { - // "title": "Star Wars", - // "link": "http://www.starwars.com", - // "description": "Star Wars blog.", - // "item": [ - // { - // "title": "Episode VII", - // "description": "Episode VII production", - // "link": "episode-vii-production.aspx", - // "category": [ - // "episode-vii", - // "movie" - // ] - // } - // ] - // } - // } - #endregion + Console.WriteLine(o.ToString()); + // { + // "channel": { + // "title": "Star Wars", + // "link": "http://www.starwars.com", + // "description": "Star Wars blog.", + // "item": [ + // { + // "title": "Episode VII", + // "description": "Episode VII production", + // "link": "episode-vii-production.aspx", + // "category": [ + // "episode-vii", + // "movie" + // ] + // } + // ] + // } + // } + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateJsonCollectionInitializer.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateJsonCollectionInitializer.cs index a32533fd..fddc4b04 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateJsonCollectionInitializer.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateJsonCollectionInitializer.cs @@ -6,34 +6,34 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class CreateJsonCollectionInitializer - { - public void Example() + public class CreateJsonCollectionInitializer { - #region Usage - JObject o = new JObject + public void Example() { - {"Cpu", "Intel"}, - {"Memory", 32}, - { - "Drives", new JArray - { - "DVD", - "SSD" - } - } - }; - - Console.WriteLine(o.ToString()); - // { - // "Cpu": "Intel", - // "Memory": 32, - // "Drives": [ - // "DVD", - // "SSD" - // ] - // } - #endregion + #region Usage + JObject o = new JObject + { + { "Cpu", "Intel" }, + { "Memory", 32 }, + { + "Drives", new JArray + { + "DVD", + "SSD" + } + } + }; + + Console.WriteLine(o.ToString()); + // { + // "Cpu": "Intel", + // "Memory": 32, + // "Drives": [ + // "DVD", + // "SSD" + // ] + // } + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateJsonDeclaratively.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateJsonDeclaratively.cs index b88418e4..71e31a64 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateJsonDeclaratively.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateJsonDeclaratively.cs @@ -6,78 +6,78 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class CreateJsonDeclaratively - { - #region Types - public class Post + public class CreateJsonDeclaratively { - public string Title { get; set; } - public string Description { get; set; } - public string Link { get; set; } - public IList Categories { get; set; } + #region Types + public class Post + { + public string Title { get; set; } + public string Description { get; set; } + public string Link { get; set; } + public IList Categories { get; set; } + } + #endregion + + private List GetPosts() + { + return null; + } + + public void Example() + { + #region Usage + List posts = GetPosts(); + + JObject rss = + new JObject( + new JProperty("channel", + new JObject( + new JProperty("title", "James Newton-King"), + new JProperty("link", "http://james.newtonking.com"), + new JProperty("description", "James Newton-King's blog."), + new JProperty("item", + new JArray( + from p in posts + orderby p.Title + select new JObject( + new JProperty("title", p.Title), + new JProperty("description", p.Description), + new JProperty("link", p.Link), + new JProperty("category", + new JArray( + from c in p.Categories + select new JValue(c))))))))); + + Console.WriteLine(rss.ToString()); + + // { + // "channel": { + // "title": "James Newton-King", + // "link": "http://james.newtonking.com", + // "description": "James Newton-King's blog.", + // "item": [ + // { + // "title": "Json.NET 1.3 + New license + Now on CodePlex", + // "description": "Annoucing the release of Json.NET 1.3, the MIT license and being available on CodePlex", + // "link": "http://james.newtonking.com/projects/json-net.aspx", + // "category": [ + // "Json.NET", + // "CodePlex" + // ] + // }, + // { + // "title": "LINQ to JSON beta", + // "description": "Annoucing LINQ to JSON", + // "link": "http://james.newtonking.com/projects/json-net.aspx", + // "category": [ + // "Json.NET", + // "LINQ" + // ] + // } + // ] + // } + // } + #endregion + } } - #endregion - - private List GetPosts() - { - return null; - } - - public void Example() - { - #region Usage - List posts = GetPosts(); - - JObject rss = - new JObject( - new JProperty("channel", - new JObject( - new JProperty("title", "James Newton-King"), - new JProperty("link", "http://james.newtonking.com"), - new JProperty("description", "James Newton-King's blog."), - new JProperty("item", - new JArray( - from p in posts - orderby p.Title - select new JObject( - new JProperty("title", p.Title), - new JProperty("description", p.Description), - new JProperty("link", p.Link), - new JProperty("category", - new JArray( - from c in p.Categories - select new JValue(c))))))))); - - Console.WriteLine(rss.ToString()); - - // { - // "channel": { - // "title": "James Newton-King", - // "link": "http://james.newtonking.com", - // "description": "James Newton-King's blog.", - // "item": [ - // { - // "title": "Json.NET 1.3 + New license + Now on CodePlex", - // "description": "Annoucing the release of Json.NET 1.3, the MIT license and being available on CodePlex", - // "link": "http://james.newtonking.com/projects/json-net.aspx", - // "category": [ - // "Json.NET", - // "CodePlex" - // ] - // }, - // { - // "title": "LINQ to JSON beta", - // "description": "Annoucing LINQ to JSON", - // "link": "http://james.newtonking.com/projects/json-net.aspx", - // "category": [ - // "Json.NET", - // "LINQ" - // ] - // } - // ] - // } - // } - #endregion - } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateJsonDynamic.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateJsonDynamic.cs index 4d5d43be..4e8a6a84 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateJsonDynamic.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateJsonDynamic.cs @@ -6,32 +6,32 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class CreateJsonDynamic - { - public void Example() + public class CreateJsonDynamic { - #region Usage - dynamic product = new JObject(); - product.ProductName = "Elbow Grease"; - product.Enabled = true; - product.Price = 4.90m; - product.StockCount = 9000; - product.StockValue = 44100; - product.Tags = new JArray("Real", "OnSale"); + public void Example() + { + #region Usage + dynamic product = new JObject(); + product.ProductName = "Elbow Grease"; + product.Enabled = true; + product.Price = 4.90m; + product.StockCount = 9000; + product.StockValue = 44100; + product.Tags = new JArray("Real", "OnSale"); - Console.WriteLine(product.ToString()); - // { - // "ProductName": "Elbow Grease", - // "Enabled": true, - // "Price": 4.90, - // "StockCount": 9000, - // "StockValue": 44100, - // "Tags": [ - // "Real", - // "OnSale" - // ] - // } - #endregion + Console.WriteLine(product.ToString()); + // { + // "ProductName": "Elbow Grease", + // "Enabled": true, + // "Price": 4.90, + // "StockCount": 9000, + // "StockValue": 44100, + // "Tags": [ + // "Real", + // "OnSale" + // ] + // } + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateJsonJTokenWriter.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateJsonJTokenWriter.cs index 7a8bee85..0e265416 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateJsonJTokenWriter.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateJsonJTokenWriter.cs @@ -6,33 +6,33 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class CreateJsonJTokenWriter - { - public void Example() + public class CreateJsonJTokenWriter { - #region Usage - JTokenWriter writer = new JTokenWriter(); - writer.WriteStartObject(); - writer.WritePropertyName("name1"); - writer.WriteValue("value1"); - writer.WritePropertyName("name2"); - writer.WriteStartArray(); - writer.WriteValue(1); - writer.WriteValue(2); - writer.WriteEndArray(); - writer.WriteEndObject(); + public void Example() + { + #region Usage + JTokenWriter writer = new JTokenWriter(); + writer.WriteStartObject(); + writer.WritePropertyName("name1"); + writer.WriteValue("value1"); + writer.WritePropertyName("name2"); + writer.WriteStartArray(); + writer.WriteValue(1); + writer.WriteValue(2); + writer.WriteEndArray(); + writer.WriteEndObject(); - JObject o = (JObject)writer.Token; + JObject o = (JObject)writer.Token; - Console.WriteLine(o.ToString()); - // { - // "name1": "value1", - // "name2": [ - // 1, - // 2 - // ] - // } - #endregion + Console.WriteLine(o.ToString()); + // { + // "name1": "value1", + // "name2": [ + // 1, + // 2 + // ] + // } + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateJsonManually.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateJsonManually.cs index e01a672f..33d7e58a 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateJsonManually.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateJsonManually.cs @@ -6,26 +6,26 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class CreateJsonManually - { - public void Example() + public class CreateJsonManually { - #region Usage - JArray array = new JArray(); - array.Add("Manual text"); - array.Add(new DateTime(2000, 5, 23)); + public void Example() + { + #region Usage + JArray array = new JArray(); + array.Add("Manual text"); + array.Add(new DateTime(2000, 5, 23)); - JObject o = new JObject(); - o["MyArray"] = array; + JObject o = new JObject(); + o["MyArray"] = array; - string json = o.ToString(); - // { - // "MyArray": [ - // "Manual text", - // "2000-05-23T00:00:00" - // ] - // } - #endregion + string json = o.ToString(); + // { + // "MyArray": [ + // "Manual text", + // "2000-05-23T00:00:00" + // ] + // } + #endregion + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateReader.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateReader.cs index bc770765..a703057b 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateReader.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateReader.cs @@ -6,46 +6,46 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class CreateReader - { - public void Example() + public class CreateReader { - #region Usage - JObject o = new JObject + public void Example() { - {"Cpu", "Intel"}, - {"Memory", 32}, - { - "Drives", new JArray - { - "DVD", - "SSD" - } - } - }; + #region Usage + JObject o = new JObject + { + { "Cpu", "Intel" }, + { "Memory", 32 }, + { + "Drives", new JArray + { + "DVD", + "SSD" + } + } + }; - JsonReader reader = o.CreateReader(); - while (reader.Read()) - { - Console.Write(reader.TokenType); - if (reader.Value != null) - Console.Write(" - " + reader.Value); + JsonReader reader = o.CreateReader(); + while (reader.Read()) + { + Console.Write(reader.TokenType); + if (reader.Value != null) + Console.Write(" - " + reader.Value); - Console.WriteLine(); - } + Console.WriteLine(); + } - // StartObject - // PropertyName - Cpu - // String - Intel - // PropertyName - Memory - // Integer - 32 - // PropertyName - Drives - // StartArray - // String - DVD - // String - SSD - // EndArray - // EndObject - #endregion + // StartObject + // PropertyName - Cpu + // String - Intel + // PropertyName - Memory + // Integer - 32 + // PropertyName - Drives + // StartArray + // String - DVD + // String - SSD + // EndArray + // EndObject + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateWriter.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateWriter.cs index 6a3af59d..aa85552f 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateWriter.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/CreateWriter.cs @@ -6,34 +6,34 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class CreateWriter - { - public void Example() + public class CreateWriter { - #region Usage - JObject o = new JObject + public void Example() { - {"name1", "value1"}, - {"name2", "value2"} - }; + #region Usage + JObject o = new JObject + { + { "name1", "value1" }, + { "name2", "value2" } + }; - JsonWriter writer = o.CreateWriter(); - writer.WritePropertyName("name3"); - writer.WriteStartArray(); - writer.WriteValue(1); - writer.WriteValue(2); - writer.WriteEndArray(); + JsonWriter writer = o.CreateWriter(); + writer.WritePropertyName("name3"); + writer.WriteStartArray(); + writer.WriteValue(1); + writer.WriteValue(2); + writer.WriteEndArray(); - Console.WriteLine(o.ToString()); - // { - // "name1": "value1", - // "name2": "value2", - // "name3": [ - // 1, - // 2 - // ] - // } - #endregion + Console.WriteLine(o.ToString()); + // { + // "name1": "value1", + // "name2": "value2", + // "name3": [ + // 1, + // 2 + // ] + // } + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/DeepEquals.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/DeepEquals.cs index 13b1d371..8eed17f8 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/DeepEquals.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/DeepEquals.cs @@ -6,41 +6,41 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class DeepEquals - { - public void Example() + public class DeepEquals { - #region Usage - JValue s1 = new JValue("A string"); - JValue s2 = new JValue("A string"); - JValue s3 = new JValue("A STRING"); - - Console.WriteLine(JToken.DeepEquals(s1, s2)); - // true - - Console.WriteLine(JToken.DeepEquals(s2, s3)); - // false - - JObject o1 = new JObject + public void Example() { - {"Integer", 12345}, - {"String", "A string"}, - {"Items", new JArray(1, 2)} - }; + #region Usage + JValue s1 = new JValue("A string"); + JValue s2 = new JValue("A string"); + JValue s3 = new JValue("A STRING"); - JObject o2 = new JObject - { - {"Integer", 12345}, - {"String", "A string"}, - {"Items", new JArray(1, 2)} - }; + Console.WriteLine(JToken.DeepEquals(s1, s2)); + // true - Console.WriteLine(JToken.DeepEquals(o1, o2)); - // true + Console.WriteLine(JToken.DeepEquals(s2, s3)); + // false - Console.WriteLine(JToken.DeepEquals(s1, o1["String"])); - // true - #endregion + JObject o1 = new JObject + { + { "Integer", 12345 }, + { "String", "A string" }, + { "Items", new JArray(1, 2) } + }; + + JObject o2 = new JObject + { + { "Integer", 12345 }, + { "String", "A string" }, + { "Items", new JArray(1, 2) } + }; + + Console.WriteLine(JToken.DeepEquals(o1, o2)); + // true + + Console.WriteLine(JToken.DeepEquals(s1, o1["String"])); + // true + #endregion + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/DeserializeWithLinq.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/DeserializeWithLinq.cs index d2bb9e7e..bf09a5a5 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/DeserializeWithLinq.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/DeserializeWithLinq.cs @@ -7,50 +7,50 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class DeserializeWithLinq - { - #region Types - public class BlogPost + public class DeserializeWithLinq { - public string Title { get; set; } - public string AuthorName { get; set; } - public string AuthorTwitter { get; set; } - public string Body { get; set; } - public DateTime PostedDate { get; set; } - } - #endregion - - public void Example() - { - #region Usage - string json = @"[ + #region Types + public class BlogPost { - 'Title': 'Json.NET is awesome!', - 'Author': { - 'Name': 'James Newton-King', - 'Twitter': '@JamesNK', - 'Picture': '/jamesnk.png' - }, - 'Date': '2013-01-23T19:30:00', - 'BodyHtml': '<h3>Title!</h3>\r\n<p>Content!</p>' + public string Title { get; set; } + public string AuthorName { get; set; } + public string AuthorTwitter { get; set; } + public string Body { get; set; } + public DateTime PostedDate { get; set; } } - ]"; + #endregion - JArray blogPostArray = JArray.Parse(json); - - IList blogPosts = blogPostArray.Select(p => new BlogPost + public void Example() { - Title = (string) p["Title"], - AuthorName = (string) p["Author"]["Name"], - AuthorTwitter = (string) p["Author"]["Twitter"], - PostedDate = (DateTime) p["Date"], - Body = HttpUtility.HtmlDecode((string) p["BodyHtml"]) - }).ToList(); + #region Usage + string json = @"[ + { + 'Title': 'Json.NET is awesome!', + 'Author': { + 'Name': 'James Newton-King', + 'Twitter': '@JamesNK', + 'Picture': '/jamesnk.png' + }, + 'Date': '2013-01-23T19:30:00', + 'BodyHtml': '<h3>Title!</h3>\r\n<p>Content!</p>' + } + ]"; - Console.WriteLine(blogPosts[0].Body); - //

Title!

- //

Content!

- #endregion + JArray blogPostArray = JArray.Parse(json); + + IList blogPosts = blogPostArray.Select(p => new BlogPost + { + Title = (string)p["Title"], + AuthorName = (string)p["Author"]["Name"], + AuthorTwitter = (string)p["Author"]["Twitter"], + PostedDate = (DateTime)p["Date"], + Body = HttpUtility.HtmlDecode((string)p["BodyHtml"]) + }).ToList(); + + Console.WriteLine(blogPosts[0].Body); + //

Title!

+ //

Content!

+ #endregion + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/FromObject.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/FromObject.cs index 4d02103a..686fb4a9 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/FromObject.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/FromObject.cs @@ -6,65 +6,65 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class FromObject - { - #region Types - public class Computer + public class FromObject { - public string Cpu { get; set; } - public int Memory { get; set; } - public IList Drives { get; set; } - } - #endregion - - public void Example() - { - #region Usage - JValue i = (JValue)JToken.FromObject(12345); - - Console.WriteLine(i.Type); - // Integer - Console.WriteLine(i.ToString()); - // 12345 - - JValue s = (JValue)JToken.FromObject("A string"); - - Console.WriteLine(s.Type); - // String - Console.WriteLine(s.ToString()); - // A string - - Computer computer = new Computer + #region Types + public class Computer { - Cpu = "Intel", - Memory = 32, - Drives = new List + public string Cpu { get; set; } + public int Memory { get; set; } + public IList Drives { get; set; } + } + #endregion + + public void Example() + { + #region Usage + JValue i = (JValue)JToken.FromObject(12345); + + Console.WriteLine(i.Type); + // Integer + Console.WriteLine(i.ToString()); + // 12345 + + JValue s = (JValue)JToken.FromObject("A string"); + + Console.WriteLine(s.Type); + // String + Console.WriteLine(s.ToString()); + // A string + + Computer computer = new Computer { - "DVD", - "SSD" - } - }; + Cpu = "Intel", + Memory = 32, + Drives = new List + { + "DVD", + "SSD" + } + }; - JObject o = (JObject)JToken.FromObject(computer); + JObject o = (JObject)JToken.FromObject(computer); - Console.WriteLine(o.ToString()); - // { - // "Cpu": "Intel", - // "Memory": 32, - // "Drives": [ - // "DVD", - // "SSD" - // ] - // } + Console.WriteLine(o.ToString()); + // { + // "Cpu": "Intel", + // "Memory": 32, + // "Drives": [ + // "DVD", + // "SSD" + // ] + // } - JArray a = (JArray)JToken.FromObject(computer.Drives); + JArray a = (JArray)JToken.FromObject(computer.Drives); - Console.WriteLine(a.ToString()); - // [ - // "DVD", - // "SSD" - // ] - #endregion + Console.WriteLine(a.ToString()); + // [ + // "DVD", + // "SSD" + // ] + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/JObjectProperties.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/JObjectProperties.cs index 4605414a..87702489 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/JObjectProperties.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/JObjectProperties.cs @@ -6,31 +6,31 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class JObjectProperties - { - public void Example() + public class JObjectProperties { - #region Usage - JObject o = new JObject + public void Example() { - { "name1", "value1" }, - { "name2", "value2"} - }; + #region Usage + JObject o = new JObject + { + { "name1", "value1" }, + { "name2", "value2" } + }; - foreach (JProperty property in o.Properties()) - { - Console.WriteLine(property.Name + " - " + property.Value); - } - // name1 - value1 - // name2 - value2 + foreach (JProperty property in o.Properties()) + { + Console.WriteLine(property.Name + " - " + property.Value); + } + // name1 - value1 + // name2 - value2 - foreach (KeyValuePair property in o) - { - Console.WriteLine(property.Key + " - " + property.Value); - } - // name1 - value1 - // name2 - value2 - #endregion + foreach (KeyValuePair property in o) + { + Console.WriteLine(property.Key + " - " + property.Value); + } + // name1 - value1 + // name2 - value2 + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/JValueCast.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/JValueCast.cs index 93e519a2..f5e63334 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/JValueCast.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/JValueCast.cs @@ -6,52 +6,52 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class JValueCast - { - public void Example() + public class JValueCast { - #region Usage - JValue v1 = new JValue("1"); - int i = (int)v1; + public void Example() + { + #region Usage + JValue v1 = new JValue("1"); + int i = (int)v1; - Console.WriteLine(i); - // 1 + Console.WriteLine(i); + // 1 - JValue v2 = new JValue(true); - bool b = (bool)v2; + JValue v2 = new JValue(true); + bool b = (bool)v2; - Console.WriteLine(b); - // true + Console.WriteLine(b); + // true - JValue v3 = new JValue("19.95"); - decimal d = (decimal)v3; + JValue v3 = new JValue("19.95"); + decimal d = (decimal)v3; - Console.WriteLine(d); - // 19.95 + Console.WriteLine(d); + // 19.95 - JValue v4 = new JValue(new DateTime(2013, 1, 21)); - string s = (string)v4; + JValue v4 = new JValue(new DateTime(2013, 1, 21)); + string s = (string)v4; - Console.WriteLine(s); - // 01/21/2013 00:00:00 + Console.WriteLine(s); + // 01/21/2013 00:00:00 - JValue v5 = new JValue("http://www.bing.com"); - Uri u = (Uri)v5; + JValue v5 = new JValue("http://www.bing.com"); + Uri u = (Uri)v5; - Console.WriteLine(u); - // http://www.bing.com/ + Console.WriteLine(u); + // http://www.bing.com/ - JValue v6 = new JValue((object)null); - u = (Uri)v6; + JValue v6 = new JValue((object)null); + u = (Uri)v6; - Console.WriteLine((u != null) ? u.ToString() : "{null}"); - // {null} + Console.WriteLine((u != null) ? u.ToString() : "{null}"); + // {null} - DateTime? dt = (DateTime?)v6; + DateTime? dt = (DateTime?)v6; - Console.WriteLine((dt != null) ? dt.ToString() : "{null}"); - // {null} - #endregion + Console.WriteLine((dt != null) ? dt.ToString() : "{null}"); + // {null} + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/JValueValue.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/JValueValue.cs index fcf4b55b..56ad9557 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/JValueValue.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/JValueValue.cs @@ -6,25 +6,25 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class JValueValue - { - public void Example() + public class JValueValue { - #region Usage - JValue s = new JValue("A string value"); + public void Example() + { + #region Usage + JValue s = new JValue("A string value"); - Console.WriteLine(s.Value.GetType().Name); - // String - Console.WriteLine(s.Value); - // A string value + Console.WriteLine(s.Value.GetType().Name); + // String + Console.WriteLine(s.Value); + // A string value - JValue u = new JValue(new Uri("http://www.google.com/")); + JValue u = new JValue(new Uri("http://www.google.com/")); - Console.WriteLine(u.Value.GetType().Name); - // Uri - Console.WriteLine(u.Value); - // http://www.google.com/ - #endregion + Console.WriteLine(u.Value.GetType().Name); + // Uri + Console.WriteLine(u.Value); + // http://www.google.com/ + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ModifyJson.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ModifyJson.cs index 93b6d687..e86d7f0f 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ModifyJson.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ModifyJson.cs @@ -6,50 +6,50 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class ModifyJson - { - public void Example() + public class ModifyJson { - #region Usage - string json = @"{ - 'channel': { - 'title': 'Star Wars', - 'link': 'http://www.starwars.com', - 'description': 'Star Wars blog.', - 'obsolete': 'Obsolete value', - 'item': [] + public void Example() + { + #region Usage + string json = @"{ + 'channel': { + 'title': 'Star Wars', + 'link': 'http://www.starwars.com', + 'description': 'Star Wars blog.', + 'obsolete': 'Obsolete value', + 'item': [] + } + }"; + + JObject rss = JObject.Parse(json); + + JObject channel = (JObject)rss["channel"]; + + channel["title"] = ((string)channel["title"]).ToUpper(); + channel["description"] = ((string)channel["description"]).ToUpper(); + + channel.Property("obsolete").Remove(); + + channel.Property("description").AddAfterSelf(new JProperty("new", "New value")); + + JArray item = (JArray)channel["item"]; + item.Add("Item 1"); + item.Add("Item 2"); + + Console.WriteLine(rss.ToString()); + // { + // "channel": { + // "title": "STAR WARS", + // "link": "http://www.starwars.com", + // "description": "STAR WARS BLOG.", + // "new": "New value", + // "item": [ + // "Item 1", + // "Item 2" + // ] + // } + // } + #endregion } - }"; - - JObject rss = JObject.Parse(json); - - JObject channel = (JObject)rss["channel"]; - - channel["title"] = ((string)channel["title"]).ToUpper(); - channel["description"] = ((string)channel["description"]).ToUpper(); - - channel.Property("obsolete").Remove(); - - channel.Property("description").AddAfterSelf(new JProperty("new", "New value")); - - JArray item = (JArray) channel["item"]; - item.Add("Item 1"); - item.Add("Item 2"); - - Console.WriteLine(rss.ToString()); - // { - // "channel": { - // "title": "STAR WARS", - // "link": "http://www.starwars.com", - // "description": "STAR WARS BLOG.", - // "new": "New value", - // "item": [ - // "Item 1", - // "Item 2" - // ] - // } - // } - #endregion } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ParseJsonAny.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ParseJsonAny.cs index 53cb3e45..2bbcc376 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ParseJsonAny.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ParseJsonAny.cs @@ -6,31 +6,31 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class ParseJsonAny - { - public void Example() + public class ParseJsonAny { - #region Usage - JToken t1 = JToken.Parse("{}"); + public void Example() + { + #region Usage + JToken t1 = JToken.Parse("{}"); - Console.WriteLine(t1.Type); - // Object + Console.WriteLine(t1.Type); + // Object - JToken t2 = JToken.Parse("[]"); + JToken t2 = JToken.Parse("[]"); - Console.WriteLine(t2.Type); - // Array + Console.WriteLine(t2.Type); + // Array - JToken t3 = JToken.Parse("null"); + JToken t3 = JToken.Parse("null"); - Console.WriteLine(t3.Type); - // Null + Console.WriteLine(t3.Type); + // Null - JToken t4 = JToken.Parse(@"'A string!'"); + JToken t4 = JToken.Parse(@"'A string!'"); - Console.WriteLine(t4.Type); - // String - #endregion + Console.WriteLine(t4.Type); + // String + #endregion + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ParseJsonArray.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ParseJsonArray.cs index 72d7f95f..4f576c0a 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ParseJsonArray.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ParseJsonArray.cs @@ -6,26 +6,26 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class ParseJsonArray - { - public void Example() + public class ParseJsonArray { - #region Usage - string json = @"[ - 'Small', - 'Medium', - 'Large' - ]"; + public void Example() + { + #region Usage + string json = @"[ + 'Small', + 'Medium', + 'Large' + ]"; - JArray a = JArray.Parse(json); + JArray a = JArray.Parse(json); - Console.WriteLine(a.ToString()); - // [ - // "Small", - // "Medium", - // "Large" - // ] - #endregion + Console.WriteLine(a.ToString()); + // [ + // "Small", + // "Medium", + // "Large" + // ] + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ParseJsonObject.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ParseJsonObject.cs index b4c21907..dc062343 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ParseJsonObject.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ParseJsonObject.cs @@ -6,30 +6,30 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class ParseJsonObject - { - public void Example() + public class ParseJsonObject { - #region Usage - string json = @"{ - CPU: 'Intel', - Drives: [ - 'DVD read/writer', - '500 gigabyte hard drive' - ] - }"; + public void Example() + { + #region Usage + string json = @"{ + CPU: 'Intel', + Drives: [ + 'DVD read/writer', + '500 gigabyte hard drive' + ] + }"; - JObject o = JObject.Parse(json); + JObject o = JObject.Parse(json); - Console.WriteLine(o.ToString()); - // { - // "CPU": "Intel", - // "Drives": [ - // "DVD read/writer", - // "500 gigabyte hard drive" - // ] - // } - #endregion + Console.WriteLine(o.ToString()); + // { + // "CPU": "Intel", + // "Drives": [ + // "DVD read/writer", + // "500 gigabyte hard drive" + // ] + // } + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/QueryJson.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/QueryJson.cs index f64068f0..3701bd0e 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/QueryJson.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/QueryJson.cs @@ -6,64 +6,64 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class QueryJson - { - public void Example() + public class QueryJson { - #region Usage - string json = @"{ - 'channel': { - 'title': 'James Newton-King', - 'link': 'http://james.newtonking.com', - 'description': 'James Newton-King\'s blog.', - 'item': [ - { - 'title': 'Json.NET 1.3 + New license + Now on CodePlex', - 'description': 'Annoucing the release of Json.NET 1.3, the MIT license and the source on CodePlex', - 'link': 'http://james.newtonking.com/projects/json-net.aspx', - 'category': [ - 'Json.NET', - 'CodePlex' - ] - }, - { - 'title': 'LINQ to JSON beta', - 'description': 'Annoucing LINQ to JSON', - 'link': 'http://james.newtonking.com/projects/json-net.aspx', - 'category': [ - 'Json.NET', - 'LINQ' - ] - } - ] + public void Example() + { + #region Usage + string json = @"{ + 'channel': { + 'title': 'James Newton-King', + 'link': 'http://james.newtonking.com', + 'description': 'James Newton-King\'s blog.', + 'item': [ + { + 'title': 'Json.NET 1.3 + New license + Now on CodePlex', + 'description': 'Annoucing the release of Json.NET 1.3, the MIT license and the source on CodePlex', + 'link': 'http://james.newtonking.com/projects/json-net.aspx', + 'category': [ + 'Json.NET', + 'CodePlex' + ] + }, + { + 'title': 'LINQ to JSON beta', + 'description': 'Annoucing LINQ to JSON', + 'link': 'http://james.newtonking.com/projects/json-net.aspx', + 'category': [ + 'Json.NET', + 'LINQ' + ] + } + ] + } + }"; + + JObject rss = JObject.Parse(json); + + string rssTitle = (string)rss["channel"]["title"]; + + Console.WriteLine(rssTitle); + // James Newton-King + + string itemTitle = (string)rss["channel"]["item"][0]["title"]; + + Console.WriteLine(itemTitle); + // Json.NET 1.3 + New license + Now on CodePlex + + JArray categories = (JArray)rss["channel"]["item"][0]["category"]; + + Console.WriteLine(categories); + // [ + // "Json.NET", + // "CodePlex" + // ] + + IList categoriesText = categories.Select(c => (string)c).ToList(); + + Console.WriteLine(string.Join(", ", categoriesText)); + // Json.NET, CodePlex + #endregion } - }"; - - JObject rss = JObject.Parse(json); - - string rssTitle = (string)rss["channel"]["title"]; - - Console.WriteLine(rssTitle); - // James Newton-King - - string itemTitle = (string)rss["channel"]["item"][0]["title"]; - - Console.WriteLine(itemTitle); - // Json.NET 1.3 + New license + Now on CodePlex - - JArray categories = (JArray)rss["channel"]["item"][0]["category"]; - - Console.WriteLine(categories); - // [ - // "Json.NET", - // "CodePlex" - // ] - - IList categoriesText = categories.Select(c => (string)c).ToList(); - - Console.WriteLine(string.Join(", ", categoriesText)); - // Json.NET, CodePlex - #endregion } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/QueryJsonDynamic.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/QueryJsonDynamic.cs index 74d76ea6..29a81a79 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/QueryJsonDynamic.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/QueryJsonDynamic.cs @@ -7,43 +7,43 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class QueryJsonDynamic - { - public void Example() + public class QueryJsonDynamic { - #region Usage - string json = @"[ + public void Example() { - 'Title': 'Json.NET is awesome!', - 'Author': { - 'Name': 'James Newton-King', - 'Twitter': '@JamesNK', - 'Picture': '/jamesnk.png' - }, - 'Date': '2013-01-23T19:30:00', - 'BodyHtml': '<h3>Title!</h3>\r\n<p>Content!</p>' + #region Usage + string json = @"[ + { + 'Title': 'Json.NET is awesome!', + 'Author': { + 'Name': 'James Newton-King', + 'Twitter': '@JamesNK', + 'Picture': '/jamesnk.png' + }, + 'Date': '2013-01-23T19:30:00', + 'BodyHtml': '<h3>Title!</h3>\r\n<p>Content!</p>' + } + ]"; + + dynamic blogPosts = JArray.Parse(json); + + dynamic blogPost = blogPosts[0]; + + string title = blogPost.Title; + + Console.WriteLine(title); + // Json.NET is awesome! + + string author = blogPost.Author.Name; + + Console.WriteLine(author); + // James Newton-King + + DateTime postDate = blogPost.Date; + + Console.WriteLine(postDate); + // 23/01/2013 7:30:00 p.m. + #endregion } - ]"; - - dynamic blogPosts = JArray.Parse(json); - - dynamic blogPost = blogPosts[0]; - - string title = blogPost.Title; - - Console.WriteLine(title); - // Json.NET is awesome! - - string author = blogPost.Author.Name; - - Console.WriteLine(author); - // James Newton-King - - DateTime postDate = blogPost.Date; - - Console.WriteLine(postDate); - // 23/01/2013 7:30:00 p.m. - #endregion } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/QueryJsonLinq.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/QueryJsonLinq.cs index 6fac53f7..3c4b529f 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/QueryJsonLinq.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/QueryJsonLinq.cs @@ -6,66 +6,67 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class QueryJsonLinq - { - public void Example() + public class QueryJsonLinq { - #region Usage - string json = @"{ - 'channel': { - 'title': 'James Newton-King', - 'link': 'http://james.newtonking.com', - 'description': 'James Newton-King\'s blog.', - 'item': [ + public void Example() + { + #region Usage + string json = @"{ + 'channel': { + 'title': 'James Newton-King', + 'link': 'http://james.newtonking.com', + 'description': 'James Newton-King\'s blog.', + 'item': [ + { + 'title': 'Json.NET 1.3 + New license + Now on CodePlex', + 'description': 'Annoucing the release of Json.NET 1.3, the MIT license and the source on CodePlex', + 'link': 'http://james.newtonking.com/projects/json-net.aspx', + 'category': [ + 'Json.NET', + 'CodePlex' + ] + }, + { + 'title': 'LINQ to JSON beta', + 'description': 'Annoucing LINQ to JSON', + 'link': 'http://james.newtonking.com/projects/json-net.aspx', + 'category': [ + 'Json.NET', + 'LINQ' + ] + } + ] + } + }"; + + JObject rss = JObject.Parse(json); + + var postTitles = + from p in rss["channel"]["item"] + select (string)p["title"]; + + foreach (var item in postTitles) { - 'title': 'Json.NET 1.3 + New license + Now on CodePlex', - 'description': 'Annoucing the release of Json.NET 1.3, the MIT license and the source on CodePlex', - 'link': 'http://james.newtonking.com/projects/json-net.aspx', - 'category': [ - 'Json.NET', - 'CodePlex' - ] - }, - { - 'title': 'LINQ to JSON beta', - 'description': 'Annoucing LINQ to JSON', - 'link': 'http://james.newtonking.com/projects/json-net.aspx', - 'category': [ - 'Json.NET', - 'LINQ' - ] + Console.WriteLine(item); } - ] + //LINQ to JSON beta + //Json.NET 1.3 + New license + Now on CodePlex + + var categories = + from c in rss["channel"]["item"].Children()["category"].Values() + group c by c + into g + orderby g.Count() descending + select new { Category = g.Key, Count = g.Count() }; + + foreach (var c in categories) + { + Console.WriteLine(c.Category + " - Count: " + c.Count); + } + //Json.NET - Count: 2 + //LINQ - Count: 1 + //CodePlex - Count: 1 + #endregion } - }"; - - JObject rss = JObject.Parse(json); - - var postTitles = - from p in rss["channel"]["item"] - select (string)p["title"]; - - foreach (var item in postTitles) - { - Console.WriteLine(item); - } - //LINQ to JSON beta - //Json.NET 1.3 + New license + Now on CodePlex - - var categories = - from c in rss["channel"]["item"].Children()["category"].Values() - group c by c into g - orderby g.Count() descending - select new { Category = g.Key, Count = g.Count() }; - - foreach (var c in categories) - { - Console.WriteLine(c.Category + " - Count: " + c.Count); - } - //Json.NET - Count: 2 - //LINQ - Count: 1 - //CodePlex - Count: 1 - #endregion } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/QueryJsonSelectToken.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/QueryJsonSelectToken.cs index 7f035659..96f89917 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/QueryJsonSelectToken.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/QueryJsonSelectToken.cs @@ -6,57 +6,57 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class QueryJsonSelectToken - { - public void Example() + public class QueryJsonSelectToken { - #region Usage - JObject o = JObject.Parse(@"{ - 'Stores': [ - 'Lambton Quay', - 'Willis Street' - ], - 'Manufacturers': [ - { - 'Name': 'Acme Co', - 'Products': [ - { - 'Name': 'Anvil', - 'Price': 50 - } - ] - }, - { - 'Name': 'Contoso', - 'Products': [ - { - 'Name': 'Elbow Grease', - 'Price': 99.95 - }, - { - 'Name': 'Headlight Fluid', - 'Price': 4 - } - ] - } - ] - }"); + public void Example() + { + #region Usage + JObject o = JObject.Parse(@"{ + 'Stores': [ + 'Lambton Quay', + 'Willis Street' + ], + 'Manufacturers': [ + { + 'Name': 'Acme Co', + 'Products': [ + { + 'Name': 'Anvil', + 'Price': 50 + } + ] + }, + { + 'Name': 'Contoso', + 'Products': [ + { + 'Name': 'Elbow Grease', + 'Price': 99.95 + }, + { + 'Name': 'Headlight Fluid', + 'Price': 4 + } + ] + } + ] + }"); - string name = (string)o.SelectToken("Manufacturers[0].Name"); + string name = (string)o.SelectToken("Manufacturers[0].Name"); - Console.WriteLine(name); - // Acme Co + Console.WriteLine(name); + // Acme Co - decimal productPrice = (decimal)o.SelectToken("Manufacturers[0].Products[0].Price"); + decimal productPrice = (decimal)o.SelectToken("Manufacturers[0].Products[0].Price"); - Console.WriteLine(productPrice); - // 50 + Console.WriteLine(productPrice); + // 50 - string productName = (string)o.SelectToken("Manufacturers[1].Products[0].Name"); + string productName = (string)o.SelectToken("Manufacturers[1].Products[0].Name"); - Console.WriteLine(productName); - // Elbow Grease - #endregion + Console.WriteLine(productName); + // Elbow Grease + #endregion + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/QueryJsonSelectTokenWithLinq.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/QueryJsonSelectTokenWithLinq.cs index ddc900f8..488e82c9 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/QueryJsonSelectTokenWithLinq.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/QueryJsonSelectTokenWithLinq.cs @@ -6,58 +6,58 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class QueryJsonSelectTokenWithLinq - { - public void Example() + public class QueryJsonSelectTokenWithLinq { - #region Usage - JObject o = JObject.Parse(@"{ - 'Stores': [ - 'Lambton Quay', - 'Willis Street' - ], - 'Manufacturers': [ - { - 'Name': 'Acme Co', - 'Products': [ - { - 'Name': 'Anvil', - 'Price': 50 - } - ] - }, - { - 'Name': 'Contoso', - 'Products': [ - { - 'Name': 'Elbow Grease', - 'Price': 99.95 - }, - { - 'Name': 'Headlight Fluid', - 'Price': 4 - } - ] - } - ] - }"); + public void Example() + { + #region Usage + JObject o = JObject.Parse(@"{ + 'Stores': [ + 'Lambton Quay', + 'Willis Street' + ], + 'Manufacturers': [ + { + 'Name': 'Acme Co', + 'Products': [ + { + 'Name': 'Anvil', + 'Price': 50 + } + ] + }, + { + 'Name': 'Contoso', + 'Products': [ + { + 'Name': 'Elbow Grease', + 'Price': 99.95 + }, + { + 'Name': 'Headlight Fluid', + 'Price': 4 + } + ] + } + ] + }"); - IList storeNames = o.SelectToken("Stores").Select(s => (string)s).ToList(); + IList storeNames = o.SelectToken("Stores").Select(s => (string)s).ToList(); - Console.WriteLine(string.Join(", ", storeNames)); - // Lambton Quay, Willis Street + Console.WriteLine(string.Join(", ", storeNames)); + // Lambton Quay, Willis Street - IList firstProductNames = o["Manufacturers"].Select(m => (string)m.SelectToken("Products[1].Name")) - .Where(n => n != null).ToList(); + IList firstProductNames = o["Manufacturers"].Select(m => (string)m.SelectToken("Products[1].Name")) + .Where(n => n != null).ToList(); - Console.WriteLine(string.Join(", ", firstProductNames)); - // Headlight Fluid + Console.WriteLine(string.Join(", ", firstProductNames)); + // Headlight Fluid - decimal totalPrice = o["Manufacturers"].Sum(m => (decimal)m.SelectToken("Products[0].Price")); + decimal totalPrice = o["Manufacturers"].Sum(m => (decimal)m.SelectToken("Products[0].Price")); - Console.WriteLine(totalPrice); - // 149.95 - #endregion + Console.WriteLine(totalPrice); + // 149.95 + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ReadJTokenFromBson.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ReadJTokenFromBson.cs index dd6e8218..94d86453 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ReadJTokenFromBson.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ReadJTokenFromBson.cs @@ -8,25 +8,25 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class ReadJTokenFromBson - { - public void Example() + public class ReadJTokenFromBson { - #region Usage - byte[] data = Convert.FromBase64String("KQAAAAJuYW1lMQAHAAAAdmFsdWUxAAJuYW1lMgAHAAAAdmFsdWUyAAA="); - MemoryStream ms = new MemoryStream(data); + public void Example() + { + #region Usage + byte[] data = Convert.FromBase64String("KQAAAAJuYW1lMQAHAAAAdmFsdWUxAAJuYW1lMgAHAAAAdmFsdWUyAAA="); + MemoryStream ms = new MemoryStream(data); - JObject o; - using (BsonReader reader = new BsonReader(ms)) - { - o = (JObject)JToken.ReadFrom(reader); - } + JObject o; + using (BsonReader reader = new BsonReader(ms)) + { + o = (JObject)JToken.ReadFrom(reader); + } - string value = (string)o["name1"]; + string value = (string)o["name1"]; - Console.WriteLine(value); - // value1 - #endregion + Console.WriteLine(value); + // value1 + #endregion + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ReadJson.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ReadJson.cs index e13310ef..567115f7 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ReadJson.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ReadJson.cs @@ -7,20 +7,20 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class ReadJson - { - public void Example() + public class ReadJson { - #region Usage - JObject o1 = JObject.Parse(File.ReadAllText(@"c:\videogames.json")); + public void Example() + { + #region Usage + JObject o1 = JObject.Parse(File.ReadAllText(@"c:\videogames.json")); - // read JSON directly from a file - using (StreamReader file = File.OpenText(@"c:\videogames.json")) - using (JsonTextReader reader = new JsonTextReader(file)) - { - JObject o2 = (JObject) JToken.ReadFrom(reader); - } - #endregion + // read JSON directly from a file + using (StreamReader file = File.OpenText(@"c:\videogames.json")) + using (JsonTextReader reader = new JsonTextReader(file)) + { + JObject o2 = (JObject)JToken.ReadFrom(reader); + } + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/SerializeWithLinq.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/SerializeWithLinq.cs index bef15727..de88dab2 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/SerializeWithLinq.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/SerializeWithLinq.cs @@ -7,64 +7,64 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class SerializeWithLinq - { - #region Types - public class BlogPost + public class SerializeWithLinq { - public string Title { get; set; } - public string AuthorName { get; set; } - public string AuthorTwitter { get; set; } - public string Body { get; set; } - public DateTime PostedDate { get; set; } - } - #endregion - - public void Example() - { - #region Usage - IList blogPosts = new List + #region Types + public class BlogPost { - new BlogPost - { - Title = "Json.NET is awesome!", - AuthorName = "James Newton-King", - AuthorTwitter = "JamesNK", - PostedDate = new DateTime(2013, 1, 23, 19, 30, 0), - Body = @"

Title!

-

Content!

" - } - }; + public string Title { get; set; } + public string AuthorName { get; set; } + public string AuthorTwitter { get; set; } + public string Body { get; set; } + public DateTime PostedDate { get; set; } + } + #endregion - JArray blogPostsArray = new JArray( - blogPosts.Select(p => new JObject - { - {"Title", p.Title}, + public void Example() + { + #region Usage + IList blogPosts = new List { - "Author", new JObject + new BlogPost { - {"Name", p.AuthorName}, - {"Twitter", p.AuthorTwitter} + Title = "Json.NET is awesome!", + AuthorName = "James Newton-King", + AuthorTwitter = "JamesNK", + PostedDate = new DateTime(2013, 1, 23, 19, 30, 0), + Body = @"

Title!

+

Content!

" } - }, - {"Date", p.PostedDate}, - {"BodyHtml", HttpUtility.HtmlEncode(p.Body)}, - }) - ); + }; - Console.WriteLine(blogPostsArray.ToString()); - // [ - // { - // "Title": "Json.NET is awesome!", - // "Author": { - // "Name": "James Newton-King", - // "Twitter": "JamesNK" - // }, - // "Date": "2013-01-23T19:30:00", - // "BodyHtml": "<h3>Title!</h3>\r\n<p>Content!</p>" - // } - // ] - #endregion + JArray blogPostsArray = new JArray( + blogPosts.Select(p => new JObject + { + { "Title", p.Title }, + { + "Author", new JObject + { + { "Name", p.AuthorName }, + { "Twitter", p.AuthorTwitter } + } + }, + { "Date", p.PostedDate }, + { "BodyHtml", HttpUtility.HtmlEncode(p.Body) }, + }) + ); + + Console.WriteLine(blogPostsArray.ToString()); + // [ + // { + // "Title": "Json.NET is awesome!", + // "Author": { + // "Name": "James Newton-King", + // "Twitter": "JamesNK" + // }, + // "Date": "2013-01-23T19:30:00", + // "BodyHtml": "<h3>Title!</h3>\r\n<p>Content!</p>" + // } + // ] + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ToObjectComplex.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ToObjectComplex.cs index b2ba20b7..da1210ab 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ToObjectComplex.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ToObjectComplex.cs @@ -6,41 +6,41 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class ToObjectComplex - { - #region Types - public class Person + public class ToObjectComplex { - public string Name { get; set; } + #region Types + public class Person + { + public string Name { get; set; } + } + #endregion + + public void Example() + { + #region Usage + string json = @"{ + 'd': [ + { + 'Name': 'John Smith' + }, + { + 'Name': 'Mike Smith' + } + ] + }"; + + JObject o = JObject.Parse(json); + + JArray a = (JArray)o["d"]; + + IList person = a.ToObject>(); + + Console.WriteLine(person[0].Name); + // John Smith + + Console.WriteLine(person[1].Name); + // Mike Smith + #endregion + } } - #endregion - - public void Example() - { - #region Usage - string json = @"{ - 'd': [ - { - 'Name': 'John Smith' - }, - { - 'Name': 'Mike Smith' - } - ] - }"; - - JObject o = JObject.Parse(json); - - JArray a = (JArray)o["d"]; - - IList person = a.ToObject>(); - - Console.WriteLine(person[0].Name); - // John Smith - - Console.WriteLine(person[1].Name); - // Mike Smith - #endregion - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ToObjectGeneric.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ToObjectGeneric.cs index 4e2596d5..1d358a20 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ToObjectGeneric.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ToObjectGeneric.cs @@ -6,28 +6,28 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class ToObjectGeneric - { - public void Example() + public class ToObjectGeneric { - #region Usage - JValue v1 = new JValue(true); + public void Example() + { + #region Usage + JValue v1 = new JValue(true); - bool b = v1.ToObject(); + bool b = v1.ToObject(); - Console.WriteLine(b); - // true + Console.WriteLine(b); + // true - int i = v1.ToObject(); + int i = v1.ToObject(); - Console.WriteLine(i); - // 1 + Console.WriteLine(i); + // 1 - string s = v1.ToObject(); + string s = v1.ToObject(); - Console.WriteLine(s); - // "True" - #endregion + Console.WriteLine(s); + // "True" + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ToObjectType.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ToObjectType.cs index db54548c..9f4ade2f 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ToObjectType.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ToObjectType.cs @@ -6,28 +6,28 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class ToObjectType - { - public void Example() + public class ToObjectType { - #region Usage - JValue v1 = new JValue(true); + public void Example() + { + #region Usage + JValue v1 = new JValue(true); - bool b = (bool)v1.ToObject(typeof(bool)); + bool b = (bool)v1.ToObject(typeof(bool)); - Console.WriteLine(b); - // true + Console.WriteLine(b); + // true - int i = (int)v1.ToObject(typeof(int)); + int i = (int)v1.ToObject(typeof(int)); - Console.WriteLine(i); - // 1 + Console.WriteLine(i); + // 1 - string s = (string)v1.ToObject(typeof(string)); + string s = (string)v1.ToObject(typeof(string)); - Console.WriteLine(s); - // "True" - #endregion + Console.WriteLine(s); + // "True" + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ToString.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ToString.cs index 5235987f..56842669 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ToString.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ToString.cs @@ -7,26 +7,26 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class ToString - { - public void Example() + public class ToString { - #region Usage - JObject o = JObject.Parse(@"{'string1':'value','integer2':99,'datetime3':'2000-05-23T00:00:00'}"); + public void Example() + { + #region Usage + JObject o = JObject.Parse(@"{'string1':'value','integer2':99,'datetime3':'2000-05-23T00:00:00'}"); - Console.WriteLine(o.ToString()); - // { - // "string1": "value", - // "integer2": 99, - // "datetime3": "2000-05-23T00:00:00" - // } + Console.WriteLine(o.ToString()); + // { + // "string1": "value", + // "integer2": 99, + // "datetime3": "2000-05-23T00:00:00" + // } - Console.WriteLine(o.ToString(Formatting.None)); - // {"string1":"value","integer2":99,"datetime3":"2000-05-23T00:00:00"} + Console.WriteLine(o.ToString(Formatting.None)); + // {"string1":"value","integer2":99,"datetime3":"2000-05-23T00:00:00"} - Console.WriteLine(o.ToString(Formatting.None, new JavaScriptDateTimeConverter())); - // {"string1":"value","integer2":99,"datetime3":new Date(959032800000)} - #endregion + Console.WriteLine(o.ToString(Formatting.None, new JavaScriptDateTimeConverter())); + // {"string1":"value","integer2":99,"datetime3":new Date(959032800000)} + #endregion + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ToStringJsonConverter.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ToStringJsonConverter.cs index 6cc516e3..00992667 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ToStringJsonConverter.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/ToStringJsonConverter.cs @@ -7,16 +7,16 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class ToStringJsonConverter - { - public void Example() + public class ToStringJsonConverter { - #region Usage - JObject o = JObject.Parse(@"{'string1':'value','integer2':99,'datetime3':'2000-05-23T00:00:00'}"); + public void Example() + { + #region Usage + JObject o = JObject.Parse(@"{'string1':'value','integer2':99,'datetime3':'2000-05-23T00:00:00'}"); - Console.WriteLine(o.ToString(Formatting.None, new JavaScriptDateTimeConverter())); - // {"string1":"value","integer2":99,"datetime3":new Date(959032800000)} - #endregion + Console.WriteLine(o.ToString(Formatting.None, new JavaScriptDateTimeConverter())); + // {"string1":"value","integer2":99,"datetime3":new Date(959032800000)} + #endregion + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/WriteJTokenToBson.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/WriteJTokenToBson.cs index 9835c642..413f79e4 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/WriteJTokenToBson.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/WriteJTokenToBson.cs @@ -8,28 +8,28 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class WriteJTokenToBson - { - public void Example() + public class WriteJTokenToBson { - #region Usage - JObject o = new JObject - { - {"name1","value1"}, - {"name2","value2"} - }; + public void Example() + { + #region Usage + JObject o = new JObject + { + { "name1", "value1" }, + { "name2", "value2" } + }; - MemoryStream ms = new MemoryStream(); - using (BsonWriter writer = new BsonWriter(ms)) - { - o.WriteTo(writer); - } + MemoryStream ms = new MemoryStream(); + using (BsonWriter writer = new BsonWriter(ms)) + { + o.WriteTo(writer); + } - string data = Convert.ToBase64String(ms.ToArray()); + string data = Convert.ToBase64String(ms.ToArray()); - Console.WriteLine(data); - // KQAAAAJuYW1lMQAHAAAAdmFsdWUxAAJuYW1lMgAHAAAAdmFsdWUyAAA= - #endregion + Console.WriteLine(data); + // KQAAAAJuYW1lMQAHAAAAdmFsdWUxAAJuYW1lMgAHAAAAdmFsdWUyAAA= + #endregion + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/WriteToJsonFile.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/WriteToJsonFile.cs index 85161282..166baec2 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/WriteToJsonFile.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Linq/WriteToJsonFile.cs @@ -7,25 +7,25 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Documentation.Samples.Linq { - public class WriteToJsonFile - { - public void Example() + public class WriteToJsonFile { - #region Usage - JObject videogameRatings = new JObject( - new JProperty("Halo", 9), - new JProperty("Starcraft", 9), - new JProperty("Call of Duty", 7.5)); + public void Example() + { + #region Usage + JObject videogameRatings = new JObject( + new JProperty("Halo", 9), + new JProperty("Starcraft", 9), + new JProperty("Call of Duty", 7.5)); - File.WriteAllText(@"c:\videogames.json", videogameRatings.ToString()); + File.WriteAllText(@"c:\videogames.json", videogameRatings.ToString()); - // write JSON directly to a file - using (StreamWriter file = File.CreateText(@"c:\videogames.json")) - using (JsonTextWriter writer = new JsonTextWriter(file)) - { - videogameRatings.WriteTo(writer); - } - #endregion + // write JSON directly to a file + using (StreamWriter file = File.CreateText(@"c:\videogames.json")) + using (JsonTextWriter writer = new JsonTextWriter(file)) + { + videogameRatings.WriteTo(writer); + } + #endregion + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/CreateJsonSchemaManually.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/CreateJsonSchemaManually.cs index bdbe68be..945a2a7e 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/CreateJsonSchemaManually.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/CreateJsonSchemaManually.cs @@ -7,53 +7,53 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Schema { - public class CreateJsonSchemaManually - { - public void Example() + public class CreateJsonSchemaManually { - #region Usage - JsonSchema schema = new JsonSchema(); - schema.Type = JsonSchemaType.Object; - schema.Properties = new Dictionary + public void Example() { - {"name", new JsonSchema {Type = JsonSchemaType.String}}, - { - "hobbies", new JsonSchema - { - Type = JsonSchemaType.Array, - Items = new List { new JsonSchema {Type = JsonSchemaType.String} } - } - }, - }; + #region Usage + JsonSchema schema = new JsonSchema(); + schema.Type = JsonSchemaType.Object; + schema.Properties = new Dictionary + { + { "name", new JsonSchema { Type = JsonSchemaType.String } }, + { + "hobbies", new JsonSchema + { + Type = JsonSchemaType.Array, + Items = new List { new JsonSchema { Type = JsonSchemaType.String } } + } + }, + }; - string schemaJson = schema.ToString(); + string schemaJson = schema.ToString(); - Console.WriteLine(schemaJson); - // { - // "type": "object", - // "properties": { - // "name": { - // "type": "string" - // }, - // "hobbies": { - // "type": "array", - // "items": { - // "type": "string" - // } - // } - // } - // } + Console.WriteLine(schemaJson); + // { + // "type": "object", + // "properties": { + // "name": { + // "type": "string" + // }, + // "hobbies": { + // "type": "array", + // "items": { + // "type": "string" + // } + // } + // } + // } - JObject person = JObject.Parse(@"{ + JObject person = JObject.Parse(@"{ 'name': 'James', 'hobbies': ['.NET', 'Blogging', 'Reading', 'Xbox', 'LOLCATS'] }"); - bool valid = person.IsValid(schema); + bool valid = person.IsValid(schema); - Console.WriteLine(valid); - // true - #endregion + Console.WriteLine(valid); + // true + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/JTokenIsValid.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/JTokenIsValid.cs index 8b5e49a4..f3063b57 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/JTokenIsValid.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/JTokenIsValid.cs @@ -7,33 +7,33 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Schema { - public class JTokenIsValid - { - public void Example() + public class JTokenIsValid { - #region Usage - JsonSchema schema = JsonSchema.Parse(@"{ - 'description': 'A person', - 'type': 'object', - 'properties': { - 'name': {'type':'string'}, - 'hobbies': { - 'type': 'array', - 'items': {'type':'string'} - } + public void Example() + { + #region Usage + JsonSchema schema = JsonSchema.Parse(@"{ + 'description': 'A person', + 'type': 'object', + 'properties': { + 'name': {'type':'string'}, + 'hobbies': { + 'type': 'array', + 'items': {'type':'string'} + } + } + }"); + + JObject person = JObject.Parse(@"{ + 'name': 'James', + 'hobbies': ['.NET', 'Blogging', 'Reading', 'Xbox', 'LOLCATS'] + }"); + + bool valid = person.IsValid(schema); + + Console.WriteLine(valid); + // true + #endregion } - }"); - - JObject person = JObject.Parse(@"{ - 'name': 'James', - 'hobbies': ['.NET', 'Blogging', 'Reading', 'Xbox', 'LOLCATS'] - }"); - - bool valid = person.IsValid(schema); - - Console.WriteLine(valid); - // true - #endregion } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/JTokenIsValidWithMessages.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/JTokenIsValidWithMessages.cs index 34388b7d..b45eb958 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/JTokenIsValidWithMessages.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/JTokenIsValidWithMessages.cs @@ -7,43 +7,43 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Schema { - public class JTokenIsValidWithMessages - { - public void Example() + public class JTokenIsValidWithMessages { - #region Usage - string schemaJson = @"{ - 'description': 'A person', - 'type': 'object', - 'properties': { - 'name': {'type':'string'}, - 'hobbies': { - 'type': 'array', - 'items': {'type':'string'} - } + public void Example() + { + #region Usage + string schemaJson = @"{ + 'description': 'A person', + 'type': 'object', + 'properties': { + 'name': {'type':'string'}, + 'hobbies': { + 'type': 'array', + 'items': {'type':'string'} + } + } + }"; + + JsonSchema schema = JsonSchema.Parse(schemaJson); + + JObject person = JObject.Parse(@"{ + 'name': null, + 'hobbies': ['Invalid content', 0.123456789] + }"); + + IList messages; + bool valid = person.IsValid(schema, out messages); + + Console.WriteLine(valid); + // false + + foreach (string message in messages) + { + Console.WriteLine(message); + } + // Invalid type. Expected String but got Null. Line 2, position 21. + // Invalid type. Expected String but got Float. Line 3, position 51. + #endregion } - }"; - - JsonSchema schema = JsonSchema.Parse(schemaJson); - - JObject person = JObject.Parse(@"{ - 'name': null, - 'hobbies': ['Invalid content', 0.123456789] - }"); - - IList messages; - bool valid = person.IsValid(schema, out messages); - - Console.WriteLine(valid); - // false - - foreach (string message in messages) - { - Console.WriteLine(message); - } - // Invalid type. Expected String but got Null. Line 2, position 21. - // Invalid type. Expected String but got Float. Line 3, position 51. - #endregion } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/JTokenValidateWithEvent.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/JTokenValidateWithEvent.cs index f988a793..8dc03834 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/JTokenValidateWithEvent.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/JTokenValidateWithEvent.cs @@ -7,42 +7,42 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Schema { - public class JTokenValidateWithEvent - { - public void Example() + public class JTokenValidateWithEvent { - #region Usage - string schemaJson = @"{ - 'description': 'A person', - 'type': 'object', - 'properties': { - 'name': {'type':'string'}, - 'hobbies': { - 'type': 'array', - 'items': {'type':'string'} - } + public void Example() + { + #region Usage + string schemaJson = @"{ + 'description': 'A person', + 'type': 'object', + 'properties': { + 'name': {'type':'string'}, + 'hobbies': { + 'type': 'array', + 'items': {'type':'string'} + } + } + }"; + + JsonSchema schema = JsonSchema.Parse(schemaJson); + + JObject person = JObject.Parse(@"{ + 'name': null, + 'hobbies': ['Invalid content', 0.123456789] + }"); + + IList messages = new List(); + ValidationEventHandler validationEventHandler = (sender, args) => { messages.Add(args.Message); }; + + person.Validate(schema, validationEventHandler); + + foreach (string message in messages) + { + Console.WriteLine(message); + } + // Invalid type. Expected String but got Null. Line 2, position 21. + // Invalid type. Expected String but got Float. Line 3, position 51. + #endregion } - }"; - - JsonSchema schema = JsonSchema.Parse(schemaJson); - - JObject person = JObject.Parse(@"{ - 'name': null, - 'hobbies': ['Invalid content', 0.123456789] - }"); - - IList messages = new List(); - ValidationEventHandler validationEventHandler = (sender, args) => { messages.Add(args.Message); }; - - person.Validate(schema, validationEventHandler); - - foreach (string message in messages) - { - Console.WriteLine(message); - } - // Invalid type. Expected String but got Null. Line 2, position 21. - // Invalid type. Expected String but got Float. Line 3, position 51. - #endregion } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/JsonSchemaParse.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/JsonSchemaParse.cs index 86a6a624..91047148 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/JsonSchemaParse.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/JsonSchemaParse.cs @@ -7,35 +7,35 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Schema { - public class JsonSchemaParse - { - public void Example() + public class JsonSchemaParse { - #region Usage - string schemaJson = @"{ - 'description': 'A person', - 'type': 'object', - 'properties': { - 'name': {'type':'string'}, - 'hobbies': { - 'type': 'array', - 'items': {'type':'string'} - } + public void Example() + { + #region Usage + string schemaJson = @"{ + 'description': 'A person', + 'type': 'object', + 'properties': { + 'name': {'type':'string'}, + 'hobbies': { + 'type': 'array', + 'items': {'type':'string'} + } + } + }"; + + JsonSchema schema = JsonSchema.Parse(schemaJson); + + Console.WriteLine(schema.Type); + // Object + + foreach (var property in schema.Properties) + { + Console.WriteLine(property.Key + " - " + property.Value.Type); + } + // name - String + // hobbies - Array + #endregion } - }"; - - JsonSchema schema = JsonSchema.Parse(schemaJson); - - Console.WriteLine(schema.Type); - // Object - - foreach (var property in schema.Properties) - { - Console.WriteLine(property.Key + " - " + property.Value.Type); - } - // name - String - // hobbies - Array - #endregion } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/JsonValidatingReaderAndSerializer.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/JsonValidatingReaderAndSerializer.cs index 9363f44a..9d9ecf1f 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/JsonValidatingReaderAndSerializer.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/JsonValidatingReaderAndSerializer.cs @@ -7,55 +7,55 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Schema { - public class JsonValidatingReaderAndSerializer - { - #region Types - public class Person + public class JsonValidatingReaderAndSerializer { - public string Name { get; set; } - public IList Hobbies { get; set; } - } - #endregion - - public void Example() - { - #region Usage - string schemaJson = @"{ - 'description': 'A person', - 'type': 'object', - 'properties': { - 'name': {'type':'string'}, - 'hobbies': { - 'type': 'array', - 'items': {'type':'string'} - } + #region Types + public class Person + { + public string Name { get; set; } + public IList Hobbies { get; set; } } - }"; + #endregion - string json = @"{ - 'name': 'James', - 'hobbies': ['.NET', 'Blogging', 'Reading', 'Xbox', 'LOLCATS'] - }"; + public void Example() + { + #region Usage + string schemaJson = @"{ + 'description': 'A person', + 'type': 'object', + 'properties': { + 'name': {'type':'string'}, + 'hobbies': { + 'type': 'array', + 'items': {'type':'string'} + } + } + }"; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); + string json = @"{ + 'name': 'James', + 'hobbies': ['.NET', 'Blogging', 'Reading', 'Xbox', 'LOLCATS'] + }"; - JsonValidatingReader validatingReader = new JsonValidatingReader(reader); - validatingReader.Schema = JsonSchema.Parse(schemaJson); + JsonTextReader reader = new JsonTextReader(new StringReader(json)); - IList messages = new List(); - validatingReader.ValidationEventHandler += (o, a) => messages.Add(a.Message); + JsonValidatingReader validatingReader = new JsonValidatingReader(reader); + validatingReader.Schema = JsonSchema.Parse(schemaJson); - JsonSerializer serializer = new JsonSerializer(); - Person p = serializer.Deserialize(validatingReader); + IList messages = new List(); + validatingReader.ValidationEventHandler += (o, a) => messages.Add(a.Message); - Console.WriteLine(p.Name); - // James + JsonSerializer serializer = new JsonSerializer(); + Person p = serializer.Deserialize(validatingReader); - bool isValid = (messages.Count == 0); + Console.WriteLine(p.Name); + // James - Console.WriteLine(isValid); - // true - #endregion + bool isValid = (messages.Count == 0); + + Console.WriteLine(isValid); + // true + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/LoadJsonSchemaFromFile.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/LoadJsonSchemaFromFile.cs index b2e4ef94..92544217 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/LoadJsonSchemaFromFile.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/LoadJsonSchemaFromFile.cs @@ -7,21 +7,21 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Schema { - public class LoadJsonSchemaFromFile - { - public void Example() + public class LoadJsonSchemaFromFile { - #region Usage - // read file into a string and parse JsonSchema from the string - JsonSchema schema1 = JsonSchema.Parse(File.ReadAllText(@"c:\schema.json")); + public void Example() + { + #region Usage + // read file into a string and parse JsonSchema from the string + JsonSchema schema1 = JsonSchema.Parse(File.ReadAllText(@"c:\schema.json")); - // read JsonSchema directly from a file - using (StreamReader file = File.OpenText(@"c:\schema.json")) - using (JsonTextReader reader = new JsonTextReader(file)) - { - JsonSchema schema2 = JsonSchema.Read(reader); - } - #endregion + // read JsonSchema directly from a file + using (StreamReader file = File.OpenText(@"c:\schema.json")) + using (JsonTextReader reader = new JsonTextReader(file)) + { + JsonSchema schema2 = JsonSchema.Read(reader); + } + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/RefJsonSchemaResolver.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/RefJsonSchemaResolver.cs index b97acbdd..8915c75b 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/RefJsonSchemaResolver.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/RefJsonSchemaResolver.cs @@ -7,51 +7,51 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Schema { - public class RefJsonSchemaResolver - { - public void Example() + public class RefJsonSchemaResolver { - #region Usage - string schemaJson; - JsonSchemaResolver resolver = new JsonSchemaResolver(); + public void Example() + { + #region Usage + string schemaJson; + JsonSchemaResolver resolver = new JsonSchemaResolver(); - schemaJson = @"{ - 'id': 'person', - 'type': 'object', - 'properties': { - 'name': {'type':'string'}, - 'age': {'type':'integer'} + schemaJson = @"{ + 'id': 'person', + 'type': 'object', + 'properties': { + 'name': {'type':'string'}, + 'age': {'type':'integer'} + } + }"; + + JsonSchema personSchema = JsonSchema.Parse(schemaJson, resolver); + + schemaJson = @"{ + 'id': 'employee', + 'type': 'object', + 'extends': {'$ref':'person'}, + 'properties': { + 'salary': {'type':'number'}, + 'jobTitle': {'type':'string'} + } + }"; + + JsonSchema employeeSchema = JsonSchema.Parse(schemaJson, resolver); + + string json = @"{ + 'name': 'James', + 'age': 29, + 'salary': 9000.01, + 'jobTitle': 'Junior Vice President' + }"; + + JObject employee = JObject.Parse(json); + + bool valid = employee.IsValid(employeeSchema); + + Console.WriteLine(valid); + // true + #endregion } - }"; - - JsonSchema personSchema = JsonSchema.Parse(schemaJson, resolver); - - schemaJson = @"{ - 'id': 'employee', - 'type': 'object', - 'extends': {'$ref':'person'}, - 'properties': { - 'salary': {'type':'number'}, - 'jobTitle': {'type':'string'} - } - }"; - - JsonSchema employeeSchema = JsonSchema.Parse(schemaJson, resolver); - - string json = @"{ - 'name': 'James', - 'age': 29, - 'salary': 9000.01, - 'jobTitle': 'Junior Vice President' - }"; - - JObject employee = JObject.Parse(json); - - bool valid = employee.IsValid(employeeSchema); - - Console.WriteLine(valid); - // true - #endregion } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/SaveJsonSchemaToFile.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/SaveJsonSchemaToFile.cs index cf35e223..de76fc0d 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/SaveJsonSchemaToFile.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Schema/SaveJsonSchemaToFile.cs @@ -7,26 +7,26 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Schema { - public class SaveJsonSchemaToFile - { - public void Example() + public class SaveJsonSchemaToFile { - #region Usage - JsonSchema schema = new JsonSchema + public void Example() { - Type = JsonSchemaType.Object - }; + #region Usage + JsonSchema schema = new JsonSchema + { + Type = JsonSchemaType.Object + }; - // serialize JsonSchema to a string and then write string to a file - File.WriteAllText(@"c:\schema.json", schema.ToString()); + // serialize JsonSchema to a string and then write string to a file + File.WriteAllText(@"c:\schema.json", schema.ToString()); - // serialize JsonSchema directly to a file - using (StreamWriter file = File.CreateText(@"c:\schema.json")) - using (JsonTextWriter writer = new JsonTextWriter(file)) - { - schema.WriteTo(writer); - } - #endregion + // serialize JsonSchema directly to a file + using (StreamWriter file = File.CreateText(@"c:\schema.json")) + using (JsonTextWriter writer = new JsonTextWriter(file)) + { + schema.WriteTo(writer); + } + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/CustomContractResolver.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/CustomContractResolver.cs index c72b13bc..b84283c5 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/CustomContractResolver.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/CustomContractResolver.cs @@ -6,67 +6,68 @@ using Newtonsoft.Json.Serialization; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class CustomContractResolver - { - #region Types - public class DynamicContractResolver : DefaultContractResolver + public class CustomContractResolver { - private readonly char _startingWithChar; - public DynamicContractResolver(char startingWithChar) - { - _startingWithChar = startingWithChar; - } - - protected override IList CreateProperties(Type type, MemberSerialization memberSerialization) - { - IList properties = base.CreateProperties(type, memberSerialization); - - // only serializer properties that start with the specified character - properties = - properties.Where(p => p.PropertyName.StartsWith(_startingWithChar.ToString())).ToList(); - - return properties; - } - } - - public class Person - { - public string FirstName { get; set; } - public string LastName { get; set; } - - public string FullName - { - get { return FirstName + " " + LastName; } - } - } - #endregion - - public void Example() - { - #region Usage - Person person = new Person + #region Types + public class DynamicContractResolver : DefaultContractResolver { - FirstName = "Dennis", - LastName = "Deepwater-Diver" - }; + private readonly char _startingWithChar; - string startingWithF = JsonConvert.SerializeObject(person, Formatting.Indented, - new JsonSerializerSettings { ContractResolver = new DynamicContractResolver('F') }); + public DynamicContractResolver(char startingWithChar) + { + _startingWithChar = startingWithChar; + } - Console.WriteLine(startingWithF); - // { - // "FirstName": "Dennis", - // "FullName": "Dennis Deepwater-Diver" - // } + protected override IList CreateProperties(Type type, MemberSerialization memberSerialization) + { + IList properties = base.CreateProperties(type, memberSerialization); - string startingWithL = JsonConvert.SerializeObject(person, Formatting.Indented, - new JsonSerializerSettings { ContractResolver = new DynamicContractResolver('L') }); + // only serializer properties that start with the specified character + properties = + properties.Where(p => p.PropertyName.StartsWith(_startingWithChar.ToString())).ToList(); - Console.WriteLine(startingWithL); - // { - // "LastName": "Deepwater-Diver" - // } - #endregion + return properties; + } + } + + public class Person + { + public string FirstName { get; set; } + public string LastName { get; set; } + + public string FullName + { + get { return FirstName + " " + LastName; } + } + } + #endregion + + public void Example() + { + #region Usage + Person person = new Person + { + FirstName = "Dennis", + LastName = "Deepwater-Diver" + }; + + string startingWithF = JsonConvert.SerializeObject(person, Formatting.Indented, + new JsonSerializerSettings { ContractResolver = new DynamicContractResolver('F') }); + + Console.WriteLine(startingWithF); + // { + // "FirstName": "Dennis", + // "FullName": "Dennis Deepwater-Diver" + // } + + string startingWithL = JsonConvert.SerializeObject(person, Formatting.Indented, + new JsonSerializerSettings { ContractResolver = new DynamicContractResolver('L') }); + + Console.WriteLine(startingWithL); + // { + // "LastName": "Deepwater-Diver" + // } + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/CustomJsonConverter.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/CustomJsonConverter.cs index 86b52690..b2345eee 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/CustomJsonConverter.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/CustomJsonConverter.cs @@ -6,95 +6,95 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class CustomJsonConverter - { - #region Types - public class KeysJsonConverter : JsonConverter + public class CustomJsonConverter { - private readonly Type[] _types; - - public KeysJsonConverter(params Type[] types) - { - _types = types; - } - - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - JToken t = JToken.FromObject(value); - - if (t.Type != JTokenType.Object) + #region Types + public class KeysJsonConverter : JsonConverter { - t.WriteTo(writer); + private readonly Type[] _types; + + public KeysJsonConverter(params Type[] types) + { + _types = types; + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + JToken t = JToken.FromObject(value); + + if (t.Type != JTokenType.Object) + { + t.WriteTo(writer); + } + else + { + JObject o = (JObject)t; + IList propertyNames = o.Properties().Select(p => p.Name).ToList(); + + o.AddFirst(new JProperty("Keys", new JArray(propertyNames))); + + o.WriteTo(writer); + } + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter."); + } + + public override bool CanRead + { + get { return false; } + } + + public override bool CanConvert(Type objectType) + { + return _types.Any(t => t == objectType); + } } - else + + public class Employee { - JObject o = (JObject)t; - IList propertyNames = o.Properties().Select(p => p.Name).ToList(); - - o.AddFirst(new JProperty("Keys", new JArray(propertyNames))); - - o.WriteTo(writer); + public string FirstName { get; set; } + public string LastName { get; set; } + public IList Roles { get; set; } } - } + #endregion - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter."); - } - - public override bool CanRead - { - get { return false; } - } - - public override bool CanConvert(Type objectType) - { - return _types.Any(t => t == objectType); - } - } - - public class Employee - { - public string FirstName { get; set; } - public string LastName { get; set; } - public IList Roles { get; set; } - } - #endregion - - public void Example() - { - #region Usage - Employee employee = new Employee - { - FirstName = "James", - LastName = "Newton-King", - Roles = new List + public void Example() { - "Admin" + #region Usage + Employee employee = new Employee + { + FirstName = "James", + LastName = "Newton-King", + Roles = new List + { + "Admin" + } + }; + + string json = JsonConvert.SerializeObject(employee, Formatting.Indented, new KeysJsonConverter(typeof(Employee))); + + Console.WriteLine(json); + // { + // "Keys": [ + // "FirstName", + // "LastName", + // "Roles" + // ], + // "FirstName": "James", + // "LastName": "Newton-King", + // "Roles": [ + // "Admin" + // ] + // } + + Employee newEmployee = JsonConvert.DeserializeObject(json, new KeysJsonConverter(typeof(Employee))); + + Console.WriteLine(newEmployee.FirstName); + // James + #endregion } - }; - - string json = JsonConvert.SerializeObject(employee, Formatting.Indented, new KeysJsonConverter(typeof(Employee))); - - Console.WriteLine(json); - // { - // "Keys": [ - // "FirstName", - // "LastName", - // "Roles" - // ], - // "FirstName": "James", - // "LastName": "Newton-King", - // "Roles": [ - // "Admin" - // ] - // } - - Employee newEmployee = JsonConvert.DeserializeObject(json, new KeysJsonConverter(typeof(Employee))); - - Console.WriteLine(newEmployee.FirstName); - // James - #endregion } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/CustomTraceWriter.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/CustomTraceWriter.cs index 0eeb6e36..9c636bdd 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/CustomTraceWriter.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/CustomTraceWriter.cs @@ -7,75 +7,75 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class CustomTraceWriter - { - #region Types - public class NLogTraceWriter : ITraceWriter + public class CustomTraceWriter { - private static readonly Logger Logger = LogManager.GetLogger("NLogTraceWriter"); - - public TraceLevel LevelFilter - { - // trace all messages. nlog can handle filtering - get { return TraceLevel.Verbose; } - } - - public void Trace(TraceLevel level, string message, Exception ex) - { - LogEventInfo logEvent = new LogEventInfo + #region Types + public class NLogTraceWriter : ITraceWriter { - Message = message, - Level = GetLogLevel(level), - Exception = ex - }; + private static readonly Logger Logger = LogManager.GetLogger("NLogTraceWriter"); - // log Json.NET message to NLog - Logger.Log(logEvent); - } + 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 + }; + + // log Json.NET message to NLog + Logger.Log(logEvent); + } + + 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; + } + } } - } - } - #endregion + #endregion - public void Example() - { - #region Usage - IList countries = new List + public void Example() { - "New Zealand", - "Australia", - "Denmark", - "China" - }; + #region Usage + IList countries = new List + { + "New Zealand", + "Australia", + "Denmark", + "China" + }; - string json = JsonConvert.SerializeObject(countries, Formatting.Indented, new JsonSerializerSettings - { - TraceWriter = new NLogTraceWriter() - }); + string json = JsonConvert.SerializeObject(countries, Formatting.Indented, new JsonSerializerSettings + { + TraceWriter = new NLogTraceWriter() + }); - Console.WriteLine(json); - // [ - // "New Zealand", - // "Australia", - // "Denmark", - // "China" - // ] - #endregion + Console.WriteLine(json); + // [ + // "New Zealand", + // "Australia", + // "Denmark", + // "China" + // ] + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DataContractAndDataMember.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DataContractAndDataMember.cs index 61d059a2..516b639b 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DataContractAndDataMember.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DataContractAndDataMember.cs @@ -6,41 +6,42 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class DataContractAndDataMember - { - #region Types - [DataContract] - public class File + public class DataContractAndDataMember { - // excluded from serialization - // does not have DataMemberAttribute - public Guid Id { get; set; } - - [DataMember] - public string Name { get; set; } - [DataMember] - public int Size { get; set; } - } - #endregion - - public void Example() - { - #region Usage - File file = new File + #region Types + [DataContract] + public class File { - Id = Guid.NewGuid(), - Name = "ImportantLegalDocuments.docx", - Size = 50*1024 - }; + // excluded from serialization + // does not have DataMemberAttribute + public Guid Id { get; set; } - string json = JsonConvert.SerializeObject(file, Formatting.Indented); + [DataMember] + public string Name { get; set; } - Console.WriteLine(json); - // { - // "Name": "ImportantLegalDocuments.docx", - // "Size": 51200 - // } - #endregion + [DataMember] + public int Size { get; set; } + } + #endregion + + public void Example() + { + #region Usage + File file = new File + { + Id = Guid.NewGuid(), + Name = "ImportantLegalDocuments.docx", + Size = 50 * 1024 + }; + + string json = JsonConvert.SerializeObject(file, Formatting.Indented); + + Console.WriteLine(json); + // { + // "Name": "ImportantLegalDocuments.docx", + // "Size": 51200 + // } + #endregion + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DefaultValueAttributeIgnore.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DefaultValueAttributeIgnore.cs index a65354ac..fcd58272 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DefaultValueAttributeIgnore.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DefaultValueAttributeIgnore.cs @@ -6,44 +6,44 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class DefaultValueAttributeIgnore - { - #region Types - public class Customer + public class DefaultValueAttributeIgnore { - public string FirstName { get; set; } - public string LastName { get; set; } - - [DefaultValue(" ")] - public string FullName - { - get { return FirstName + " " + LastName; } - } - } - #endregion - - public void Example() - { - #region Usage - Customer customer = new Customer(); - - string jsonIncludeDefaultValues = JsonConvert.SerializeObject(customer, Formatting.Indented); - - Console.WriteLine(jsonIncludeDefaultValues); - // { - // "FirstName": null, - // "LastName": null, - // "FullName": " " - // } - - string jsonIgnoreDefaultValues = JsonConvert.SerializeObject(customer, Formatting.Indented, new JsonSerializerSettings + #region Types + public class Customer { - DefaultValueHandling = DefaultValueHandling.Ignore - }); + public string FirstName { get; set; } + public string LastName { get; set; } - Console.WriteLine(jsonIgnoreDefaultValues); - // {} - #endregion + [DefaultValue(" ")] + public string FullName + { + get { return FirstName + " " + LastName; } + } + } + #endregion + + public void Example() + { + #region Usage + Customer customer = new Customer(); + + string jsonIncludeDefaultValues = JsonConvert.SerializeObject(customer, Formatting.Indented); + + Console.WriteLine(jsonIncludeDefaultValues); + // { + // "FirstName": null, + // "LastName": null, + // "FullName": " " + // } + + string jsonIgnoreDefaultValues = JsonConvert.SerializeObject(customer, Formatting.Indented, new JsonSerializerSettings + { + DefaultValueHandling = DefaultValueHandling.Ignore + }); + + Console.WriteLine(jsonIgnoreDefaultValues); + // {} + #endregion + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DefaultValueHandlingIgnore.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DefaultValueHandlingIgnore.cs index 8bd0532f..9b67d571 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DefaultValueHandlingIgnore.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DefaultValueHandlingIgnore.cs @@ -5,41 +5,41 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class DefaultValueHandlingIgnore - { - #region Types - public class Person + public class DefaultValueHandlingIgnore { - public string Name { get; set; } - public int Age { get; set; } - public Person Partner { get; set; } - public decimal? Salary { get; set; } - } - #endregion - - public void Example() - { - #region Usage - Person person = new Person(); - - string jsonIncludeDefaultValues = JsonConvert.SerializeObject(person, Formatting.Indented); - - Console.WriteLine(jsonIncludeDefaultValues); - // { - // "Name": null, - // "Age": 0, - // "Partner": null, - // "Salary": null - // } - - string jsonIgnoreDefaultValues = JsonConvert.SerializeObject(person, Formatting.Indented, new JsonSerializerSettings + #region Types + public class Person { - DefaultValueHandling = DefaultValueHandling.Ignore - }); + public string Name { get; set; } + public int Age { get; set; } + public Person Partner { get; set; } + public decimal? Salary { get; set; } + } + #endregion - Console.WriteLine(jsonIgnoreDefaultValues); - // {} - #endregion + public void Example() + { + #region Usage + Person person = new Person(); + + string jsonIncludeDefaultValues = JsonConvert.SerializeObject(person, Formatting.Indented); + + Console.WriteLine(jsonIncludeDefaultValues); + // { + // "Name": null, + // "Age": 0, + // "Partner": null, + // "Salary": null + // } + + string jsonIgnoreDefaultValues = JsonConvert.SerializeObject(person, Formatting.Indented, new JsonSerializerSettings + { + DefaultValueHandling = DefaultValueHandling.Ignore + }); + + Console.WriteLine(jsonIgnoreDefaultValues); + // {} + #endregion + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeAnonymousType.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeAnonymousType.cs index e15d219c..61033362 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeAnonymousType.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeAnonymousType.cs @@ -5,25 +5,25 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class DeserializeAnonymousType - { - public void Example() + public class DeserializeAnonymousType { - #region Usage - var definition = new {Name = ""}; + public void Example() + { + #region Usage + var definition = new { Name = "" }; - string json1 = @"{'Name':'James'}"; - var customer1 = JsonConvert.DeserializeAnonymousType(json1, definition); + string json1 = @"{'Name':'James'}"; + var customer1 = JsonConvert.DeserializeAnonymousType(json1, definition); - Console.WriteLine(customer1.Name); - // James + Console.WriteLine(customer1.Name); + // James - string json2 = @"{'Name':'Mike'}"; - var customer2 = JsonConvert.DeserializeAnonymousType(json2, definition); + string json2 = @"{'Name':'Mike'}"; + var customer2 = JsonConvert.DeserializeAnonymousType(json2, definition); - Console.WriteLine(customer2.Name); - // Mike - #endregion + Console.WriteLine(customer2.Name); + // Mike + #endregion + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeCollection.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeCollection.cs index bdd6dee3..4db5f329 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeCollection.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeCollection.cs @@ -5,18 +5,18 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class DeserializeCollection - { - public void Example() + public class DeserializeCollection { - #region Usage - string json = @"['Starcraft','Halo','Legend of Zelda']"; + public void Example() + { + #region Usage + string json = @"['Starcraft','Halo','Legend of Zelda']"; - List videogames = JsonConvert.DeserializeObject>(json); + List videogames = JsonConvert.DeserializeObject>(json); - Console.WriteLine(string.Join(", ", videogames)); - // Starcraft, Halo, Legend of Zelda - #endregion + Console.WriteLine(string.Join(", ", videogames)); + // Starcraft, Halo, Legend of Zelda + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeConstructorHandling.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeConstructorHandling.cs index 24d21f32..6e203682 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeConstructorHandling.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeConstructorHandling.cs @@ -6,51 +6,51 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class DeserializeConstructorHandling - { - #region Types - public class Website + public class DeserializeConstructorHandling { - public string Url { get; set; } - - private Website() - { - } - - public Website(Website website) - { - if (website == null) - throw new ArgumentNullException("website"); - - Url = website.Url; - } - } - #endregion - - public void Example() - { - #region Usage - string json = @"{'Url':'http://www.google.com'}"; - - try - { - JsonConvert.DeserializeObject(json); - } - catch (TargetInvocationException ex) - { - Console.WriteLine(ex); - // Value cannot be null. - // Parameter name: website - } - - Website website = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + #region Types + public class Website { - ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor - }); + public string Url { get; set; } - Console.WriteLine(website.Url); - // http://www.google.com - #endregion + private Website() + { + } + + public Website(Website website) + { + if (website == null) + throw new ArgumentNullException("website"); + + Url = website.Url; + } + } + #endregion + + public void Example() + { + #region Usage + string json = @"{'Url':'http://www.google.com'}"; + + try + { + JsonConvert.DeserializeObject(json); + } + catch (TargetInvocationException ex) + { + Console.WriteLine(ex); + // Value cannot be null. + // Parameter name: website + } + + Website website = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor + }); + + Console.WriteLine(website.Url); + // http://www.google.com + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeCustomCreationConverter.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeCustomCreationConverter.cs index 6fa5ef36..32f2b39b 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeCustomCreationConverter.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeCustomCreationConverter.cs @@ -6,52 +6,52 @@ using Newtonsoft.Json.Converters; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class DeserializeCustomCreationConverter - { - #region Types - public class Person + public class DeserializeCustomCreationConverter { - public string FirstName { get; set; } - public string LastName { get; set; } - public DateTime BirthDate { get; set; } + #region Types + public class Person + { + public string FirstName { get; set; } + public string LastName { get; set; } + public DateTime BirthDate { get; set; } + } + + public class Employee : Person + { + public string Department { get; set; } + public string JobTitle { get; set; } + } + + public class PersonConverter : CustomCreationConverter + { + public override Person Create(Type objectType) + { + return new Employee(); + } + } + #endregion + + public void Example() + { + #region Usage + string json = @"{ + 'Department': 'Furniture', + 'JobTitle': 'Carpenter', + 'FirstName': 'John', + 'LastName': 'Joinery', + 'BirthDate': '1983-02-02T00:00:00' + }"; + + Person person = JsonConvert.DeserializeObject(json, new PersonConverter()); + + Console.WriteLine(person.GetType().Name); + // Employee + + Employee employee = (Employee)person; + + Console.WriteLine(employee.JobTitle); + // Capenter + #endregion + } } - - public class Employee : Person - { - public string Department { get; set; } - public string JobTitle { get; set; } - } - - public class PersonConverter : CustomCreationConverter - { - public override Person Create(Type objectType) - { - return new Employee(); - } - } - #endregion - - public void Example() - { - #region Usage - string json = @"{ - 'Department': 'Furniture', - 'JobTitle': 'Carpenter', - 'FirstName': 'John', - 'LastName': 'Joinery', - 'BirthDate': '1983-02-02T00:00:00' - }"; - - Person person = JsonConvert.DeserializeObject(json, new PersonConverter()); - - Console.WriteLine(person.GetType().Name); - // Employee - - Employee employee = (Employee) person; - - Console.WriteLine(employee.JobTitle); - // Capenter - #endregion - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeDataSet.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeDataSet.cs index 49eacf8a..986d8d42 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeDataSet.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeDataSet.cs @@ -7,38 +7,38 @@ using NUnit.Framework; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class DeserializeDataSet - { - public void Example() + public class DeserializeDataSet { - #region Usage - string json = @"{ - 'Table1': [ - { - 'id': 0, - 'item': 'item 0' - }, - { - 'id': 1, - 'item': 'item 1' - } - ] - }"; + public void Example() + { + #region Usage + string json = @"{ + 'Table1': [ + { + 'id': 0, + 'item': 'item 0' + }, + { + 'id': 1, + 'item': 'item 1' + } + ] + }"; - DataSet dataSet = JsonConvert.DeserializeObject(json); + DataSet dataSet = JsonConvert.DeserializeObject(json); - DataTable dataTable = dataSet.Tables["Table1"]; + DataTable dataTable = dataSet.Tables["Table1"]; - Console.WriteLine(dataTable.Rows.Count); - // 2 + Console.WriteLine(dataTable.Rows.Count); + // 2 - foreach (DataRow row in dataTable.Rows) - { - Console.WriteLine(row["id"] + " - " + row["item"]); - } - // 0 - item 0 - // 1 - item 1 - #endregion + foreach (DataRow row in dataTable.Rows) + { + Console.WriteLine(row["id"] + " - " + row["item"]); + } + // 0 - item 0 + // 1 - item 1 + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeDictionary.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeDictionary.cs index b13e3d2f..ba0add37 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeDictionary.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeDictionary.cs @@ -5,24 +5,24 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class DeserializeDictionary - { - public void Example() + public class DeserializeDictionary { - #region Usage - string json = @"{ - 'href': '/account/login.aspx', - 'target': '_blank' - }"; + public void Example() + { + #region Usage + string json = @"{ + 'href': '/account/login.aspx', + 'target': '_blank' + }"; - Dictionary htmlAttributes = JsonConvert.DeserializeObject>(json); + Dictionary htmlAttributes = JsonConvert.DeserializeObject>(json); - Console.WriteLine(htmlAttributes["href"]); - // /account/login.aspx + Console.WriteLine(htmlAttributes["href"]); + // /account/login.aspx - Console.WriteLine(htmlAttributes["target"]); - // _blank - #endregion + Console.WriteLine(htmlAttributes["target"]); + // _blank + #endregion + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeMissingMemberHandling.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeMissingMemberHandling.cs index f9f31a5f..5912a87c 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeMissingMemberHandling.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeMissingMemberHandling.cs @@ -5,38 +5,38 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class DeserializeMissingMemberHandling - { - #region Types - public class Account + public class DeserializeMissingMemberHandling { - public string FullName { get; set; } - public bool Deleted { get; set; } - } - #endregion + #region Types + public class Account + { + public string FullName { get; set; } + public bool Deleted { get; set; } + } + #endregion - public void Example() - { - #region Usage - string json = @"{ - 'FullName': 'Dan Deleted', - 'Deleted': true, - 'DeletedDate': '2013-01-20T00:00:00' - }"; + public void Example() + { + #region Usage + string json = @"{ + 'FullName': 'Dan Deleted', + 'Deleted': true, + 'DeletedDate': '2013-01-20T00:00:00' + }"; - try - { - JsonConvert.DeserializeObject(json, new JsonSerializerSettings - { - MissingMemberHandling = MissingMemberHandling.Error - }); - } - catch (JsonSerializationException ex) - { - Console.WriteLine(ex.Message); - // Could not find member 'DeletedDate' on object of type 'Account'. Path 'DeletedDate', line 4, position 23. - } - #endregion + try + { + JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + MissingMemberHandling = MissingMemberHandling.Error + }); + } + catch (JsonSerializationException ex) + { + Console.WriteLine(ex.Message); + // Could not find member 'DeletedDate' on object of type 'Account'. Path 'DeletedDate', line 4, position 23. + } + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeObject.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeObject.cs index dabb0197..dcbfeb56 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeObject.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeObject.cs @@ -5,36 +5,36 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class DeserializeObject - { - #region Types - public class Account + public class DeserializeObject { - public string Email { get; set; } - public bool Active { get; set; } - public DateTime CreatedDate { get; set; } - public IList Roles { get; set; } + #region Types + public class Account + { + public string Email { get; set; } + public bool Active { get; set; } + public DateTime CreatedDate { get; set; } + public IList Roles { get; set; } + } + #endregion + + public void Example() + { + #region Usage + string json = @"{ + 'Email': 'james@example.com', + 'Active': true, + 'CreatedDate': '2013-01-20T00:00:00Z', + 'Roles': [ + 'User', + 'Admin' + ] + }"; + + Account account = JsonConvert.DeserializeObject(json); + + Console.WriteLine(account.Email); + // james@example.com + #endregion + } } - #endregion - - public void Example() - { - #region Usage - string json = @"{ - 'Email': 'james@example.com', - 'Active': true, - 'CreatedDate': '2013-01-20T00:00:00Z', - 'Roles': [ - 'User', - 'Admin' - ] - }"; - - Account account = JsonConvert.DeserializeObject(json); - - Console.WriteLine(account.Email); - // james@example.com - #endregion - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeObjectCreationHandling.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeObjectCreationHandling.cs index 94fd0822..67668c3a 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeObjectCreationHandling.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeObjectCreationHandling.cs @@ -5,64 +5,64 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class DeserializeObjectCreationHandling - { - #region Types - public class UserViewModel + public class DeserializeObjectCreationHandling { - public string Name { get; set; } - public IList Offices { get; private set; } - - public UserViewModel() - { - Offices = new List - { - "Auckland", - "Wellington", - "Christchurch" - }; - } - } - #endregion - - public void Example() - { - #region Usage - string json = @"{ - 'Name': 'James', - 'Offices': [ - 'Auckland', - 'Wellington', - 'Christchurch' - ] - }"; - - UserViewModel model1 = JsonConvert.DeserializeObject(json); - - foreach (string office in model1.Offices) - { - Console.WriteLine(office); - } - // Auckland - // Wellington - // Christchurch - // Auckland - // Wellington - // Christchurch - - UserViewModel model2 = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + #region Types + public class UserViewModel { - ObjectCreationHandling = ObjectCreationHandling.Replace - }); + public string Name { get; set; } + public IList Offices { get; private set; } - foreach (string office in model2.Offices) - { - Console.WriteLine(office); - } - // Auckland - // Wellington - // Christchurch - #endregion + public UserViewModel() + { + Offices = new List + { + "Auckland", + "Wellington", + "Christchurch" + }; + } + } + #endregion + + public void Example() + { + #region Usage + string json = @"{ + 'Name': 'James', + 'Offices': [ + 'Auckland', + 'Wellington', + 'Christchurch' + ] + }"; + + UserViewModel model1 = JsonConvert.DeserializeObject(json); + + foreach (string office in model1.Offices) + { + Console.WriteLine(office); + } + // Auckland + // Wellington + // Christchurch + // Auckland + // Wellington + // Christchurch + + UserViewModel model2 = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + ObjectCreationHandling = ObjectCreationHandling.Replace + }); + + foreach (string office in model2.Offices) + { + Console.WriteLine(office); + } + // Auckland + // Wellington + // Christchurch + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeWithJsonSerializerFromFile.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeWithJsonSerializerFromFile.cs index 7c37df6f..b0e1f40c 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeWithJsonSerializerFromFile.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/DeserializeWithJsonSerializerFromFile.cs @@ -7,29 +7,29 @@ using File = System.IO.File; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class DeserializeWithJsonSerializerFromFile - { - #region Types - public class Movie + public class DeserializeWithJsonSerializerFromFile { - public string Name { get; set; } - public int Year { get; set; } - } - #endregion + #region Types + public class Movie + { + public string Name { get; set; } + public int Year { get; set; } + } + #endregion - public void Example() - { - #region Usage - // read file into a string and deserialize JSON to a type - Movie movie1 = JsonConvert.DeserializeObject(File.ReadAllText(@"c:\movie.json")); + public void Example() + { + #region Usage + // read file into a string and deserialize JSON to a type + Movie movie1 = JsonConvert.DeserializeObject(File.ReadAllText(@"c:\movie.json")); - // deserialize JSON directly from a file - using (StreamReader file = File.OpenText(@"c:\movie.json")) - { - JsonSerializer serializer = new JsonSerializer(); - Movie movie2 = (Movie)serializer.Deserialize(file, typeof (Movie)); - } - #endregion + // deserialize JSON directly from a file + using (StreamReader file = File.OpenText(@"c:\movie.json")) + { + JsonSerializer serializer = new JsonSerializer(); + Movie movie2 = (Movie)serializer.Deserialize(file, typeof(Movie)); + } + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/ErrorHandlingAttribute.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/ErrorHandlingAttribute.cs index 687c29d0..0755a5ab 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/ErrorHandlingAttribute.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/ErrorHandlingAttribute.cs @@ -7,56 +7,58 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class ErrorHandlingAttribute - { - #region Types - public class Employee + public class ErrorHandlingAttribute { - private List _roles; - - public string Name { get; set; } - public int Age { get; set; } - public List Roles - { - get + #region Types + public class Employee { - if (_roles == null) - throw new Exception("Roles not loaded!"); + private List _roles; - return _roles; + public string Name { get; set; } + public int Age { get; set; } + + public List Roles + { + get + { + if (_roles == null) + throw new Exception("Roles not loaded!"); + + return _roles; + } + set { _roles = value; } + } + + public string Title { get; set; } + + [OnError] + internal void OnError(StreamingContext context, ErrorContext errorContext) + { + errorContext.Handled = true; + } } - set { _roles = value; } - } - public string Title { get; set; } + #endregion - [OnError] - internal void OnError(StreamingContext context, ErrorContext errorContext) - { - errorContext.Handled = true; - } + public void Example() + { + #region Usage + Employee person = new Employee + { + Name = "George Michael Bluth", + Age = 16, + Roles = null, + Title = "Mister Manager" + }; + + string json = JsonConvert.SerializeObject(person, Formatting.Indented); + + Console.WriteLine(json); + // { + // "Name": "George Michael Bluth", + // "Age": 16, + // "Title": "Mister Manager" + // } + #endregion + } } - #endregion - - public void Example() - { - #region Usage - Employee person = new Employee - { - Name = "George Michael Bluth", - Age = 16, - Roles = null, - Title = "Mister Manager" - }; - - string json = JsonConvert.SerializeObject(person, Formatting.Indented); - - Console.WriteLine(json); - // { - // "Name": "George Michael Bluth", - // "Age": 16, - // "Title": "Mister Manager" - // } - #endregion - } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/ErrorHandlingEvent.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/ErrorHandlingEvent.cs index 35dcb991..04b47cf3 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/ErrorHandlingEvent.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/ErrorHandlingEvent.cs @@ -7,41 +7,41 @@ using Newtonsoft.Json.Serialization; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class ErrorHandlingEvent - { - public void Example() + public class ErrorHandlingEvent { - #region Usage - List errors = new List(); - - List c = JsonConvert.DeserializeObject>(@"[ - '2009-09-09T00:00:00Z', - 'I am not a date and will error!', - [ - 1 - ], - '1977-02-20T00:00:00Z', - null, - '2000-12-01T00:00:00Z' - ]", - new JsonSerializerSettings + public void Example() { - Error = delegate(object sender, ErrorEventArgs args) - { - errors.Add(args.ErrorContext.Error.Message); - args.ErrorContext.Handled = true; - }, - Converters = { new IsoDateTimeConverter() } - }); + #region Usage + List errors = new List(); - // 2009-09-09T00:00:00Z - // 1977-02-20T00:00:00Z - // 2000-12-01T00:00:00Z + List c = JsonConvert.DeserializeObject>(@"[ + '2009-09-09T00:00:00Z', + 'I am not a date and will error!', + [ + 1 + ], + '1977-02-20T00:00:00Z', + null, + '2000-12-01T00:00:00Z' + ]", + new JsonSerializerSettings + { + Error = delegate(object sender, ErrorEventArgs args) + { + errors.Add(args.ErrorContext.Error.Message); + args.ErrorContext.Handled = true; + }, + Converters = { new IsoDateTimeConverter() } + }); - // The string was not recognized as a valid DateTime. There is a unknown word starting at index 0. - // Unexpected token parsing date. Expected String, got StartArray. - // Cannot convert null value to System.DateTime. - #endregion + // 2009-09-09T00:00:00Z + // 1977-02-20T00:00:00Z + // 2000-12-01T00:00:00Z + + // The string was not recognized as a valid DateTime. There is a unknown word starting at index 0. + // Unexpected token parsing date. Expected String, got StartArray. + // Cannot convert null value to System.DateTime. + #endregion + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonConverterAttributeClass.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonConverterAttributeClass.cs index c913772a..437605a3 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonConverterAttributeClass.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonConverterAttributeClass.cs @@ -6,52 +6,52 @@ using Newtonsoft.Json.Converters; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class JsonConverterAttributeClass - { - #region Types - public class UserConverter : JsonConverter + public class JsonConverterAttributeClass { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - User user = (User) value; + #region Types + public class UserConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + User user = (User)value; - writer.WriteValue(user.UserName); - } + writer.WriteValue(user.UserName); + } - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - User user = new User(); - user.UserName = (string)reader.Value; + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + User user = new User(); + user.UserName = (string)reader.Value; - return user; - } + return user; + } - public override bool CanConvert(Type objectType) - { - return objectType == typeof (User); - } + public override bool CanConvert(Type objectType) + { + return objectType == typeof(User); + } + } + + [JsonConverter(typeof(UserConverter))] + public class User + { + public string UserName { get; set; } + } + #endregion + + public void Example() + { + #region Usage + User user = new User + { + UserName = @"domain\username" + }; + + string json = JsonConvert.SerializeObject(user, Formatting.Indented); + + Console.WriteLine(json); + // "domain\\username" + #endregion + } } - - [JsonConverter(typeof(UserConverter))] - public class User - { - public string UserName { get; set; } - } - #endregion - - public void Example() - { - #region Usage - User user = new User - { - UserName = @"domain\username" - }; - - string json = JsonConvert.SerializeObject(user, Formatting.Indented); - - Console.WriteLine(json); - // "domain\\username" - #endregion - } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonConverterAttributeProperty.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonConverterAttributeProperty.cs index e4ac7420..89779276 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonConverterAttributeProperty.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonConverterAttributeProperty.cs @@ -6,42 +6,42 @@ using Newtonsoft.Json.Converters; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class JsonConverterAttributeProperty - { - #region Types - public enum UserStatus + public class JsonConverterAttributeProperty { - NotConfirmed, - Active, - Deleted - } - - public class User - { - public string UserName { get; set; } - - [JsonConverter(typeof(StringEnumConverter))] - public UserStatus Status { get; set; } - } - #endregion - - public void Example() - { - #region Usage - User user = new User + #region Types + public enum UserStatus { - UserName = @"domain\username", - Status = UserStatus.Deleted - }; + NotConfirmed, + Active, + Deleted + } - string json = JsonConvert.SerializeObject(user, Formatting.Indented); + public class User + { + public string UserName { get; set; } - Console.WriteLine(json); - // { - // "UserName": "domain\\username", - // "Status": "Deleted" - // } - #endregion + [JsonConverter(typeof(StringEnumConverter))] + public UserStatus Status { get; set; } + } + #endregion + + public void Example() + { + #region Usage + User user = new User + { + UserName = @"domain\username", + Status = UserStatus.Deleted + }; + + string json = JsonConvert.SerializeObject(user, Formatting.Indented); + + Console.WriteLine(json); + // { + // "UserName": "domain\\username", + // "Status": "Deleted" + // } + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonObjectAttributeOptIn.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonObjectAttributeOptIn.cs index 10c47277..461fc22e 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonObjectAttributeOptIn.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonObjectAttributeOptIn.cs @@ -5,41 +5,42 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class JsonObjectAttributeOptIn - { - #region Types - [JsonObject(MemberSerialization.OptIn)] - public class File + public class JsonObjectAttributeOptIn { - // excluded from serialization - // does not have JsonPropertyAttribute - public Guid Id { get; set; } - - [JsonProperty] - public string Name { get; set; } - [JsonProperty] - public int Size { get; set; } - } - #endregion - - public void Example() - { - #region Usage - File file = new File + #region Types + [JsonObject(MemberSerialization.OptIn)] + public class File { - Id = Guid.NewGuid(), - Name = "ImportantLegalDocuments.docx", - Size = 50 * 1024 - }; + // excluded from serialization + // does not have JsonPropertyAttribute + public Guid Id { get; set; } - string json = JsonConvert.SerializeObject(file, Formatting.Indented); + [JsonProperty] + public string Name { get; set; } - Console.WriteLine(json); - // { - // "Name": "ImportantLegalDocuments.docx", - // "Size": 51200 - // } - #endregion + [JsonProperty] + public int Size { get; set; } + } + #endregion + + public void Example() + { + #region Usage + File file = new File + { + Id = Guid.NewGuid(), + Name = "ImportantLegalDocuments.docx", + Size = 50 * 1024 + }; + + string json = JsonConvert.SerializeObject(file, Formatting.Indented); + + Console.WriteLine(json); + // { + // "Name": "ImportantLegalDocuments.docx", + // "Size": 51200 + // } + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonObjectAttributeOverrideIEnumerable.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonObjectAttributeOverrideIEnumerable.cs index d05e9556..d394ec4c 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonObjectAttributeOverrideIEnumerable.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonObjectAttributeOverrideIEnumerable.cs @@ -6,56 +6,56 @@ using System.Collections; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class JsonObjectAttributeOverrideIEnumerable - { - #region Types - [JsonObject] - public class Directory : IEnumerable + public class JsonObjectAttributeOverrideIEnumerable { - public string Name { get; set; } - public IList Files { get; set; } - - public Directory() - { - Files = new List(); - } - - public IEnumerator GetEnumerator() - { - return Files.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } - #endregion - - public void Example() - { - #region Usage - Directory directory = new Directory + #region Types + [JsonObject] + public class Directory : IEnumerable { - Name = "My Documents", - Files = + public string Name { get; set; } + public IList Files { get; set; } + + public Directory() { - "ImportantLegalDocuments.docx", - "WiseFinancalAdvice.xlsx" + Files = new List(); } - }; - string json = JsonConvert.SerializeObject(directory, Formatting.Indented); + public IEnumerator GetEnumerator() + { + return Files.GetEnumerator(); + } - Console.WriteLine(json); - // { - // "Name": "My Documents", - // "Files": [ - // "ImportantLegalDocuments.docx", - // "WiseFinancalAdvice.xlsx" - // ] - // } - #endregion + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } + #endregion + + public void Example() + { + #region Usage + Directory directory = new Directory + { + Name = "My Documents", + Files = + { + "ImportantLegalDocuments.docx", + "WiseFinancalAdvice.xlsx" + } + }; + + string json = JsonConvert.SerializeObject(directory, Formatting.Indented); + + Console.WriteLine(json); + // { + // "Name": "My Documents", + // "Files": [ + // "ImportantLegalDocuments.docx", + // "WiseFinancalAdvice.xlsx" + // ] + // } + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonPropertyItemLevelSetting.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonPropertyItemLevelSetting.cs index c2fbb5f4..0a833459 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonPropertyItemLevelSetting.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonPropertyItemLevelSetting.cs @@ -5,70 +5,70 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class JsonPropertyItemLevelSetting - { - #region Types - public class Business + public class JsonPropertyItemLevelSetting { - public string Name { get; set; } - - [JsonProperty(ItemIsReference = true)] - public IList Employees { get; set; } - } - - public class Employee - { - public string Name { get; set; } - - [JsonProperty(IsReference = true)] - public Employee Manager { get; set; } - } - #endregion - - public void Example() - { - #region Usage - Employee manager = new Employee - { - Name = "George-Michael" - }; - Employee worker = new Employee - { - Name = "Maeby", - Manager = manager - }; - - Business business = new Business + #region Types + public class Business { - Name = "Acme Ltd.", - Employees = new List + public string Name { get; set; } + + [JsonProperty(ItemIsReference = true)] + public IList Employees { get; set; } + } + + public class Employee + { + public string Name { get; set; } + + [JsonProperty(IsReference = true)] + public Employee Manager { get; set; } + } + #endregion + + public void Example() + { + #region Usage + Employee manager = new Employee { - manager, - worker - } - }; + Name = "George-Michael" + }; + Employee worker = new Employee + { + Name = "Maeby", + Manager = manager + }; - string json = JsonConvert.SerializeObject(business, Formatting.Indented); + Business business = new Business + { + Name = "Acme Ltd.", + Employees = new List + { + manager, + worker + } + }; - Console.WriteLine(json); - // { - // "Name": "Acme Ltd.", - // "Employees": [ - // { - // "$id": "1", - // "Name": "George-Michael", - // "Manager": null - // }, - // { - // "$id": "2", - // "Name": "Maeby", - // "Manager": { - // "$ref": "1" - // } - // } - // ] - // } - #endregion + string json = JsonConvert.SerializeObject(business, Formatting.Indented); + + Console.WriteLine(json); + // { + // "Name": "Acme Ltd.", + // "Employees": [ + // { + // "$id": "1", + // "Name": "George-Michael", + // "Manager": null + // }, + // { + // "$id": "2", + // "Name": "Maeby", + // "Manager": { + // "$ref": "1" + // } + // } + // ] + // } + #endregion + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonPropertyName.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonPropertyName.cs index 33e6ffe8..a0a60d3a 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonPropertyName.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonPropertyName.cs @@ -5,36 +5,36 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class JsonPropertyName - { - #region Types - public class Videogame + public class JsonPropertyName { - [JsonProperty("name")] - public string Name { get; set; } - - [JsonProperty("release_date")] - public DateTime ReleaseDate { get; set; } - } - #endregion - - public void Example() - { - #region Usage - Videogame starcraft = new Videogame + #region Types + public class Videogame { - Name = "Starcraft", - ReleaseDate = new DateTime(1998, 1, 1) - }; + [JsonProperty("name")] + public string Name { get; set; } - string json = JsonConvert.SerializeObject(starcraft, Formatting.Indented); + [JsonProperty("release_date")] + public DateTime ReleaseDate { get; set; } + } + #endregion - Console.WriteLine(json); - // { - // "name": "Starcraft", - // "release_date": "1998-01-01T00:00:00" - // } - #endregion + public void Example() + { + #region Usage + Videogame starcraft = new Videogame + { + Name = "Starcraft", + ReleaseDate = new DateTime(1998, 1, 1) + }; + + string json = JsonConvert.SerializeObject(starcraft, Formatting.Indented); + + Console.WriteLine(json); + // { + // "name": "Starcraft", + // "release_date": "1998-01-01T00:00:00" + // } + #endregion + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonPropertyOrder.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonPropertyOrder.cs index be20d231..f20e66b2 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonPropertyOrder.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonPropertyOrder.cs @@ -5,53 +5,54 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class JsonPropertyOrder - { - #region Types - public class Account + public class JsonPropertyOrder { - public string EmailAddress { get; set; } - - // appear last - [JsonProperty(Order = 1)] - public bool Deleted { get; set; } - [JsonProperty(Order = 2)] - public DateTime DeletedDate { get; set; } - - public DateTime CreatedDate { get; set; } - public DateTime UpdatedDate { get; set; } - - // appear first - [JsonProperty(Order = -2)] - public string FullName { get; set; } - } - #endregion - - public void Example() - { - #region Usage - Account account = new Account + #region Types + public class Account { - FullName = "Aaron Account", - EmailAddress = "aaron@example.com", - Deleted = true, - DeletedDate = new DateTime(2013, 1, 25), - UpdatedDate = new DateTime(2013, 1, 25), - CreatedDate = new DateTime(2010, 10, 1) - }; + public string EmailAddress { get; set; } - string json = JsonConvert.SerializeObject(account, Formatting.Indented); + // appear last + [JsonProperty(Order = 1)] + public bool Deleted { get; set; } - Console.WriteLine(json); - // { - // "FullName": "Aaron Account", - // "EmailAddress": "aaron@example.com", - // "CreatedDate": "2010-10-01T00:00:00", - // "UpdatedDate": "2013-01-25T00:00:00", - // "Deleted": true, - // "DeletedDate": "2013-01-25T00:00:00" - // } - #endregion + [JsonProperty(Order = 2)] + public DateTime DeletedDate { get; set; } + + public DateTime CreatedDate { get; set; } + public DateTime UpdatedDate { get; set; } + + // appear first + [JsonProperty(Order = -2)] + public string FullName { get; set; } + } + #endregion + + public void Example() + { + #region Usage + Account account = new Account + { + FullName = "Aaron Account", + EmailAddress = "aaron@example.com", + Deleted = true, + DeletedDate = new DateTime(2013, 1, 25), + UpdatedDate = new DateTime(2013, 1, 25), + CreatedDate = new DateTime(2010, 10, 1) + }; + + string json = JsonConvert.SerializeObject(account, Formatting.Indented); + + Console.WriteLine(json); + // { + // "FullName": "Aaron Account", + // "EmailAddress": "aaron@example.com", + // "CreatedDate": "2010-10-01T00:00:00", + // "UpdatedDate": "2013-01-25T00:00:00", + // "Deleted": true, + // "DeletedDate": "2013-01-25T00:00:00" + // } + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonPropertyPropertyLevelSetting.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonPropertyPropertyLevelSetting.cs index 17e85014..dc9ae436 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonPropertyPropertyLevelSetting.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonPropertyPropertyLevelSetting.cs @@ -5,36 +5,36 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class JsonPropertyPropertyLevelSetting - { - #region Types - public class Vessel + public class JsonPropertyPropertyLevelSetting { - public string Name { get; set; } - public string Class { get; set; } - - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] - public DateTime? LaunchDate { get; set; } - } - #endregion - - public void Example() - { - #region Usage - Vessel vessel = new Vessel + #region Types + public class Vessel { - Name = "Red October", - Class = "Typhoon" - }; + public string Name { get; set; } + public string Class { get; set; } - string json = JsonConvert.SerializeObject(vessel, Formatting.Indented); + [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] + public DateTime? LaunchDate { get; set; } + } + #endregion - Console.WriteLine(json); - // { - // "Name": "Red October", - // "Class": "Typhoon" - // } - #endregion + public void Example() + { + #region Usage + Vessel vessel = new Vessel + { + Name = "Red October", + Class = "Typhoon" + }; + + string json = JsonConvert.SerializeObject(vessel, Formatting.Indented); + + Console.WriteLine(json); + // { + // "Name": "Red October", + // "Class": "Typhoon" + // } + #endregion + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonPropertyRequired.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonPropertyRequired.cs index 586997f6..2a54f256 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonPropertyRequired.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/JsonPropertyRequired.cs @@ -5,35 +5,35 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class JsonPropertyRequired - { - #region Types - public class Videogame + public class JsonPropertyRequired { - [JsonProperty(Required = Required.Always)] - public string Name { get; set; } + #region Types + public class Videogame + { + [JsonProperty(Required = Required.Always)] + public string Name { get; set; } - [JsonProperty(Required = Required.AllowNull)] - public DateTime? ReleaseDate { get; set; } + [JsonProperty(Required = Required.AllowNull)] + public DateTime? ReleaseDate { get; set; } + } + #endregion + + public void Example() + { + #region Usage + string json = @"{ + 'Name': 'Starcraft III', + 'ReleaseDate': null + }"; + + Videogame starcraft = JsonConvert.DeserializeObject(json); + + Console.WriteLine(starcraft.Name); + // Starcraft III + + Console.WriteLine(starcraft.ReleaseDate); + // null + #endregion + } } - #endregion - - public void Example() - { - #region Usage - string json = @"{ - 'Name': 'Starcraft III', - 'ReleaseDate': null - }"; - - Videogame starcraft = JsonConvert.DeserializeObject(json); - - Console.WriteLine(starcraft.Name); - // Starcraft III - - Console.WriteLine(starcraft.ReleaseDate); - // null - #endregion - } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/MaxDepth.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/MaxDepth.cs index e8b3f077..81855d29 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/MaxDepth.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/MaxDepth.cs @@ -5,34 +5,34 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class MaxDepth - { - public void Example() + public class MaxDepth { - #region Usage - string json = @"[ - [ - [ - '1', - 'Two', - 'III' - ] - ] - ]"; + public void Example() + { + #region Usage + string json = @"[ + [ + [ + '1', + 'Two', + 'III' + ] + ] + ]"; - try - { - JsonConvert.DeserializeObject>>>(json, new JsonSerializerSettings - { - MaxDepth = 2 - }); - } - catch (JsonReaderException ex) - { - Console.WriteLine(ex.Message); - // The reader's MaxDepth of 2 has been exceeded. Path '[0][0]', line 3, position 12. - } - #endregion + try + { + JsonConvert.DeserializeObject>>>(json, new JsonSerializerSettings + { + MaxDepth = 2 + }); + } + catch (JsonReaderException ex) + { + Console.WriteLine(ex.Message); + // The reader's MaxDepth of 2 has been exceeded. Path '[0][0]', line 3, position 12. + } + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/NullValueHandlingIgnore.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/NullValueHandlingIgnore.cs index 01574aeb..5d812e2f 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/NullValueHandlingIgnore.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/NullValueHandlingIgnore.cs @@ -5,48 +5,48 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class NullValueHandlingIgnore - { - #region Types - public class Person + public class NullValueHandlingIgnore { - public string Name { get; set; } - public int Age { get; set; } - public Person Partner { get; set; } - public decimal? Salary { get; set; } - } - #endregion - - public void Example() - { - #region Usage - Person person = new Person + #region Types + public class Person { - Name = "Nigal Newborn", - Age = 1 - }; + public string Name { get; set; } + public int Age { get; set; } + public Person Partner { get; set; } + public decimal? Salary { get; set; } + } + #endregion - string jsonIncludeNullValues = JsonConvert.SerializeObject(person, Formatting.Indented); - - Console.WriteLine(jsonIncludeNullValues); - // { - // "Name": "Nigal Newborn", - // "Age": 1, - // "Partner": null, - // "Salary": null - // } - - string jsonIgnoreNullValues = JsonConvert.SerializeObject(person, Formatting.Indented, new JsonSerializerSettings + public void Example() { - NullValueHandling = NullValueHandling.Ignore - }); + #region Usage + Person person = new Person + { + Name = "Nigal Newborn", + Age = 1 + }; - Console.WriteLine(jsonIgnoreNullValues); - // { - // "Name": "Nigal Newborn", - // "Age": 1 - // } - #endregion + string jsonIncludeNullValues = JsonConvert.SerializeObject(person, Formatting.Indented); + + Console.WriteLine(jsonIncludeNullValues); + // { + // "Name": "Nigal Newborn", + // "Age": 1, + // "Partner": null, + // "Salary": null + // } + + string jsonIgnoreNullValues = JsonConvert.SerializeObject(person, Formatting.Indented, new JsonSerializerSettings + { + NullValueHandling = NullValueHandling.Ignore + }); + + Console.WriteLine(jsonIgnoreNullValues); + // { + // "Name": "Nigal Newborn", + // "Age": 1 + // } + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/PopulateObject.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/PopulateObject.cs index c5b7be9f..ffff6e80 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/PopulateObject.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/PopulateObject.cs @@ -5,51 +5,51 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class PopulateObject - { - #region Types - public class Account + public class PopulateObject { - public string Email { get; set; } - public bool Active { get; set; } - public DateTime CreatedDate { get; set; } - public IList Roles { get; set; } - } - #endregion - - public void Example() - { - #region Usage - Account account = new Account + #region Types + public class Account { - Email = "james@example.com", - Active = true, - CreatedDate = new DateTime(2013, 1, 20, 0, 0, 0, DateTimeKind.Utc), - Roles = new List + public string Email { get; set; } + public bool Active { get; set; } + public DateTime CreatedDate { get; set; } + public IList Roles { get; set; } + } + #endregion + + public void Example() + { + #region Usage + Account account = new Account { - "User", - "Admin" - } - }; + Email = "james@example.com", + Active = true, + CreatedDate = new DateTime(2013, 1, 20, 0, 0, 0, DateTimeKind.Utc), + Roles = new List + { + "User", + "Admin" + } + }; - string json = @"{ - 'Active': false, - 'Roles': [ - 'Expired' - ] - }"; + string json = @"{ + 'Active': false, + 'Roles': [ + 'Expired' + ] + }"; - JsonConvert.PopulateObject(json, account); + JsonConvert.PopulateObject(json, account); - Console.WriteLine(account.Email); - // james@example.com + Console.WriteLine(account.Email); + // james@example.com - Console.WriteLine(account.Active); - // false + Console.WriteLine(account.Active); + // false - Console.WriteLine(string.Join(", ", account.Roles)); - // User, Admin, Expired - #endregion + Console.WriteLine(string.Join(", ", account.Roles)); + // User, Admin, Expired + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/PreserveReferencesHandlingObject.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/PreserveReferencesHandlingObject.cs index edd781d2..3fcb6c6e 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/PreserveReferencesHandlingObject.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/PreserveReferencesHandlingObject.cs @@ -5,98 +5,98 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class PreserveReferencesHandlingObject - { - #region Types - public class Directory + public class PreserveReferencesHandlingObject { - public string Name { get; set; } - public Directory Parent { get; set; } - public IList Files { get; set; } - } - - public class File - { - public string Name { get; set; } - public Directory Parent { get; set; } - } - #endregion - - public void Example() - { - #region Usage - Directory root = new Directory { Name = "Root" }; - Directory documents = new Directory { Name = "My Documents", Parent = root }; - - File file = new File { Name = "ImportantLegalDocument.docx", Parent = documents }; - - documents.Files = new List { file }; - - try - { - JsonConvert.SerializeObject(documents, Formatting.Indented); - } - catch (JsonSerializationException) - { - // Self referencing loop detected for property 'Parent' with type - // 'Newtonsoft.Json.Tests.Documentation.Examples.ReferenceLoopHandlingObject+Directory'. Path 'Files[0]'. - } - - string preserveReferenacesAll = JsonConvert.SerializeObject(documents, Formatting.Indented, new JsonSerializerSettings + #region Types + public class Directory { - PreserveReferencesHandling = PreserveReferencesHandling.All - }); + public string Name { get; set; } + public Directory Parent { get; set; } + public IList Files { get; set; } + } - Console.WriteLine(preserveReferenacesAll); - // { - // "$id": "1", - // "Name": "My Documents", - // "Parent": { - // "$id": "2", - // "Name": "Root", - // "Parent": null, - // "Files": null - // }, - // "Files": { - // "$id": "3", - // "$values": [ - // { - // "$id": "4", - // "Name": "ImportantLegalDocument.docx", - // "Parent": { - // "$ref": "1" - // } - // } - // ] - // } - // } + public class File + { + public string Name { get; set; } + public Directory Parent { get; set; } + } + #endregion - string preserveReferenacesObjects = JsonConvert.SerializeObject(documents, Formatting.Indented, new JsonSerializerSettings - { - PreserveReferencesHandling = PreserveReferencesHandling.Objects - }); + public void Example() + { + #region Usage + Directory root = new Directory { Name = "Root" }; + Directory documents = new Directory { Name = "My Documents", Parent = root }; - Console.WriteLine(preserveReferenacesObjects); - // { - // "$id": "1", - // "Name": "My Documents", - // "Parent": { - // "$id": "2", - // "Name": "Root", - // "Parent": null, - // "Files": null - // }, - // "Files": [ - // { - // "$id": "3", - // "Name": "ImportantLegalDocument.docx", - // "Parent": { - // "$ref": "1" - // } - // } - // ] - // } - #endregion + File file = new File { Name = "ImportantLegalDocument.docx", Parent = documents }; + + documents.Files = new List { file }; + + try + { + JsonConvert.SerializeObject(documents, Formatting.Indented); + } + catch (JsonSerializationException) + { + // Self referencing loop detected for property 'Parent' with type + // 'Newtonsoft.Json.Tests.Documentation.Examples.ReferenceLoopHandlingObject+Directory'. Path 'Files[0]'. + } + + string preserveReferenacesAll = JsonConvert.SerializeObject(documents, Formatting.Indented, new JsonSerializerSettings + { + PreserveReferencesHandling = PreserveReferencesHandling.All + }); + + Console.WriteLine(preserveReferenacesAll); + // { + // "$id": "1", + // "Name": "My Documents", + // "Parent": { + // "$id": "2", + // "Name": "Root", + // "Parent": null, + // "Files": null + // }, + // "Files": { + // "$id": "3", + // "$values": [ + // { + // "$id": "4", + // "Name": "ImportantLegalDocument.docx", + // "Parent": { + // "$ref": "1" + // } + // } + // ] + // } + // } + + string preserveReferenacesObjects = JsonConvert.SerializeObject(documents, Formatting.Indented, new JsonSerializerSettings + { + PreserveReferencesHandling = PreserveReferencesHandling.Objects + }); + + Console.WriteLine(preserveReferenacesObjects); + // { + // "$id": "1", + // "Name": "My Documents", + // "Parent": { + // "$id": "2", + // "Name": "Root", + // "Parent": null, + // "Files": null + // }, + // "Files": [ + // { + // "$id": "3", + // "Name": "ImportantLegalDocument.docx", + // "Parent": { + // "$ref": "1" + // } + // } + // ] + // } + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/PropertyJsonIgnore.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/PropertyJsonIgnore.cs index 1e51d9c9..c6fa8108 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/PropertyJsonIgnore.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/PropertyJsonIgnore.cs @@ -5,33 +5,34 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class PropertyJsonIgnore - { - #region Types - public class Account + public class PropertyJsonIgnore { - public string FullName { get; set; } - public string EmailAddress { get; set; } - [JsonIgnore] - public string PasswordHash { get; set; } - } - #endregion - - public void Example() - { - #region Usage - Account account = new Account + #region Types + public class Account { - FullName = "Joe User", - EmailAddress = "joe@example.com", - PasswordHash = "VHdlZXQgJ1F1aWNrc2lsdmVyJyB0byBASmFtZXNOSw==" - }; + public string FullName { get; set; } + public string EmailAddress { get; set; } - string json = JsonConvert.SerializeObject(account); + [JsonIgnore] + public string PasswordHash { get; set; } + } + #endregion - Console.WriteLine(json); - // {"FullName":"Joe User","EmailAddress":"joe@example.com"} - #endregion + public void Example() + { + #region Usage + Account account = new Account + { + FullName = "Joe User", + EmailAddress = "joe@example.com", + PasswordHash = "VHdlZXQgJ1F1aWNrc2lsdmVyJyB0byBASmFtZXNOSw==" + }; + + string json = JsonConvert.SerializeObject(account); + + Console.WriteLine(json); + // {"FullName":"Joe User","EmailAddress":"joe@example.com"} + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/ReferenceLoopHandlingIgnore.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/ReferenceLoopHandlingIgnore.cs index ed6d0771..baeb339b 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/ReferenceLoopHandlingIgnore.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/ReferenceLoopHandlingIgnore.cs @@ -5,37 +5,37 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class ReferenceLoopHandlingIgnore - { - #region Types - public class Employee + public class ReferenceLoopHandlingIgnore { - public string Name { get; set; } - public Employee Manager { get; set; } - } - #endregion - - public void Example() - { - #region Usage - Employee joe = new Employee { Name = "Joe User" }; - Employee mike = new Employee { Name = "Mike Manager" }; - joe.Manager = mike; - mike.Manager = mike; - - string json = JsonConvert.SerializeObject(joe, Formatting.Indented, new JsonSerializerSettings + #region Types + public class Employee { - ReferenceLoopHandling = ReferenceLoopHandling.Ignore - }); + public string Name { get; set; } + public Employee Manager { get; set; } + } + #endregion - Console.WriteLine(json); - // { - // "Name": "Joe User", - // "Manager": { - // "Name": "Mike Manager" - // } - // } - #endregion + public void Example() + { + #region Usage + Employee joe = new Employee { Name = "Joe User" }; + Employee mike = new Employee { Name = "Mike Manager" }; + joe.Manager = mike; + mike.Manager = mike; + + string json = JsonConvert.SerializeObject(joe, Formatting.Indented, new JsonSerializerSettings + { + ReferenceLoopHandling = ReferenceLoopHandling.Ignore + }); + + Console.WriteLine(json); + // { + // "Name": "Joe User", + // "Manager": { + // "Name": "Mike Manager" + // } + // } + #endregion + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializationCallbackAttributes.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializationCallbackAttributes.cs index afbb0ea8..3b120049 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializationCallbackAttributes.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializationCallbackAttributes.cs @@ -6,102 +6,102 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class SerializationCallbackAttributes - { - #region Types - public class SerializationEventTestObject + public class SerializationCallbackAttributes { - // 2222 - // This member is serialized and deserialized with no change. - public int Member1 { get; set; } + #region Types + public class SerializationEventTestObject + { + // 2222 + // This member is serialized and deserialized with no change. + public int Member1 { get; set; } - // The value of this field is set and reset during and - // after serialization. - public string Member2 { get; set; } + // The value of this field is set and reset during and + // after serialization. + public string Member2 { get; set; } - // This field is not serialized. The OnDeserializedAttribute - // is used to set the member value after serialization. - [JsonIgnore] - public string Member3 { get; set; } + // This field is not serialized. The OnDeserializedAttribute + // is used to set the member value after serialization. + [JsonIgnore] + public string Member3 { get; set; } - // This field is set to null, but populated after deserialization. - public string Member4 { get; set; } + // This field is set to null, but populated after deserialization. + public string Member4 { get; set; } - public SerializationEventTestObject() - { - Member1 = 11; - Member2 = "Hello World!"; - Member3 = "This is a nonserialized value"; - Member4 = null; - } + public SerializationEventTestObject() + { + Member1 = 11; + Member2 = "Hello World!"; + Member3 = "This is a nonserialized value"; + Member4 = null; + } - [OnSerializing] - internal void OnSerializingMethod(StreamingContext context) - { - Member2 = "This value went into the data file during serialization."; - } + [OnSerializing] + internal void OnSerializingMethod(StreamingContext context) + { + Member2 = "This value went into the data file during serialization."; + } - [OnSerialized] - internal void OnSerializedMethod(StreamingContext context) - { - Member2 = "This value was reset after serialization."; - } + [OnSerialized] + internal void OnSerializedMethod(StreamingContext context) + { + Member2 = "This value was reset after serialization."; + } - [OnDeserializing] - internal void OnDeserializingMethod(StreamingContext context) - { - Member3 = "This value was set during deserialization"; - } + [OnDeserializing] + internal void OnDeserializingMethod(StreamingContext context) + { + Member3 = "This value was set during deserialization"; + } - [OnDeserialized] - internal void OnDeserializedMethod(StreamingContext context) - { - Member4 = "This value was set after deserialization."; - } + [OnDeserialized] + internal void OnDeserializedMethod(StreamingContext context) + { + Member4 = "This value was set after deserialization."; + } + } + #endregion + + public void Example() + { + #region Usage + SerializationEventTestObject obj = new SerializationEventTestObject(); + + Console.WriteLine(obj.Member1); + // 11 + Console.WriteLine(obj.Member2); + // Hello World! + Console.WriteLine(obj.Member3); + // This is a nonserialized value + Console.WriteLine(obj.Member4); + // null + + string json = JsonConvert.SerializeObject(obj, Formatting.Indented); + // { + // "Member1": 11, + // "Member2": "This value went into the data file during serialization.", + // "Member4": null + // } + + Console.WriteLine(obj.Member1); + // 11 + Console.WriteLine(obj.Member2); + // This value was reset after serialization. + Console.WriteLine(obj.Member3); + // This is a nonserialized value + Console.WriteLine(obj.Member4); + // null + + obj = JsonConvert.DeserializeObject(json); + + Console.WriteLine(obj.Member1); + // 11 + Console.WriteLine(obj.Member2); + // This value went into the data file during serialization. + Console.WriteLine(obj.Member3); + // This value was set during deserialization + Console.WriteLine(obj.Member4); + // This value was set after deserialization. + #endregion + } } - #endregion - - public void Example() - { - #region Usage - SerializationEventTestObject obj = new SerializationEventTestObject(); - - Console.WriteLine(obj.Member1); - // 11 - Console.WriteLine(obj.Member2); - // Hello World! - Console.WriteLine(obj.Member3); - // This is a nonserialized value - Console.WriteLine(obj.Member4); - // null - - string json = JsonConvert.SerializeObject(obj, Formatting.Indented); - // { - // "Member1": 11, - // "Member2": "This value went into the data file during serialization.", - // "Member4": null - // } - - Console.WriteLine(obj.Member1); - // 11 - Console.WriteLine(obj.Member2); - // This value was reset after serialization. - Console.WriteLine(obj.Member3); - // This is a nonserialized value - Console.WriteLine(obj.Member4); - // null - - obj = JsonConvert.DeserializeObject(json); - - Console.WriteLine(obj.Member1); - // 11 - Console.WriteLine(obj.Member2); - // This value went into the data file during serialization. - Console.WriteLine(obj.Member3); - // This value was set during deserialization - Console.WriteLine(obj.Member4); - // This value was set after deserialization. - #endregion - } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeCollection.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeCollection.cs index ff812846..20681bcf 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeCollection.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeCollection.cs @@ -5,23 +5,23 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class SerializeCollection - { - public void Example() + public class SerializeCollection { - #region Usage - List videogames = new List + public void Example() { - "Starcraft", - "Halo", - "Legend of Zelda" - }; + #region Usage + List videogames = new List + { + "Starcraft", + "Halo", + "Legend of Zelda" + }; - string json = JsonConvert.SerializeObject(videogames); + string json = JsonConvert.SerializeObject(videogames); - Console.WriteLine(json); - // ["Starcraft","Halo","Legend of Zelda"] - #endregion + Console.WriteLine(json); + // ["Starcraft","Halo","Legend of Zelda"] + #endregion + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeConditionalProperty.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeConditionalProperty.cs index a0335de8..b89fa130 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeConditionalProperty.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeConditionalProperty.cs @@ -5,51 +5,51 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class SerializeConditionalProperty - { - #region Types - public class Employee + public class SerializeConditionalProperty { - public string Name { get; set; } - public Employee Manager { get; set; } + #region Types + public class Employee + { + public string Name { get; set; } + public Employee Manager { get; set; } - public bool ShouldSerializeManager() - { - // don't serialize the Manager property if an employee is their own manager - return (Manager != this); - } + public bool ShouldSerializeManager() + { + // don't serialize the Manager property if an employee is their own manager + return (Manager != this); + } + } + #endregion + + public void Example() + { + #region Usage + Employee joe = new Employee(); + joe.Name = "Joe Employee"; + Employee mike = new Employee(); + mike.Name = "Mike Manager"; + + joe.Manager = mike; + + // mike is his own manager + // ShouldSerialize will skip this property + mike.Manager = mike; + + string json = JsonConvert.SerializeObject(new[] { joe, mike }, Formatting.Indented); + + Console.WriteLine(json); + // [ + // { + // "Name": "Joe Employee", + // "Manager": { + // "Name": "Mike Manager" + // } + // }, + // { + // "Name": "Mike Manager" + // } + // ] + #endregion + } } - #endregion - - public void Example() - { - #region Usage - Employee joe = new Employee(); - joe.Name = "Joe Employee"; - Employee mike = new Employee(); - mike.Name = "Mike Manager"; - - joe.Manager = mike; - - // mike is his own manager - // ShouldSerialize will skip this property - mike.Manager = mike; - - string json = JsonConvert.SerializeObject(new[] { joe, mike }, Formatting.Indented); - - Console.WriteLine(json); - // [ - // { - // "Name": "Joe Employee", - // "Manager": { - // "Name": "Mike Manager" - // } - // }, - // { - // "Name": "Mike Manager" - // } - // ] - #endregion - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeContractResolver.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeContractResolver.cs index 873b3b82..d6a4ce96 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeContractResolver.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeContractResolver.cs @@ -6,42 +6,42 @@ using Newtonsoft.Json.Serialization; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class SerializeContractResolver - { - #region Types - public class Person + public class SerializeContractResolver { - public string FirstName { get; set; } - public string LastName { get; set; } - - public string FullName - { - get { return FirstName + " " + LastName; } - } - } - #endregion - - public void Example() - { - #region Usage - Person person = new Person + #region Types + public class Person { - FirstName = "Sarah", - LastName = "Security" - }; + public string FirstName { get; set; } + public string LastName { get; set; } - string json = JsonConvert.SerializeObject(person, Formatting.Indented, new JsonSerializerSettings + public string FullName + { + get { return FirstName + " " + LastName; } + } + } + #endregion + + public void Example() { - ContractResolver = new CamelCasePropertyNamesContractResolver() - }); + #region Usage + Person person = new Person + { + FirstName = "Sarah", + LastName = "Security" + }; - Console.WriteLine(json); - // { - // "firstName": "Sarah", - // "lastName": "Security", - // "fullName": "Sarah Security" - // } - #endregion + string json = JsonConvert.SerializeObject(person, Formatting.Indented, new JsonSerializerSettings + { + ContractResolver = new CamelCasePropertyNamesContractResolver() + }); + + Console.WriteLine(json); + // { + // "firstName": "Sarah", + // "lastName": "Security", + // "fullName": "Sarah Security" + // } + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeDataSet.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeDataSet.cs index 46a58c61..955a7fa5 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeDataSet.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeDataSet.cs @@ -7,47 +7,47 @@ using NUnit.Framework; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class SerializeDataSet - { - public void Example() + public class SerializeDataSet { - #region Usage - DataSet dataSet = new DataSet("dataSet"); - dataSet.Namespace = "NetFrameWork"; - DataTable table = new DataTable(); - DataColumn idColumn = new DataColumn("id", typeof(int)); - idColumn.AutoIncrement = true; + public void Example() + { + #region Usage + DataSet dataSet = new DataSet("dataSet"); + dataSet.Namespace = "NetFrameWork"; + DataTable table = new DataTable(); + DataColumn idColumn = new DataColumn("id", typeof(int)); + idColumn.AutoIncrement = true; - DataColumn itemColumn = new DataColumn("item"); - table.Columns.Add(idColumn); - table.Columns.Add(itemColumn); - dataSet.Tables.Add(table); + DataColumn itemColumn = new DataColumn("item"); + table.Columns.Add(idColumn); + table.Columns.Add(itemColumn); + dataSet.Tables.Add(table); - for (int i = 0; i < 2; i++) - { - DataRow newRow = table.NewRow(); - newRow["item"] = "item " + i; - table.Rows.Add(newRow); - } + for (int i = 0; i < 2; i++) + { + DataRow newRow = table.NewRow(); + newRow["item"] = "item " + i; + table.Rows.Add(newRow); + } - dataSet.AcceptChanges(); + dataSet.AcceptChanges(); - string json = JsonConvert.SerializeObject(dataSet, Formatting.Indented); + string json = JsonConvert.SerializeObject(dataSet, Formatting.Indented); - Console.WriteLine(json); - // { - // "Table1": [ - // { - // "id": 0, - // "item": "item 0" - // }, - // { - // "id": 1, - // "item": "item 1" - // } - // ] - // } - #endregion + Console.WriteLine(json); + // { + // "Table1": [ + // { + // "id": 0, + // "item": "item 0" + // }, + // { + // "id": 1, + // "item": "item 1" + // } + // ] + // } + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeDateFormatHandling.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeDateFormatHandling.cs index 5675e9c7..a9903556 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeDateFormatHandling.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeDateFormatHandling.cs @@ -5,26 +5,26 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class SerializeDateFormatHandling - { - public void Example() + public class SerializeDateFormatHandling { - #region Usage - DateTime mayanEndOfTheWorld = new DateTime(2012, 12, 21); - - string jsonIsoDate = JsonConvert.SerializeObject(mayanEndOfTheWorld); - - Console.WriteLine(jsonIsoDate); - // "2012-12-21T00:00:00" - - string jsonMsDate = JsonConvert.SerializeObject(mayanEndOfTheWorld, new JsonSerializerSettings + public void Example() { - DateFormatHandling = DateFormatHandling.MicrosoftDateFormat - }); + #region Usage + DateTime mayanEndOfTheWorld = new DateTime(2012, 12, 21); - Console.WriteLine(jsonMsDate); - // "\/Date(1356044400000+0100)\/" - #endregion + string jsonIsoDate = JsonConvert.SerializeObject(mayanEndOfTheWorld); + + Console.WriteLine(jsonIsoDate); + // "2012-12-21T00:00:00" + + string jsonMsDate = JsonConvert.SerializeObject(mayanEndOfTheWorld, new JsonSerializerSettings + { + DateFormatHandling = DateFormatHandling.MicrosoftDateFormat + }); + + Console.WriteLine(jsonMsDate); + // "\/Date(1356044400000+0100)\/" + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeDateTimeZoneHandling.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeDateTimeZoneHandling.cs index af3f706c..a086f15e 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeDateTimeZoneHandling.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeDateTimeZoneHandling.cs @@ -5,87 +5,87 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class SerializeDateTimeZoneHandling - { - #region Types - public class Flight + public class SerializeDateTimeZoneHandling { - public string Destination { get; set; } - public DateTime DepartureDate { get; set; } - public DateTime DepartureDateUtc { get; set; } - public DateTime DepartureDateLocal { get; set; } - public TimeSpan Duration { get; set; } - } - #endregion - - public void Example() - { - #region Usage - Flight flight = new Flight + #region Types + public class Flight { - Destination = "Dubai", - DepartureDate = new DateTime(2013, 1, 21, 0, 0, 0, DateTimeKind.Unspecified), - DepartureDateUtc = new DateTime(2013, 1, 21, 0, 0, 0, DateTimeKind.Utc), - DepartureDateLocal = new DateTime(2013, 1, 21, 0, 0, 0, DateTimeKind.Local), - Duration = TimeSpan.FromHours(5.5) - }; + public string Destination { get; set; } + public DateTime DepartureDate { get; set; } + public DateTime DepartureDateUtc { get; set; } + public DateTime DepartureDateLocal { get; set; } + public TimeSpan Duration { get; set; } + } + #endregion - string jsonWithRoundtripTimeZone = JsonConvert.SerializeObject(flight, Formatting.Indented, new JsonSerializerSettings - { - DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind - }); + public void Example() + { + #region Usage + Flight flight = new Flight + { + Destination = "Dubai", + DepartureDate = new DateTime(2013, 1, 21, 0, 0, 0, DateTimeKind.Unspecified), + DepartureDateUtc = new DateTime(2013, 1, 21, 0, 0, 0, DateTimeKind.Utc), + DepartureDateLocal = new DateTime(2013, 1, 21, 0, 0, 0, DateTimeKind.Local), + Duration = TimeSpan.FromHours(5.5) + }; - Console.WriteLine(jsonWithRoundtripTimeZone); - // { - // "Destination": "Dubai", - // "DepartureDate": "2013-01-21T00:00:00", - // "DepartureDateUtc": "2013-01-21T00:00:00Z", - // "DepartureDateLocal": "2013-01-21T00:00:00+01:00", - // "Duration": "05:30:00" - // } + string jsonWithRoundtripTimeZone = JsonConvert.SerializeObject(flight, Formatting.Indented, new JsonSerializerSettings + { + DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind + }); - string jsonWithLocalTimeZone = JsonConvert.SerializeObject(flight, Formatting.Indented, new JsonSerializerSettings - { - DateTimeZoneHandling = DateTimeZoneHandling.Local - }); + Console.WriteLine(jsonWithRoundtripTimeZone); + // { + // "Destination": "Dubai", + // "DepartureDate": "2013-01-21T00:00:00", + // "DepartureDateUtc": "2013-01-21T00:00:00Z", + // "DepartureDateLocal": "2013-01-21T00:00:00+01:00", + // "Duration": "05:30:00" + // } - Console.WriteLine(jsonWithLocalTimeZone); - // { - // "Destination": "Dubai", - // "DepartureDate": "2013-01-21T00:00:00+01:00", - // "DepartureDateUtc": "2013-01-21T01:00:00+01:00", - // "DepartureDateLocal": "2013-01-21T00:00:00+01:00", - // "Duration": "05:30:00" - // } + string jsonWithLocalTimeZone = JsonConvert.SerializeObject(flight, Formatting.Indented, new JsonSerializerSettings + { + DateTimeZoneHandling = DateTimeZoneHandling.Local + }); - string jsonWithUtcTimeZone = JsonConvert.SerializeObject(flight, Formatting.Indented, new JsonSerializerSettings - { - DateTimeZoneHandling = DateTimeZoneHandling.Utc - }); + Console.WriteLine(jsonWithLocalTimeZone); + // { + // "Destination": "Dubai", + // "DepartureDate": "2013-01-21T00:00:00+01:00", + // "DepartureDateUtc": "2013-01-21T01:00:00+01:00", + // "DepartureDateLocal": "2013-01-21T00:00:00+01:00", + // "Duration": "05:30:00" + // } - Console.WriteLine(jsonWithUtcTimeZone); - // { - // "Destination": "Dubai", - // "DepartureDate": "2013-01-21T00:00:00Z", - // "DepartureDateUtc": "2013-01-21T00:00:00Z", - // "DepartureDateLocal": "2013-01-20T23:00:00Z", - // "Duration": "05:30:00" - // } + string jsonWithUtcTimeZone = JsonConvert.SerializeObject(flight, Formatting.Indented, new JsonSerializerSettings + { + DateTimeZoneHandling = DateTimeZoneHandling.Utc + }); - string jsonWithUnspecifiedTimeZone = JsonConvert.SerializeObject(flight, Formatting.Indented, new JsonSerializerSettings - { - DateTimeZoneHandling = DateTimeZoneHandling.Unspecified - }); + Console.WriteLine(jsonWithUtcTimeZone); + // { + // "Destination": "Dubai", + // "DepartureDate": "2013-01-21T00:00:00Z", + // "DepartureDateUtc": "2013-01-21T00:00:00Z", + // "DepartureDateLocal": "2013-01-20T23:00:00Z", + // "Duration": "05:30:00" + // } - Console.WriteLine(jsonWithUnspecifiedTimeZone); - // { - // "Destination": "Dubai", - // "DepartureDate": "2013-01-21T00:00:00", - // "DepartureDateUtc": "2013-01-21T00:00:00", - // "DepartureDateLocal": "2013-01-21T00:00:00", - // "Duration": "05:30:00" - // } - #endregion + string jsonWithUnspecifiedTimeZone = JsonConvert.SerializeObject(flight, Formatting.Indented, new JsonSerializerSettings + { + DateTimeZoneHandling = DateTimeZoneHandling.Unspecified + }); + + Console.WriteLine(jsonWithUnspecifiedTimeZone); + // { + // "Destination": "Dubai", + // "DepartureDate": "2013-01-21T00:00:00", + // "DepartureDateUtc": "2013-01-21T00:00:00", + // "DepartureDateLocal": "2013-01-21T00:00:00", + // "Duration": "05:30:00" + // } + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeDictionary.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeDictionary.cs index 12b8f47d..c3832c10 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeDictionary.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeDictionary.cs @@ -5,27 +5,27 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class SerializeDictionary - { - public void Example() + public class SerializeDictionary { - #region Usage - Dictionary points = new Dictionary + public void Example() { - { "James", 9001 }, - { "Jo", 3474 }, - { "Jess", 11926 } - }; + #region Usage + Dictionary points = new Dictionary + { + { "James", 9001 }, + { "Jo", 3474 }, + { "Jess", 11926 } + }; - string json = JsonConvert.SerializeObject(points, Formatting.Indented); + string json = JsonConvert.SerializeObject(points, Formatting.Indented); - Console.WriteLine(json); - // { - // "James": 9001, - // "Jo": 3474, - // "Jess": 11926 - // } - #endregion + Console.WriteLine(json); + // { + // "James": 9001, + // "Jo": 3474, + // "Jess": 11926 + // } + #endregion + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeObject.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeObject.cs index 77e3e92b..91dc044f 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeObject.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeObject.cs @@ -5,46 +5,46 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class SerializeObject - { - #region Types - public class Account + public class SerializeObject { - public string Email { get; set; } - public bool Active { get; set; } - public DateTime CreatedDate { get; set; } - public IList Roles { get; set; } - } - #endregion - - public void Example() - { - #region Usage - Account account = new Account + #region Types + public class Account { - Email = "james@example.com", - Active = true, - CreatedDate = new DateTime(2013, 1, 20, 0, 0, 0, DateTimeKind.Utc), - Roles = new List + public string Email { get; set; } + public bool Active { get; set; } + public DateTime CreatedDate { get; set; } + public IList Roles { get; set; } + } + #endregion + + public void Example() + { + #region Usage + Account account = new Account { - "User", - "Admin" - } - }; + Email = "james@example.com", + Active = true, + CreatedDate = new DateTime(2013, 1, 20, 0, 0, 0, DateTimeKind.Utc), + Roles = new List + { + "User", + "Admin" + } + }; - string json = JsonConvert.SerializeObject(account, Formatting.Indented); - // { - // "Email": "james@example.com", - // "Active": true, - // "CreatedDate": "2013-01-20T00:00:00Z", - // "Roles": [ - // "User", - // "Admin" - // ] - // } + string json = JsonConvert.SerializeObject(account, Formatting.Indented); + // { + // "Email": "james@example.com", + // "Active": true, + // "CreatedDate": "2013-01-20T00:00:00Z", + // "Roles": [ + // "User", + // "Admin" + // ] + // } - Console.WriteLine(json); - #endregion + Console.WriteLine(json); + #endregion + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeRawJson.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeRawJson.cs index 2ecd2ec1..5020d35e 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeRawJson.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeRawJson.cs @@ -6,33 +6,33 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class SerializeRawJson - { - #region Types - public class JavaScriptSettings + public class SerializeRawJson { - public JRaw OnLoadFunction { get; set; } - public JRaw OnUnloadFunction { get; set; } - } - #endregion - - public void Example() - { - #region Usage - JavaScriptSettings settings = new JavaScriptSettings + #region Types + public class JavaScriptSettings { - OnLoadFunction = new JRaw("OnLoad"), - OnUnloadFunction = new JRaw("function(e) { alert(e); }") - }; + public JRaw OnLoadFunction { get; set; } + public JRaw OnUnloadFunction { get; set; } + } + #endregion - string json = JsonConvert.SerializeObject(settings, Formatting.Indented); + public void Example() + { + #region Usage + JavaScriptSettings settings = new JavaScriptSettings + { + OnLoadFunction = new JRaw("OnLoad"), + OnUnloadFunction = new JRaw("function(e) { alert(e); }") + }; - Console.WriteLine(json); - // { - // "OnLoadFunction": OnLoad, - // "OnUnloadFunction": function(e) { alert(e); } - // } - #endregion + string json = JsonConvert.SerializeObject(settings, Formatting.Indented); + + Console.WriteLine(json); + // { + // "OnLoadFunction": OnLoad, + // "OnUnloadFunction": function(e) { alert(e); } + // } + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeSerializationBinder.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeSerializationBinder.cs index 765ab32b..e6930539 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeSerializationBinder.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeSerializationBinder.cs @@ -6,68 +6,68 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class SerializeSerializationBinder - { - #region Types - public class KnownTypesBinder : SerializationBinder + public class SerializeSerializationBinder { - public IList KnownTypes { get; set; } - - public override Type BindToType(string assemblyName, string typeName) - { - return KnownTypes.SingleOrDefault(t => t.Name == typeName); - } + #region Types + public class KnownTypesBinder : SerializationBinder + { + public IList KnownTypes { get; set; } - public override void BindToName(Type serializedType, out string assemblyName, out string typeName) - { - assemblyName = null; - typeName = serializedType.Name; - } + public override Type BindToType(string assemblyName, string typeName) + { + return KnownTypes.SingleOrDefault(t => t.Name == typeName); + } + + public override void BindToName(Type serializedType, out string assemblyName, out string typeName) + { + assemblyName = null; + typeName = serializedType.Name; + } + } + + public class Car + { + public string Maker { get; set; } + public string Model { get; set; } + } + #endregion + + public void Example() + { + #region Usage + KnownTypesBinder knownTypesBinder = new KnownTypesBinder + { + KnownTypes = new List { typeof(Car) } + }; + + Car car = new Car + { + Maker = "Ford", + Model = "Explorer" + }; + + string json = JsonConvert.SerializeObject(car, Formatting.Indented, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Objects, + Binder = knownTypesBinder + }); + + Console.WriteLine(json); + // { + // "$type": "Car", + // "Maker": "Ford", + // "Model": "Explorer" + // } + + object newValue = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Objects, + Binder = knownTypesBinder + }); + + Console.WriteLine(newValue.GetType().Name); + // Car + #endregion + } } - - public class Car - { - public string Maker { get; set; } - public string Model { get; set; } - } - #endregion - - public void Example() - { - #region Usage - KnownTypesBinder knownTypesBinder = new KnownTypesBinder - { - KnownTypes = new List {typeof (Car)} - }; - - Car car = new Car - { - Maker = "Ford", - Model = "Explorer" - }; - - string json = JsonConvert.SerializeObject(car, Formatting.Indented, new JsonSerializerSettings - { - TypeNameHandling = TypeNameHandling.Objects, - Binder = knownTypesBinder - }); - - Console.WriteLine(json); - // { - // "$type": "Car", - // "Maker": "Ford", - // "Model": "Explorer" - // } - - object newValue = JsonConvert.DeserializeObject(json, new JsonSerializerSettings - { - TypeNameHandling = TypeNameHandling.Objects, - Binder = knownTypesBinder - }); - - Console.WriteLine(newValue.GetType().Name); - // Car - #endregion - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeTypeNameHandling.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeTypeNameHandling.cs index fabf8444..db86854a 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeTypeNameHandling.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeTypeNameHandling.cs @@ -5,89 +5,89 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class SerializeTypeNameHandling - { - #region Types - public abstract class Business + public class SerializeTypeNameHandling { - public string Name { get; set; } - } - - public class Hotel : Business - { - public int Stars { get; set; } - } - - public class Stockholder - { - public string FullName { get; set; } - public IList Businesses { get; set; } - } - #endregion - - public void Example() - { - #region Usage - Stockholder stockholder = new Stockholder + #region Types + public abstract class Business { - FullName = "Steve Stockholder", - Businesses = new List + public string Name { get; set; } + } + + public class Hotel : Business + { + public int Stars { get; set; } + } + + public class Stockholder + { + public string FullName { get; set; } + public IList Businesses { get; set; } + } + #endregion + + public void Example() + { + #region Usage + Stockholder stockholder = new Stockholder { - new Hotel + FullName = "Steve Stockholder", + Businesses = new List { - Name = "Hudson Hotel", - Stars = 4 + new Hotel + { + Name = "Hudson Hotel", + Stars = 4 + } } - } - }; + }; - string jsonTypeNameAll = JsonConvert.SerializeObject(stockholder, Formatting.Indented, new JsonSerializerSettings - { - TypeNameHandling = TypeNameHandling.All - }); + string jsonTypeNameAll = JsonConvert.SerializeObject(stockholder, Formatting.Indented, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.All + }); - Console.WriteLine(jsonTypeNameAll); - // { - // "$type": "Newtonsoft.Json.Samples.Stockholder, Newtonsoft.Json.Tests", - // "FullName": "Steve Stockholder", - // "Businesses": { - // "$type": "System.Collections.Generic.List`1[[Newtonsoft.Json.Samples.Business, Newtonsoft.Json.Tests]], mscorlib", - // "$values": [ - // { - // "$type": "Newtonsoft.Json.Samples.Hotel, Newtonsoft.Json.Tests", - // "Stars": 4, - // "Name": "Hudson Hotel" - // } - // ] - // } - // } + Console.WriteLine(jsonTypeNameAll); + // { + // "$type": "Newtonsoft.Json.Samples.Stockholder, Newtonsoft.Json.Tests", + // "FullName": "Steve Stockholder", + // "Businesses": { + // "$type": "System.Collections.Generic.List`1[[Newtonsoft.Json.Samples.Business, Newtonsoft.Json.Tests]], mscorlib", + // "$values": [ + // { + // "$type": "Newtonsoft.Json.Samples.Hotel, Newtonsoft.Json.Tests", + // "Stars": 4, + // "Name": "Hudson Hotel" + // } + // ] + // } + // } - string jsonTypeNameAuto = JsonConvert.SerializeObject(stockholder, Formatting.Indented, new JsonSerializerSettings - { - TypeNameHandling = TypeNameHandling.Auto - }); + string jsonTypeNameAuto = JsonConvert.SerializeObject(stockholder, Formatting.Indented, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Auto + }); - Console.WriteLine(jsonTypeNameAuto); - // { - // "FullName": "Steve Stockholder", - // "Businesses": [ - // { - // "$type": "Newtonsoft.Json.Samples.Hotel, Newtonsoft.Json.Tests", - // "Stars": 4, - // "Name": "Hudson Hotel" - // } - // ] - // } + Console.WriteLine(jsonTypeNameAuto); + // { + // "FullName": "Steve Stockholder", + // "Businesses": [ + // { + // "$type": "Newtonsoft.Json.Samples.Hotel, Newtonsoft.Json.Tests", + // "Stars": 4, + // "Name": "Hudson Hotel" + // } + // ] + // } - // for security TypeNameHandling is required when deserializing - Stockholder newStockholder = JsonConvert.DeserializeObject(jsonTypeNameAuto, new JsonSerializerSettings - { - TypeNameHandling = TypeNameHandling.Auto - }); + // for security TypeNameHandling is required when deserializing + Stockholder newStockholder = JsonConvert.DeserializeObject(jsonTypeNameAuto, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Auto + }); - Console.WriteLine(newStockholder.Businesses[0].GetType().Name); - // Hotel - #endregion + Console.WriteLine(newStockholder.Businesses[0].GetType().Name); + // Hotel + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeUnindentedJson.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeUnindentedJson.cs index b361f75f..0d033448 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeUnindentedJson.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeUnindentedJson.cs @@ -5,38 +5,38 @@ using System.Text; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class SerializeUnindentedJson - { - #region Types - public class Account + public class SerializeUnindentedJson { - public string Email { get; set; } - public bool Active { get; set; } - public DateTime CreatedDate { get; set; } - public IList Roles { get; set; } - } - #endregion - - public void Example() - { - #region Usage - Account account = new Account + #region Types + public class Account { - Email = "james@example.com", - Active = true, - CreatedDate = new DateTime(2013, 1, 20, 0, 0, 0, DateTimeKind.Utc), - Roles = new List + public string Email { get; set; } + public bool Active { get; set; } + public DateTime CreatedDate { get; set; } + public IList Roles { get; set; } + } + #endregion + + public void Example() + { + #region Usage + Account account = new Account { - "User", - "Admin" - } - }; + Email = "james@example.com", + Active = true, + CreatedDate = new DateTime(2013, 1, 20, 0, 0, 0, DateTimeKind.Utc), + Roles = new List + { + "User", + "Admin" + } + }; - string json = JsonConvert.SerializeObject(account); - // {"Email":"james@example.com","Active":true,"CreatedDate":"2013-01-20T00:00:00Z","Roles":["User","Admin"]} + string json = JsonConvert.SerializeObject(account); + // {"Email":"james@example.com","Active":true,"CreatedDate":"2013-01-20T00:00:00Z","Roles":["User","Admin"]} - Console.WriteLine(json); - #endregion + Console.WriteLine(json); + #endregion + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeWithJsonConverters.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeWithJsonConverters.cs index 8602b668..71e4b1f7 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeWithJsonConverters.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeWithJsonConverters.cs @@ -6,34 +6,34 @@ using Newtonsoft.Json.Converters; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class SerializeWithJsonConverters - { - public void Example() + public class SerializeWithJsonConverters { - #region Usage - List stringComparisons = new List + public void Example() { - StringComparison.CurrentCulture, - StringComparison.InvariantCulture - }; + #region Usage + List stringComparisons = new List + { + StringComparison.CurrentCulture, + StringComparison.InvariantCulture + }; - string jsonWithoutConverter = JsonConvert.SerializeObject(stringComparisons); + string jsonWithoutConverter = JsonConvert.SerializeObject(stringComparisons); - Console.WriteLine(jsonWithoutConverter); - // [0,2] + Console.WriteLine(jsonWithoutConverter); + // [0,2] - string jsonWithConverter = JsonConvert.SerializeObject(stringComparisons, new StringEnumConverter()); + string jsonWithConverter = JsonConvert.SerializeObject(stringComparisons, new StringEnumConverter()); - Console.WriteLine(jsonWithConverter); - // ["CurrentCulture","InvariantCulture"] + Console.WriteLine(jsonWithConverter); + // ["CurrentCulture","InvariantCulture"] - List newStringComparsions = JsonConvert.DeserializeObject>( - jsonWithConverter, - new StringEnumConverter()); + List newStringComparsions = JsonConvert.DeserializeObject>( + jsonWithConverter, + new StringEnumConverter()); - Console.WriteLine(string.Join(", ", newStringComparsions.Select(c => c.ToString()))); - // CurrentCulture, InvariantCulture - #endregion + Console.WriteLine(string.Join(", ", newStringComparsions.Select(c => c.ToString()))); + // CurrentCulture, InvariantCulture + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeWithJsonSerializerToFile.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeWithJsonSerializerToFile.cs index 41586bbf..b87fec44 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeWithJsonSerializerToFile.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/SerializeWithJsonSerializerToFile.cs @@ -7,35 +7,35 @@ using File = System.IO.File; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class SerializeWithJsonSerializerToFile - { - #region Types - public class Movie + public class SerializeWithJsonSerializerToFile { - public string Name { get; set; } - public int Year { get; set; } - } - #endregion - - public void Example() - { - #region Usage - Movie movie = new Movie + #region Types + public class Movie { - Name = "Bad Boys", - Year = 1995 - }; + public string Name { get; set; } + public int Year { get; set; } + } + #endregion - // serialize JSON to a string and then write string to a file - File.WriteAllText(@"c:\movie.json", JsonConvert.SerializeObject(movie)); + public void Example() + { + #region Usage + Movie movie = new Movie + { + Name = "Bad Boys", + Year = 1995 + }; - // serialize JSON directly to a file - using (StreamWriter file = File.CreateText(@"c:\movie.json")) - { - JsonSerializer serializer = new JsonSerializer(); - serializer.Serialize(file, movie); - } - #endregion + // serialize JSON to a string and then write string to a file + File.WriteAllText(@"c:\movie.json", JsonConvert.SerializeObject(movie)); + + // serialize JSON directly to a file + using (StreamWriter file = File.CreateText(@"c:\movie.json")) + { + JsonSerializer serializer = new JsonSerializer(); + serializer.Serialize(file, movie); + } + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/TraceWriter.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/TraceWriter.cs index 655ec8fb..fb8e9d92 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/TraceWriter.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Serializer/TraceWriter.cs @@ -6,37 +6,37 @@ using Newtonsoft.Json.Serialization; namespace Newtonsoft.Json.Tests.Documentation.Samples.Serializer { - public class TraceWriter - { - #region Types - public class Account + public class TraceWriter { - public string FullName { get; set; } - public bool Deleted { get; set; } - } - #endregion - - public void Example() - { - #region Usage - string json = @"{ - 'FullName': 'Dan Deleted', - 'Deleted': true, - 'DeletedDate': '2013-01-20T00:00:00' - }"; - - MemoryTraceWriter traceWriter = new MemoryTraceWriter(); - - Account account = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + #region Types + public class Account { - TraceWriter = traceWriter - }); + public string FullName { get; set; } + public bool Deleted { get; set; } + } + #endregion - Console.WriteLine(traceWriter.ToString()); - // 2013-01-21T01:36:24.422 Info Started deserializing Newtonsoft.Json.Tests.Documentation.Examples.TraceWriter+Account. Path 'FullName', line 2, position 20. - // 2013-01-21T01:36:24.442 Verbose Could not find member 'DeletedDate' on Newtonsoft.Json.Tests.Documentation.Examples.TraceWriter+Account. Path 'DeletedDate', line 4, position 23. - // 2013-01-21T01:36:24.447 Info Finished deserializing Newtonsoft.Json.Tests.Documentation.Examples.TraceWriter+Account. Path '', line 5, position 8. - #endregion + public void Example() + { + #region Usage + string json = @"{ + 'FullName': 'Dan Deleted', + 'Deleted': true, + 'DeletedDate': '2013-01-20T00:00:00' + }"; + + MemoryTraceWriter traceWriter = new MemoryTraceWriter(); + + Account account = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + TraceWriter = traceWriter + }); + + Console.WriteLine(traceWriter.ToString()); + // 2013-01-21T01:36:24.422 Info Started deserializing Newtonsoft.Json.Tests.Documentation.Examples.TraceWriter+Account. Path 'FullName', line 2, position 20. + // 2013-01-21T01:36:24.442 Verbose Could not find member 'DeletedDate' on Newtonsoft.Json.Tests.Documentation.Examples.TraceWriter+Account. Path 'DeletedDate', line 4, position 23. + // 2013-01-21T01:36:24.447 Info Finished deserializing Newtonsoft.Json.Tests.Documentation.Examples.TraceWriter+Account. Path '', line 5, position 8. + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Xml/ConvertJsonToXml.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Xml/ConvertJsonToXml.cs index 2448209c..918bf7d5 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Xml/ConvertJsonToXml.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Xml/ConvertJsonToXml.cs @@ -6,42 +6,42 @@ using System.Xml.Linq; namespace Newtonsoft.Json.Tests.Documentation.Samples.Xml { - public class ConvertJsonToXml - { - public void Example() + public class ConvertJsonToXml { - #region Usage - string json = @"{ - '@Id': 1, - 'Email': 'james@example.com', - 'Active': true, - 'CreatedDate': '2013-01-20T00:00:00Z', - 'Roles': [ - 'User', - 'Admin' - ], - 'Team': { - '@Id': 2, - 'Name': 'Software Developers', - 'Description': 'Creators of fine software products and services.' + public void Example() + { + #region Usage + string json = @"{ + '@Id': 1, + 'Email': 'james@example.com', + 'Active': true, + 'CreatedDate': '2013-01-20T00:00:00Z', + 'Roles': [ + 'User', + 'Admin' + ], + 'Team': { + '@Id': 2, + 'Name': 'Software Developers', + 'Description': 'Creators of fine software products and services.' + } + }"; + + XNode node = JsonConvert.DeserializeXNode(json, "Root"); + + Console.WriteLine(node.ToString()); + // + // james@example.com + // true + // 2013-01-20T00:00:00Z + // User + // Admin + // + // Software Developers + // Creators of fine software products and services. + // + // + #endregion } - }"; - - XNode node = JsonConvert.DeserializeXNode(json, "Root"); - - Console.WriteLine(node.ToString()); - // - // james@example.com - // true - // 2013-01-20T00:00:00Z - // User - // Admin - // - // Software Developers - // Creators of fine software products and services. - // - // - #endregion } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Xml/ConvertXmlToJson.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Xml/ConvertXmlToJson.cs index 00603dee..54b45459 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Xml/ConvertXmlToJson.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Xml/ConvertXmlToJson.cs @@ -6,50 +6,50 @@ using System.Xml; namespace Newtonsoft.Json.Tests.Documentation.Samples.Xml { - public class ConvertXmlToJson - { - public void Example() + public class ConvertXmlToJson { - #region Usage - string xml = @" - - - Alan - http://www.google.com - - - Louis - http://www.yahoo.com - - "; + public void Example() + { + #region Usage + string xml = @" + + + Alan + http://www.google.com + + + Louis + http://www.yahoo.com + + "; - XmlDocument doc = new XmlDocument(); - doc.LoadXml(xml); + XmlDocument doc = new XmlDocument(); + doc.LoadXml(xml); - string json = JsonConvert.SerializeXmlNode(doc); + string json = JsonConvert.SerializeXmlNode(doc); - Console.WriteLine(json); - // { - // "?xml": { - // "@version": "1.0", - // "@standalone": "no" - // }, - // "root": { - // "person": [ - // { - // "@id": "1", - // "name": "Alan", - // "url": "http://www.google.com" - // }, - // { - // "@id": "2", - // "name": "Louis", - // "url": "http://www.yahoo.com" - // } - // ] - // } - // } - #endregion + Console.WriteLine(json); + // { + // "?xml": { + // "@version": "1.0", + // "@standalone": "no" + // }, + // "root": { + // "person": [ + // { + // "@id": "1", + // "name": "Alan", + // "url": "http://www.google.com" + // }, + // { + // "@id": "2", + // "name": "Louis", + // "url": "http://www.yahoo.com" + // } + // ] + // } + // } + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Xml/ConvertXmlToJsonForceArray.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Xml/ConvertXmlToJsonForceArray.cs index 49c1f755..29a5f6f6 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Xml/ConvertXmlToJsonForceArray.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Xml/ConvertXmlToJsonForceArray.cs @@ -6,55 +6,55 @@ using System.Xml; namespace Newtonsoft.Json.Tests.Documentation.Samples.Xml { - public class ConvertXmlToJsonForceArray - { - public void Example() + public class ConvertXmlToJsonForceArray { - #region Usage - string xml = @" - Alan - http://www.google.com - Admin1 - "; + public void Example() + { + #region Usage + string xml = @" + Alan + http://www.google.com + Admin1 + "; - XmlDocument doc = new XmlDocument(); - doc.LoadXml(xml); + XmlDocument doc = new XmlDocument(); + doc.LoadXml(xml); - string json = JsonConvert.SerializeXmlNode(doc); + string json = JsonConvert.SerializeXmlNode(doc); - Console.WriteLine(json); - // { - // "person": { - // "@id": "1", - // "name": "Alan", - // "url": "http://www.google.com", - // "role": "Admin1" - // } - // } + Console.WriteLine(json); + // { + // "person": { + // "@id": "1", + // "name": "Alan", + // "url": "http://www.google.com", + // "role": "Admin1" + // } + // } - xml = @" - Alan - http://www.google.com - Admin - "; + xml = @" + Alan + http://www.google.com + Admin + "; - doc = new XmlDocument(); - doc.LoadXml(xml); + doc = new XmlDocument(); + doc.LoadXml(xml); - json = JsonConvert.SerializeXmlNode(doc); + json = JsonConvert.SerializeXmlNode(doc); - Console.WriteLine(json); - // { - // "person": { - // "@id": "1", - // "name": "Alan", - // "url": "http://www.google.com", - // "role": [ - // "Admin" - // ] - // } - // } - #endregion + Console.WriteLine(json); + // { + // "person": { + // "@id": "1", + // "name": "Alan", + // "url": "http://www.google.com", + // "role": [ + // "Admin" + // ] + // } + // } + #endregion + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/SerializationTests.cs b/Src/Newtonsoft.Json.Tests/Documentation/SerializationTests.cs index 2b82d61f..31d4f25b 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/SerializationTests.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/SerializationTests.cs @@ -49,177 +49,177 @@ using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs; namespace Newtonsoft.Json.Tests.Documentation { - public class SerializationTests - { - public void SerializeObject() + public class SerializationTests { - #region SerializeObject - Product product = new Product(); + public void SerializeObject() + { + #region SerializeObject + Product product = new Product(); - product.Name = "Apple"; - product.ExpiryDate = new DateTime(2008, 12, 28); - product.Price = 3.99M; - product.Sizes = new string[] { "Small", "Medium", "Large" }; + product.Name = "Apple"; + product.ExpiryDate = new DateTime(2008, 12, 28); + product.Price = 3.99M; + product.Sizes = new string[] { "Small", "Medium", "Large" }; - string output = JsonConvert.SerializeObject(product); - //{ - // "Name": "Apple", - // "ExpiryDate": "2008-12-28T00:00:00", - // "Price": 3.99, - // "Sizes": [ - // "Small", - // "Medium", - // "Large" - // ] - //} + string output = JsonConvert.SerializeObject(product); + //{ + // "Name": "Apple", + // "ExpiryDate": "2008-12-28T00:00:00", + // "Price": 3.99, + // "Sizes": [ + // "Small", + // "Medium", + // "Large" + // ] + //} - Product deserializedProduct = JsonConvert.DeserializeObject(output); - #endregion - } + Product deserializedProduct = JsonConvert.DeserializeObject(output); + #endregion + } - public void JsonSerializerToStream() - { - #region JsonSerializerToStream - Product product = new Product(); - product.ExpiryDate = new DateTime(2008, 12, 28); + public void JsonSerializerToStream() + { + #region JsonSerializerToStream + Product product = new Product(); + product.ExpiryDate = new DateTime(2008, 12, 28); - JsonSerializer serializer = new JsonSerializer(); - serializer.Converters.Add(new JavaScriptDateTimeConverter()); - serializer.NullValueHandling = NullValueHandling.Ignore; + JsonSerializer serializer = new JsonSerializer(); + serializer.Converters.Add(new JavaScriptDateTimeConverter()); + serializer.NullValueHandling = NullValueHandling.Ignore; - using (StreamWriter sw = new StreamWriter(@"c:\json.txt")) - using (JsonWriter writer = new JsonTextWriter(sw)) - { - serializer.Serialize(writer, product); - // {"ExpiryDate":new Date(1230375600000),"Price":0} - } - #endregion - } + using (StreamWriter sw = new StreamWriter(@"c:\json.txt")) + using (JsonWriter writer = new JsonTextWriter(sw)) + { + serializer.Serialize(writer, product); + // {"ExpiryDate":new Date(1230375600000),"Price":0} + } + #endregion + } - #region SerializationAttributes - [JsonObject(MemberSerialization.OptIn)] - public class Person - { - // "John Smith" - [JsonProperty] - public string Name { get; set; } + #region SerializationAttributes + [JsonObject(MemberSerialization.OptIn)] + public class Person + { + // "John Smith" + [JsonProperty] + public string Name { get; set; } - // "2000-12-15T22:11:03" - [JsonProperty] - public DateTime BirthDate { get; set; } + // "2000-12-15T22:11:03" + [JsonProperty] + public DateTime BirthDate { get; set; } - // new Date(976918263055) - [JsonProperty] - [JsonConverter(typeof(JavaScriptDateTimeConverter))] - public DateTime LastModified { get; set; } + // new Date(976918263055) + [JsonProperty] + [JsonConverter(typeof(JavaScriptDateTimeConverter))] + public DateTime LastModified { get; set; } - // not serialized because mode is opt-in - public string Department { get; set; } - } - #endregion + // not serialized because mode is opt-in + public string Department { get; set; } + } + #endregion - #region SerializationCallbacksObject - public class SerializationEventTestObject - { - // 2222 - // This member is serialized and deserialized with no change. - public int Member1 { get; set; } + #region SerializationCallbacksObject + public class SerializationEventTestObject + { + // 2222 + // This member is serialized and deserialized with no change. + public int Member1 { get; set; } - // The value of this field is set and reset during and - // after serialization. - public string Member2 { get; set; } + // The value of this field is set and reset during and + // after serialization. + public string Member2 { get; set; } - // This field is not serialized. The OnDeserializedAttribute - // is used to set the member value after serialization. - [JsonIgnore] - public string Member3 { get; set; } + // This field is not serialized. The OnDeserializedAttribute + // is used to set the member value after serialization. + [JsonIgnore] + public string Member3 { get; set; } - // This field is set to null, but populated after deserialization. - public string Member4 { get; set; } + // This field is set to null, but populated after deserialization. + public string Member4 { get; set; } - public SerializationEventTestObject() - { - Member1 = 11; - Member2 = "Hello World!"; - Member3 = "This is a nonserialized value"; - Member4 = null; - } + public SerializationEventTestObject() + { + Member1 = 11; + Member2 = "Hello World!"; + Member3 = "This is a nonserialized value"; + Member4 = null; + } - [OnSerializing] - internal void OnSerializingMethod(StreamingContext context) - { - Member2 = "This value went into the data file during serialization."; - } + [OnSerializing] + internal void OnSerializingMethod(StreamingContext context) + { + Member2 = "This value went into the data file during serialization."; + } - [OnSerialized] - internal void OnSerializedMethod(StreamingContext context) - { - Member2 = "This value was reset after serialization."; - } + [OnSerialized] + internal void OnSerializedMethod(StreamingContext context) + { + Member2 = "This value was reset after serialization."; + } - [OnDeserializing] - internal void OnDeserializingMethod(StreamingContext context) - { - Member3 = "This value was set during deserialization"; - } + [OnDeserializing] + internal void OnDeserializingMethod(StreamingContext context) + { + Member3 = "This value was set during deserialization"; + } - [OnDeserialized] - internal void OnDeserializedMethod(StreamingContext context) - { - Member4 = "This value was set after deserialization."; - } - } - #endregion + [OnDeserialized] + internal void OnDeserializedMethod(StreamingContext context) + { + Member4 = "This value was set after deserialization."; + } + } + #endregion - public void SerializationCallbacksExample() - { - #region SerializationCallbacksExample - SerializationEventTestObject obj = new SerializationEventTestObject(); + public void SerializationCallbacksExample() + { + #region SerializationCallbacksExample + SerializationEventTestObject obj = new SerializationEventTestObject(); - Console.WriteLine(obj.Member1); - // 11 - Console.WriteLine(obj.Member2); - // Hello World! - Console.WriteLine(obj.Member3); - // This is a nonserialized value - Console.WriteLine(obj.Member4); - // null + Console.WriteLine(obj.Member1); + // 11 + Console.WriteLine(obj.Member2); + // Hello World! + Console.WriteLine(obj.Member3); + // This is a nonserialized value + Console.WriteLine(obj.Member4); + // null - string json = JsonConvert.SerializeObject(obj, Formatting.Indented); - // { - // "Member1": 11, - // "Member2": "This value went into the data file during serialization.", - // "Member4": null - // } + string json = JsonConvert.SerializeObject(obj, Formatting.Indented); + // { + // "Member1": 11, + // "Member2": "This value went into the data file during serialization.", + // "Member4": null + // } - Console.WriteLine(obj.Member1); - // 11 - Console.WriteLine(obj.Member2); - // This value was reset after serialization. - Console.WriteLine(obj.Member3); - // This is a nonserialized value - Console.WriteLine(obj.Member4); - // null + Console.WriteLine(obj.Member1); + // 11 + Console.WriteLine(obj.Member2); + // This value was reset after serialization. + Console.WriteLine(obj.Member3); + // This is a nonserialized value + Console.WriteLine(obj.Member4); + // null - obj = JsonConvert.DeserializeObject(json); + obj = JsonConvert.DeserializeObject(json); - Console.WriteLine(obj.Member1); - // 11 - Console.WriteLine(obj.Member2); - // This value went into the data file during serialization. - Console.WriteLine(obj.Member3); - // This value was set during deserialization - Console.WriteLine(obj.Member4); - // This value was set after deserialization. - #endregion - } + Console.WriteLine(obj.Member1); + // 11 + Console.WriteLine(obj.Member2); + // This value went into the data file during serialization. + Console.WriteLine(obj.Member3); + // This value was set during deserialization + Console.WriteLine(obj.Member4); + // This value was set after deserialization. + #endregion + } - public void SerializationErrorHandling() - { - #region SerializationErrorHandling - List errors = new List(); + public void SerializationErrorHandling() + { + #region SerializationErrorHandling + List errors = new List(); - List c = JsonConvert.DeserializeObject>(@"[ + List c = JsonConvert.DeserializeObject>(@"[ '2009-09-09T00:00:00Z', 'I am not a date and will error!', [ @@ -229,308 +229,310 @@ namespace Newtonsoft.Json.Tests.Documentation null, '2000-12-01T00:00:00Z' ]", - new JsonSerializerSettings - { - Error = delegate(object sender, ErrorEventArgs args) - { - errors.Add(args.ErrorContext.Error.Message); - args.ErrorContext.Handled = true; - }, - Converters = { new IsoDateTimeConverter() } - }); + new JsonSerializerSettings + { + Error = delegate(object sender, ErrorEventArgs args) + { + errors.Add(args.ErrorContext.Error.Message); + args.ErrorContext.Handled = true; + }, + Converters = { new IsoDateTimeConverter() } + }); - // 2009-09-09T00:00:00Z - // 1977-02-20T00:00:00Z - // 2000-12-01T00:00:00Z + // 2009-09-09T00:00:00Z + // 1977-02-20T00:00:00Z + // 2000-12-01T00:00:00Z - // The string was not recognized as a valid DateTime. There is a unknown word starting at index 0. - // Unexpected token parsing date. Expected String, got StartArray. - // Cannot convert null value to System.DateTime. - #endregion - } - - public void SerializationErrorHandlingWithParent() - { - #region SerializationErrorHandlingWithParent - List errors = new List(); - - JsonSerializer serializer = new JsonSerializer(); - serializer.Error += delegate(object sender, ErrorEventArgs args) - { - // only log an error once - if (args.CurrentObject == args.ErrorContext.OriginalObject) - errors.Add(args.ErrorContext.Error.Message); - }; - #endregion - } - - #region SerializationErrorHandlingAttributeObject - public class PersonError - { - private List _roles; - - public string Name { get; set; } - public int Age { get; set; } - public List Roles - { - get - { - if (_roles == null) - throw new Exception("Roles not loaded!"); - - return _roles; + // The string was not recognized as a valid DateTime. There is a unknown word starting at index 0. + // Unexpected token parsing date. Expected String, got StartArray. + // Cannot convert null value to System.DateTime. + #endregion } - set { _roles = value; } - } - public string Title { get; set; } - [OnError] - internal void OnError(StreamingContext context, ErrorContext errorContext) - { - errorContext.Handled = true; - } - } - #endregion + public void SerializationErrorHandlingWithParent() + { + #region SerializationErrorHandlingWithParent + List errors = new List(); - public void SerializationErrorHandlingAttributeExample() - { - #region SerializationErrorHandlingAttributeExample - PersonError person = new PersonError - { - Name = "George Michael Bluth", - Age = 16, - Roles = null, - Title = "Mister Manager" - }; + JsonSerializer serializer = new JsonSerializer(); + serializer.Error += delegate(object sender, ErrorEventArgs args) + { + // only log an error once + if (args.CurrentObject == args.ErrorContext.OriginalObject) + errors.Add(args.ErrorContext.Error.Message); + }; + #endregion + } - string json = JsonConvert.SerializeObject(person, Formatting.Indented); + #region SerializationErrorHandlingAttributeObject + public class PersonError + { + private List _roles; - Console.WriteLine(json); - //{ - // "Name": "George Michael Bluth", - // "Age": 16, - // "Title": "Mister Manager" - //} - #endregion - } + public string Name { get; set; } + public int Age { get; set; } - public void PreservingObjectReferencesOff() - { - #region PreservingObjectReferencesOff - Person p = new Person - { - BirthDate = new DateTime(1980, 12, 23, 0, 0, 0, DateTimeKind.Utc), - LastModified = new DateTime(2009, 2, 20, 12, 59, 21, DateTimeKind.Utc), - Name = "James" - }; + public List Roles + { + get + { + if (_roles == null) + throw new Exception("Roles not loaded!"); - List people = new List(); - people.Add(p); - people.Add(p); + return _roles; + } + set { _roles = value; } + } - string json = JsonConvert.SerializeObject(people, Formatting.Indented); - //[ - // { - // "Name": "James", - // "BirthDate": "1980-12-23T00:00:00Z", - // "LastModified": "2009-02-20T12:59:21Z" - // }, - // { - // "Name": "James", - // "BirthDate": "1980-12-23T00:00:00Z", - // "LastModified": "2009-02-20T12:59:21Z" - // } - //] - #endregion - } + public string Title { get; set; } - public void PreservingObjectReferencesOn() - { - List people = new List(); + [OnError] + internal void OnError(StreamingContext context, ErrorContext errorContext) + { + errorContext.Handled = true; + } + } + #endregion - #region PreservingObjectReferencesOn - string json = JsonConvert.SerializeObject(people, Formatting.Indented, - new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects }); + public void SerializationErrorHandlingAttributeExample() + { + #region SerializationErrorHandlingAttributeExample + PersonError person = new PersonError + { + Name = "George Michael Bluth", + Age = 16, + Roles = null, + Title = "Mister Manager" + }; - //[ - // { - // "$id": "1", - // "Name": "James", - // "BirthDate": "1983-03-08T00:00Z", - // "LastModified": "2012-03-21T05:40Z" - // }, - // { - // "$ref": "1" - // } - //] + string json = JsonConvert.SerializeObject(person, Formatting.Indented); - List deserializedPeople = JsonConvert.DeserializeObject>(json, - new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects }); + Console.WriteLine(json); + //{ + // "Name": "George Michael Bluth", + // "Age": 16, + // "Title": "Mister Manager" + //} + #endregion + } - Console.WriteLine(deserializedPeople.Count); - // 2 + public void PreservingObjectReferencesOff() + { + #region PreservingObjectReferencesOff + Person p = new Person + { + BirthDate = new DateTime(1980, 12, 23, 0, 0, 0, DateTimeKind.Utc), + LastModified = new DateTime(2009, 2, 20, 12, 59, 21, DateTimeKind.Utc), + Name = "James" + }; - Person p1 = deserializedPeople[0]; - Person p2 = deserializedPeople[1]; + List people = new List(); + people.Add(p); + people.Add(p); - Console.WriteLine(p1.Name); - // James - Console.WriteLine(p2.Name); - // James + string json = JsonConvert.SerializeObject(people, Formatting.Indented); + //[ + // { + // "Name": "James", + // "BirthDate": "1980-12-23T00:00:00Z", + // "LastModified": "2009-02-20T12:59:21Z" + // }, + // { + // "Name": "James", + // "BirthDate": "1980-12-23T00:00:00Z", + // "LastModified": "2009-02-20T12:59:21Z" + // } + //] + #endregion + } - bool equal = Object.ReferenceEquals(p1, p2); - // true - #endregion - } + public void PreservingObjectReferencesOn() + { + List people = new List(); - #region PreservingObjectReferencesAttribute - [JsonObject(IsReference = true)] - public class EmployeeReference - { - public string Name { get; set; } - public EmployeeReference Manager { get; set; } - } - #endregion + #region PreservingObjectReferencesOn + string json = JsonConvert.SerializeObject(people, Formatting.Indented, + new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects }); - #region CustomCreationConverterObject - public interface IPerson - { - string FirstName { get; set; } - string LastName { get; set; } - DateTime BirthDate { get; set; } - } + //[ + // { + // "$id": "1", + // "Name": "James", + // "BirthDate": "1983-03-08T00:00Z", + // "LastModified": "2012-03-21T05:40Z" + // }, + // { + // "$ref": "1" + // } + //] - public class Employee : IPerson - { - public string FirstName { get; set; } - public string LastName { get; set; } - public DateTime BirthDate { get; set; } + List deserializedPeople = JsonConvert.DeserializeObject>(json, + new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects }); - public string Department { get; set; } - public string JobTitle { get; set; } - } + Console.WriteLine(deserializedPeople.Count); + // 2 - public class PersonConverter : CustomCreationConverter - { - public override IPerson Create(Type objectType) - { - return new Employee(); - } - } - #endregion + Person p1 = deserializedPeople[0]; + Person p2 = deserializedPeople[1]; - public void CustomCreationConverterExample() - { - string json = null; + Console.WriteLine(p1.Name); + // James + Console.WriteLine(p2.Name); + // James - #region CustomCreationConverterExample - //[ - // { - // "FirstName": "Maurice", - // "LastName": "Moss", - // "BirthDate": "1981-03-08T00:00Z", - // "Department": "IT", - // "JobTitle": "Support" - // }, - // { - // "FirstName": "Jen", - // "LastName": "Barber", - // "BirthDate": "1985-12-10T00:00Z", - // "Department": "IT", - // "JobTitle": "Manager" - // } - //] + bool equal = Object.ReferenceEquals(p1, p2); + // true + #endregion + } - List people = JsonConvert.DeserializeObject>(json, new PersonConverter()); + #region PreservingObjectReferencesAttribute + [JsonObject(IsReference = true)] + public class EmployeeReference + { + public string Name { get; set; } + public EmployeeReference Manager { get; set; } + } + #endregion - IPerson person = people[0]; + #region CustomCreationConverterObject + public interface IPerson + { + string FirstName { get; set; } + string LastName { get; set; } + DateTime BirthDate { get; set; } + } - Console.WriteLine(person.GetType()); - // Newtonsoft.Json.Tests.Employee + public class Employee : IPerson + { + public string FirstName { get; set; } + public string LastName { get; set; } + public DateTime BirthDate { get; set; } - Console.WriteLine(person.FirstName); - // Maurice + public string Department { get; set; } + public string JobTitle { get; set; } + } - Employee employee = (Employee)person; + public class PersonConverter : CustomCreationConverter + { + public override IPerson Create(Type objectType) + { + return new Employee(); + } + } + #endregion - Console.WriteLine(employee.JobTitle); - // Support - #endregion - } + public void CustomCreationConverterExample() + { + string json = null; - public void ContractResolver() - { - #region ContractResolver - Product product = new Product - { - ExpiryDate = new DateTime(2010, 12, 20, 18, 1, 0, DateTimeKind.Utc), - Name = "Widget", - Price = 9.99m, - Sizes = new[] { "Small", "Medium", "Large" } - }; + #region CustomCreationConverterExample + //[ + // { + // "FirstName": "Maurice", + // "LastName": "Moss", + // "BirthDate": "1981-03-08T00:00Z", + // "Department": "IT", + // "JobTitle": "Support" + // }, + // { + // "FirstName": "Jen", + // "LastName": "Barber", + // "BirthDate": "1985-12-10T00:00Z", + // "Department": "IT", + // "JobTitle": "Manager" + // } + //] - string json = - JsonConvert.SerializeObject( - product, - Formatting.Indented, - new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() } - ); + List people = JsonConvert.DeserializeObject>(json, new PersonConverter()); - //{ - // "name": "Widget", - // "expiryDate": "2010-12-20T18:01Z", - // "price": 9.99, - // "sizes": [ - // "Small", - // "Medium", - // "Large" - // ] - //} - #endregion - } + IPerson person = people[0]; - public void SerializingCollectionsSerializing() - { - #region SerializingCollectionsSerializing - Product p1 = new Product - { - Name = "Product 1", - Price = 99.95m, - ExpiryDate = new DateTime(2000, 12, 29, 0, 0, 0, DateTimeKind.Utc), - }; - Product p2 = new Product - { - Name = "Product 2", - Price = 12.50m, - ExpiryDate = new DateTime(2009, 7, 31, 0, 0, 0, DateTimeKind.Utc), - }; + Console.WriteLine(person.GetType()); + // Newtonsoft.Json.Tests.Employee - List products = new List(); - products.Add(p1); - products.Add(p2); + Console.WriteLine(person.FirstName); + // Maurice - string json = JsonConvert.SerializeObject(products, Formatting.Indented); - //[ - // { - // "Name": "Product 1", - // "ExpiryDate": "2000-12-29T00:00Z", - // "Price": 99.95, - // "Sizes": null - // }, - // { - // "Name": "Product 2", - // "ExpiryDate": "2009-07-31T00:00Z", - // "Price": 12.50, - // "Sizes": null - // } - //] - #endregion - } + Employee employee = (Employee)person; - public void SerializingCollectionsDeserializing() - { - #region SerializingCollectionsDeserializing - string json = @"[ + Console.WriteLine(employee.JobTitle); + // Support + #endregion + } + + public void ContractResolver() + { + #region ContractResolver + Product product = new Product + { + ExpiryDate = new DateTime(2010, 12, 20, 18, 1, 0, DateTimeKind.Utc), + Name = "Widget", + Price = 9.99m, + Sizes = new[] { "Small", "Medium", "Large" } + }; + + string json = + JsonConvert.SerializeObject( + product, + Formatting.Indented, + new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() } + ); + + //{ + // "name": "Widget", + // "expiryDate": "2010-12-20T18:01Z", + // "price": 9.99, + // "sizes": [ + // "Small", + // "Medium", + // "Large" + // ] + //} + #endregion + } + + public void SerializingCollectionsSerializing() + { + #region SerializingCollectionsSerializing + Product p1 = new Product + { + Name = "Product 1", + Price = 99.95m, + ExpiryDate = new DateTime(2000, 12, 29, 0, 0, 0, DateTimeKind.Utc), + }; + Product p2 = new Product + { + Name = "Product 2", + Price = 12.50m, + ExpiryDate = new DateTime(2009, 7, 31, 0, 0, 0, DateTimeKind.Utc), + }; + + List products = new List(); + products.Add(p1); + products.Add(p2); + + string json = JsonConvert.SerializeObject(products, Formatting.Indented); + //[ + // { + // "Name": "Product 1", + // "ExpiryDate": "2000-12-29T00:00Z", + // "Price": 99.95, + // "Sizes": null + // }, + // { + // "Name": "Product 2", + // "ExpiryDate": "2009-07-31T00:00Z", + // "Price": 12.50, + // "Sizes": null + // } + //] + #endregion + } + + public void SerializingCollectionsDeserializing() + { + #region SerializingCollectionsDeserializing + string json = @"[ { 'Name': 'Product 1', 'ExpiryDate': '2000-12-29T00:00Z', @@ -545,270 +547,273 @@ namespace Newtonsoft.Json.Tests.Documentation } ]"; - List products = JsonConvert.DeserializeObject>(json); + List products = JsonConvert.DeserializeObject>(json); - Console.WriteLine(products.Count); - // 2 - - Product p1 = products[0]; - - Console.WriteLine(p1.Name); - // Product 1 - #endregion - } + Console.WriteLine(products.Count); + // 2 - public void SerializingCollectionsDeserializingDictionaries() - { - #region SerializingCollectionsDeserializingDictionaries - string json = @"{""key1"":""value1"",""key2"":""value2""}"; + Product p1 = products[0]; - Dictionary values = JsonConvert.DeserializeObject>(json); + Console.WriteLine(p1.Name); + // Product 1 + #endregion + } - Console.WriteLine(values.Count); - // 2 + public void SerializingCollectionsDeserializingDictionaries() + { + #region SerializingCollectionsDeserializingDictionaries + string json = @"{""key1"":""value1"",""key2"":""value2""}"; - Console.WriteLine(values["key1"]); - // value1 - #endregion - } + Dictionary values = JsonConvert.DeserializeObject>(json); - #region SerializingDatesInJson - public class LogEntry - { - public string Details { get; set; } - public DateTime LogDate { get; set; } - } + Console.WriteLine(values.Count); + // 2 - public void WriteJsonDates() - { - LogEntry entry = new LogEntry - { - LogDate = new DateTime(2009, 2, 15, 0, 0, 0, DateTimeKind.Utc), - Details = "Application started." - }; + Console.WriteLine(values["key1"]); + // value1 + #endregion + } - // default as of Json.NET 4.5 - string isoJson = JsonConvert.SerializeObject(entry); - // {"Details":"Application started.","LogDate":"2009-02-15T00:00:00Z"} + #region SerializingDatesInJson + public class LogEntry + { + public string Details { get; set; } + public DateTime LogDate { get; set; } + } - JsonSerializerSettings microsoftDateFormatSettings = new JsonSerializerSettings - { - DateFormatHandling = DateFormatHandling.MicrosoftDateFormat - }; - string microsoftJson = JsonConvert.SerializeObject(entry, microsoftDateFormatSettings); - // {"Details":"Application started.","LogDate":"\/Date(1234656000000)\/"} + public void WriteJsonDates() + { + LogEntry entry = new LogEntry + { + LogDate = new DateTime(2009, 2, 15, 0, 0, 0, DateTimeKind.Utc), + Details = "Application started." + }; - string javascriptJson = JsonConvert.SerializeObject(entry, new JavaScriptDateTimeConverter()); - // {"Details":"Application started.","LogDate":new Date(1234656000000)} - } - #endregion + // default as of Json.NET 4.5 + string isoJson = JsonConvert.SerializeObject(entry); + // {"Details":"Application started.","LogDate":"2009-02-15T00:00:00Z"} - #region ReducingSerializedJsonSizeOptOut - public class Car - { - // included in JSON - public string Model { get; set; } - public DateTime Year { get; set; } - public List Features { get; set; } + JsonSerializerSettings microsoftDateFormatSettings = new JsonSerializerSettings + { + DateFormatHandling = DateFormatHandling.MicrosoftDateFormat + }; + string microsoftJson = JsonConvert.SerializeObject(entry, microsoftDateFormatSettings); + // {"Details":"Application started.","LogDate":"\/Date(1234656000000)\/"} - // ignored - [JsonIgnore] - public DateTime LastModified { get; set; } - } - #endregion + string javascriptJson = JsonConvert.SerializeObject(entry, new JavaScriptDateTimeConverter()); + // {"Details":"Application started.","LogDate":new Date(1234656000000)} + } + #endregion - #region ReducingSerializedJsonSizeOptIn - [DataContract] - public class Computer - { - // included in JSON - [DataMember] - public string Name { get; set; } - [DataMember] - public decimal SalePrice { get; set; } + #region ReducingSerializedJsonSizeOptOut + public class Car + { + // included in JSON + public string Model { get; set; } + public DateTime Year { get; set; } + public List Features { get; set; } - // ignored - public string Manufacture { get; set; } - public int StockCount { get; set; } - public decimal WholeSalePrice { get; set; } - public DateTime NextShipmentDate { get; set; } - } - #endregion + // ignored + [JsonIgnore] + public DateTime LastModified { get; set; } + } + #endregion - #region ReducingSerializedJsonSizeNullValueHandlingObject - public class Movie - { - public string Name { get; set; } - public string Description { get; set; } - public string Classification { get; set; } - public string Studio { get; set; } - public DateTime? ReleaseDate { get; set; } - public List ReleaseCountries { get; set; } - } - #endregion + #region ReducingSerializedJsonSizeOptIn + [DataContract] + public class Computer + { + // included in JSON + [DataMember] + public string Name { get; set; } - public void ReducingSerializedJsonSizeNullValueHandlingExample() - { - #region ReducingSerializedJsonSizeNullValueHandlingExample - Movie movie = new Movie(); - movie.Name = "Bad Boys III"; - movie.Description = "It's no Bad Boys"; + [DataMember] + public decimal SalePrice { get; set; } - string included = JsonConvert.SerializeObject(movie, - Formatting.Indented, - new JsonSerializerSettings { }); + // ignored + public string Manufacture { get; set; } + public int StockCount { get; set; } + public decimal WholeSalePrice { get; set; } + public DateTime NextShipmentDate { get; set; } + } + #endregion - // { - // "Name": "Bad Boys III", - // "Description": "It's no Bad Boys", - // "Classification": null, - // "Studio": null, - // "ReleaseDate": null, - // "ReleaseCountries": null - // } + #region ReducingSerializedJsonSizeNullValueHandlingObject + public class Movie + { + public string Name { get; set; } + public string Description { get; set; } + public string Classification { get; set; } + public string Studio { get; set; } + public DateTime? ReleaseDate { get; set; } + public List ReleaseCountries { get; set; } + } + #endregion - string ignored = JsonConvert.SerializeObject(movie, - Formatting.Indented, - new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + public void ReducingSerializedJsonSizeNullValueHandlingExample() + { + #region ReducingSerializedJsonSizeNullValueHandlingExample + Movie movie = new Movie(); + movie.Name = "Bad Boys III"; + movie.Description = "It's no Bad Boys"; - // { - // "Name": "Bad Boys III", - // "Description": "It's no Bad Boys" - // } - #endregion - } + string included = JsonConvert.SerializeObject(movie, + Formatting.Indented, + new JsonSerializerSettings { }); - #region ReducingSerializedJsonSizeDefaultValueHandlingObject - public class Invoice - { - public string Company { get; set; } - public decimal Amount { get; set; } + // { + // "Name": "Bad Boys III", + // "Description": "It's no Bad Boys", + // "Classification": null, + // "Studio": null, + // "ReleaseDate": null, + // "ReleaseCountries": null + // } - // false is default value of bool - public bool Paid { get; set; } - // null is default value of nullable - public DateTime? PaidDate { get; set; } + string ignored = JsonConvert.SerializeObject(movie, + Formatting.Indented, + new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); - // customize default values - [DefaultValue(30)] - public int FollowUpDays { get; set; } - [DefaultValue("")] - public string FollowUpEmailAddress { get; set; } - } - #endregion + // { + // "Name": "Bad Boys III", + // "Description": "It's no Bad Boys" + // } + #endregion + } - public void ReducingSerializedJsonSizeDefaultValueHandlingExample() - { - #region ReducingSerializedJsonSizeDefaultValueHandlingExample - Invoice invoice = new Invoice - { - Company = "Acme Ltd.", - Amount = 50.0m, - Paid = false, - FollowUpDays = 30, - FollowUpEmailAddress = string.Empty, - PaidDate = null - }; + #region ReducingSerializedJsonSizeDefaultValueHandlingObject + public class Invoice + { + public string Company { get; set; } + public decimal Amount { get; set; } - string included = JsonConvert.SerializeObject(invoice, - Formatting.Indented, - new JsonSerializerSettings { }); + // false is default value of bool + public bool Paid { get; set; } + // null is default value of nullable + public DateTime? PaidDate { get; set; } - // { - // "Company": "Acme Ltd.", - // "Amount": 50.0, - // "Paid": false, - // "PaidDate": null, - // "FollowUpDays": 30, - // "FollowUpEmailAddress": "" - // } + // customize default values + [DefaultValue(30)] + public int FollowUpDays { get; set; } - string ignored = JsonConvert.SerializeObject(invoice, - Formatting.Indented, - new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore }); + [DefaultValue("")] + public string FollowUpEmailAddress { get; set; } + } + #endregion - // { - // "Company": "Acme Ltd.", - // "Amount": 50.0 - // } - #endregion - } + public void ReducingSerializedJsonSizeDefaultValueHandlingExample() + { + #region ReducingSerializedJsonSizeDefaultValueHandlingExample + Invoice invoice = new Invoice + { + Company = "Acme Ltd.", + Amount = 50.0m, + Paid = false, + FollowUpDays = 30, + FollowUpEmailAddress = string.Empty, + PaidDate = null + }; - #region ReducingSerializedJsonSizeContractResolverObject - public class DynamicContractResolver : DefaultContractResolver - { - private readonly char _startingWithChar; - public DynamicContractResolver(char startingWithChar) - { - _startingWithChar = startingWithChar; - } + string included = JsonConvert.SerializeObject(invoice, + Formatting.Indented, + new JsonSerializerSettings { }); - protected override IList CreateProperties(Type type, MemberSerialization memberSerialization) - { - IList properties = base.CreateProperties(type, memberSerialization); + // { + // "Company": "Acme Ltd.", + // "Amount": 50.0, + // "Paid": false, + // "PaidDate": null, + // "FollowUpDays": 30, + // "FollowUpEmailAddress": "" + // } - // only serializer properties that start with the specified character - properties = - properties.Where(p => p.PropertyName.StartsWith(_startingWithChar.ToString())).ToList(); + string ignored = JsonConvert.SerializeObject(invoice, + Formatting.Indented, + new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore }); - return properties; - } - } + // { + // "Company": "Acme Ltd.", + // "Amount": 50.0 + // } + #endregion + } - public class Book - { - public string BookName { get; set; } - public decimal BookPrice { get; set; } - public string AuthorName { get; set; } - public int AuthorAge { get; set; } - public string AuthorCountry { get; set; } - } - #endregion + #region ReducingSerializedJsonSizeContractResolverObject + public class DynamicContractResolver : DefaultContractResolver + { + private readonly char _startingWithChar; - public void ReducingSerializedJsonSizeContractResolverExample() - { - #region ReducingSerializedJsonSizeContractResolverExample - Book book = new Book - { - BookName = "The Gathering Storm", - BookPrice = 16.19m, - AuthorName = "Brandon Sanderson", - AuthorAge = 34, - AuthorCountry = "United States of America" - }; + public DynamicContractResolver(char startingWithChar) + { + _startingWithChar = startingWithChar; + } - string startingWithA = JsonConvert.SerializeObject(book, Formatting.Indented, - new JsonSerializerSettings { ContractResolver = new DynamicContractResolver('A') }); + protected override IList CreateProperties(Type type, MemberSerialization memberSerialization) + { + IList properties = base.CreateProperties(type, memberSerialization); - // { - // "AuthorName": "Brandon Sanderson", - // "AuthorAge": 34, - // "AuthorCountry": "United States of America" - // } + // only serializer properties that start with the specified character + properties = + properties.Where(p => p.PropertyName.StartsWith(_startingWithChar.ToString())).ToList(); - string startingWithB = JsonConvert.SerializeObject(book, Formatting.Indented, - new JsonSerializerSettings { ContractResolver = new DynamicContractResolver('B') }); + return properties; + } + } - // { - // "BookName": "The Gathering Storm", - // "BookPrice": 16.19 - // } - #endregion - } + public class Book + { + public string BookName { get; set; } + public decimal BookPrice { get; set; } + public string AuthorName { get; set; } + public int AuthorAge { get; set; } + public string AuthorCountry { get; set; } + } + #endregion - #region SerializingPartialJsonFragmentsObject - public class SearchResult - { - public string Title { get; set; } - public string Content { get; set; } - public string Url { get; set; } - } - #endregion + public void ReducingSerializedJsonSizeContractResolverExample() + { + #region ReducingSerializedJsonSizeContractResolverExample + Book book = new Book + { + BookName = "The Gathering Storm", + BookPrice = 16.19m, + AuthorName = "Brandon Sanderson", + AuthorAge = 34, + AuthorCountry = "United States of America" + }; - public void SerializingPartialJsonFragmentsExample() - { - #region SerializingPartialJsonFragmentsExample - string googleSearchText = @"{ + string startingWithA = JsonConvert.SerializeObject(book, Formatting.Indented, + new JsonSerializerSettings { ContractResolver = new DynamicContractResolver('A') }); + + // { + // "AuthorName": "Brandon Sanderson", + // "AuthorAge": 34, + // "AuthorCountry": "United States of America" + // } + + string startingWithB = JsonConvert.SerializeObject(book, Formatting.Indented, + new JsonSerializerSettings { ContractResolver = new DynamicContractResolver('B') }); + + // { + // "BookName": "The Gathering Storm", + // "BookPrice": 16.19 + // } + #endregion + } + + #region SerializingPartialJsonFragmentsObject + public class SearchResult + { + public string Title { get; set; } + public string Content { get; set; } + public string Url { get; set; } + } + #endregion + + public void SerializingPartialJsonFragmentsExample() + { + #region SerializingPartialJsonFragmentsExample + string googleSearchText = @"{ 'responseData': { 'results': [ { @@ -860,52 +865,53 @@ namespace Newtonsoft.Json.Tests.Documentation 'responseStatus': 200 }"; - JObject googleSearch = JObject.Parse(googleSearchText); + JObject googleSearch = JObject.Parse(googleSearchText); - // get JSON result objects into a list - IList results = googleSearch["responseData"]["results"].Children().ToList(); + // get JSON result objects into a list + IList results = googleSearch["responseData"]["results"].Children().ToList(); - // serialize JSON results into .NET objects - IList searchResults = new List(); - foreach (JToken result in results) - { - SearchResult searchResult = JsonConvert.DeserializeObject(result.ToString()); - searchResults.Add(searchResult); - } + // serialize JSON results into .NET objects + IList searchResults = new List(); + foreach (JToken result in results) + { + SearchResult searchResult = JsonConvert.DeserializeObject(result.ToString()); + searchResults.Add(searchResult); + } - // Title = Paris Hilton - Wikipedia, the free encyclopedia - // Content = [1] In 2006, she released her debut album... - // Url = http://en.wikipedia.org/wiki/Paris_Hilton + // Title = Paris Hilton - Wikipedia, the free encyclopedia + // Content = [1] In 2006, she released her debut album... + // Url = http://en.wikipedia.org/wiki/Paris_Hilton - // Title = Paris Hilton - // Content = Self: Zoolander. Socialite Paris Hilton... - // Url = http://www.imdb.com/name/nm0385296/ - #endregion - } + // Title = Paris Hilton + // Content = Self: Zoolander. Socialite Paris Hilton... + // Url = http://www.imdb.com/name/nm0385296/ + #endregion + } - public void SerializeMultidimensionalArrayExample() - { - string[,] famousCouples = new string[,] + public void SerializeMultidimensionalArrayExample() { - {"Adam", "Eve"}, - {"Bonnie", "Clyde"}, - {"Donald", "Daisy"}, - {"Han", "Leia"} - }; + string[,] famousCouples = new string[,] + { + { "Adam", "Eve" }, + { "Bonnie", "Clyde" }, + { "Donald", "Daisy" }, + { "Han", "Leia" } + }; - string json = JsonConvert.SerializeObject(famousCouples, Formatting.Indented); - // [ - // ["Adam", "Eve"], - // ["Bonnie", "Clyde"], - // ["Donald", "Daisy"], - // ["Han", "Leia"] - // ] + string json = JsonConvert.SerializeObject(famousCouples, Formatting.Indented); + // [ + // ["Adam", "Eve"], + // ["Bonnie", "Clyde"], + // ["Donald", "Daisy"], + // ["Han", "Leia"] + // ] - string[,] deserialized = JsonConvert.DeserializeObject(json); + string[,] deserialized = JsonConvert.DeserializeObject(json); - Console.WriteLine(deserialized[3, 0] + ", " + deserialized[3, 1]); - // Han, Leia + Console.WriteLine(deserialized[3, 0] + ", " + deserialized[3, 1]); + // Han, Leia + } } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/TraceWriterTests.cs b/Src/Newtonsoft.Json.Tests/Documentation/TraceWriterTests.cs index d12570ad..b4d7d614 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/TraceWriterTests.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/TraceWriterTests.cs @@ -53,122 +53,123 @@ using System.Globalization; namespace Newtonsoft.Json.Tests.Documentation { - 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 class LogEventInfo { + public LogLevel Level; + public string Message; + public Exception Exception; } - } - public static class LogManager - { - public static Logger GetLogger(string className) + public class LogLevel { - return new Logger(); + public static LogLevel Info; + public static LogLevel Trace; + public static LogLevel Error; + public static LogLevel Warn; + public static LogLevel Off; } - } - - [TestFixture] - public class TraceWriterTests : TestFixtureBase - { - #region CustomTraceWriterExample - public class NLogTraceWriter : ITraceWriter + + public class Logger { - private static readonly Logger Logger = LogManager.GetLogger("NLogTraceWriter"); - - public TraceLevel LevelFilter - { - // trace all messages. nlog can handle filtering - get { return TraceLevel.Verbose; } - } - - public void Trace(TraceLevel level, string message, Exception ex) - { - LogEventInfo logEvent = new LogEventInfo + public void Log(LogEventInfo logEvent) { - Message = message, - Level = GetLogLevel(level), - Exception = ex - }; - - // log Json.NET message to NLog - Logger.Log(logEvent); - } - - 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; } - } } - #endregion - [Test] - public void MemoryTraceWriterTest() + public static class LogManager { - #region MemoryTraceWriterExample - 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.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 ''. - // 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(916, memoryTraceWriter.ToString().Length); - Assert.AreEqual(7, memoryTraceWriter.GetTraceMessages().Count()); + public static Logger GetLogger(string className) + { + return new Logger(); + } + } + + [TestFixture] + public class TraceWriterTests : TestFixtureBase + { + #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; } + } + + public void Trace(TraceLevel level, string message, Exception ex) + { + LogEventInfo logEvent = new LogEventInfo + { + Message = message, + Level = GetLogLevel(level), + Exception = ex + }; + + // log Json.NET message to NLog + Logger.Log(logEvent); + } + + 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; + } + } + } + #endregion + + [Test] + public void MemoryTraceWriterTest() + { + #region MemoryTraceWriterExample + 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.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 ''. + // 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(916, memoryTraceWriter.ToString().Length); + Assert.AreEqual(7, memoryTraceWriter.GetTraceMessages().Count()); + } } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/ExceptionTests.cs b/Src/Newtonsoft.Json.Tests/ExceptionTests.cs index 39d38cad..babfc8ad 100644 --- a/Src/Newtonsoft.Json.Tests/ExceptionTests.cs +++ b/Src/Newtonsoft.Json.Tests/ExceptionTests.cs @@ -27,6 +27,7 @@ using System; using Newtonsoft.Json.Schema; #if !NETFX_CORE using NUnit.Framework; + #else using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; @@ -35,67 +36,67 @@ using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAtt namespace Newtonsoft.Json.Tests { - [TestFixture] - public class ExceptionTests : TestFixtureBase - { - [Test] - public void JsonSerializationException() + [TestFixture] + public class ExceptionTests : TestFixtureBase { - JsonSerializationException exception = new JsonSerializationException(); - Assert.AreEqual("Exception of type 'Newtonsoft.Json.JsonSerializationException' was thrown.", exception.Message); + [Test] + public void JsonSerializationException() + { + JsonSerializationException exception = new JsonSerializationException(); + Assert.AreEqual("Exception of type 'Newtonsoft.Json.JsonSerializationException' was thrown.", exception.Message); - exception = new JsonSerializationException("Message!"); - Assert.AreEqual("Message!", exception.Message); - Assert.AreEqual(null, exception.InnerException); + exception = new JsonSerializationException("Message!"); + Assert.AreEqual("Message!", exception.Message); + Assert.AreEqual(null, exception.InnerException); - exception = new JsonSerializationException("Message!", new Exception("Inner!")); - Assert.AreEqual("Message!", exception.Message); - Assert.AreEqual("Inner!", exception.InnerException.Message); + exception = new JsonSerializationException("Message!", new Exception("Inner!")); + Assert.AreEqual("Message!", exception.Message); + Assert.AreEqual("Inner!", exception.InnerException.Message); + } + + [Test] + public void JsonWriterException() + { + JsonWriterException exception = new JsonWriterException(); + Assert.AreEqual("Exception of type 'Newtonsoft.Json.JsonWriterException' was thrown.", exception.Message); + + exception = new JsonWriterException("Message!"); + Assert.AreEqual("Message!", exception.Message); + Assert.AreEqual(null, exception.InnerException); + + exception = new JsonWriterException("Message!", new Exception("Inner!")); + Assert.AreEqual("Message!", exception.Message); + Assert.AreEqual("Inner!", exception.InnerException.Message); + } + + [Test] + public void JsonReaderException() + { + JsonReaderException exception = new JsonReaderException(); + Assert.AreEqual("Exception of type 'Newtonsoft.Json.JsonReaderException' was thrown.", exception.Message); + + exception = new JsonReaderException("Message!"); + Assert.AreEqual("Message!", exception.Message); + Assert.AreEqual(null, exception.InnerException); + + exception = new JsonReaderException("Message!", new Exception("Inner!")); + Assert.AreEqual("Message!", exception.Message); + Assert.AreEqual("Inner!", exception.InnerException.Message); + } + + [Test] + public void JsonSchemaException() + { + JsonSchemaException exception = new JsonSchemaException(); + Assert.AreEqual("Exception of type 'Newtonsoft.Json.Schema.JsonSchemaException' was thrown.", exception.Message); + + exception = new JsonSchemaException("Message!"); + Assert.AreEqual("Message!", exception.Message); + Assert.AreEqual(null, exception.InnerException); + + exception = new JsonSchemaException("Message!", new Exception("Inner!")); + Assert.AreEqual("Message!", exception.Message); + Assert.AreEqual("Inner!", exception.InnerException.Message); + } } - - [Test] - public void JsonWriterException() - { - JsonWriterException exception = new JsonWriterException(); - Assert.AreEqual("Exception of type 'Newtonsoft.Json.JsonWriterException' was thrown.", exception.Message); - - exception = new JsonWriterException("Message!"); - Assert.AreEqual("Message!", exception.Message); - Assert.AreEqual(null, exception.InnerException); - - exception = new JsonWriterException("Message!", new Exception("Inner!")); - Assert.AreEqual("Message!", exception.Message); - Assert.AreEqual("Inner!", exception.InnerException.Message); - } - - [Test] - public void JsonReaderException() - { - JsonReaderException exception = new JsonReaderException(); - Assert.AreEqual("Exception of type 'Newtonsoft.Json.JsonReaderException' was thrown.", exception.Message); - - exception = new JsonReaderException("Message!"); - Assert.AreEqual("Message!", exception.Message); - Assert.AreEqual(null, exception.InnerException); - - exception = new JsonReaderException("Message!", new Exception("Inner!")); - Assert.AreEqual("Message!", exception.Message); - Assert.AreEqual("Inner!", exception.InnerException.Message); - } - - [Test] - public void JsonSchemaException() - { - JsonSchemaException exception = new JsonSchemaException(); - Assert.AreEqual("Exception of type 'Newtonsoft.Json.Schema.JsonSchemaException' was thrown.", exception.Message); - - exception = new JsonSchemaException("Message!"); - Assert.AreEqual("Message!", exception.Message); - Assert.AreEqual(null, exception.InnerException); - - exception = new JsonSchemaException("Message!", new Exception("Inner!")); - Assert.AreEqual("Message!", exception.Message); - Assert.AreEqual("Inner!", exception.InnerException.Message); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/JsonArrayAttributeTests.cs b/Src/Newtonsoft.Json.Tests/JsonArrayAttributeTests.cs index b90fd052..a04aec1b 100644 --- a/Src/Newtonsoft.Json.Tests/JsonArrayAttributeTests.cs +++ b/Src/Newtonsoft.Json.Tests/JsonArrayAttributeTests.cs @@ -25,6 +25,7 @@ #if !NETFX_CORE using NUnit.Framework; + #else using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; @@ -33,47 +34,47 @@ using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAtt namespace Newtonsoft.Json.Tests { - [TestFixture] - public class JsonArrayAttributeTests : TestFixtureBase - { - [Test] - public void IsReferenceTest() + [TestFixture] + public class JsonArrayAttributeTests : TestFixtureBase { - JsonPropertyAttribute attribute = new JsonPropertyAttribute(); - Assert.AreEqual(null, attribute._isReference); - Assert.AreEqual(false, attribute.IsReference); + [Test] + public void IsReferenceTest() + { + JsonPropertyAttribute attribute = new JsonPropertyAttribute(); + Assert.AreEqual(null, attribute._isReference); + Assert.AreEqual(false, attribute.IsReference); - attribute.IsReference = false; - Assert.AreEqual(false, attribute._isReference); - Assert.AreEqual(false, attribute.IsReference); + attribute.IsReference = false; + Assert.AreEqual(false, attribute._isReference); + Assert.AreEqual(false, attribute.IsReference); - attribute.IsReference = true; - Assert.AreEqual(true, attribute._isReference); - Assert.AreEqual(true, attribute.IsReference); + attribute.IsReference = true; + Assert.AreEqual(true, attribute._isReference); + Assert.AreEqual(true, attribute.IsReference); + } + + [Test] + public void NullValueHandlingTest() + { + JsonPropertyAttribute attribute = new JsonPropertyAttribute(); + Assert.AreEqual(null, attribute._nullValueHandling); + Assert.AreEqual(NullValueHandling.Include, attribute.NullValueHandling); + + attribute.NullValueHandling = NullValueHandling.Ignore; + Assert.AreEqual(NullValueHandling.Ignore, attribute._nullValueHandling); + Assert.AreEqual(NullValueHandling.Ignore, attribute.NullValueHandling); + } + + [Test] + public void DefaultValueHandlingTest() + { + JsonPropertyAttribute attribute = new JsonPropertyAttribute(); + Assert.AreEqual(null, attribute._defaultValueHandling); + Assert.AreEqual(DefaultValueHandling.Include, attribute.DefaultValueHandling); + + attribute.DefaultValueHandling = DefaultValueHandling.Ignore; + Assert.AreEqual(DefaultValueHandling.Ignore, attribute._defaultValueHandling); + Assert.AreEqual(DefaultValueHandling.Ignore, attribute.DefaultValueHandling); + } } - - [Test] - public void NullValueHandlingTest() - { - JsonPropertyAttribute attribute = new JsonPropertyAttribute(); - Assert.AreEqual(null, attribute._nullValueHandling); - Assert.AreEqual(NullValueHandling.Include, attribute.NullValueHandling); - - attribute.NullValueHandling = NullValueHandling.Ignore; - Assert.AreEqual(NullValueHandling.Ignore, attribute._nullValueHandling); - Assert.AreEqual(NullValueHandling.Ignore, attribute.NullValueHandling); - } - - [Test] - public void DefaultValueHandlingTest() - { - JsonPropertyAttribute attribute = new JsonPropertyAttribute(); - Assert.AreEqual(null, attribute._defaultValueHandling); - Assert.AreEqual(DefaultValueHandling.Include, attribute.DefaultValueHandling); - - attribute.DefaultValueHandling = DefaultValueHandling.Ignore; - Assert.AreEqual(DefaultValueHandling.Ignore, attribute._defaultValueHandling); - Assert.AreEqual(DefaultValueHandling.Ignore, attribute.DefaultValueHandling); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/JsonConvertTest.cs b/Src/Newtonsoft.Json.Tests/JsonConvertTest.cs index 19bcc66f..89e92b85 100644 --- a/Src/Newtonsoft.Json.Tests/JsonConvertTest.cs +++ b/Src/Newtonsoft.Json.Tests/JsonConvertTest.cs @@ -40,6 +40,7 @@ using Newtonsoft.Json.Tests.TestObjects; using Newtonsoft.Json.Utilities; #if !NETFX_CORE using NUnit.Framework; + #else using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; @@ -48,848 +49,845 @@ using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAtt namespace Newtonsoft.Json.Tests { - [TestFixture] - public class JsonConvertTest : TestFixtureBase - { - [Test] - public void DefaultSettings() + [TestFixture] + public class JsonConvertTest : TestFixtureBase { - try - { - JsonConvert.DefaultSettings = () => new JsonSerializerSettings + [Test] + public void DefaultSettings() { - Formatting = Formatting.Indented - }; + try + { + JsonConvert.DefaultSettings = () => new JsonSerializerSettings + { + Formatting = Formatting.Indented + }; - string json = JsonConvert.SerializeObject(new { test = new[] { 1, 2, 3 } }); + string json = JsonConvert.SerializeObject(new { test = new[] { 1, 2, 3 } }); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""test"": [ 1, 2, 3 ] }", json); - } - finally - { - JsonConvert.DefaultSettings = null; - } - } + } + finally + { + JsonConvert.DefaultSettings = null; + } + } - [Test] - public void DefaultSettings_Example() - { - try - { - JsonConvert.DefaultSettings = () => new JsonSerializerSettings + [Test] + public void DefaultSettings_Example() { - Formatting = Formatting.Indented, - ContractResolver = new CamelCasePropertyNamesContractResolver() - }; + try + { + JsonConvert.DefaultSettings = () => new JsonSerializerSettings + { + Formatting = Formatting.Indented, + ContractResolver = new CamelCasePropertyNamesContractResolver() + }; - Employee e = new Employee - { - FirstName = "Eric", - LastName = "Example", - BirthDate = new DateTime(1980, 4, 20, 0, 0, 0, DateTimeKind.Utc), - Department = "IT", - JobTitle = "Web Dude" - }; + Employee e = new Employee + { + FirstName = "Eric", + LastName = "Example", + BirthDate = new DateTime(1980, 4, 20, 0, 0, 0, DateTimeKind.Utc), + Department = "IT", + JobTitle = "Web Dude" + }; - string json = JsonConvert.SerializeObject(e); - // { - // "firstName": "Eric", - // "lastName": "Example", - // "birthDate": "1980-04-20T00:00:00Z", - // "department": "IT", - // "jobTitle": "Web Dude" - // } + string json = JsonConvert.SerializeObject(e); + // { + // "firstName": "Eric", + // "lastName": "Example", + // "birthDate": "1980-04-20T00:00:00Z", + // "department": "IT", + // "jobTitle": "Web Dude" + // } - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""firstName"": ""Eric"", ""lastName"": ""Example"", ""birthDate"": ""1980-04-20T00:00:00Z"", ""department"": ""IT"", ""jobTitle"": ""Web Dude"" }", json); - } - finally - { - JsonConvert.DefaultSettings = null; - } - } + } + finally + { + JsonConvert.DefaultSettings = null; + } + } - [Test] - public void DefaultSettings_Override() - { - try - { - JsonConvert.DefaultSettings = () => new JsonSerializerSettings + [Test] + public void DefaultSettings_Override() { - Formatting = Formatting.Indented - }; + try + { + JsonConvert.DefaultSettings = () => new JsonSerializerSettings + { + Formatting = Formatting.Indented + }; - string json = JsonConvert.SerializeObject(new { test = new[] { 1, 2, 3 } }, new JsonSerializerSettings + string json = JsonConvert.SerializeObject(new { test = new[] { 1, 2, 3 } }, new JsonSerializerSettings + { + Formatting = Formatting.None + }); + + Assert.AreEqual(@"{""test"":[1,2,3]}", json); + } + finally + { + JsonConvert.DefaultSettings = null; + } + } + + [Test] + public void DefaultSettings_Override_JsonConverterOrder() { - Formatting = Formatting.None - }); + try + { + JsonConvert.DefaultSettings = () => new JsonSerializerSettings + { + Formatting = Formatting.Indented, + Converters = { new IsoDateTimeConverter { DateTimeFormat = "yyyy" } } + }; - Assert.AreEqual(@"{""test"":[1,2,3]}", json); - } - finally - { - JsonConvert.DefaultSettings = null; - } - } + string json = JsonConvert.SerializeObject(new[] { new DateTime(2000, 12, 12, 4, 2, 4, DateTimeKind.Utc) }, new JsonSerializerSettings + { + Formatting = Formatting.None, + Converters = + { + // should take precedence + new JavaScriptDateTimeConverter(), + new IsoDateTimeConverter { DateTimeFormat = "dd" } + } + }); - [Test] - public void DefaultSettings_Override_JsonConverterOrder() - { - try - { - JsonConvert.DefaultSettings = () => new JsonSerializerSettings + Assert.AreEqual(@"[new Date(976593724000)]", json); + } + finally + { + JsonConvert.DefaultSettings = null; + } + } + + [Test] + public void DefaultSettings_Create() { - Formatting = Formatting.Indented, - Converters = { new IsoDateTimeConverter { DateTimeFormat = "yyyy" } } - }; + try + { + JsonConvert.DefaultSettings = () => new JsonSerializerSettings + { + Formatting = Formatting.Indented + }; - string json = JsonConvert.SerializeObject(new[] { new DateTime(2000, 12, 12, 4, 2, 4, DateTimeKind.Utc) }, new JsonSerializerSettings - { - Formatting = Formatting.None, - Converters = - { - // should take precedence - new JavaScriptDateTimeConverter(), - new IsoDateTimeConverter { DateTimeFormat = "dd" } - } - }); + IList l = new List { 1, 2, 3 }; - Assert.AreEqual(@"[new Date(976593724000)]", json); - } - finally - { - JsonConvert.DefaultSettings = null; - } - } + StringWriter sw = new StringWriter(); + JsonSerializer serializer = JsonSerializer.CreateDefault(); + serializer.Serialize(sw, l); - [Test] - public void DefaultSettings_Create() - { - try - { - JsonConvert.DefaultSettings = () => new JsonSerializerSettings - { - Formatting = Formatting.Indented - }; - - IList l = new List { 1, 2, 3 }; - - StringWriter sw = new StringWriter(); - JsonSerializer serializer = JsonSerializer.CreateDefault(); - serializer.Serialize(sw, l); - - Assert.AreEqual(@"[ + Assert.AreEqual(@"[ 1, 2, 3 ]", sw.ToString()); - sw = new StringWriter(); - serializer.Formatting = Formatting.None; - serializer.Serialize(sw, l); + sw = new StringWriter(); + serializer.Formatting = Formatting.None; + serializer.Serialize(sw, l); - Assert.AreEqual(@"[1,2,3]", sw.ToString()); + Assert.AreEqual(@"[1,2,3]", sw.ToString()); - sw = new StringWriter(); - serializer = new JsonSerializer(); - serializer.Serialize(sw, l); + sw = new StringWriter(); + serializer = new JsonSerializer(); + serializer.Serialize(sw, l); - Assert.AreEqual(@"[1,2,3]", sw.ToString()); + Assert.AreEqual(@"[1,2,3]", sw.ToString()); - sw = new StringWriter(); - serializer = JsonSerializer.Create(); - serializer.Serialize(sw, l); + sw = new StringWriter(); + serializer = JsonSerializer.Create(); + serializer.Serialize(sw, l); - Assert.AreEqual(@"[1,2,3]", sw.ToString()); - } - finally - { - JsonConvert.DefaultSettings = null; - } - } + Assert.AreEqual(@"[1,2,3]", sw.ToString()); + } + finally + { + JsonConvert.DefaultSettings = null; + } + } - [Test] - public void DefaultSettings_CreateWithSettings() - { - try - { - JsonConvert.DefaultSettings = () => new JsonSerializerSettings + [Test] + public void DefaultSettings_CreateWithSettings() { - Formatting = Formatting.Indented - }; + try + { + JsonConvert.DefaultSettings = () => new JsonSerializerSettings + { + Formatting = Formatting.Indented + }; - IList l = new List { 1, 2, 3 }; + IList l = new List { 1, 2, 3 }; - StringWriter sw = new StringWriter(); - JsonSerializer serializer = JsonSerializer.CreateDefault(new JsonSerializerSettings - { - Converters = { new IntConverter() } - }); - serializer.Serialize(sw, l); + StringWriter sw = new StringWriter(); + JsonSerializer serializer = JsonSerializer.CreateDefault(new JsonSerializerSettings + { + Converters = { new IntConverter() } + }); + serializer.Serialize(sw, l); - Assert.AreEqual(@"[ + Assert.AreEqual(@"[ 2, 4, 6 ]", sw.ToString()); - sw = new StringWriter(); - serializer.Converters.Clear(); - serializer.Serialize(sw, l); + sw = new StringWriter(); + serializer.Converters.Clear(); + serializer.Serialize(sw, l); - Assert.AreEqual(@"[ + Assert.AreEqual(@"[ 1, 2, 3 ]", sw.ToString()); - sw = new StringWriter(); - serializer = JsonSerializer.Create(new JsonSerializerSettings { Formatting = Formatting.Indented }); - serializer.Serialize(sw, l); + sw = new StringWriter(); + serializer = JsonSerializer.Create(new JsonSerializerSettings { Formatting = Formatting.Indented }); + serializer.Serialize(sw, l); - Assert.AreEqual(@"[ + Assert.AreEqual(@"[ 1, 2, 3 ]", sw.ToString()); - } - finally - { - JsonConvert.DefaultSettings = null; - } - } + } + finally + { + JsonConvert.DefaultSettings = null; + } + } - public class IntConverter : JsonConverter - { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - int i = (int)value; - writer.WriteValue(i * 2); - } + public class IntConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + int i = (int)value; + writer.WriteValue(i * 2); + } - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - throw new NotImplementedException(); - } + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + throw new NotImplementedException(); + } - public override bool CanConvert(Type objectType) - { - return objectType == typeof(int); - } - } + public override bool CanConvert(Type objectType) + { + return objectType == typeof(int); + } + } - [Test] - public void DeserializeObject_EmptyString() - { - object result = JsonConvert.DeserializeObject(string.Empty); - Assert.IsNull(result); - } + [Test] + public void DeserializeObject_EmptyString() + { + object result = JsonConvert.DeserializeObject(string.Empty); + Assert.IsNull(result); + } - [Test] - public void DeserializeObject_Integer() - { - object result = JsonConvert.DeserializeObject("1"); - Assert.AreEqual(1L, result); - } + [Test] + public void DeserializeObject_Integer() + { + object result = JsonConvert.DeserializeObject("1"); + Assert.AreEqual(1L, result); + } - [Test] - public void DeserializeObject_Integer_EmptyString() - { - int? value = JsonConvert.DeserializeObject(""); - Assert.IsNull(value); - } + [Test] + public void DeserializeObject_Integer_EmptyString() + { + int? value = JsonConvert.DeserializeObject(""); + Assert.IsNull(value); + } - [Test] - public void DeserializeObject_Decimal_EmptyString() - { - decimal? value = JsonConvert.DeserializeObject(""); - Assert.IsNull(value); - } + [Test] + public void DeserializeObject_Decimal_EmptyString() + { + decimal? value = JsonConvert.DeserializeObject(""); + Assert.IsNull(value); + } - [Test] - public void DeserializeObject_DateTime_EmptyString() - { - DateTime? value = JsonConvert.DeserializeObject(""); - Assert.IsNull(value); - } + [Test] + public void DeserializeObject_DateTime_EmptyString() + { + DateTime? value = JsonConvert.DeserializeObject(""); + Assert.IsNull(value); + } - [Test] - public void EscapeJavaScriptString() - { - string result; + [Test] + public void EscapeJavaScriptString() + { + string result; - result = JavaScriptUtils.ToEscapedJavaScriptString("How now brown cow?", '"', true); - Assert.AreEqual(@"""How now brown cow?""", result); + result = JavaScriptUtils.ToEscapedJavaScriptString("How now brown cow?", '"', true); + Assert.AreEqual(@"""How now brown cow?""", result); - result = JavaScriptUtils.ToEscapedJavaScriptString("How now 'brown' cow?", '"', true); - Assert.AreEqual(@"""How now 'brown' cow?""", result); + result = JavaScriptUtils.ToEscapedJavaScriptString("How now 'brown' cow?", '"', true); + Assert.AreEqual(@"""How now 'brown' cow?""", result); - result = JavaScriptUtils.ToEscapedJavaScriptString("How now cow?", '"', true); - Assert.AreEqual(@"""How now cow?""", result); + result = JavaScriptUtils.ToEscapedJavaScriptString("How now cow?", '"', true); + Assert.AreEqual(@"""How now cow?""", result); - result = JavaScriptUtils.ToEscapedJavaScriptString(@"How + result = JavaScriptUtils.ToEscapedJavaScriptString(@"How now brown cow?", '"', true); - Assert.AreEqual(@"""How \r\nnow brown cow?""", result); + Assert.AreEqual(@"""How \r\nnow brown cow?""", result); - result = JavaScriptUtils.ToEscapedJavaScriptString("\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007", '"', true); - Assert.AreEqual(@"""\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007""", result); + result = JavaScriptUtils.ToEscapedJavaScriptString("\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007", '"', true); + Assert.AreEqual(@"""\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007""", result); - result = - JavaScriptUtils.ToEscapedJavaScriptString("\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013", '"', true); - Assert.AreEqual(@"""\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013""", result); + result = + JavaScriptUtils.ToEscapedJavaScriptString("\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013", '"', true); + Assert.AreEqual(@"""\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013""", result); - result = - JavaScriptUtils.ToEscapedJavaScriptString( - "\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f ", '"', true); - Assert.AreEqual(@"""\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f """, result); + result = + JavaScriptUtils.ToEscapedJavaScriptString( + "\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f ", '"', true); + Assert.AreEqual(@"""\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f """, result); - result = - JavaScriptUtils.ToEscapedJavaScriptString( - "!\"#$%&\u0027()*+,-./0123456789:;\u003c=\u003e?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]", '"', true); - Assert.AreEqual(@"""!\""#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]""", result); + result = + JavaScriptUtils.ToEscapedJavaScriptString( + "!\"#$%&\u0027()*+,-./0123456789:;\u003c=\u003e?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]", '"', true); + Assert.AreEqual(@"""!\""#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]""", result); - result = JavaScriptUtils.ToEscapedJavaScriptString("^_`abcdefghijklmnopqrstuvwxyz{|}~", '"', true); - Assert.AreEqual(@"""^_`abcdefghijklmnopqrstuvwxyz{|}~""", result); + result = JavaScriptUtils.ToEscapedJavaScriptString("^_`abcdefghijklmnopqrstuvwxyz{|}~", '"', true); + Assert.AreEqual(@"""^_`abcdefghijklmnopqrstuvwxyz{|}~""", result); - string data = - "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&\u0027()*+,-./0123456789:;\u003c=\u003e?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; - string expected = - @"""\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\""#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"""; + string data = + "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&\u0027()*+,-./0123456789:;\u003c=\u003e?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; + string expected = + @"""\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\""#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"""; - result = JavaScriptUtils.ToEscapedJavaScriptString(data, '"', true); - Assert.AreEqual(expected, result); + result = JavaScriptUtils.ToEscapedJavaScriptString(data, '"', true); + Assert.AreEqual(expected, result); - result = JavaScriptUtils.ToEscapedJavaScriptString("Fred's cat.", '\'', true); - Assert.AreEqual(result, @"'Fred\'s cat.'"); + result = JavaScriptUtils.ToEscapedJavaScriptString("Fred's cat.", '\'', true); + Assert.AreEqual(result, @"'Fred\'s cat.'"); - result = JavaScriptUtils.ToEscapedJavaScriptString(@"""How are you gentlemen?"" said Cats.", '"', true); - Assert.AreEqual(result, @"""\""How are you gentlemen?\"" said Cats."""); + result = JavaScriptUtils.ToEscapedJavaScriptString(@"""How are you gentlemen?"" said Cats.", '"', true); + Assert.AreEqual(result, @"""\""How are you gentlemen?\"" said Cats."""); - result = JavaScriptUtils.ToEscapedJavaScriptString(@"""How are' you gentlemen?"" said Cats.", '"', true); - Assert.AreEqual(result, @"""\""How are' you gentlemen?\"" said Cats."""); + result = JavaScriptUtils.ToEscapedJavaScriptString(@"""How are' you gentlemen?"" said Cats.", '"', true); + Assert.AreEqual(result, @"""\""How are' you gentlemen?\"" said Cats."""); - result = JavaScriptUtils.ToEscapedJavaScriptString(@"Fred's ""cat"".", '\'', true); - Assert.AreEqual(result, @"'Fred\'s ""cat"".'"); + result = JavaScriptUtils.ToEscapedJavaScriptString(@"Fred's ""cat"".", '\'', true); + Assert.AreEqual(result, @"'Fred\'s ""cat"".'"); - result = JavaScriptUtils.ToEscapedJavaScriptString("\u001farray\u003caddress", '"', true); - Assert.AreEqual(result, @"""\u001farray("Unsupported type: System.Version. Use the JsonSerializer class to get the object's JSON representation.", - () => - { - JsonConvert.ToString(new Version(1, 0)); - }); - } + [Test] + public void ToStringInvalid() + { + ExceptionAssert.Throws("Unsupported type: System.Version. Use the JsonSerializer class to get the object's JSON representation.", + () => { JsonConvert.ToString(new Version(1, 0)); }); + } - [Test] - public void GuidToString() - { - Guid guid = new Guid("BED7F4EA-1A96-11d2-8F08-00A0C9A6186D"); - string json = JsonConvert.ToString(guid); - Assert.AreEqual(@"""bed7f4ea-1a96-11d2-8f08-00a0c9a6186d""", json); - } + [Test] + public void GuidToString() + { + Guid guid = new Guid("BED7F4EA-1A96-11d2-8F08-00A0C9A6186D"); + string json = JsonConvert.ToString(guid); + Assert.AreEqual(@"""bed7f4ea-1a96-11d2-8f08-00a0c9a6186d""", json); + } - [Test] - public void EnumToString() - { - string json = JsonConvert.ToString(StringComparison.CurrentCultureIgnoreCase); - Assert.AreEqual("1", json); - } + [Test] + public void EnumToString() + { + string json = JsonConvert.ToString(StringComparison.CurrentCultureIgnoreCase); + Assert.AreEqual("1", json); + } - [Test] - public void ObjectToString() - { - object value; + [Test] + public void ObjectToString() + { + object value; - value = 1; - Assert.AreEqual("1", JsonConvert.ToString(value)); + value = 1; + Assert.AreEqual("1", JsonConvert.ToString(value)); - value = 1.1; - Assert.AreEqual("1.1", JsonConvert.ToString(value)); + value = 1.1; + Assert.AreEqual("1.1", JsonConvert.ToString(value)); - value = 1.1m; - Assert.AreEqual("1.1", JsonConvert.ToString(value)); + value = 1.1m; + Assert.AreEqual("1.1", JsonConvert.ToString(value)); - value = (float)1.1; - Assert.AreEqual("1.1", JsonConvert.ToString(value)); + value = (float)1.1; + Assert.AreEqual("1.1", JsonConvert.ToString(value)); - value = (short)1; - Assert.AreEqual("1", JsonConvert.ToString(value)); + value = (short)1; + Assert.AreEqual("1", JsonConvert.ToString(value)); - value = (long)1; - Assert.AreEqual("1", JsonConvert.ToString(value)); + value = (long)1; + Assert.AreEqual("1", JsonConvert.ToString(value)); - value = (byte)1; - Assert.AreEqual("1", JsonConvert.ToString(value)); + value = (byte)1; + Assert.AreEqual("1", JsonConvert.ToString(value)); - value = (uint)1; - Assert.AreEqual("1", JsonConvert.ToString(value)); + value = (uint)1; + Assert.AreEqual("1", JsonConvert.ToString(value)); - value = (ushort)1; - Assert.AreEqual("1", JsonConvert.ToString(value)); + value = (ushort)1; + Assert.AreEqual("1", JsonConvert.ToString(value)); - value = (sbyte)1; - Assert.AreEqual("1", JsonConvert.ToString(value)); + value = (sbyte)1; + Assert.AreEqual("1", JsonConvert.ToString(value)); - value = (ulong)1; - Assert.AreEqual("1", JsonConvert.ToString(value)); + value = (ulong)1; + Assert.AreEqual("1", JsonConvert.ToString(value)); - value = new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc); - Assert.AreEqual(@"""1970-01-01T00:00:00Z""", JsonConvert.ToString(value)); + value = new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc); + Assert.AreEqual(@"""1970-01-01T00:00:00Z""", JsonConvert.ToString(value)); - value = new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc); - Assert.AreEqual(@"""\/Date(0)\/""", JsonConvert.ToString((DateTime)value, DateFormatHandling.MicrosoftDateFormat, DateTimeZoneHandling.RoundtripKind)); + value = new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc); + Assert.AreEqual(@"""\/Date(0)\/""", JsonConvert.ToString((DateTime)value, DateFormatHandling.MicrosoftDateFormat, DateTimeZoneHandling.RoundtripKind)); #if !NET20 - value = new DateTimeOffset(DateTimeUtils.InitialJavaScriptDateTicks, TimeSpan.Zero); - Assert.AreEqual(@"""1970-01-01T00:00:00+00:00""", JsonConvert.ToString(value)); + value = new DateTimeOffset(DateTimeUtils.InitialJavaScriptDateTicks, TimeSpan.Zero); + Assert.AreEqual(@"""1970-01-01T00:00:00+00:00""", JsonConvert.ToString(value)); - value = new DateTimeOffset(DateTimeUtils.InitialJavaScriptDateTicks, TimeSpan.Zero); - Assert.AreEqual(@"""\/Date(0+0000)\/""", JsonConvert.ToString((DateTimeOffset)value, DateFormatHandling.MicrosoftDateFormat)); + value = new DateTimeOffset(DateTimeUtils.InitialJavaScriptDateTicks, TimeSpan.Zero); + Assert.AreEqual(@"""\/Date(0+0000)\/""", JsonConvert.ToString((DateTimeOffset)value, DateFormatHandling.MicrosoftDateFormat)); #endif - value = null; - Assert.AreEqual("null", JsonConvert.ToString(value)); + value = null; + Assert.AreEqual("null", JsonConvert.ToString(value)); #if !(NETFX_CORE || PORTABLE || PORTABLE40) - value = DBNull.Value; - Assert.AreEqual("null", JsonConvert.ToString(value)); + value = DBNull.Value; + Assert.AreEqual("null", JsonConvert.ToString(value)); #endif - value = "I am a string"; - Assert.AreEqual(@"""I am a string""", JsonConvert.ToString(value)); + value = "I am a string"; + Assert.AreEqual(@"""I am a string""", JsonConvert.ToString(value)); - value = true; - Assert.AreEqual("true", JsonConvert.ToString(value)); + value = true; + Assert.AreEqual("true", JsonConvert.ToString(value)); - value = 'c'; - Assert.AreEqual(@"""c""", JsonConvert.ToString(value)); - } + value = 'c'; + Assert.AreEqual(@"""c""", JsonConvert.ToString(value)); + } - [Test] - public void TestInvalidStrings() - { - ExceptionAssert.Throws("Additional text encountered after finished reading JSON content: t. Path '', line 1, position 19.", - () => - { - string orig = @"this is a string ""that has quotes"" "; + [Test] + public void TestInvalidStrings() + { + ExceptionAssert.Throws("Additional text encountered after finished reading JSON content: t. Path '', line 1, position 19.", + () => + { + string orig = @"this is a string ""that has quotes"" "; - string serialized = JsonConvert.SerializeObject(orig); + string serialized = JsonConvert.SerializeObject(orig); - // *** Make string invalid by stripping \" \" - serialized = serialized.Replace(@"\""", "\""); + // *** Make string invalid by stripping \" \" + serialized = serialized.Replace(@"\""", "\""); - JsonConvert.DeserializeObject(serialized); - }); - } + JsonConvert.DeserializeObject(serialized); + }); + } - [Test] - public void DeserializeValueObjects() - { - int i = JsonConvert.DeserializeObject("1"); - Assert.AreEqual(1, i); + [Test] + public void DeserializeValueObjects() + { + int i = JsonConvert.DeserializeObject("1"); + Assert.AreEqual(1, i); #if !NET20 - DateTimeOffset d = JsonConvert.DeserializeObject(@"""\/Date(-59011455539000+0000)\/"""); - Assert.AreEqual(new DateTimeOffset(new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Utc)), d); + DateTimeOffset d = JsonConvert.DeserializeObject(@"""\/Date(-59011455539000+0000)\/"""); + Assert.AreEqual(new DateTimeOffset(new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Utc)), d); #endif - bool b = JsonConvert.DeserializeObject("true"); - Assert.AreEqual(true, b); + bool b = JsonConvert.DeserializeObject("true"); + Assert.AreEqual(true, b); - object n = JsonConvert.DeserializeObject("null"); - Assert.AreEqual(null, n); + object n = JsonConvert.DeserializeObject("null"); + Assert.AreEqual(null, n); - object u = JsonConvert.DeserializeObject("undefined"); - Assert.AreEqual(null, u); - } + object u = JsonConvert.DeserializeObject("undefined"); + Assert.AreEqual(null, u); + } - [Test] - public void FloatToString() - { - Assert.AreEqual("1.1", JsonConvert.ToString(1.1)); - Assert.AreEqual("1.11", JsonConvert.ToString(1.11)); - Assert.AreEqual("1.111", JsonConvert.ToString(1.111)); - Assert.AreEqual("1.1111", JsonConvert.ToString(1.1111)); - Assert.AreEqual("1.11111", JsonConvert.ToString(1.11111)); - Assert.AreEqual("1.111111", JsonConvert.ToString(1.111111)); - Assert.AreEqual("1.0", JsonConvert.ToString(1.0)); - Assert.AreEqual("1.0", JsonConvert.ToString(1d)); - Assert.AreEqual("-1.0", JsonConvert.ToString(-1d)); - Assert.AreEqual("1.01", JsonConvert.ToString(1.01)); - Assert.AreEqual("1.001", JsonConvert.ToString(1.001)); - Assert.AreEqual(JsonConvert.PositiveInfinity, JsonConvert.ToString(Double.PositiveInfinity)); - Assert.AreEqual(JsonConvert.NegativeInfinity, JsonConvert.ToString(Double.NegativeInfinity)); - Assert.AreEqual(JsonConvert.NaN, JsonConvert.ToString(Double.NaN)); - } + [Test] + public void FloatToString() + { + Assert.AreEqual("1.1", JsonConvert.ToString(1.1)); + Assert.AreEqual("1.11", JsonConvert.ToString(1.11)); + Assert.AreEqual("1.111", JsonConvert.ToString(1.111)); + Assert.AreEqual("1.1111", JsonConvert.ToString(1.1111)); + Assert.AreEqual("1.11111", JsonConvert.ToString(1.11111)); + Assert.AreEqual("1.111111", JsonConvert.ToString(1.111111)); + Assert.AreEqual("1.0", JsonConvert.ToString(1.0)); + Assert.AreEqual("1.0", JsonConvert.ToString(1d)); + Assert.AreEqual("-1.0", JsonConvert.ToString(-1d)); + Assert.AreEqual("1.01", JsonConvert.ToString(1.01)); + Assert.AreEqual("1.001", JsonConvert.ToString(1.001)); + Assert.AreEqual(JsonConvert.PositiveInfinity, JsonConvert.ToString(Double.PositiveInfinity)); + Assert.AreEqual(JsonConvert.NegativeInfinity, JsonConvert.ToString(Double.NegativeInfinity)); + Assert.AreEqual(JsonConvert.NaN, JsonConvert.ToString(Double.NaN)); + } - [Test] - public void DecimalToString() - { - Assert.AreEqual("1.1", JsonConvert.ToString(1.1m)); - Assert.AreEqual("1.11", JsonConvert.ToString(1.11m)); - Assert.AreEqual("1.111", JsonConvert.ToString(1.111m)); - Assert.AreEqual("1.1111", JsonConvert.ToString(1.1111m)); - Assert.AreEqual("1.11111", JsonConvert.ToString(1.11111m)); - Assert.AreEqual("1.111111", JsonConvert.ToString(1.111111m)); - Assert.AreEqual("1.0", JsonConvert.ToString(1.0m)); - Assert.AreEqual("-1.0", JsonConvert.ToString(-1.0m)); - Assert.AreEqual("-1.0", JsonConvert.ToString(-1m)); - Assert.AreEqual("1.0", JsonConvert.ToString(1m)); - Assert.AreEqual("1.01", JsonConvert.ToString(1.01m)); - Assert.AreEqual("1.001", JsonConvert.ToString(1.001m)); - Assert.AreEqual("79228162514264337593543950335.0", JsonConvert.ToString(Decimal.MaxValue)); - Assert.AreEqual("-79228162514264337593543950335.0", JsonConvert.ToString(Decimal.MinValue)); - } + [Test] + public void DecimalToString() + { + Assert.AreEqual("1.1", JsonConvert.ToString(1.1m)); + Assert.AreEqual("1.11", JsonConvert.ToString(1.11m)); + Assert.AreEqual("1.111", JsonConvert.ToString(1.111m)); + Assert.AreEqual("1.1111", JsonConvert.ToString(1.1111m)); + Assert.AreEqual("1.11111", JsonConvert.ToString(1.11111m)); + Assert.AreEqual("1.111111", JsonConvert.ToString(1.111111m)); + Assert.AreEqual("1.0", JsonConvert.ToString(1.0m)); + Assert.AreEqual("-1.0", JsonConvert.ToString(-1.0m)); + Assert.AreEqual("-1.0", JsonConvert.ToString(-1m)); + Assert.AreEqual("1.0", JsonConvert.ToString(1m)); + Assert.AreEqual("1.01", JsonConvert.ToString(1.01m)); + Assert.AreEqual("1.001", JsonConvert.ToString(1.001m)); + Assert.AreEqual("79228162514264337593543950335.0", JsonConvert.ToString(Decimal.MaxValue)); + Assert.AreEqual("-79228162514264337593543950335.0", JsonConvert.ToString(Decimal.MinValue)); + } - [Test] - public void StringEscaping() - { - string v = @"It's a good day + [Test] + public void StringEscaping() + { + string v = @"It's a good day ""sunshine"""; - string json = JsonConvert.ToString(v); - Assert.AreEqual(@"""It's a good day\r\n\""sunshine\""""", json); - } + string json = JsonConvert.ToString(v); + Assert.AreEqual(@"""It's a good day\r\n\""sunshine\""""", json); + } - [Test] - public void WriteDateTime() - { - DateTimeResult result = null; + [Test] + public void WriteDateTime() + { + DateTimeResult result = null; - result = TestDateTime("DateTime Max", DateTime.MaxValue); - Assert.AreEqual("9999-12-31T23:59:59.9999999", result.IsoDateRoundtrip); - Assert.AreEqual("9999-12-31T23:59:59.9999999" + GetOffset(DateTime.MaxValue, DateFormatHandling.IsoDateFormat), result.IsoDateLocal); - Assert.AreEqual("9999-12-31T23:59:59.9999999", result.IsoDateUnspecified); - Assert.AreEqual("9999-12-31T23:59:59.9999999Z", result.IsoDateUtc); - Assert.AreEqual(@"\/Date(253402300799999)\/", result.MsDateRoundtrip); - Assert.AreEqual(@"\/Date(253402300799999" + GetOffset(DateTime.MaxValue, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateLocal); - Assert.AreEqual(@"\/Date(253402300799999)\/", result.MsDateUnspecified); - Assert.AreEqual(@"\/Date(253402300799999)\/", result.MsDateUtc); + result = TestDateTime("DateTime Max", DateTime.MaxValue); + Assert.AreEqual("9999-12-31T23:59:59.9999999", result.IsoDateRoundtrip); + Assert.AreEqual("9999-12-31T23:59:59.9999999" + GetOffset(DateTime.MaxValue, DateFormatHandling.IsoDateFormat), result.IsoDateLocal); + Assert.AreEqual("9999-12-31T23:59:59.9999999", result.IsoDateUnspecified); + Assert.AreEqual("9999-12-31T23:59:59.9999999Z", result.IsoDateUtc); + Assert.AreEqual(@"\/Date(253402300799999)\/", result.MsDateRoundtrip); + Assert.AreEqual(@"\/Date(253402300799999" + GetOffset(DateTime.MaxValue, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateLocal); + Assert.AreEqual(@"\/Date(253402300799999)\/", result.MsDateUnspecified); + Assert.AreEqual(@"\/Date(253402300799999)\/", result.MsDateUtc); - DateTime year2000local = new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Local); - string localToUtcDate = year2000local.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.FFFFFFFK"); + DateTime year2000local = new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Local); + string localToUtcDate = year2000local.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.FFFFFFFK"); - result = TestDateTime("DateTime Local", year2000local); - Assert.AreEqual("2000-01-01T01:01:01" + GetOffset(year2000local, DateFormatHandling.IsoDateFormat), result.IsoDateRoundtrip); - Assert.AreEqual("2000-01-01T01:01:01" + GetOffset(year2000local, DateFormatHandling.IsoDateFormat), result.IsoDateLocal); - Assert.AreEqual("2000-01-01T01:01:01", result.IsoDateUnspecified); - Assert.AreEqual(localToUtcDate, result.IsoDateUtc); - Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(year2000local) + GetOffset(year2000local, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateRoundtrip); - Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(year2000local) + GetOffset(year2000local, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateLocal); - Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(year2000local) + GetOffset(year2000local, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateUnspecified); - Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(year2000local) + @")\/", result.MsDateUtc); + result = TestDateTime("DateTime Local", year2000local); + Assert.AreEqual("2000-01-01T01:01:01" + GetOffset(year2000local, DateFormatHandling.IsoDateFormat), result.IsoDateRoundtrip); + Assert.AreEqual("2000-01-01T01:01:01" + GetOffset(year2000local, DateFormatHandling.IsoDateFormat), result.IsoDateLocal); + Assert.AreEqual("2000-01-01T01:01:01", result.IsoDateUnspecified); + Assert.AreEqual(localToUtcDate, result.IsoDateUtc); + Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(year2000local) + GetOffset(year2000local, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateRoundtrip); + Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(year2000local) + GetOffset(year2000local, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateLocal); + Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(year2000local) + GetOffset(year2000local, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateUnspecified); + Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(year2000local) + @")\/", result.MsDateUtc); - DateTime millisecondsLocal = new DateTime(2000, 1, 1, 1, 1, 1, 999, DateTimeKind.Local); - localToUtcDate = millisecondsLocal.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.FFFFFFFK"); + DateTime millisecondsLocal = new DateTime(2000, 1, 1, 1, 1, 1, 999, DateTimeKind.Local); + localToUtcDate = millisecondsLocal.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.FFFFFFFK"); - result = TestDateTime("DateTime Local with milliseconds", millisecondsLocal); - Assert.AreEqual("2000-01-01T01:01:01.999" + GetOffset(millisecondsLocal, DateFormatHandling.IsoDateFormat), result.IsoDateRoundtrip); - Assert.AreEqual("2000-01-01T01:01:01.999" + GetOffset(millisecondsLocal, DateFormatHandling.IsoDateFormat), result.IsoDateLocal); - Assert.AreEqual("2000-01-01T01:01:01.999", result.IsoDateUnspecified); - Assert.AreEqual(localToUtcDate, result.IsoDateUtc); - Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(millisecondsLocal) + GetOffset(millisecondsLocal, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateRoundtrip); - Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(millisecondsLocal) + GetOffset(millisecondsLocal, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateLocal); - Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(millisecondsLocal) + GetOffset(millisecondsLocal, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateUnspecified); - Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(millisecondsLocal) + @")\/", result.MsDateUtc); + result = TestDateTime("DateTime Local with milliseconds", millisecondsLocal); + Assert.AreEqual("2000-01-01T01:01:01.999" + GetOffset(millisecondsLocal, DateFormatHandling.IsoDateFormat), result.IsoDateRoundtrip); + Assert.AreEqual("2000-01-01T01:01:01.999" + GetOffset(millisecondsLocal, DateFormatHandling.IsoDateFormat), result.IsoDateLocal); + Assert.AreEqual("2000-01-01T01:01:01.999", result.IsoDateUnspecified); + Assert.AreEqual(localToUtcDate, result.IsoDateUtc); + Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(millisecondsLocal) + GetOffset(millisecondsLocal, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateRoundtrip); + Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(millisecondsLocal) + GetOffset(millisecondsLocal, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateLocal); + Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(millisecondsLocal) + GetOffset(millisecondsLocal, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateUnspecified); + Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(millisecondsLocal) + @")\/", result.MsDateUtc); - DateTime ticksLocal = new DateTime(634663873826822481, DateTimeKind.Local); - localToUtcDate = ticksLocal.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.FFFFFFFK"); - - result = TestDateTime("DateTime Local with ticks", ticksLocal); - Assert.AreEqual("2012-03-03T16:03:02.6822481" + GetOffset(ticksLocal, DateFormatHandling.IsoDateFormat), result.IsoDateRoundtrip); - Assert.AreEqual("2012-03-03T16:03:02.6822481" + GetOffset(ticksLocal, DateFormatHandling.IsoDateFormat), result.IsoDateLocal); - Assert.AreEqual("2012-03-03T16:03:02.6822481", result.IsoDateUnspecified); - Assert.AreEqual(localToUtcDate, result.IsoDateUtc); - Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(ticksLocal) + GetOffset(ticksLocal, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateRoundtrip); - Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(ticksLocal) + GetOffset(ticksLocal, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateLocal); - Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(ticksLocal) + GetOffset(ticksLocal, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateUnspecified); - Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(ticksLocal) + @")\/", result.MsDateUtc); + DateTime ticksLocal = new DateTime(634663873826822481, DateTimeKind.Local); + localToUtcDate = ticksLocal.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.FFFFFFFK"); - DateTime year2000Unspecified = new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Unspecified); + result = TestDateTime("DateTime Local with ticks", ticksLocal); + Assert.AreEqual("2012-03-03T16:03:02.6822481" + GetOffset(ticksLocal, DateFormatHandling.IsoDateFormat), result.IsoDateRoundtrip); + Assert.AreEqual("2012-03-03T16:03:02.6822481" + GetOffset(ticksLocal, DateFormatHandling.IsoDateFormat), result.IsoDateLocal); + Assert.AreEqual("2012-03-03T16:03:02.6822481", result.IsoDateUnspecified); + Assert.AreEqual(localToUtcDate, result.IsoDateUtc); + Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(ticksLocal) + GetOffset(ticksLocal, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateRoundtrip); + Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(ticksLocal) + GetOffset(ticksLocal, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateLocal); + Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(ticksLocal) + GetOffset(ticksLocal, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateUnspecified); + Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(ticksLocal) + @")\/", result.MsDateUtc); - result = TestDateTime("DateTime Unspecified", year2000Unspecified); - Assert.AreEqual("2000-01-01T01:01:01", result.IsoDateRoundtrip); - Assert.AreEqual("2000-01-01T01:01:01" + GetOffset(year2000Unspecified, DateFormatHandling.IsoDateFormat), result.IsoDateLocal); - Assert.AreEqual("2000-01-01T01:01:01", result.IsoDateUnspecified); - Assert.AreEqual("2000-01-01T01:01:01Z", result.IsoDateUtc); - Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(year2000Unspecified) + GetOffset(year2000Unspecified, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateRoundtrip); - Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(year2000Unspecified) + GetOffset(year2000Unspecified, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateLocal); - Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(year2000Unspecified) + GetOffset(year2000Unspecified, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateUnspecified); - Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(year2000Unspecified.ToLocalTime()) + @")\/", result.MsDateUtc); + DateTime year2000Unspecified = new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Unspecified); - DateTime year2000Utc = new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc); - string utcTolocalDate = year2000Utc.ToLocalTime().ToString("yyyy-MM-ddTHH:mm:ss"); + result = TestDateTime("DateTime Unspecified", year2000Unspecified); + Assert.AreEqual("2000-01-01T01:01:01", result.IsoDateRoundtrip); + Assert.AreEqual("2000-01-01T01:01:01" + GetOffset(year2000Unspecified, DateFormatHandling.IsoDateFormat), result.IsoDateLocal); + Assert.AreEqual("2000-01-01T01:01:01", result.IsoDateUnspecified); + Assert.AreEqual("2000-01-01T01:01:01Z", result.IsoDateUtc); + Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(year2000Unspecified) + GetOffset(year2000Unspecified, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateRoundtrip); + Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(year2000Unspecified) + GetOffset(year2000Unspecified, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateLocal); + Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(year2000Unspecified) + GetOffset(year2000Unspecified, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateUnspecified); + Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(year2000Unspecified.ToLocalTime()) + @")\/", result.MsDateUtc); - result = TestDateTime("DateTime Utc", year2000Utc); - Assert.AreEqual("2000-01-01T01:01:01Z", result.IsoDateRoundtrip); - Assert.AreEqual(utcTolocalDate + GetOffset(year2000Utc, DateFormatHandling.IsoDateFormat), result.IsoDateLocal); - Assert.AreEqual("2000-01-01T01:01:01", result.IsoDateUnspecified); - Assert.AreEqual("2000-01-01T01:01:01Z", result.IsoDateUtc); - Assert.AreEqual(@"\/Date(946688461000)\/", result.MsDateRoundtrip); - Assert.AreEqual(@"\/Date(946688461000" + GetOffset(year2000Utc, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateLocal); - Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(DateTime.SpecifyKind(year2000Utc, DateTimeKind.Unspecified)) + GetOffset(year2000Utc, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateUnspecified); - Assert.AreEqual(@"\/Date(946688461000)\/", result.MsDateUtc); + DateTime year2000Utc = new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc); + string utcTolocalDate = year2000Utc.ToLocalTime().ToString("yyyy-MM-ddTHH:mm:ss"); - DateTime unixEpoc = new DateTime(621355968000000000, DateTimeKind.Utc); - utcTolocalDate = unixEpoc.ToLocalTime().ToString("yyyy-MM-ddTHH:mm:ss"); + result = TestDateTime("DateTime Utc", year2000Utc); + Assert.AreEqual("2000-01-01T01:01:01Z", result.IsoDateRoundtrip); + Assert.AreEqual(utcTolocalDate + GetOffset(year2000Utc, DateFormatHandling.IsoDateFormat), result.IsoDateLocal); + Assert.AreEqual("2000-01-01T01:01:01", result.IsoDateUnspecified); + Assert.AreEqual("2000-01-01T01:01:01Z", result.IsoDateUtc); + Assert.AreEqual(@"\/Date(946688461000)\/", result.MsDateRoundtrip); + Assert.AreEqual(@"\/Date(946688461000" + GetOffset(year2000Utc, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateLocal); + Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(DateTime.SpecifyKind(year2000Utc, DateTimeKind.Unspecified)) + GetOffset(year2000Utc, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateUnspecified); + Assert.AreEqual(@"\/Date(946688461000)\/", result.MsDateUtc); - result = TestDateTime("DateTime Unix Epoc", unixEpoc); - Assert.AreEqual("1970-01-01T00:00:00Z", result.IsoDateRoundtrip); - Assert.AreEqual(utcTolocalDate + GetOffset(unixEpoc, DateFormatHandling.IsoDateFormat), result.IsoDateLocal); - Assert.AreEqual("1970-01-01T00:00:00", result.IsoDateUnspecified); - Assert.AreEqual("1970-01-01T00:00:00Z", result.IsoDateUtc); - Assert.AreEqual(@"\/Date(0)\/", result.MsDateRoundtrip); - Assert.AreEqual(@"\/Date(0" + GetOffset(unixEpoc, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateLocal); - Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(DateTime.SpecifyKind(unixEpoc, DateTimeKind.Unspecified)) + GetOffset(unixEpoc, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateUnspecified); - Assert.AreEqual(@"\/Date(0)\/", result.MsDateUtc); + DateTime unixEpoc = new DateTime(621355968000000000, DateTimeKind.Utc); + utcTolocalDate = unixEpoc.ToLocalTime().ToString("yyyy-MM-ddTHH:mm:ss"); - result = TestDateTime("DateTime Min", DateTime.MinValue); - Assert.AreEqual("0001-01-01T00:00:00", result.IsoDateRoundtrip); - Assert.AreEqual("0001-01-01T00:00:00" + GetOffset(DateTime.MinValue, DateFormatHandling.IsoDateFormat), result.IsoDateLocal); - Assert.AreEqual("0001-01-01T00:00:00", result.IsoDateUnspecified); - Assert.AreEqual("0001-01-01T00:00:00Z", result.IsoDateUtc); - Assert.AreEqual(@"\/Date(-62135596800000)\/", result.MsDateRoundtrip); - Assert.AreEqual(@"\/Date(-62135596800000" + GetOffset(DateTime.MinValue, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateLocal); - Assert.AreEqual(@"\/Date(-62135596800000)\/", result.MsDateUnspecified); - Assert.AreEqual(@"\/Date(-62135596800000)\/", result.MsDateUtc); + result = TestDateTime("DateTime Unix Epoc", unixEpoc); + Assert.AreEqual("1970-01-01T00:00:00Z", result.IsoDateRoundtrip); + Assert.AreEqual(utcTolocalDate + GetOffset(unixEpoc, DateFormatHandling.IsoDateFormat), result.IsoDateLocal); + Assert.AreEqual("1970-01-01T00:00:00", result.IsoDateUnspecified); + Assert.AreEqual("1970-01-01T00:00:00Z", result.IsoDateUtc); + Assert.AreEqual(@"\/Date(0)\/", result.MsDateRoundtrip); + Assert.AreEqual(@"\/Date(0" + GetOffset(unixEpoc, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateLocal); + Assert.AreEqual(@"\/Date(" + DateTimeUtils.ConvertDateTimeToJavaScriptTicks(DateTime.SpecifyKind(unixEpoc, DateTimeKind.Unspecified)) + GetOffset(unixEpoc, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateUnspecified); + Assert.AreEqual(@"\/Date(0)\/", result.MsDateUtc); - result = TestDateTime("DateTime Default", default(DateTime)); - Assert.AreEqual("0001-01-01T00:00:00", result.IsoDateRoundtrip); - Assert.AreEqual("0001-01-01T00:00:00" + GetOffset(default(DateTime), DateFormatHandling.IsoDateFormat), result.IsoDateLocal); - Assert.AreEqual("0001-01-01T00:00:00", result.IsoDateUnspecified); - Assert.AreEqual("0001-01-01T00:00:00Z", result.IsoDateUtc); - Assert.AreEqual(@"\/Date(-62135596800000)\/", result.MsDateRoundtrip); - Assert.AreEqual(@"\/Date(-62135596800000" + GetOffset(default(DateTime), DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateLocal); - Assert.AreEqual(@"\/Date(-62135596800000)\/", result.MsDateUnspecified); - Assert.AreEqual(@"\/Date(-62135596800000)\/", result.MsDateUtc); + result = TestDateTime("DateTime Min", DateTime.MinValue); + Assert.AreEqual("0001-01-01T00:00:00", result.IsoDateRoundtrip); + Assert.AreEqual("0001-01-01T00:00:00" + GetOffset(DateTime.MinValue, DateFormatHandling.IsoDateFormat), result.IsoDateLocal); + Assert.AreEqual("0001-01-01T00:00:00", result.IsoDateUnspecified); + Assert.AreEqual("0001-01-01T00:00:00Z", result.IsoDateUtc); + Assert.AreEqual(@"\/Date(-62135596800000)\/", result.MsDateRoundtrip); + Assert.AreEqual(@"\/Date(-62135596800000" + GetOffset(DateTime.MinValue, DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateLocal); + Assert.AreEqual(@"\/Date(-62135596800000)\/", result.MsDateUnspecified); + Assert.AreEqual(@"\/Date(-62135596800000)\/", result.MsDateUtc); + + result = TestDateTime("DateTime Default", default(DateTime)); + Assert.AreEqual("0001-01-01T00:00:00", result.IsoDateRoundtrip); + Assert.AreEqual("0001-01-01T00:00:00" + GetOffset(default(DateTime), DateFormatHandling.IsoDateFormat), result.IsoDateLocal); + Assert.AreEqual("0001-01-01T00:00:00", result.IsoDateUnspecified); + Assert.AreEqual("0001-01-01T00:00:00Z", result.IsoDateUtc); + Assert.AreEqual(@"\/Date(-62135596800000)\/", result.MsDateRoundtrip); + Assert.AreEqual(@"\/Date(-62135596800000" + GetOffset(default(DateTime), DateFormatHandling.MicrosoftDateFormat) + @")\/", result.MsDateLocal); + Assert.AreEqual(@"\/Date(-62135596800000)\/", result.MsDateUnspecified); + Assert.AreEqual(@"\/Date(-62135596800000)\/", result.MsDateUtc); #if !NET20 - result = TestDateTime("DateTimeOffset TimeSpan Zero", new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero)); - Assert.AreEqual("2000-01-01T01:01:01+00:00", result.IsoDateRoundtrip); - Assert.AreEqual(@"\/Date(946688461000+0000)\/", result.MsDateRoundtrip); + result = TestDateTime("DateTimeOffset TimeSpan Zero", new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero)); + Assert.AreEqual("2000-01-01T01:01:01+00:00", result.IsoDateRoundtrip); + Assert.AreEqual(@"\/Date(946688461000+0000)\/", result.MsDateRoundtrip); - result = TestDateTime("DateTimeOffset TimeSpan 1 hour", new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(1))); - Assert.AreEqual("2000-01-01T01:01:01+01:00", result.IsoDateRoundtrip); - Assert.AreEqual(@"\/Date(946684861000+0100)\/", result.MsDateRoundtrip); + result = TestDateTime("DateTimeOffset TimeSpan 1 hour", new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(1))); + Assert.AreEqual("2000-01-01T01:01:01+01:00", result.IsoDateRoundtrip); + Assert.AreEqual(@"\/Date(946684861000+0100)\/", result.MsDateRoundtrip); - result = TestDateTime("DateTimeOffset TimeSpan 1.5 hour", new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(1.5))); - Assert.AreEqual("2000-01-01T01:01:01+01:30", result.IsoDateRoundtrip); - Assert.AreEqual(@"\/Date(946683061000+0130)\/", result.MsDateRoundtrip); + result = TestDateTime("DateTimeOffset TimeSpan 1.5 hour", new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(1.5))); + Assert.AreEqual("2000-01-01T01:01:01+01:30", result.IsoDateRoundtrip); + Assert.AreEqual(@"\/Date(946683061000+0130)\/", result.MsDateRoundtrip); - result = TestDateTime("DateTimeOffset TimeSpan 13 hour", new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(13))); - Assert.AreEqual("2000-01-01T01:01:01+13:00", result.IsoDateRoundtrip); - Assert.AreEqual(@"\/Date(946641661000+1300)\/", result.MsDateRoundtrip); + result = TestDateTime("DateTimeOffset TimeSpan 13 hour", new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(13))); + Assert.AreEqual("2000-01-01T01:01:01+13:00", result.IsoDateRoundtrip); + Assert.AreEqual(@"\/Date(946641661000+1300)\/", result.MsDateRoundtrip); - result = TestDateTime("DateTimeOffset TimeSpan with ticks", new DateTimeOffset(634663873826822481, TimeSpan.Zero)); - Assert.AreEqual("2012-03-03T16:03:02.6822481+00:00", result.IsoDateRoundtrip); - Assert.AreEqual(@"\/Date(1330790582682+0000)\/", result.MsDateRoundtrip); + result = TestDateTime("DateTimeOffset TimeSpan with ticks", new DateTimeOffset(634663873826822481, TimeSpan.Zero)); + Assert.AreEqual("2012-03-03T16:03:02.6822481+00:00", result.IsoDateRoundtrip); + Assert.AreEqual(@"\/Date(1330790582682+0000)\/", result.MsDateRoundtrip); - result = TestDateTime("DateTimeOffset Min", DateTimeOffset.MinValue); - Assert.AreEqual("0001-01-01T00:00:00+00:00", result.IsoDateRoundtrip); - Assert.AreEqual(@"\/Date(-62135596800000+0000)\/", result.MsDateRoundtrip); + result = TestDateTime("DateTimeOffset Min", DateTimeOffset.MinValue); + Assert.AreEqual("0001-01-01T00:00:00+00:00", result.IsoDateRoundtrip); + Assert.AreEqual(@"\/Date(-62135596800000+0000)\/", result.MsDateRoundtrip); - result = TestDateTime("DateTimeOffset Max", DateTimeOffset.MaxValue); - Assert.AreEqual("9999-12-31T23:59:59.9999999+00:00", result.IsoDateRoundtrip); - Assert.AreEqual(@"\/Date(253402300799999+0000)\/", result.MsDateRoundtrip); + result = TestDateTime("DateTimeOffset Max", DateTimeOffset.MaxValue); + Assert.AreEqual("9999-12-31T23:59:59.9999999+00:00", result.IsoDateRoundtrip); + Assert.AreEqual(@"\/Date(253402300799999+0000)\/", result.MsDateRoundtrip); - result = TestDateTime("DateTimeOffset Default", default(DateTimeOffset)); - Assert.AreEqual("0001-01-01T00:00:00+00:00", result.IsoDateRoundtrip); - Assert.AreEqual(@"\/Date(-62135596800000+0000)\/", result.MsDateRoundtrip); + result = TestDateTime("DateTimeOffset Default", default(DateTimeOffset)); + Assert.AreEqual("0001-01-01T00:00:00+00:00", result.IsoDateRoundtrip); + Assert.AreEqual(@"\/Date(-62135596800000+0000)\/", result.MsDateRoundtrip); #endif - } + } - public class DateTimeResult - { - public string IsoDateRoundtrip { get; set; } - public string IsoDateLocal { get; set; } - public string IsoDateUnspecified { get; set; } - public string IsoDateUtc { get; set; } + public class DateTimeResult + { + public string IsoDateRoundtrip { get; set; } + public string IsoDateLocal { get; set; } + public string IsoDateUnspecified { get; set; } + public string IsoDateUtc { get; set; } - public string MsDateRoundtrip { get; set; } - public string MsDateLocal { get; set; } - public string MsDateUnspecified { get; set; } - public string MsDateUtc { get; set; } - } + public string MsDateRoundtrip { get; set; } + public string MsDateLocal { get; set; } + public string MsDateUnspecified { get; set; } + public string MsDateUtc { get; set; } + } - private DateTimeResult TestDateTime(string name, T value) - { - Console.WriteLine(name); + private DateTimeResult TestDateTime(string name, T value) + { + Console.WriteLine(name); - DateTimeResult result = new DateTimeResult(); + DateTimeResult result = new DateTimeResult(); - result.IsoDateRoundtrip = TestDateTimeFormat(value, DateFormatHandling.IsoDateFormat, DateTimeZoneHandling.RoundtripKind); - if (value is DateTime) - { - result.IsoDateLocal = TestDateTimeFormat(value, DateFormatHandling.IsoDateFormat, DateTimeZoneHandling.Local); - result.IsoDateUnspecified = TestDateTimeFormat(value, DateFormatHandling.IsoDateFormat, DateTimeZoneHandling.Unspecified); - result.IsoDateUtc = TestDateTimeFormat(value, DateFormatHandling.IsoDateFormat, DateTimeZoneHandling.Utc); - } + result.IsoDateRoundtrip = TestDateTimeFormat(value, DateFormatHandling.IsoDateFormat, DateTimeZoneHandling.RoundtripKind); + if (value is DateTime) + { + result.IsoDateLocal = TestDateTimeFormat(value, DateFormatHandling.IsoDateFormat, DateTimeZoneHandling.Local); + result.IsoDateUnspecified = TestDateTimeFormat(value, DateFormatHandling.IsoDateFormat, DateTimeZoneHandling.Unspecified); + result.IsoDateUtc = TestDateTimeFormat(value, DateFormatHandling.IsoDateFormat, DateTimeZoneHandling.Utc); + } - result.MsDateRoundtrip = TestDateTimeFormat(value, DateFormatHandling.MicrosoftDateFormat, DateTimeZoneHandling.RoundtripKind); - if (value is DateTime) - { - result.MsDateLocal = TestDateTimeFormat(value, DateFormatHandling.MicrosoftDateFormat, DateTimeZoneHandling.Local); - result.MsDateUnspecified = TestDateTimeFormat(value, DateFormatHandling.MicrosoftDateFormat, DateTimeZoneHandling.Unspecified); - result.MsDateUtc = TestDateTimeFormat(value, DateFormatHandling.MicrosoftDateFormat, DateTimeZoneHandling.Utc); - } + result.MsDateRoundtrip = TestDateTimeFormat(value, DateFormatHandling.MicrosoftDateFormat, DateTimeZoneHandling.RoundtripKind); + if (value is DateTime) + { + result.MsDateLocal = TestDateTimeFormat(value, DateFormatHandling.MicrosoftDateFormat, DateTimeZoneHandling.Local); + result.MsDateUnspecified = TestDateTimeFormat(value, DateFormatHandling.MicrosoftDateFormat, DateTimeZoneHandling.Unspecified); + result.MsDateUtc = TestDateTimeFormat(value, DateFormatHandling.MicrosoftDateFormat, DateTimeZoneHandling.Utc); + } - TestDateTimeFormat(value, new IsoDateTimeConverter()); + TestDateTimeFormat(value, new IsoDateTimeConverter()); #if !NETFX_CORE - if (value is DateTime) - { - Console.WriteLine(XmlConvert.ToString((DateTime)(object)value, XmlDateTimeSerializationMode.RoundtripKind)); - } - else - { - Console.WriteLine(XmlConvert.ToString((DateTimeOffset)(object)value)); - } + if (value is DateTime) + { + Console.WriteLine(XmlConvert.ToString((DateTime)(object)value, XmlDateTimeSerializationMode.RoundtripKind)); + } + else + { + Console.WriteLine(XmlConvert.ToString((DateTimeOffset)(object)value)); + } #endif #if !NET20 - MemoryStream ms = new MemoryStream(); - DataContractSerializer s = new DataContractSerializer(typeof(T)); - s.WriteObject(ms, value); - string json = Encoding.UTF8.GetString(ms.ToArray(), 0, Convert.ToInt32(ms.Length)); - Console.WriteLine(json); + MemoryStream ms = new MemoryStream(); + DataContractSerializer s = new DataContractSerializer(typeof(T)); + s.WriteObject(ms, value); + string json = Encoding.UTF8.GetString(ms.ToArray(), 0, Convert.ToInt32(ms.Length)); + Console.WriteLine(json); #endif - Console.WriteLine(); + Console.WriteLine(); - return result; - } + return result; + } - private static string TestDateTimeFormat(T value, DateFormatHandling format, DateTimeZoneHandling timeZoneHandling) - { - string date = null; + private static string TestDateTimeFormat(T value, DateFormatHandling format, DateTimeZoneHandling timeZoneHandling) + { + string date = null; - if (value is DateTime) - { - date = JsonConvert.ToString((DateTime)(object)value, format, timeZoneHandling); - } - else - { + if (value is DateTime) + { + date = JsonConvert.ToString((DateTime)(object)value, format, timeZoneHandling); + } + else + { #if !NET20 - date = JsonConvert.ToString((DateTimeOffset)(object)value, format); + date = JsonConvert.ToString((DateTimeOffset)(object)value, format); #endif - } + } - Console.WriteLine(format.ToString("g") + "-" + timeZoneHandling.ToString("g") + ": " + date); + Console.WriteLine(format.ToString("g") + "-" + timeZoneHandling.ToString("g") + ": " + date); - if (timeZoneHandling == DateTimeZoneHandling.RoundtripKind) - { - T parsed = JsonConvert.DeserializeObject(date); - try - { - Assert.AreEqual(value, parsed); + if (timeZoneHandling == DateTimeZoneHandling.RoundtripKind) + { + T parsed = JsonConvert.DeserializeObject(date); + try + { + Assert.AreEqual(value, parsed); + } + catch (Exception) + { + long valueTicks = GetTicks(value); + long parsedTicks = GetTicks(parsed); + + valueTicks = (valueTicks / 10000) * 10000; + + Assert.AreEqual(valueTicks, parsedTicks); + } + } + + return date.Trim('"'); } - catch (Exception) + + private static void TestDateTimeFormat(T value, JsonConverter converter) { - long valueTicks = GetTicks(value); - long parsedTicks = GetTicks(parsed); + string date = Write(value, converter); - valueTicks = (valueTicks/10000)*10000; + Console.WriteLine(converter.GetType().Name + ": " + date); - Assert.AreEqual(valueTicks, parsedTicks); + T parsed = Read(date, converter); + + try + { + Assert.AreEqual(value, parsed); + } + catch (Exception) + { + // JavaScript ticks aren't as precise, recheck after rounding + long valueTicks = GetTicks(value); + long parsedTicks = GetTicks(parsed); + + valueTicks = (valueTicks / 10000) * 10000; + + Assert.AreEqual(valueTicks, parsedTicks); + } } - } - return date.Trim('"'); - } + public static long GetTicks(object value) + { + return (value is DateTime) ? ((DateTime)value).Ticks : ((DateTimeOffset)value).Ticks; + } - private static void TestDateTimeFormat(T value, JsonConverter converter) - { - string date = Write(value, converter); + public static string Write(object value, JsonConverter converter) + { + StringWriter sw = new StringWriter(); + JsonTextWriter writer = new JsonTextWriter(sw); + converter.WriteJson(writer, value, null); - Console.WriteLine(converter.GetType().Name + ": " + date); + writer.Flush(); + return sw.ToString(); + } - T parsed = Read(date, converter); + public static T Read(string text, JsonConverter converter) + { + JsonTextReader reader = new JsonTextReader(new StringReader(text)); + reader.ReadAsString(); - try - { - Assert.AreEqual(value, parsed); - } - catch (Exception) - { - // JavaScript ticks aren't as precise, recheck after rounding - long valueTicks = GetTicks(value); - long parsedTicks = GetTicks(parsed); - - valueTicks = (valueTicks / 10000) * 10000; - - Assert.AreEqual(valueTicks, parsedTicks); - } - } - - public static long GetTicks(object value) - { - return (value is DateTime) ? ((DateTime)value).Ticks : ((DateTimeOffset)value).Ticks; - } - - public static string Write(object value, JsonConverter converter) - { - StringWriter sw = new StringWriter(); - JsonTextWriter writer = new JsonTextWriter(sw); - converter.WriteJson(writer, value, null); - - writer.Flush(); - return sw.ToString(); - } - - public static T Read(string text, JsonConverter converter) - { - JsonTextReader reader = new JsonTextReader(new StringReader(text)); - reader.ReadAsString(); - - return (T)converter.ReadJson(reader, typeof(T), null, null); - } + return (T)converter.ReadJson(reader, typeof(T), null, null); + } #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40) - [Test] - public void Async() - { - Task task = null; - - task = JsonConvert.SerializeObjectAsync(42); - task.Wait(); + [Test] + public void Async() + { + Task task = null; - Assert.AreEqual("42", task.Result); + task = JsonConvert.SerializeObjectAsync(42); + task.Wait(); - task = JsonConvert.SerializeObjectAsync(new[] {1, 2, 3, 4, 5}, Formatting.Indented); - task.Wait(); + Assert.AreEqual("42", task.Result); - Assert.AreEqual(@"[ + task = JsonConvert.SerializeObjectAsync(new[] { 1, 2, 3, 4, 5 }, Formatting.Indented); + task.Wait(); + + Assert.AreEqual(@"[ 1, 2, 3, @@ -897,74 +895,74 @@ now brown cow?", '"', true); 5 ]", task.Result); - task = JsonConvert.SerializeObjectAsync(DateTime.MaxValue, Formatting.None, new JsonSerializerSettings - { - DateFormatHandling = DateFormatHandling.MicrosoftDateFormat - }); - task.Wait(); + task = JsonConvert.SerializeObjectAsync(DateTime.MaxValue, Formatting.None, new JsonSerializerSettings + { + DateFormatHandling = DateFormatHandling.MicrosoftDateFormat + }); + task.Wait(); - Assert.AreEqual(@"""\/Date(253402300799999)\/""", task.Result); + Assert.AreEqual(@"""\/Date(253402300799999)\/""", task.Result); - var taskObject = JsonConvert.DeserializeObjectAsync("[]"); - taskObject.Wait(); + var taskObject = JsonConvert.DeserializeObjectAsync("[]"); + taskObject.Wait(); - CollectionAssert.AreEquivalent(new JArray(), (JArray)taskObject.Result); + CollectionAssert.AreEquivalent(new JArray(), (JArray)taskObject.Result); - Task taskVersionArray = JsonConvert.DeserializeObjectAsync("['2.0']", typeof(Version[]), new JsonSerializerSettings - { - Converters = {new VersionConverter()} - }); - taskVersionArray.Wait(); + Task taskVersionArray = JsonConvert.DeserializeObjectAsync("['2.0']", typeof(Version[]), new JsonSerializerSettings + { + Converters = { new VersionConverter() } + }); + taskVersionArray.Wait(); - Version[] versionArray = (Version[])taskVersionArray.Result; + Version[] versionArray = (Version[])taskVersionArray.Result; - Assert.AreEqual(1, versionArray.Length); - Assert.AreEqual(2, versionArray[0].Major); + Assert.AreEqual(1, versionArray.Length); + Assert.AreEqual(2, versionArray[0].Major); - Task taskInt = JsonConvert.DeserializeObjectAsync("5"); - taskInt.Wait(); + Task taskInt = JsonConvert.DeserializeObjectAsync("5"); + taskInt.Wait(); - Assert.AreEqual(5, taskInt.Result); + Assert.AreEqual(5, taskInt.Result); - var taskVersion = JsonConvert.DeserializeObjectAsync("'2.0'", new JsonSerializerSettings - { - Converters = {new VersionConverter()} - }); - taskVersion.Wait(); + var taskVersion = JsonConvert.DeserializeObjectAsync("'2.0'", new JsonSerializerSettings + { + Converters = { new VersionConverter() } + }); + taskVersion.Wait(); - Assert.AreEqual(2, taskVersion.Result.Major); + Assert.AreEqual(2, taskVersion.Result.Major); - Movie p = new Movie(); - p.Name = "Existing,"; + Movie p = new Movie(); + p.Name = "Existing,"; - Task taskVoid = JsonConvert.PopulateObjectAsync("{'Name':'Appended'}", p, new JsonSerializerSettings - { - Converters = new List { new JsonSerializerTest.StringAppenderConverter() } - }); + Task taskVoid = JsonConvert.PopulateObjectAsync("{'Name':'Appended'}", p, new JsonSerializerSettings + { + Converters = new List { new JsonSerializerTest.StringAppenderConverter() } + }); - taskVoid.Wait(); + taskVoid.Wait(); - Assert.AreEqual("Existing,Appended", p.Name); - } + Assert.AreEqual("Existing,Appended", p.Name); + } #endif - [Test] - public void SerializeObjectDateTimeZoneHandling() - { - string json = JsonConvert.SerializeObject( - new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Unspecified), - new JsonSerializerSettings + [Test] + public void SerializeObjectDateTimeZoneHandling() { - DateTimeZoneHandling = DateTimeZoneHandling.Utc - }); + string json = JsonConvert.SerializeObject( + new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Unspecified), + new JsonSerializerSettings + { + DateTimeZoneHandling = DateTimeZoneHandling.Utc + }); - Assert.AreEqual(@"""2000-01-01T01:01:01Z""", json); - } + Assert.AreEqual(@"""2000-01-01T01:01:01Z""", json); + } - [Test] - public void DeserializeObject() - { - string json = @"{ + [Test] + public void DeserializeObject() + { + string json = @"{ 'Name': 'Bad Boys', 'ReleaseDate': '1995-4-7T00:00:00', 'Genres': [ @@ -973,40 +971,40 @@ now brown cow?", '"', true); ] }"; - Movie m = JsonConvert.DeserializeObject(json); + Movie m = JsonConvert.DeserializeObject(json); - string name = m.Name; - // Bad Boys + string name = m.Name; + // Bad Boys - Assert.AreEqual("Bad Boys", m.Name); + Assert.AreEqual("Bad Boys", m.Name); + } + + //[Test] + public void StackOverflowTest() + { + StringBuilder sb = new StringBuilder(); + + int depth = 900; + for (int i = 0; i < depth; i++) + { + sb.Append("{'A':"); + } + + // invalid json + sb.Append("{***}"); + for (int i = 0; i < depth; i++) + { + sb.Append("}"); + } + + string json = sb.ToString(); + JsonSerializer serializer = new JsonSerializer() { }; + serializer.Deserialize(new JsonTextReader(new StringReader(json))); + } + + public class Nest + { + public Nest A { get; set; } + } } - - //[Test] - public void StackOverflowTest() - { - StringBuilder sb = new StringBuilder(); - - int depth = 900; - for (int i = 0; i < depth; i++) - { - sb.Append("{'A':"); - } - - // invalid json - sb.Append("{***}"); - for (int i = 0; i < depth; i++) - { - sb.Append("}"); - } - - string json = sb.ToString(); - JsonSerializer serializer = new JsonSerializer() { }; - serializer.Deserialize(new JsonTextReader(new StringReader(json))); - } - - public class Nest - { - public Nest A { get; set; } - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs b/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs index ca628dcc..af8f9f6a 100644 --- a/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs +++ b/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs @@ -44,116 +44,113 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Tests { - [TestFixture] - public class JsonTextReaderTest : TestFixtureBase - { - [Test] - public void ThrowErrorWhenParsingUnquoteStringThatStartsWithNE() + [TestFixture] + public class JsonTextReaderTest : TestFixtureBase { - const string json = @"{ ""ItemName"": ""value"", ""u"":netanelsalinger,""r"":9 }"; + [Test] + public void ThrowErrorWhenParsingUnquoteStringThatStartsWithNE() + { + const string json = @"{ ""ItemName"": ""value"", ""u"":netanelsalinger,""r"":9 }"; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); + JsonTextReader reader = new JsonTextReader(new StringReader(json)); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - ExceptionAssert.Throws("Unexpected content while parsing JSON. Path 'u', line 1, position 27.", - () => - { - reader.Read(); - }); - } + ExceptionAssert.Throws("Unexpected content while parsing JSON. Path 'u', line 1, position 27.", + () => { reader.Read(); }); + } - [Test] - public void FloatParseHandling() - { - string json = "[1.0,1,9.9,1E-06]"; + [Test] + public void FloatParseHandling() + { + string json = "[1.0,1,9.9,1E-06]"; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - reader.FloatParseHandling = Json.FloatParseHandling.Decimal; + JsonTextReader reader = new JsonTextReader(new StringReader(json)); + reader.FloatParseHandling = Json.FloatParseHandling.Decimal; - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(1.0m, reader.Value); - Assert.AreEqual(typeof(decimal), reader.ValueType); - Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(1.0m, reader.Value); + Assert.AreEqual(typeof(decimal), reader.ValueType); + Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(1L, reader.Value); - Assert.AreEqual(typeof(long), reader.ValueType); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(1L, reader.Value); + Assert.AreEqual(typeof(long), reader.ValueType); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(9.9m, reader.Value); - Assert.AreEqual(typeof(decimal), reader.ValueType); - Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(9.9m, reader.Value); + Assert.AreEqual(typeof(decimal), reader.ValueType); + Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(Convert.ToDecimal(1E-06), reader.Value); - Assert.AreEqual(typeof(decimal), reader.ValueType); - Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(Convert.ToDecimal(1E-06), reader.Value); + Assert.AreEqual(typeof(decimal), reader.ValueType); + Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - } + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + } - [Test] - public void FloatParseHandling_NaN() - { - string json = "[NaN]"; + [Test] + public void FloatParseHandling_NaN() + { + string json = "[NaN]"; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - reader.FloatParseHandling = Json.FloatParseHandling.Decimal; + JsonTextReader reader = new JsonTextReader(new StringReader(json)); + reader.FloatParseHandling = Json.FloatParseHandling.Decimal; - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - ExceptionAssert.Throws( - "Cannot read NaN as a decimal.", - () => reader.Read()); - } + ExceptionAssert.Throws( + "Cannot read NaN as a decimal.", + () => reader.Read()); + } - [Test] - public void UnescapeDoubleQuotes() - { - string json = @"{""recipe_id"":""12"",""recipe_name"":""Apocalypse Leather Armors"",""recipe_text"":""#C16------------------------------\r\n#C12Ingredients #C20\r\n#C16------------------------------\r\n\r\na piece of Leather Armor\r\n( ie #L \""Enhanced Leather Armor Boots\"" \""85644\"" )\r\n\r\n\r\n#L \""Hacker Tool\"" \""87814\""\r\n\r\n\r\n#L \""Clanalizer\"" \""208313\""\r\n\r\n\r\n#C16------------------------------\r\n#C12Recipe #C16\r\n#C16------------------------------#C20\r\n\r\nHacker Tool\r\n#C15+#C20\r\na piece of Leather Armor\r\n#C15=#C20\r\n\r\na piece of Hacked Leather Armor\r\n( ie : #L \""Hacked Leather Armor Boots\"" \""245979\"" )\r\n#C16Skills: | BE |#C20\r\n\r\n#C14------------------------------#C20\r\n\r\nClanalizer\r\n#C15+#C20\r\na piece of Hacked Leather Armor\r\n#C15=#C20\r\n\r\na piece of Apocalypse Leather Armor\r\n( ie : #L \""Apocalypse Leather Armor Boots\"" \""245966\"" )\r\n#C16Skills: | ?? |#C20\r\n\r\n#C16------------------------------\r\n#C12Details#C16\r\n#C16------------------------------#C20\r\n\r\n#L \""Apocalypse Leather Armor Boots\"" \""245967\""\r\n#L \""Apocalypse Leather Armor Gloves\"" \""245969\""\r\n#L \""Apocalypse Leather Armor Helmet\"" \""245975\""\r\n#L \""Apocalypse Leather Armor Pants\"" \""245971\""\r\n#L \""Apocalypse Leather Armor Sleeves\"" \""245973\""\r\n#L \""Apocalypse Leather Body Armor\"" \""245965\""\r\n\r\n#C16------------------------------\r\n#C12Comments#C16\r\n#C16------------------------------#C20\r\n\r\nNice froob armor.. but ugleh!\r\n\r\n"",""recipe_author"":null}"; + [Test] + public void UnescapeDoubleQuotes() + { + string json = @"{""recipe_id"":""12"",""recipe_name"":""Apocalypse Leather Armors"",""recipe_text"":""#C16------------------------------\r\n#C12Ingredients #C20\r\n#C16------------------------------\r\n\r\na piece of Leather Armor\r\n( ie #L \""Enhanced Leather Armor Boots\"" \""85644\"" )\r\n\r\n\r\n#L \""Hacker Tool\"" \""87814\""\r\n\r\n\r\n#L \""Clanalizer\"" \""208313\""\r\n\r\n\r\n#C16------------------------------\r\n#C12Recipe #C16\r\n#C16------------------------------#C20\r\n\r\nHacker Tool\r\n#C15+#C20\r\na piece of Leather Armor\r\n#C15=#C20\r\n\r\na piece of Hacked Leather Armor\r\n( ie : #L \""Hacked Leather Armor Boots\"" \""245979\"" )\r\n#C16Skills: | BE |#C20\r\n\r\n#C14------------------------------#C20\r\n\r\nClanalizer\r\n#C15+#C20\r\na piece of Hacked Leather Armor\r\n#C15=#C20\r\n\r\na piece of Apocalypse Leather Armor\r\n( ie : #L \""Apocalypse Leather Armor Boots\"" \""245966\"" )\r\n#C16Skills: | ?? |#C20\r\n\r\n#C16------------------------------\r\n#C12Details#C16\r\n#C16------------------------------#C20\r\n\r\n#L \""Apocalypse Leather Armor Boots\"" \""245967\""\r\n#L \""Apocalypse Leather Armor Gloves\"" \""245969\""\r\n#L \""Apocalypse Leather Armor Helmet\"" \""245975\""\r\n#L \""Apocalypse Leather Armor Pants\"" \""245971\""\r\n#L \""Apocalypse Leather Armor Sleeves\"" \""245973\""\r\n#L \""Apocalypse Leather Body Armor\"" \""245965\""\r\n\r\n#C16------------------------------\r\n#C12Comments#C16\r\n#C16------------------------------#C20\r\n\r\nNice froob armor.. but ugleh!\r\n\r\n"",""recipe_author"":null}"; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); + JsonTextReader reader = new JsonTextReader(new StringReader(json)); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("recipe_text", reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("recipe_text", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual(@"#C16------------------------------ + Assert.AreEqual(@"#C16------------------------------ #C12Ingredients #C20 #C16------------------------------ @@ -209,97 +206,97 @@ a piece of Apocalypse Leather Armor Nice froob armor.. but ugleh! ", reader.Value); - } + } - [Test] - public void SurrogatePairValid() - { - string json = @"{ ""MATHEMATICAL ITALIC CAPITAL ALPHA"": ""\uD835\uDEE2"" }"; + [Test] + public void SurrogatePairValid() + { + string json = @"{ ""MATHEMATICAL ITALIC CAPITAL ALPHA"": ""\uD835\uDEE2"" }"; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); + JsonTextReader reader = new JsonTextReader(new StringReader(json)); - Assert.IsTrue(reader.Read()); - Assert.IsTrue(reader.Read()); + Assert.IsTrue(reader.Read()); + Assert.IsTrue(reader.Read()); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); - string s = reader.Value.ToString(); - Assert.AreEqual(2, s.Length); + string s = reader.Value.ToString(); + Assert.AreEqual(2, s.Length); - StringInfo stringInfo = new StringInfo(s); - Assert.AreEqual(1, stringInfo.LengthInTextElements); - } + StringInfo stringInfo = new StringInfo(s); + Assert.AreEqual(1, stringInfo.LengthInTextElements); + } - [Test] - public void SurrogatePairReplacement() - { - // existing good surrogate pair - Assert.AreEqual("ABC \ud800\udc00 DEF", ReadString("ABC \\ud800\\udc00 DEF")); + [Test] + public void SurrogatePairReplacement() + { + // existing good surrogate pair + Assert.AreEqual("ABC \ud800\udc00 DEF", ReadString("ABC \\ud800\\udc00 DEF")); - // invalid surrogates (two high back-to-back) - Assert.AreEqual("ABC \ufffd\ufffd DEF", ReadString("ABC \\ud800\\ud800 DEF")); + // invalid surrogates (two high back-to-back) + Assert.AreEqual("ABC \ufffd\ufffd DEF", ReadString("ABC \\ud800\\ud800 DEF")); - // invalid surrogates (two high back-to-back) - Assert.AreEqual("ABC \ufffd\ufffd\u1234 DEF", ReadString("ABC \\ud800\\ud800\\u1234 DEF")); + // invalid surrogates (two high back-to-back) + Assert.AreEqual("ABC \ufffd\ufffd\u1234 DEF", ReadString("ABC \\ud800\\ud800\\u1234 DEF")); - // invalid surrogates (three high back-to-back) - Assert.AreEqual("ABC \ufffd\ufffd\ufffd DEF", ReadString("ABC \\ud800\\ud800\\ud800 DEF")); + // invalid surrogates (three high back-to-back) + Assert.AreEqual("ABC \ufffd\ufffd\ufffd DEF", ReadString("ABC \\ud800\\ud800\\ud800 DEF")); - // invalid surrogates (high followed by a good surrogate pair) - Assert.AreEqual("ABC \ufffd\ud800\udc00 DEF", ReadString("ABC \\ud800\\ud800\\udc00 DEF")); + // invalid surrogates (high followed by a good surrogate pair) + Assert.AreEqual("ABC \ufffd\ud800\udc00 DEF", ReadString("ABC \\ud800\\ud800\\udc00 DEF")); - // invalid high surrogate at end of string - Assert.AreEqual("ABC \ufffd", ReadString("ABC \\ud800")); + // invalid high surrogate at end of string + Assert.AreEqual("ABC \ufffd", ReadString("ABC \\ud800")); - // high surrogate not followed by low surrogate - Assert.AreEqual("ABC \ufffd DEF", ReadString("ABC \\ud800 DEF")); + // high surrogate not followed by low surrogate + Assert.AreEqual("ABC \ufffd DEF", ReadString("ABC \\ud800 DEF")); - // low surrogate not preceded by high surrogate - Assert.AreEqual("ABC \ufffd\ufffd DEF", ReadString("ABC \\udc00\\ud800 DEF")); + // low surrogate not preceded by high surrogate + Assert.AreEqual("ABC \ufffd\ufffd DEF", ReadString("ABC \\udc00\\ud800 DEF")); - // make sure unencoded invalid surrogate characters don't make it through - Assert.AreEqual("\ufffd\ufffd\ufffd", ReadString("\udc00\ud800\ud800")); + // make sure unencoded invalid surrogate characters don't make it through + Assert.AreEqual("\ufffd\ufffd\ufffd", ReadString("\udc00\ud800\ud800")); - Assert.AreEqual("ABC \ufffd\b", ReadString("ABC \\ud800\\b")); - Assert.AreEqual("ABC \ufffd ", ReadString("ABC \\ud800 ")); - Assert.AreEqual("ABC \b\ufffd", ReadString("ABC \\b\\ud800")); - } + Assert.AreEqual("ABC \ufffd\b", ReadString("ABC \\ud800\\b")); + Assert.AreEqual("ABC \ufffd ", ReadString("ABC \\ud800 ")); + Assert.AreEqual("ABC \b\ufffd", ReadString("ABC \\b\\ud800")); + } - private string ReadString(string input) - { - MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(@"""" + input + @"""")); + private string ReadString(string input) + { + MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(@"""" + input + @"""")); - JsonTextReader reader = new JsonTextReader(new StreamReader(ms)); - reader.Read(); + JsonTextReader reader = new JsonTextReader(new StreamReader(ms)); + reader.Read(); - string s = (string)reader.Value; + string s = (string)reader.Value; - return s; - } + return s; + } - [Test] - public void CloseInput() - { - MemoryStream ms = new MemoryStream(); - JsonTextReader reader = new JsonTextReader(new StreamReader(ms)); + [Test] + public void CloseInput() + { + MemoryStream ms = new MemoryStream(); + JsonTextReader reader = new JsonTextReader(new StreamReader(ms)); - Assert.IsTrue(ms.CanRead); - reader.Close(); - Assert.IsFalse(ms.CanRead); + Assert.IsTrue(ms.CanRead); + reader.Close(); + Assert.IsFalse(ms.CanRead); - ms = new MemoryStream(); - reader = new JsonTextReader(new StreamReader(ms)) { CloseInput = false }; + ms = new MemoryStream(); + reader = new JsonTextReader(new StreamReader(ms)) { CloseInput = false }; - Assert.IsTrue(ms.CanRead); - reader.Close(); - Assert.IsTrue(ms.CanRead); - } - - [Test] - public void YahooFinance() - { - string input = @"{ + Assert.IsTrue(ms.CanRead); + reader.Close(); + Assert.IsTrue(ms.CanRead); + } + + [Test] + public void YahooFinance() + { + string input = @"{ ""matches"" : [ {""t"":""C"", ""n"":""Citigroup Inc."", ""e"":""NYSE"", ""id"":""662713""} ,{""t"":""CHL"", ""n"":""China Mobile Ltd. (ADR)"", ""e"":""NYSE"", ""id"":""660998""} @@ -320,103 +317,100 @@ Nice froob armor.. but ugleh! } "; - using (JsonReader jsonReader = new JsonTextReader(new StringReader(input))) - { - while (jsonReader.Read()) - { - Console.WriteLine(jsonReader.Value); + using (JsonReader jsonReader = new JsonTextReader(new StringReader(input))) + { + while (jsonReader.Read()) + { + Console.WriteLine(jsonReader.Value); + } + } } - } - } - [Test] - public void ReadConstructor() - { - string json = @"{""DefaultConverter"":new Date(0, ""hi""),""MemberConverter"":""1970-01-01T00:00:00Z""}"; + [Test] + public void ReadConstructor() + { + string json = @"{""DefaultConverter"":new Date(0, ""hi""),""MemberConverter"":""1970-01-01T00:00:00Z""}"; - JsonReader reader = new JsonTextReader(new StreamReader(new SlowStream(json, new UTF8Encoding(false), 1))); + JsonReader reader = new JsonTextReader(new StreamReader(new SlowStream(json, new UTF8Encoding(false), 1))); - Assert.IsTrue(reader.Read()); - Assert.IsTrue(reader.Read()); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartConstructor, reader.TokenType); - Assert.AreEqual("Date", reader.Value); + Assert.IsTrue(reader.Read()); + Assert.IsTrue(reader.Read()); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartConstructor, reader.TokenType); + Assert.AreEqual("Date", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(0L, reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(0L, reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual("hi", reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual("hi", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndConstructor, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndConstructor, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual("MemberConverter", reader.Value); - } + Assert.IsTrue(reader.Read()); + Assert.AreEqual("MemberConverter", reader.Value); + } - [Test] - public void ParseAdditionalContent_Comma() - { - string json = @"[ + [Test] + public void ParseAdditionalContent_Comma() + { + string json = @"[ ""Small"", ""Medium"", ""Large"" ],"; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); + JsonTextReader reader = new JsonTextReader(new StringReader(json)); - ExceptionAssert.Throws( - "Additional text encountered after finished reading JSON content: ,. Path '', line 5, position 2.", - () => - { - while (reader.Read()) - { - } - }); - } + ExceptionAssert.Throws( + "Additional text encountered after finished reading JSON content: ,. Path '', line 5, position 2.", + () => + { + while (reader.Read()) + { + } + }); + } - [Test] - public void ParseAdditionalContent_Text() - { - string json = @"[ + [Test] + public void ParseAdditionalContent_Text() + { + string json = @"[ ""Small"", ""Medium"", ""Large"" ]content"; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); + JsonTextReader reader = new JsonTextReader(new StringReader(json)); #if DEBUG - reader.SetCharBuffer(new char[2]); + reader.SetCharBuffer(new char[2]); #endif - reader.Read(); - Assert.AreEqual(1, reader.LineNumber); - - reader.Read(); - Assert.AreEqual(2, reader.LineNumber); - - reader.Read(); - Assert.AreEqual(3, reader.LineNumber); - - reader.Read(); - Assert.AreEqual(4, reader.LineNumber); - - reader.Read(); - Assert.AreEqual(5, reader.LineNumber); - - ExceptionAssert.Throws( - "Additional text encountered after finished reading JSON content: c. Path '', line 5, position 2.", - () => - { reader.Read(); - }); - } + Assert.AreEqual(1, reader.LineNumber); - [Test] - public void ParseAdditionalContent_Whitespace() - { - string json = @"[ + reader.Read(); + Assert.AreEqual(2, reader.LineNumber); + + reader.Read(); + Assert.AreEqual(3, reader.LineNumber); + + reader.Read(); + Assert.AreEqual(4, reader.LineNumber); + + reader.Read(); + Assert.AreEqual(5, reader.LineNumber); + + ExceptionAssert.Throws( + "Additional text encountered after finished reading JSON content: c. Path '', line 5, position 2.", + () => { reader.Read(); }); + } + + [Test] + public void ParseAdditionalContent_Whitespace() + { + string json = @"[ ""Small"", ""Medium"", ""Large"" @@ -424,33 +418,33 @@ Nice froob armor.. but ugleh! "; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - while (reader.Read()) - { - } - } - - [Test] - public void ParseAdditionalContent_WhitespaceThenText() - { - string json = @"'hi' a"; - - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - - ExceptionAssert.Throws( - "Additional text encountered after finished reading JSON content: a. Path '', line 1, position 5.", - () => - { + JsonTextReader reader = new JsonTextReader(new StringReader(json)); while (reader.Read()) { } - }); - } + } - [Test] - public void ReadingIndented() - { - string input = @"{ + [Test] + public void ParseAdditionalContent_WhitespaceThenText() + { + string json = @"'hi' a"; + + JsonTextReader reader = new JsonTextReader(new StringReader(json)); + + ExceptionAssert.Throws( + "Additional text encountered after finished reading JSON content: a. Path '', line 1, position 5.", + () => + { + while (reader.Read()) + { + } + }); + } + + [Test] + public void ReadingIndented() + { + string input = @"{ CPU: 'Intel', Drives: [ 'DVD read/writer', @@ -458,315 +452,309 @@ Nice froob armor.. but ugleh! ] }"; - StringReader sr = new StringReader(input); + StringReader sr = new StringReader(input); - using (JsonTextReader jsonReader = new JsonTextReader(sr)) - { + using (JsonTextReader jsonReader = new JsonTextReader(sr)) + { #if DEBUG - jsonReader.SetCharBuffer(new char[5]); + jsonReader.SetCharBuffer(new char[5]); #endif - Assert.AreEqual(jsonReader.TokenType, JsonToken.None); - Assert.AreEqual(0, jsonReader.LineNumber); - Assert.AreEqual(0, jsonReader.LinePosition); + Assert.AreEqual(jsonReader.TokenType, JsonToken.None); + Assert.AreEqual(0, jsonReader.LineNumber); + Assert.AreEqual(0, jsonReader.LinePosition); - jsonReader.Read(); - Assert.AreEqual(jsonReader.TokenType, JsonToken.StartObject); - Assert.AreEqual(1, jsonReader.LineNumber); - Assert.AreEqual(1, jsonReader.LinePosition); + jsonReader.Read(); + Assert.AreEqual(jsonReader.TokenType, JsonToken.StartObject); + Assert.AreEqual(1, jsonReader.LineNumber); + Assert.AreEqual(1, jsonReader.LinePosition); - jsonReader.Read(); - Assert.AreEqual(jsonReader.TokenType, JsonToken.PropertyName); - Assert.AreEqual(jsonReader.Value, "CPU"); - Assert.AreEqual(2, jsonReader.LineNumber); - Assert.AreEqual(7, jsonReader.LinePosition); + jsonReader.Read(); + Assert.AreEqual(jsonReader.TokenType, JsonToken.PropertyName); + Assert.AreEqual(jsonReader.Value, "CPU"); + Assert.AreEqual(2, jsonReader.LineNumber); + Assert.AreEqual(7, jsonReader.LinePosition); - jsonReader.Read(); - Assert.AreEqual(JsonToken.String, jsonReader.TokenType); - Assert.AreEqual("Intel", jsonReader.Value); - Assert.AreEqual(2, jsonReader.LineNumber); - Assert.AreEqual(15, jsonReader.LinePosition); + jsonReader.Read(); + Assert.AreEqual(JsonToken.String, jsonReader.TokenType); + Assert.AreEqual("Intel", jsonReader.Value); + Assert.AreEqual(2, jsonReader.LineNumber); + Assert.AreEqual(15, jsonReader.LinePosition); - jsonReader.Read(); - Assert.AreEqual(jsonReader.TokenType, JsonToken.PropertyName); - Assert.AreEqual(jsonReader.Value, "Drives"); - Assert.AreEqual(3, jsonReader.LineNumber); - Assert.AreEqual(10, jsonReader.LinePosition); + jsonReader.Read(); + Assert.AreEqual(jsonReader.TokenType, JsonToken.PropertyName); + Assert.AreEqual(jsonReader.Value, "Drives"); + Assert.AreEqual(3, jsonReader.LineNumber); + Assert.AreEqual(10, jsonReader.LinePosition); - jsonReader.Read(); - Assert.AreEqual(jsonReader.TokenType, JsonToken.StartArray); - Assert.AreEqual(3, jsonReader.LineNumber); - Assert.AreEqual(12, jsonReader.LinePosition); + jsonReader.Read(); + Assert.AreEqual(jsonReader.TokenType, JsonToken.StartArray); + Assert.AreEqual(3, jsonReader.LineNumber); + Assert.AreEqual(12, jsonReader.LinePosition); - jsonReader.Read(); - Assert.AreEqual(jsonReader.TokenType, JsonToken.String); - Assert.AreEqual(jsonReader.Value, "DVD read/writer"); - Assert.AreEqual(jsonReader.QuoteChar, '\''); - Assert.AreEqual(4, jsonReader.LineNumber); - Assert.AreEqual(22, jsonReader.LinePosition); + jsonReader.Read(); + Assert.AreEqual(jsonReader.TokenType, JsonToken.String); + Assert.AreEqual(jsonReader.Value, "DVD read/writer"); + Assert.AreEqual(jsonReader.QuoteChar, '\''); + Assert.AreEqual(4, jsonReader.LineNumber); + Assert.AreEqual(22, jsonReader.LinePosition); - jsonReader.Read(); - Assert.AreEqual(jsonReader.TokenType, JsonToken.String); - Assert.AreEqual(jsonReader.Value, "500 gigabyte hard drive"); - Assert.AreEqual(jsonReader.QuoteChar, '"'); - Assert.AreEqual(5, jsonReader.LineNumber); - Assert.AreEqual(30, jsonReader.LinePosition); + jsonReader.Read(); + Assert.AreEqual(jsonReader.TokenType, JsonToken.String); + Assert.AreEqual(jsonReader.Value, "500 gigabyte hard drive"); + Assert.AreEqual(jsonReader.QuoteChar, '"'); + Assert.AreEqual(5, jsonReader.LineNumber); + Assert.AreEqual(30, jsonReader.LinePosition); - jsonReader.Read(); - Assert.AreEqual(jsonReader.TokenType, JsonToken.EndArray); - Assert.AreEqual(6, jsonReader.LineNumber); - Assert.AreEqual(4, jsonReader.LinePosition); + jsonReader.Read(); + Assert.AreEqual(jsonReader.TokenType, JsonToken.EndArray); + Assert.AreEqual(6, jsonReader.LineNumber); + Assert.AreEqual(4, jsonReader.LinePosition); - jsonReader.Read(); - Assert.AreEqual(jsonReader.TokenType, JsonToken.EndObject); - Assert.AreEqual(7, jsonReader.LineNumber); - Assert.AreEqual(2, jsonReader.LinePosition); + jsonReader.Read(); + Assert.AreEqual(jsonReader.TokenType, JsonToken.EndObject); + Assert.AreEqual(7, jsonReader.LineNumber); + Assert.AreEqual(2, jsonReader.LinePosition); - Assert.IsFalse(jsonReader.Read()); - } - } + Assert.IsFalse(jsonReader.Read()); + } + } - [Test] - public void Depth() - { - string input = @"{ + [Test] + public void Depth() + { + string input = @"{ value:'Purple', array:[1,2,new Date(1)], subobject:{prop:1,proparray:[1]} }"; - StringReader sr = new StringReader(input); + StringReader sr = new StringReader(input); - using (JsonReader reader = new JsonTextReader(sr)) - { - Assert.AreEqual(0, reader.Depth); + using (JsonReader reader = new JsonTextReader(sr)) + { + Assert.AreEqual(0, reader.Depth); - reader.Read(); - Assert.AreEqual(reader.TokenType, JsonToken.StartObject); - Assert.AreEqual(0, reader.Depth); - Assert.AreEqual("", reader.Path); + reader.Read(); + Assert.AreEqual(reader.TokenType, JsonToken.StartObject); + Assert.AreEqual(0, reader.Depth); + Assert.AreEqual("", reader.Path); - reader.Read(); - Assert.AreEqual(reader.TokenType, JsonToken.PropertyName); - Assert.AreEqual(1, reader.Depth); - Assert.AreEqual("value", reader.Path); + reader.Read(); + Assert.AreEqual(reader.TokenType, JsonToken.PropertyName); + Assert.AreEqual(1, reader.Depth); + Assert.AreEqual("value", reader.Path); - reader.Read(); - Assert.AreEqual(reader.TokenType, JsonToken.String); - Assert.AreEqual(reader.Value, @"Purple"); - Assert.AreEqual(reader.QuoteChar, '\''); - Assert.AreEqual(1, reader.Depth); - Assert.AreEqual("value", reader.Path); + reader.Read(); + Assert.AreEqual(reader.TokenType, JsonToken.String); + Assert.AreEqual(reader.Value, @"Purple"); + Assert.AreEqual(reader.QuoteChar, '\''); + Assert.AreEqual(1, reader.Depth); + Assert.AreEqual("value", reader.Path); - reader.Read(); - Assert.AreEqual(reader.TokenType, JsonToken.PropertyName); - Assert.AreEqual(1, reader.Depth); - Assert.AreEqual("array", reader.Path); + reader.Read(); + Assert.AreEqual(reader.TokenType, JsonToken.PropertyName); + Assert.AreEqual(1, reader.Depth); + Assert.AreEqual("array", reader.Path); - reader.Read(); - Assert.AreEqual(reader.TokenType, JsonToken.StartArray); - Assert.AreEqual(1, reader.Depth); - Assert.AreEqual("array", reader.Path); + reader.Read(); + Assert.AreEqual(reader.TokenType, JsonToken.StartArray); + Assert.AreEqual(1, reader.Depth); + Assert.AreEqual("array", reader.Path); - reader.Read(); - Assert.AreEqual(reader.TokenType, JsonToken.Integer); - Assert.AreEqual(1L, reader.Value); - Assert.AreEqual(2, reader.Depth); - Assert.AreEqual("array[0]", reader.Path); + reader.Read(); + Assert.AreEqual(reader.TokenType, JsonToken.Integer); + Assert.AreEqual(1L, reader.Value); + Assert.AreEqual(2, reader.Depth); + Assert.AreEqual("array[0]", reader.Path); - reader.Read(); - Assert.AreEqual(reader.TokenType, JsonToken.Integer); - Assert.AreEqual(2L, reader.Value); - Assert.AreEqual(2, reader.Depth); - Assert.AreEqual("array[1]", reader.Path); + reader.Read(); + Assert.AreEqual(reader.TokenType, JsonToken.Integer); + Assert.AreEqual(2L, reader.Value); + Assert.AreEqual(2, reader.Depth); + Assert.AreEqual("array[1]", reader.Path); - reader.Read(); - Assert.AreEqual(reader.TokenType, JsonToken.StartConstructor); - Assert.AreEqual("Date", reader.Value); - Assert.AreEqual(2, reader.Depth); - Assert.AreEqual("array[2]", reader.Path); + reader.Read(); + Assert.AreEqual(reader.TokenType, JsonToken.StartConstructor); + Assert.AreEqual("Date", reader.Value); + Assert.AreEqual(2, reader.Depth); + Assert.AreEqual("array[2]", reader.Path); - reader.Read(); - Assert.AreEqual(reader.TokenType, JsonToken.Integer); - Assert.AreEqual(1L, reader.Value); - Assert.AreEqual(3, reader.Depth); - Assert.AreEqual("array[2][0]", reader.Path); + reader.Read(); + Assert.AreEqual(reader.TokenType, JsonToken.Integer); + Assert.AreEqual(1L, reader.Value); + Assert.AreEqual(3, reader.Depth); + Assert.AreEqual("array[2][0]", reader.Path); - reader.Read(); - Assert.AreEqual(reader.TokenType, JsonToken.EndConstructor); - Assert.AreEqual(null, reader.Value); - Assert.AreEqual(2, reader.Depth); - Assert.AreEqual("array[2]", reader.Path); + reader.Read(); + Assert.AreEqual(reader.TokenType, JsonToken.EndConstructor); + Assert.AreEqual(null, reader.Value); + Assert.AreEqual(2, reader.Depth); + Assert.AreEqual("array[2]", reader.Path); - reader.Read(); - Assert.AreEqual(reader.TokenType, JsonToken.EndArray); - Assert.AreEqual(1, reader.Depth); - Assert.AreEqual("array", reader.Path); + reader.Read(); + Assert.AreEqual(reader.TokenType, JsonToken.EndArray); + Assert.AreEqual(1, reader.Depth); + Assert.AreEqual("array", reader.Path); - reader.Read(); - Assert.AreEqual(reader.TokenType, JsonToken.PropertyName); - Assert.AreEqual(1, reader.Depth); - Assert.AreEqual("subobject", reader.Path); + reader.Read(); + Assert.AreEqual(reader.TokenType, JsonToken.PropertyName); + Assert.AreEqual(1, reader.Depth); + Assert.AreEqual("subobject", reader.Path); - reader.Read(); - Assert.AreEqual(reader.TokenType, JsonToken.StartObject); - Assert.AreEqual(1, reader.Depth); - Assert.AreEqual("subobject", reader.Path); + reader.Read(); + Assert.AreEqual(reader.TokenType, JsonToken.StartObject); + Assert.AreEqual(1, reader.Depth); + Assert.AreEqual("subobject", reader.Path); - reader.Read(); - Assert.AreEqual(reader.TokenType, JsonToken.PropertyName); - Assert.AreEqual(2, reader.Depth); - Assert.AreEqual("subobject.prop", reader.Path); + reader.Read(); + Assert.AreEqual(reader.TokenType, JsonToken.PropertyName); + Assert.AreEqual(2, reader.Depth); + Assert.AreEqual("subobject.prop", reader.Path); - reader.Read(); - Assert.AreEqual(reader.TokenType, JsonToken.Integer); - Assert.AreEqual(2, reader.Depth); - Assert.AreEqual("subobject.prop", reader.Path); + reader.Read(); + Assert.AreEqual(reader.TokenType, JsonToken.Integer); + Assert.AreEqual(2, reader.Depth); + Assert.AreEqual("subobject.prop", reader.Path); - reader.Read(); - Assert.AreEqual(reader.TokenType, JsonToken.PropertyName); - Assert.AreEqual(2, reader.Depth); - Assert.AreEqual("subobject.proparray", reader.Path); + reader.Read(); + Assert.AreEqual(reader.TokenType, JsonToken.PropertyName); + Assert.AreEqual(2, reader.Depth); + Assert.AreEqual("subobject.proparray", reader.Path); - reader.Read(); - Assert.AreEqual(reader.TokenType, JsonToken.StartArray); - Assert.AreEqual(2, reader.Depth); - Assert.AreEqual("subobject.proparray", reader.Path); + reader.Read(); + Assert.AreEqual(reader.TokenType, JsonToken.StartArray); + Assert.AreEqual(2, reader.Depth); + Assert.AreEqual("subobject.proparray", reader.Path); - reader.Read(); - Assert.AreEqual(reader.TokenType, JsonToken.Integer); - Assert.AreEqual(3, reader.Depth); - Assert.AreEqual("subobject.proparray[0]", reader.Path); + reader.Read(); + Assert.AreEqual(reader.TokenType, JsonToken.Integer); + Assert.AreEqual(3, reader.Depth); + Assert.AreEqual("subobject.proparray[0]", reader.Path); - reader.Read(); - Assert.AreEqual(reader.TokenType, JsonToken.EndArray); - Assert.AreEqual(2, reader.Depth); - Assert.AreEqual("subobject.proparray", reader.Path); + reader.Read(); + Assert.AreEqual(reader.TokenType, JsonToken.EndArray); + Assert.AreEqual(2, reader.Depth); + Assert.AreEqual("subobject.proparray", reader.Path); - reader.Read(); - Assert.AreEqual(reader.TokenType, JsonToken.EndObject); - Assert.AreEqual(1, reader.Depth); - Assert.AreEqual("subobject", reader.Path); + reader.Read(); + Assert.AreEqual(reader.TokenType, JsonToken.EndObject); + Assert.AreEqual(1, reader.Depth); + Assert.AreEqual("subobject", reader.Path); - reader.Read(); - Assert.AreEqual(reader.TokenType, JsonToken.EndObject); - Assert.AreEqual(0, reader.Depth); - Assert.AreEqual("", reader.Path); - } - } + reader.Read(); + Assert.AreEqual(reader.TokenType, JsonToken.EndObject); + Assert.AreEqual(0, reader.Depth); + Assert.AreEqual("", reader.Path); + } + } - [Test] - public void NullTextReader() - { - ExceptionAssert.Throws( - @"Value cannot be null. + [Test] + public void NullTextReader() + { + ExceptionAssert.Throws( + @"Value cannot be null. Parameter name: reader", - () => - { - new JsonTextReader(null); - }); - } + () => { new JsonTextReader(null); }); + } - [Test] - public void UnexpectedEndOfString() - { - JsonReader reader = new JsonTextReader(new StringReader("'hi")); + [Test] + public void UnexpectedEndOfString() + { + JsonReader reader = new JsonTextReader(new StringReader("'hi")); - ExceptionAssert.Throws( - "Unterminated string. Expected delimiter: '. Path '', line 1, position 3.", - () => - { + ExceptionAssert.Throws( + "Unterminated string. Expected delimiter: '. Path '', line 1, position 3.", + () => { reader.Read(); }); + } + + [Test] + public void ReadLongString() + { + string s = new string('a', 10000); + JsonReader reader = new JsonTextReader(new StringReader("'" + s + "'")); reader.Read(); - }); - } - [Test] - public void ReadLongString() - { - string s = new string('a', 10000); - JsonReader reader = new JsonTextReader(new StringReader("'" + s + "'")); - reader.Read(); + Assert.AreEqual(s, reader.Value); + } - Assert.AreEqual(s, reader.Value); - } + [Test] + public void ReadLongJsonArray() + { + int valueCount = 10000; + StringWriter sw = new StringWriter(); + JsonTextWriter writer = new JsonTextWriter(sw); + writer.WriteStartArray(); + for (int i = 0; i < valueCount; i++) + { + writer.WriteValue(i); + } + writer.WriteEndArray(); - [Test] - public void ReadLongJsonArray() - { - int valueCount = 10000; - StringWriter sw = new StringWriter(); - JsonTextWriter writer = new JsonTextWriter(sw); - writer.WriteStartArray(); - for (int i = 0; i < valueCount; i++) - { - writer.WriteValue(i); - } - writer.WriteEndArray(); + string json = sw.ToString(); - string json = sw.ToString(); + JsonTextReader reader = new JsonTextReader(new StringReader(json)); + Assert.IsTrue(reader.Read()); + for (int i = 0; i < valueCount; i++) + { + Assert.IsTrue(reader.Read()); + Assert.AreEqual((long)i, reader.Value); + } + Assert.IsTrue(reader.Read()); + Assert.IsFalse(reader.Read()); + } - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - Assert.IsTrue(reader.Read()); - for (int i = 0; i < valueCount; i++) - { - Assert.IsTrue(reader.Read()); - Assert.AreEqual((long)i, reader.Value); - } - Assert.IsTrue(reader.Read()); - Assert.IsFalse(reader.Read()); - } + [Test] + public void NullCharReading() + { + string json = "\0{\0'\0h\0i\0'\0:\0[\01\0,\0'\0'\0\0,\0null\0]\0,\0do\0:true\0}\0\0/*\0sd\0f\0*/\0/*\0sd\0f\0*/ \0"; + JsonTextReader reader = new JsonTextReader(new StreamReader(new SlowStream(json, new UTF8Encoding(false), 1))); - [Test] - public void NullCharReading() - { - string json = "\0{\0'\0h\0i\0'\0:\0[\01\0,\0'\0'\0\0,\0null\0]\0,\0do\0:true\0}\0\0/*\0sd\0f\0*/\0/*\0sd\0f\0*/ \0"; - JsonTextReader reader = new JsonTextReader(new StreamReader(new SlowStream(json, new UTF8Encoding(false), 1))); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Null, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Null, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Boolean, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Boolean, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Comment, reader.TokenType); + Assert.AreEqual("\0sd\0f\0", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Comment, reader.TokenType); - Assert.AreEqual("\0sd\0f\0", reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Comment, reader.TokenType); + Assert.AreEqual("\0sd\0f\0", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Comment, reader.TokenType); - Assert.AreEqual("\0sd\0f\0", reader.Value); + Assert.IsFalse(reader.Read()); + } - Assert.IsFalse(reader.Read()); - } - - [Test] - public void AppendCharsWhileReadingNull() - { - string json = @"[ + [Test] + public void AppendCharsWhileReadingNull() + { + string json = @"[ { ""$id"": ""1"", ""Name"": ""e1"", @@ -785,111 +773,111 @@ Parameter name: reader", } ]"; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); + JsonTextReader reader = new JsonTextReader(new StringReader(json)); #if DEBUG - reader.SetCharBuffer(new char[129]); + reader.SetCharBuffer(new char[129]); #endif - for (int i = 0; i < 15; i++) - { - reader.Read(); - } - - reader.Read(); - Assert.AreEqual(JsonToken.Null, reader.TokenType); - } - - [Test] - public void ReadInt32Overflow() - { - long i = int.MaxValue; - - JsonTextReader reader = new JsonTextReader(new StringReader(i.ToString(CultureInfo.InvariantCulture))); - reader.Read(); - Assert.AreEqual(typeof(long), reader.ValueType); - - for (int j = 1; j < 1000; j++) - { - long total = j + i; - ExceptionAssert.Throws( - "Arithmetic operation resulted in an overflow.", - () => + for (int i = 0; i < 15; i++) { - reader = new JsonTextReader(new StringReader(total.ToString(CultureInfo.InvariantCulture))); - reader.ReadAsInt32(); - }); - } - } + reader.Read(); + } - [Test] - public void ReadInt32Overflow_Negative() - { - long i = int.MinValue; + reader.Read(); + Assert.AreEqual(JsonToken.Null, reader.TokenType); + } - JsonTextReader reader = new JsonTextReader(new StringReader(i.ToString(CultureInfo.InvariantCulture))); - reader.Read(); - Assert.AreEqual(typeof(long), reader.ValueType); - Assert.AreEqual(i, reader.Value); + [Test] + public void ReadInt32Overflow() + { + long i = int.MaxValue; - for (int j = 1; j < 1000; j++) - { - long total = -j + i; - ExceptionAssert.Throws( - "Arithmetic operation resulted in an overflow.", - () => - { - reader = new JsonTextReader(new StringReader(total.ToString(CultureInfo.InvariantCulture))); - reader.ReadAsInt32(); - }); - } - } + JsonTextReader reader = new JsonTextReader(new StringReader(i.ToString(CultureInfo.InvariantCulture))); + reader.Read(); + Assert.AreEqual(typeof(long), reader.ValueType); + + for (int j = 1; j < 1000; j++) + { + long total = j + i; + ExceptionAssert.Throws( + "Arithmetic operation resulted in an overflow.", + () => + { + reader = new JsonTextReader(new StringReader(total.ToString(CultureInfo.InvariantCulture))); + reader.ReadAsInt32(); + }); + } + } + + [Test] + public void ReadInt32Overflow_Negative() + { + long i = int.MinValue; + + JsonTextReader reader = new JsonTextReader(new StringReader(i.ToString(CultureInfo.InvariantCulture))); + reader.Read(); + Assert.AreEqual(typeof(long), reader.ValueType); + Assert.AreEqual(i, reader.Value); + + for (int j = 1; j < 1000; j++) + { + long total = -j + i; + ExceptionAssert.Throws( + "Arithmetic operation resulted in an overflow.", + () => + { + reader = new JsonTextReader(new StringReader(total.ToString(CultureInfo.InvariantCulture))); + reader.ReadAsInt32(); + }); + } + } #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - [Test] - public void ReadInt64Overflow() - { - BigInteger i = new BigInteger(long.MaxValue); + [Test] + public void ReadInt64Overflow() + { + BigInteger i = new BigInteger(long.MaxValue); - JsonTextReader reader = new JsonTextReader(new StringReader(i.ToString(CultureInfo.InvariantCulture))); - reader.Read(); - Assert.AreEqual(typeof(long), reader.ValueType); - - for (int j = 1; j < 1000; j++) - { - BigInteger total = i + j; + JsonTextReader reader = new JsonTextReader(new StringReader(i.ToString(CultureInfo.InvariantCulture))); + reader.Read(); + Assert.AreEqual(typeof(long), reader.ValueType); - reader = new JsonTextReader(new StringReader(total.ToString(CultureInfo.InvariantCulture))); - reader.Read(); + for (int j = 1; j < 1000; j++) + { + BigInteger total = i + j; - Assert.AreEqual(typeof(BigInteger), reader.ValueType); - } - } + reader = new JsonTextReader(new StringReader(total.ToString(CultureInfo.InvariantCulture))); + reader.Read(); - [Test] - public void ReadInt64Overflow_Negative() - { - BigInteger i = new BigInteger(long.MinValue); + Assert.AreEqual(typeof(BigInteger), reader.ValueType); + } + } - JsonTextReader reader = new JsonTextReader(new StringReader(i.ToString(CultureInfo.InvariantCulture))); - reader.Read(); - Assert.AreEqual(typeof(long), reader.ValueType); + [Test] + public void ReadInt64Overflow_Negative() + { + BigInteger i = new BigInteger(long.MinValue); - for (int j = 1; j < 1000; j++) - { - BigInteger total = i + -j; + JsonTextReader reader = new JsonTextReader(new StringReader(i.ToString(CultureInfo.InvariantCulture))); + reader.Read(); + Assert.AreEqual(typeof(long), reader.ValueType); - reader = new JsonTextReader(new StringReader(total.ToString(CultureInfo.InvariantCulture))); - reader.Read(); + for (int j = 1; j < 1000; j++) + { + BigInteger total = i + -j; - Assert.AreEqual(typeof(BigInteger), reader.ValueType); - } - } + reader = new JsonTextReader(new StringReader(total.ToString(CultureInfo.InvariantCulture))); + reader.Read(); + + Assert.AreEqual(typeof(BigInteger), reader.ValueType); + } + } #endif - [Test] - public void AppendCharsWhileReadingNewLine() - { - string json = @" + [Test] + public void AppendCharsWhileReadingNewLine() + { + string json = @" { ""description"": ""A person"", ""type"": ""object"", @@ -904,294 +892,279 @@ Parameter name: reader", } "; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); + JsonTextReader reader = new JsonTextReader(new StringReader(json)); #if DEBUG - reader.SetCharBuffer(new char[129]); + reader.SetCharBuffer(new char[129]); #endif - for (int i = 0; i < 14; i++) - { - Assert.IsTrue(reader.Read()); - } + for (int i = 0; i < 14; i++) + { + Assert.IsTrue(reader.Read()); + } - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("type", reader.Value); - } + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("type", reader.Value); + } - [Test] - public void ReadNullTerminatorStrings() - { - JsonReader reader = new JsonTextReader(new StringReader("'h\0i'")); - Assert.IsTrue(reader.Read()); - - Assert.AreEqual("h\0i", reader.Value); - } - - [Test] - public void UnexpectedEndOfHex() - { - JsonReader reader = new JsonTextReader(new StringReader(@"'h\u123")); - - ExceptionAssert.Throws( - "Unexpected end while parsing unicode character. Path '', line 1, position 4.", - () => - { - reader.Read(); - }); - } - - [Test] - public void UnexpectedEndOfControlCharacter() - { - JsonReader reader = new JsonTextReader(new StringReader(@"'h\")); - - ExceptionAssert.Throws( - "Unterminated string. Expected delimiter: '. Path '', line 1, position 3.", - () => - { - reader.Read(); - }); - } - - [Test] - public void ReadBytesWithBadCharacter() - { - JsonReader reader = new JsonTextReader(new StringReader(@"true")); - - ExceptionAssert.Throws( - "Error reading bytes. Unexpected token: Boolean. Path '', line 1, position 4.", - () => - { - reader.ReadAsBytes(); - }); - } - - [Test] - public void ReadBytesWithUnexpectedEnd() - { - string helloWorld = "Hello world!"; - byte[] helloWorldData = Encoding.UTF8.GetBytes(helloWorld); - - JsonReader reader = new JsonTextReader(new StringReader(@"'" + Convert.ToBase64String(helloWorldData))); - - ExceptionAssert.Throws( - "Unterminated string. Expected delimiter: '. Path '', line 1, position 17.", - () => - { - reader.ReadAsBytes(); - }); - } - - [Test] - public void ReadBytesNoStartWithUnexpectedEnd() - { - JsonReader reader = new JsonTextReader(new StringReader(@"[ ")); - Assert.IsTrue(reader.Read()); - - Assert.IsNull(reader.ReadAsBytes()); - Assert.AreEqual(JsonToken.None, reader.TokenType); - } - - [Test] - public void UnexpectedEndWhenParsingUnquotedProperty() - { - JsonReader reader = new JsonTextReader(new StringReader(@"{aww")); - Assert.IsTrue(reader.Read()); - - ExceptionAssert.Throws( - "Unexpected end while parsing unquoted property name. Path '', line 1, position 4.", - () => + [Test] + public void ReadNullTerminatorStrings() { - reader.Read(); - }); - } + JsonReader reader = new JsonTextReader(new StringReader("'h\0i'")); + Assert.IsTrue(reader.Read()); - [Test] - public void ReadNewLines() - { - string newLinesText = StringUtils.CarriageReturn + StringUtils.CarriageReturnLineFeed + StringUtils.LineFeed + StringUtils.CarriageReturnLineFeed + " " + StringUtils.CarriageReturn + StringUtils.CarriageReturnLineFeed; + Assert.AreEqual("h\0i", reader.Value); + } - string json = - newLinesText - + "{" + newLinesText - + "'" + newLinesText - + "name1" + newLinesText - + "'" + newLinesText - + ":" + newLinesText - + "[" + newLinesText - + "new" + newLinesText - + "Date" + newLinesText - + "(" + newLinesText - + "1" + newLinesText - + "," + newLinesText - + "null" + newLinesText - + "/*" + newLinesText - + "blah comment" + newLinesText - + "*/" + newLinesText - + ")" + newLinesText - + "," + newLinesText - + "1.1111" + newLinesText - + "]" + newLinesText - + "," + newLinesText - + "name2" + newLinesText - + ":" + newLinesText - + "{" + newLinesText - + "}" + newLinesText - + "}" + newLinesText; + [Test] + public void UnexpectedEndOfHex() + { + JsonReader reader = new JsonTextReader(new StringReader(@"'h\u123")); - int count = 0; - StringReader sr = new StringReader(newLinesText); - while (sr.ReadLine() != null) - { - count++; - } + ExceptionAssert.Throws( + "Unexpected end while parsing unicode character. Path '', line 1, position 4.", + () => { reader.Read(); }); + } - JsonTextReader reader = new JsonTextReader(new StreamReader(new SlowStream(json, new UTF8Encoding(false), 1))); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(7, reader.LineNumber); + [Test] + public void UnexpectedEndOfControlCharacter() + { + JsonReader reader = new JsonTextReader(new StringReader(@"'h\")); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(31, reader.LineNumber); - Assert.AreEqual(newLinesText + "name1" + newLinesText, reader.Value); + ExceptionAssert.Throws( + "Unterminated string. Expected delimiter: '. Path '', line 1, position 3.", + () => { reader.Read(); }); + } - Assert.IsTrue(reader.Read()); - Assert.AreEqual(37, reader.LineNumber); + [Test] + public void ReadBytesWithBadCharacter() + { + JsonReader reader = new JsonTextReader(new StringReader(@"true")); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(55, reader.LineNumber); - Assert.AreEqual(JsonToken.StartConstructor, reader.TokenType); - Assert.AreEqual("Date", reader.Value); + ExceptionAssert.Throws( + "Error reading bytes. Unexpected token: Boolean. Path '', line 1, position 4.", + () => { reader.ReadAsBytes(); }); + } - Assert.IsTrue(reader.Read()); - Assert.AreEqual(61, reader.LineNumber); - Assert.AreEqual(1L, reader.Value); + [Test] + public void ReadBytesWithUnexpectedEnd() + { + string helloWorld = "Hello world!"; + byte[] helloWorldData = Encoding.UTF8.GetBytes(helloWorld); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(73, reader.LineNumber); - Assert.AreEqual(null, reader.Value); + JsonReader reader = new JsonTextReader(new StringReader(@"'" + Convert.ToBase64String(helloWorldData))); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(91, reader.LineNumber); - Assert.AreEqual(newLinesText + "blah comment" + newLinesText, reader.Value); + ExceptionAssert.Throws( + "Unterminated string. Expected delimiter: '. Path '', line 1, position 17.", + () => { reader.ReadAsBytes(); }); + } - Assert.IsTrue(reader.Read()); - Assert.AreEqual(97, reader.LineNumber); + [Test] + public void ReadBytesNoStartWithUnexpectedEnd() + { + JsonReader reader = new JsonTextReader(new StringReader(@"[ ")); + Assert.IsTrue(reader.Read()); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(109, reader.LineNumber); + Assert.IsNull(reader.ReadAsBytes()); + Assert.AreEqual(JsonToken.None, reader.TokenType); + } - Assert.IsTrue(reader.Read()); - Assert.AreEqual(115, reader.LineNumber); + [Test] + public void UnexpectedEndWhenParsingUnquotedProperty() + { + JsonReader reader = new JsonTextReader(new StringReader(@"{aww")); + Assert.IsTrue(reader.Read()); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(133, reader.LineNumber); - Assert.AreEqual("name2", reader.Value); + ExceptionAssert.Throws( + "Unexpected end while parsing unquoted property name. Path '', line 1, position 4.", + () => { reader.Read(); }); + } - Assert.IsTrue(reader.Read()); - Assert.AreEqual(139, reader.LineNumber); + [Test] + public void ReadNewLines() + { + string newLinesText = StringUtils.CarriageReturn + StringUtils.CarriageReturnLineFeed + StringUtils.LineFeed + StringUtils.CarriageReturnLineFeed + " " + StringUtils.CarriageReturn + StringUtils.CarriageReturnLineFeed; - Assert.IsTrue(reader.Read()); - Assert.AreEqual(145, reader.LineNumber); + string json = + newLinesText + + "{" + newLinesText + + "'" + newLinesText + + "name1" + newLinesText + + "'" + newLinesText + + ":" + newLinesText + + "[" + newLinesText + + "new" + newLinesText + + "Date" + newLinesText + + "(" + newLinesText + + "1" + newLinesText + + "," + newLinesText + + "null" + newLinesText + + "/*" + newLinesText + + "blah comment" + newLinesText + + "*/" + newLinesText + + ")" + newLinesText + + "," + newLinesText + + "1.1111" + newLinesText + + "]" + newLinesText + + "," + newLinesText + + "name2" + newLinesText + + ":" + newLinesText + + "{" + newLinesText + + "}" + newLinesText + + "}" + newLinesText; - Assert.IsTrue(reader.Read()); - Assert.AreEqual(151, reader.LineNumber); - } + int count = 0; + StringReader sr = new StringReader(newLinesText); + while (sr.ReadLine() != null) + { + count++; + } - [Test] - public void ParsingQuotedPropertyWithControlCharacters() - { - JsonReader reader = new JsonTextReader(new StringReader(@"{'hi\r\nbye':1}")); - Assert.IsTrue(reader.Read()); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual(@"hi + JsonTextReader reader = new JsonTextReader(new StreamReader(new SlowStream(json, new UTF8Encoding(false), 1))); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(7, reader.LineNumber); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(31, reader.LineNumber); + Assert.AreEqual(newLinesText + "name1" + newLinesText, reader.Value); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(37, reader.LineNumber); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(55, reader.LineNumber); + Assert.AreEqual(JsonToken.StartConstructor, reader.TokenType); + Assert.AreEqual("Date", reader.Value); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(61, reader.LineNumber); + Assert.AreEqual(1L, reader.Value); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(73, reader.LineNumber); + Assert.AreEqual(null, reader.Value); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(91, reader.LineNumber); + Assert.AreEqual(newLinesText + "blah comment" + newLinesText, reader.Value); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(97, reader.LineNumber); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(109, reader.LineNumber); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(115, reader.LineNumber); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(133, reader.LineNumber); + Assert.AreEqual("name2", reader.Value); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(139, reader.LineNumber); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(145, reader.LineNumber); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(151, reader.LineNumber); + } + + [Test] + public void ParsingQuotedPropertyWithControlCharacters() + { + JsonReader reader = new JsonTextReader(new StringReader(@"{'hi\r\nbye':1}")); + Assert.IsTrue(reader.Read()); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual(@"hi bye", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.AreEqual(1L, reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - Assert.IsFalse(reader.Read()); - } + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); + Assert.AreEqual(1L, reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.IsFalse(reader.Read()); + } - [Test] - public void ReadBytesFollowingNumberInArray() - { - string helloWorld = "Hello world!"; - byte[] helloWorldData = Encoding.UTF8.GetBytes(helloWorld); + [Test] + public void ReadBytesFollowingNumberInArray() + { + string helloWorld = "Hello world!"; + byte[] helloWorldData = Encoding.UTF8.GetBytes(helloWorld); - JsonReader reader = new JsonTextReader(new StringReader(@"[1,'" + Convert.ToBase64String(helloWorldData) + @"']")); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); - byte[] data = reader.ReadAsBytes(); - CollectionAssert.AreEquivalent(helloWorldData, data); - Assert.AreEqual(JsonToken.Bytes, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + JsonReader reader = new JsonTextReader(new StringReader(@"[1,'" + Convert.ToBase64String(helloWorldData) + @"']")); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); + byte[] data = reader.ReadAsBytes(); + CollectionAssert.AreEquivalent(helloWorldData, data); + Assert.AreEqual(JsonToken.Bytes, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - Assert.IsFalse(reader.Read()); - } + Assert.IsFalse(reader.Read()); + } - [Test] - public void ReadBytesFollowingNumberInObject() - { - string helloWorld = "Hello world!"; - byte[] helloWorldData = Encoding.UTF8.GetBytes(helloWorld); + [Test] + public void ReadBytesFollowingNumberInObject() + { + string helloWorld = "Hello world!"; + byte[] helloWorldData = Encoding.UTF8.GetBytes(helloWorld); - JsonReader reader = new JsonTextReader(new StringReader(@"{num:1,data:'" + Convert.ToBase64String(helloWorldData) + @"'}")); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.IsTrue(reader.Read()); - byte[] data = reader.ReadAsBytes(); - CollectionAssert.AreEquivalent(helloWorldData, data); - Assert.AreEqual(JsonToken.Bytes, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + JsonReader reader = new JsonTextReader(new StringReader(@"{num:1,data:'" + Convert.ToBase64String(helloWorldData) + @"'}")); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); + Assert.IsTrue(reader.Read()); + byte[] data = reader.ReadAsBytes(); + CollectionAssert.AreEquivalent(helloWorldData, data); + Assert.AreEqual(JsonToken.Bytes, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - Assert.IsFalse(reader.Read()); - } + Assert.IsFalse(reader.Read()); + } - [Test] - public void ReadingEscapedStrings() - { - string input = "{value:'Purple\\r \\n monkey\\'s:\\tdishwasher'}"; + [Test] + public void ReadingEscapedStrings() + { + string input = "{value:'Purple\\r \\n monkey\\'s:\\tdishwasher'}"; - StringReader sr = new StringReader(input); + StringReader sr = new StringReader(input); - using (JsonReader jsonReader = new JsonTextReader(sr)) - { - Assert.AreEqual(0, jsonReader.Depth); + using (JsonReader jsonReader = new JsonTextReader(sr)) + { + Assert.AreEqual(0, jsonReader.Depth); - jsonReader.Read(); - Assert.AreEqual(JsonToken.StartObject, jsonReader.TokenType); - Assert.AreEqual(0, jsonReader.Depth); - - jsonReader.Read(); - Assert.AreEqual(JsonToken.PropertyName, jsonReader.TokenType); - Assert.AreEqual(1, jsonReader.Depth); + jsonReader.Read(); + Assert.AreEqual(JsonToken.StartObject, jsonReader.TokenType); + Assert.AreEqual(0, jsonReader.Depth); - jsonReader.Read(); - Assert.AreEqual(jsonReader.TokenType, JsonToken.String); - Assert.AreEqual("Purple\r \n monkey's:\tdishwasher", jsonReader.Value); - Assert.AreEqual('\'', jsonReader.QuoteChar); - Assert.AreEqual(1, jsonReader.Depth); + jsonReader.Read(); + Assert.AreEqual(JsonToken.PropertyName, jsonReader.TokenType); + Assert.AreEqual(1, jsonReader.Depth); - jsonReader.Read(); - Assert.AreEqual(JsonToken.EndObject, jsonReader.TokenType); - Assert.AreEqual(0, jsonReader.Depth); - } - } + jsonReader.Read(); + Assert.AreEqual(jsonReader.TokenType, JsonToken.String); + Assert.AreEqual("Purple\r \n monkey's:\tdishwasher", jsonReader.Value); + Assert.AreEqual('\'', jsonReader.QuoteChar); + Assert.AreEqual(1, jsonReader.Depth); - [Test] - public void ReadNewlineLastCharacter() - { - string input = @"{ + jsonReader.Read(); + Assert.AreEqual(JsonToken.EndObject, jsonReader.TokenType); + Assert.AreEqual(0, jsonReader.Depth); + } + } + + [Test] + public void ReadNewlineLastCharacter() + { + string input = @"{ CPU: 'Intel', Drives: [ /* Com*ment */ 'DVD read/writer', @@ -1199,13 +1172,13 @@ bye", reader.Value); ] }" + '\n'; - object o = JsonConvert.DeserializeObject(input); - } + object o = JsonConvert.DeserializeObject(input); + } - [Test] - public void ReadRandomJson() - { - string json = @"[ + [Test] + public void ReadRandomJson() + { + string json = @"[ true, { ""integer"": 99, @@ -1227,931 +1200,885 @@ bye", reader.Value); null ]"; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - while (reader.Read()) - { - - } - } - - [Test] - public void ParseIntegers() - { - JsonTextReader reader = null; - - reader = new JsonTextReader(new StringReader("1")); - Assert.AreEqual(1, reader.ReadAsInt32()); - - reader = new JsonTextReader(new StringReader("-1")); - Assert.AreEqual(-1, reader.ReadAsInt32()); - - reader = new JsonTextReader(new StringReader("0")); - Assert.AreEqual(0, reader.ReadAsInt32()); - - reader = new JsonTextReader(new StringReader("-0")); - Assert.AreEqual(0, reader.ReadAsInt32()); - - reader = new JsonTextReader(new StringReader(int.MaxValue.ToString())); - Assert.AreEqual(int.MaxValue, reader.ReadAsInt32()); - - reader = new JsonTextReader(new StringReader(int.MinValue.ToString())); - Assert.AreEqual(int.MinValue, reader.ReadAsInt32()); - - reader = new JsonTextReader(new StringReader(long.MaxValue.ToString())); - ExceptionAssert.Throws("Arithmetic operation resulted in an overflow.", () => reader.ReadAsInt32()); - - reader = new JsonTextReader(new StringReader("9999999999999999999999999999999999999999999999999999999999999999999999999999asdasdasd")); - ExceptionAssert.Throws("Input string was not in a correct format.", () => reader.ReadAsInt32()); - - reader = new JsonTextReader(new StringReader("1E-06")); - ExceptionAssert.Throws("Input string was not in a correct format.", () => reader.ReadAsInt32()); - - reader = new JsonTextReader(new StringReader("1.1")); - ExceptionAssert.Throws("Input string was not in a correct format.", () => reader.ReadAsInt32()); - - reader = new JsonTextReader(new StringReader("")); - Assert.AreEqual(null, reader.ReadAsInt32()); - - reader = new JsonTextReader(new StringReader("-")); - ExceptionAssert.Throws("Input string was not in a correct format.", () => reader.ReadAsInt32()); - } - - [Test] - public void WriteReadWrite() - { - StringBuilder sb = new StringBuilder(); - StringWriter sw = new StringWriter(sb); - - using (JsonWriter jsonWriter = new JsonTextWriter(sw) - { - Formatting = Formatting.Indented - }) - { - jsonWriter.WriteStartArray(); - jsonWriter.WriteValue(true); - - jsonWriter.WriteStartObject(); - jsonWriter.WritePropertyName("integer"); - jsonWriter.WriteValue(99); - jsonWriter.WritePropertyName("string"); - jsonWriter.WriteValue("how now brown cow?"); - jsonWriter.WritePropertyName("array"); - - jsonWriter.WriteStartArray(); - for (int i = 0; i < 5; i++) - { - jsonWriter.WriteValue(i); + JsonTextReader reader = new JsonTextReader(new StringReader(json)); + while (reader.Read()) + { + } } - jsonWriter.WriteStartObject(); - jsonWriter.WritePropertyName("decimal"); - jsonWriter.WriteValue(990.00990099m); - jsonWriter.WriteEndObject(); - - jsonWriter.WriteValue(5); - jsonWriter.WriteEndArray(); - - jsonWriter.WriteEndObject(); - - jsonWriter.WriteValue("This is a string."); - jsonWriter.WriteNull(); - jsonWriter.WriteNull(); - jsonWriter.WriteEndArray(); - } - - string json = sb.ToString(); - - JsonSerializer serializer = new JsonSerializer(); - - object jsonObject = serializer.Deserialize(new JsonTextReader(new StringReader(json))); - - sb = new StringBuilder(); - sw = new StringWriter(sb); - - using (JsonWriter jsonWriter = new JsonTextWriter(sw) + [Test] + public void ParseIntegers() { - Formatting = Formatting.Indented - }) - { - serializer.Serialize(jsonWriter, jsonObject); - } + JsonTextReader reader = null; - Assert.AreEqual(json, sb.ToString()); - } + reader = new JsonTextReader(new StringReader("1")); + Assert.AreEqual(1, reader.ReadAsInt32()); - [Test] - public void FloatingPointNonFiniteNumbers() - { - string input = @"[ + reader = new JsonTextReader(new StringReader("-1")); + Assert.AreEqual(-1, reader.ReadAsInt32()); + + reader = new JsonTextReader(new StringReader("0")); + Assert.AreEqual(0, reader.ReadAsInt32()); + + reader = new JsonTextReader(new StringReader("-0")); + Assert.AreEqual(0, reader.ReadAsInt32()); + + reader = new JsonTextReader(new StringReader(int.MaxValue.ToString())); + Assert.AreEqual(int.MaxValue, reader.ReadAsInt32()); + + reader = new JsonTextReader(new StringReader(int.MinValue.ToString())); + Assert.AreEqual(int.MinValue, reader.ReadAsInt32()); + + reader = new JsonTextReader(new StringReader(long.MaxValue.ToString())); + ExceptionAssert.Throws("Arithmetic operation resulted in an overflow.", () => reader.ReadAsInt32()); + + reader = new JsonTextReader(new StringReader("9999999999999999999999999999999999999999999999999999999999999999999999999999asdasdasd")); + ExceptionAssert.Throws("Input string was not in a correct format.", () => reader.ReadAsInt32()); + + reader = new JsonTextReader(new StringReader("1E-06")); + ExceptionAssert.Throws("Input string was not in a correct format.", () => reader.ReadAsInt32()); + + reader = new JsonTextReader(new StringReader("1.1")); + ExceptionAssert.Throws("Input string was not in a correct format.", () => reader.ReadAsInt32()); + + reader = new JsonTextReader(new StringReader("")); + Assert.AreEqual(null, reader.ReadAsInt32()); + + reader = new JsonTextReader(new StringReader("-")); + ExceptionAssert.Throws("Input string was not in a correct format.", () => reader.ReadAsInt32()); + } + + [Test] + public void WriteReadWrite() + { + StringBuilder sb = new StringBuilder(); + StringWriter sw = new StringWriter(sb); + + using (JsonWriter jsonWriter = new JsonTextWriter(sw) + { + Formatting = Formatting.Indented + }) + { + jsonWriter.WriteStartArray(); + jsonWriter.WriteValue(true); + + jsonWriter.WriteStartObject(); + jsonWriter.WritePropertyName("integer"); + jsonWriter.WriteValue(99); + jsonWriter.WritePropertyName("string"); + jsonWriter.WriteValue("how now brown cow?"); + jsonWriter.WritePropertyName("array"); + + jsonWriter.WriteStartArray(); + for (int i = 0; i < 5; i++) + { + jsonWriter.WriteValue(i); + } + + jsonWriter.WriteStartObject(); + jsonWriter.WritePropertyName("decimal"); + jsonWriter.WriteValue(990.00990099m); + jsonWriter.WriteEndObject(); + + jsonWriter.WriteValue(5); + jsonWriter.WriteEndArray(); + + jsonWriter.WriteEndObject(); + + jsonWriter.WriteValue("This is a string."); + jsonWriter.WriteNull(); + jsonWriter.WriteNull(); + jsonWriter.WriteEndArray(); + } + + string json = sb.ToString(); + + JsonSerializer serializer = new JsonSerializer(); + + object jsonObject = serializer.Deserialize(new JsonTextReader(new StringReader(json))); + + sb = new StringBuilder(); + sw = new StringWriter(sb); + + using (JsonWriter jsonWriter = new JsonTextWriter(sw) + { + Formatting = Formatting.Indented + }) + { + serializer.Serialize(jsonWriter, jsonObject); + } + + Assert.AreEqual(json, sb.ToString()); + } + + [Test] + public void FloatingPointNonFiniteNumbers() + { + string input = @"[ NaN, Infinity, -Infinity ]"; - StringReader sr = new StringReader(input); + StringReader sr = new StringReader(input); - using (JsonReader jsonReader = new JsonTextReader(sr)) - { - jsonReader.Read(); - Assert.AreEqual(jsonReader.TokenType, JsonToken.StartArray); + using (JsonReader jsonReader = new JsonTextReader(sr)) + { + jsonReader.Read(); + Assert.AreEqual(jsonReader.TokenType, JsonToken.StartArray); - jsonReader.Read(); - Assert.AreEqual(jsonReader.TokenType, JsonToken.Float); - Assert.AreEqual(jsonReader.Value, double.NaN); + jsonReader.Read(); + Assert.AreEqual(jsonReader.TokenType, JsonToken.Float); + Assert.AreEqual(jsonReader.Value, double.NaN); - jsonReader.Read(); - Assert.AreEqual(jsonReader.TokenType, JsonToken.Float); - Assert.AreEqual(jsonReader.Value, double.PositiveInfinity); + jsonReader.Read(); + Assert.AreEqual(jsonReader.TokenType, JsonToken.Float); + Assert.AreEqual(jsonReader.Value, double.PositiveInfinity); - jsonReader.Read(); - Assert.AreEqual(jsonReader.TokenType, JsonToken.Float); - Assert.AreEqual(jsonReader.Value, double.NegativeInfinity); + jsonReader.Read(); + Assert.AreEqual(jsonReader.TokenType, JsonToken.Float); + Assert.AreEqual(jsonReader.Value, double.NegativeInfinity); - jsonReader.Read(); - Assert.AreEqual(jsonReader.TokenType, JsonToken.EndArray); - } - } + jsonReader.Read(); + Assert.AreEqual(jsonReader.TokenType, JsonToken.EndArray); + } + } - [Test] - public void LongStringTest() - { - int length = 20000; - string json = @"[""" + new string(' ', length) + @"""]"; + [Test] + public void LongStringTest() + { + int length = 20000; + string json = @"[""" + new string(' ', length) + @"""]"; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); + JsonTextReader reader = new JsonTextReader(new StringReader(json)); - reader.Read(); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + reader.Read(); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - reader.Read(); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual(typeof(string), reader.ValueType); - Assert.AreEqual(20000, reader.Value.ToString().Length); + reader.Read(); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual(typeof(string), reader.ValueType); + Assert.AreEqual(20000, reader.Value.ToString().Length); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - Assert.IsFalse(reader.Read()); - Assert.AreEqual(JsonToken.None, reader.TokenType); - } + Assert.IsFalse(reader.Read()); + Assert.AreEqual(JsonToken.None, reader.TokenType); + } - [Test] - public void EscapedUnicodeText() - { - string json = @"[""\u003c"",""\u5f20""]"; + [Test] + public void EscapedUnicodeText() + { + string json = @"[""\u003c"",""\u5f20""]"; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); + JsonTextReader reader = new JsonTextReader(new StringReader(json)); #if DEBUG - reader.SetCharBuffer(new char[2]); + reader.SetCharBuffer(new char[2]); #endif - reader.Read(); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + reader.Read(); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - reader.Read(); - Assert.AreEqual("<", reader.Value); + reader.Read(); + Assert.AreEqual("<", reader.Value); - reader.Read(); - Assert.AreEqual(24352, Convert.ToInt32(Convert.ToChar((string)reader.Value))); + reader.Read(); + Assert.AreEqual(24352, Convert.ToInt32(Convert.ToChar((string)reader.Value))); - reader.Read(); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - } + reader.Read(); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + } - [Test] - public void ReadFloatingPointNumber() - { - string json = - @"[0.0,0.0,0.1,1.0,1.000001,1E-06,4.94065645841247E-324,Infinity,-Infinity,NaN,1.7976931348623157E+308,-1.7976931348623157E+308,Infinity,-Infinity,NaN,0e-10,0.25e-5,0.3e10]"; + [Test] + public void ReadFloatingPointNumber() + { + string json = + @"[0.0,0.0,0.1,1.0,1.000001,1E-06,4.94065645841247E-324,Infinity,-Infinity,NaN,1.7976931348623157E+308,-1.7976931348623157E+308,Infinity,-Infinity,NaN,0e-10,0.25e-5,0.3e10]"; - using (JsonReader jsonReader = new JsonTextReader(new StringReader(json))) - { - jsonReader.Read(); - Assert.AreEqual(JsonToken.StartArray, jsonReader.TokenType); + using (JsonReader jsonReader = new JsonTextReader(new StringReader(json))) + { + jsonReader.Read(); + Assert.AreEqual(JsonToken.StartArray, jsonReader.TokenType); - jsonReader.Read(); - Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); - Assert.AreEqual(0.0, jsonReader.Value); + jsonReader.Read(); + Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); + Assert.AreEqual(0.0, jsonReader.Value); - jsonReader.Read(); - Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); - Assert.AreEqual(0.0, jsonReader.Value); + jsonReader.Read(); + Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); + Assert.AreEqual(0.0, jsonReader.Value); - jsonReader.Read(); - Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); - Assert.AreEqual(0.1, jsonReader.Value); + jsonReader.Read(); + Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); + Assert.AreEqual(0.1, jsonReader.Value); - jsonReader.Read(); - Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); - Assert.AreEqual(1.0, jsonReader.Value); + jsonReader.Read(); + Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); + Assert.AreEqual(1.0, jsonReader.Value); - jsonReader.Read(); - Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); - Assert.AreEqual(1.000001, jsonReader.Value); + jsonReader.Read(); + Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); + Assert.AreEqual(1.000001, jsonReader.Value); - jsonReader.Read(); - Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); - Assert.AreEqual(1E-06, jsonReader.Value); + jsonReader.Read(); + Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); + Assert.AreEqual(1E-06, jsonReader.Value); - jsonReader.Read(); - Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); - Assert.AreEqual(4.94065645841247E-324, jsonReader.Value); + jsonReader.Read(); + Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); + Assert.AreEqual(4.94065645841247E-324, jsonReader.Value); - jsonReader.Read(); - Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); - Assert.AreEqual(double.PositiveInfinity, jsonReader.Value); + jsonReader.Read(); + Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); + Assert.AreEqual(double.PositiveInfinity, jsonReader.Value); - jsonReader.Read(); - Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); - Assert.AreEqual(double.NegativeInfinity, jsonReader.Value); + jsonReader.Read(); + Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); + Assert.AreEqual(double.NegativeInfinity, jsonReader.Value); - jsonReader.Read(); - Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); - Assert.AreEqual(double.NaN, jsonReader.Value); + jsonReader.Read(); + Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); + Assert.AreEqual(double.NaN, jsonReader.Value); - jsonReader.Read(); - Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); - Assert.AreEqual(double.MaxValue, jsonReader.Value); + jsonReader.Read(); + Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); + Assert.AreEqual(double.MaxValue, jsonReader.Value); - jsonReader.Read(); - Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); - Assert.AreEqual(double.MinValue, jsonReader.Value); + jsonReader.Read(); + Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); + Assert.AreEqual(double.MinValue, jsonReader.Value); - jsonReader.Read(); - Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); - Assert.AreEqual(double.PositiveInfinity, jsonReader.Value); + jsonReader.Read(); + Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); + Assert.AreEqual(double.PositiveInfinity, jsonReader.Value); - jsonReader.Read(); - Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); - Assert.AreEqual(double.NegativeInfinity, jsonReader.Value); + jsonReader.Read(); + Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); + Assert.AreEqual(double.NegativeInfinity, jsonReader.Value); - jsonReader.Read(); - Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); - Assert.AreEqual(double.NaN, jsonReader.Value); + jsonReader.Read(); + Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); + Assert.AreEqual(double.NaN, jsonReader.Value); - jsonReader.Read(); - Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); - Assert.AreEqual(0d, jsonReader.Value); + jsonReader.Read(); + Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); + Assert.AreEqual(0d, jsonReader.Value); - jsonReader.Read(); - Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); - Assert.AreEqual(0.0000025d, jsonReader.Value); + jsonReader.Read(); + Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); + Assert.AreEqual(0.0000025d, jsonReader.Value); - jsonReader.Read(); - Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); - Assert.AreEqual(3000000000d, jsonReader.Value); + jsonReader.Read(); + Assert.AreEqual(JsonToken.Float, jsonReader.TokenType); + Assert.AreEqual(3000000000d, jsonReader.Value); - jsonReader.Read(); - Assert.AreEqual(JsonToken.EndArray, jsonReader.TokenType); - } - } + jsonReader.Read(); + Assert.AreEqual(JsonToken.EndArray, jsonReader.TokenType); + } + } - [Test] - public void MissingColon() - { - string json = @"{ + [Test] + public void MissingColon() + { + string json = @"{ ""A"" : true, ""B"" """; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); + JsonTextReader reader = new JsonTextReader(new StringReader(json)); - reader.Read(); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + reader.Read(); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - reader.Read(); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + reader.Read(); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - reader.Read(); - Assert.AreEqual(JsonToken.Boolean, reader.TokenType); + reader.Read(); + Assert.AreEqual(JsonToken.Boolean, reader.TokenType); - ExceptionAssert.Throws( - @"Invalid character after parsing property name. Expected ':' but got: "". Path 'A', line 3, position 9.", - () => + ExceptionAssert.Throws( + @"Invalid character after parsing property name. Expected ':' but got: "". Path 'A', line 3, position 9.", + () => { reader.Read(); }); + } + + [Test] + public void ReadSingleBytes() { - reader.Read(); - }); - } + StringReader s = new StringReader(@"""SGVsbG8gd29ybGQu"""); + JsonTextReader reader = new JsonTextReader(s); - [Test] - public void ReadSingleBytes() - { - StringReader s = new StringReader(@"""SGVsbG8gd29ybGQu"""); - JsonTextReader reader = new JsonTextReader(s); + byte[] data = reader.ReadAsBytes(); + Assert.IsNotNull(data); - byte[] data = reader.ReadAsBytes(); - Assert.IsNotNull(data); + string text = Encoding.UTF8.GetString(data, 0, data.Length); + Assert.AreEqual("Hello world.", text); + } - string text = Encoding.UTF8.GetString(data, 0, data.Length); - Assert.AreEqual("Hello world.", text); - } - - [Test] - public void ReadOctalNumber() - { - StringReader s = new StringReader(@"[0372, 0xFA, 0XFA]"); - JsonTextReader jsonReader = new JsonTextReader(s); - - Assert.IsTrue(jsonReader.Read()); - Assert.AreEqual(JsonToken.StartArray, jsonReader.TokenType); - - Assert.IsTrue(jsonReader.Read()); - Assert.AreEqual(JsonToken.Integer, jsonReader.TokenType); - Assert.AreEqual(250L, jsonReader.Value); - - Assert.IsTrue(jsonReader.Read()); - Assert.AreEqual(JsonToken.Integer, jsonReader.TokenType); - Assert.AreEqual(250L, jsonReader.Value); - - Assert.IsTrue(jsonReader.Read()); - Assert.AreEqual(JsonToken.Integer, jsonReader.TokenType); - Assert.AreEqual(250L, jsonReader.Value); - - Assert.IsTrue(jsonReader.Read()); - Assert.AreEqual(JsonToken.EndArray, jsonReader.TokenType); - - Assert.IsFalse(jsonReader.Read()); - } - - [Test] - public void ReadOctalNumberAsInt64() - { - StringReader s = new StringReader(@"[0372, 0xFA, 0XFA]"); - JsonTextReader jsonReader = new JsonTextReader(s); - - Assert.IsTrue(jsonReader.Read()); - Assert.AreEqual(JsonToken.StartArray, jsonReader.TokenType); - - jsonReader.Read(); - Assert.AreEqual(JsonToken.Integer, jsonReader.TokenType); - Assert.AreEqual(typeof(long), jsonReader.ValueType); - Assert.AreEqual((long)250, (long)jsonReader.Value); - - jsonReader.Read(); - Assert.AreEqual(JsonToken.Integer, jsonReader.TokenType); - Assert.AreEqual(typeof(long), jsonReader.ValueType); - Assert.AreEqual((long)250, (long)jsonReader.Value); - - jsonReader.Read(); - Assert.AreEqual(JsonToken.Integer, jsonReader.TokenType); - Assert.AreEqual(typeof(long), jsonReader.ValueType); - Assert.AreEqual((long)250, (long)jsonReader.Value); - - Assert.IsTrue(jsonReader.Read()); - Assert.AreEqual(JsonToken.EndArray, jsonReader.TokenType); - - Assert.IsFalse(jsonReader.Read()); - } - - [Test] - public void ReadOctalNumberAsInt32() - { - StringReader s = new StringReader(@"[0372, 0xFA, 0XFA]"); - JsonTextReader jsonReader = new JsonTextReader(s); - - Assert.IsTrue(jsonReader.Read()); - Assert.AreEqual(JsonToken.StartArray, jsonReader.TokenType); - - jsonReader.ReadAsInt32(); - Assert.AreEqual(JsonToken.Integer, jsonReader.TokenType); - Assert.AreEqual(typeof(int), jsonReader.ValueType); - Assert.AreEqual(250, jsonReader.Value); - - jsonReader.ReadAsInt32(); - Assert.AreEqual(JsonToken.Integer, jsonReader.TokenType); - Assert.AreEqual(typeof(int), jsonReader.ValueType); - Assert.AreEqual(250, jsonReader.Value); - - jsonReader.ReadAsInt32(); - Assert.AreEqual(JsonToken.Integer, jsonReader.TokenType); - Assert.AreEqual(typeof(int), jsonReader.ValueType); - Assert.AreEqual(250, jsonReader.Value); - - Assert.IsTrue(jsonReader.Read()); - Assert.AreEqual(JsonToken.EndArray, jsonReader.TokenType); - - Assert.IsFalse(jsonReader.Read()); - } - - [Test] - public void ReadBadCharInArray() - { - JsonTextReader reader = new JsonTextReader(new StringReader(@"[}")); - - reader.Read(); - - ExceptionAssert.Throws( - "Unexpected character encountered while parsing value: }. Path '', line 1, position 1.", - () => + [Test] + public void ReadOctalNumber() { - reader.Read(); - }); - } + StringReader s = new StringReader(@"[0372, 0xFA, 0XFA]"); + JsonTextReader jsonReader = new JsonTextReader(s); - [Test] - public void ReadAsDecimalNoContent() - { - JsonTextReader reader = new JsonTextReader(new StringReader(@"")); + Assert.IsTrue(jsonReader.Read()); + Assert.AreEqual(JsonToken.StartArray, jsonReader.TokenType); - Assert.IsNull(reader.ReadAsDecimal()); - Assert.AreEqual(JsonToken.None, reader.TokenType); - } + Assert.IsTrue(jsonReader.Read()); + Assert.AreEqual(JsonToken.Integer, jsonReader.TokenType); + Assert.AreEqual(250L, jsonReader.Value); - [Test] - public void ReadAsBytesNoContent() - { - JsonTextReader reader = new JsonTextReader(new StringReader(@"")); + Assert.IsTrue(jsonReader.Read()); + Assert.AreEqual(JsonToken.Integer, jsonReader.TokenType); + Assert.AreEqual(250L, jsonReader.Value); - Assert.IsNull(reader.ReadAsBytes()); - Assert.AreEqual(JsonToken.None, reader.TokenType); - } + Assert.IsTrue(jsonReader.Read()); + Assert.AreEqual(JsonToken.Integer, jsonReader.TokenType); + Assert.AreEqual(250L, jsonReader.Value); - [Test] - public void ReadAsBytesNoContentWrappedObject() - { - JsonTextReader reader = new JsonTextReader(new StringReader(@"{")); + Assert.IsTrue(jsonReader.Read()); + Assert.AreEqual(JsonToken.EndArray, jsonReader.TokenType); - ExceptionAssert.Throws( - "Unexpected end when reading bytes. Path '', line 1, position 1.", - () => + Assert.IsFalse(jsonReader.Read()); + } + + [Test] + public void ReadOctalNumberAsInt64() { - reader.ReadAsBytes(); - }); - } + StringReader s = new StringReader(@"[0372, 0xFA, 0XFA]"); + JsonTextReader jsonReader = new JsonTextReader(s); + + Assert.IsTrue(jsonReader.Read()); + Assert.AreEqual(JsonToken.StartArray, jsonReader.TokenType); + + jsonReader.Read(); + Assert.AreEqual(JsonToken.Integer, jsonReader.TokenType); + Assert.AreEqual(typeof(long), jsonReader.ValueType); + Assert.AreEqual((long)250, (long)jsonReader.Value); + + jsonReader.Read(); + Assert.AreEqual(JsonToken.Integer, jsonReader.TokenType); + Assert.AreEqual(typeof(long), jsonReader.ValueType); + Assert.AreEqual((long)250, (long)jsonReader.Value); + + jsonReader.Read(); + Assert.AreEqual(JsonToken.Integer, jsonReader.TokenType); + Assert.AreEqual(typeof(long), jsonReader.ValueType); + Assert.AreEqual((long)250, (long)jsonReader.Value); + + Assert.IsTrue(jsonReader.Read()); + Assert.AreEqual(JsonToken.EndArray, jsonReader.TokenType); + + Assert.IsFalse(jsonReader.Read()); + } + + [Test] + public void ReadOctalNumberAsInt32() + { + StringReader s = new StringReader(@"[0372, 0xFA, 0XFA]"); + JsonTextReader jsonReader = new JsonTextReader(s); + + Assert.IsTrue(jsonReader.Read()); + Assert.AreEqual(JsonToken.StartArray, jsonReader.TokenType); + + jsonReader.ReadAsInt32(); + Assert.AreEqual(JsonToken.Integer, jsonReader.TokenType); + Assert.AreEqual(typeof(int), jsonReader.ValueType); + Assert.AreEqual(250, jsonReader.Value); + + jsonReader.ReadAsInt32(); + Assert.AreEqual(JsonToken.Integer, jsonReader.TokenType); + Assert.AreEqual(typeof(int), jsonReader.ValueType); + Assert.AreEqual(250, jsonReader.Value); + + jsonReader.ReadAsInt32(); + Assert.AreEqual(JsonToken.Integer, jsonReader.TokenType); + Assert.AreEqual(typeof(int), jsonReader.ValueType); + Assert.AreEqual(250, jsonReader.Value); + + Assert.IsTrue(jsonReader.Read()); + Assert.AreEqual(JsonToken.EndArray, jsonReader.TokenType); + + Assert.IsFalse(jsonReader.Read()); + } + + [Test] + public void ReadBadCharInArray() + { + JsonTextReader reader = new JsonTextReader(new StringReader(@"[}")); + + reader.Read(); + + ExceptionAssert.Throws( + "Unexpected character encountered while parsing value: }. Path '', line 1, position 1.", + () => { reader.Read(); }); + } + + [Test] + public void ReadAsDecimalNoContent() + { + JsonTextReader reader = new JsonTextReader(new StringReader(@"")); + + Assert.IsNull(reader.ReadAsDecimal()); + Assert.AreEqual(JsonToken.None, reader.TokenType); + } + + [Test] + public void ReadAsBytesNoContent() + { + JsonTextReader reader = new JsonTextReader(new StringReader(@"")); + + Assert.IsNull(reader.ReadAsBytes()); + Assert.AreEqual(JsonToken.None, reader.TokenType); + } + + [Test] + public void ReadAsBytesNoContentWrappedObject() + { + JsonTextReader reader = new JsonTextReader(new StringReader(@"{")); + + ExceptionAssert.Throws( + "Unexpected end when reading bytes. Path '', line 1, position 1.", + () => { reader.ReadAsBytes(); }); + } #if !NET20 - [Test] - public void ReadAsDateTimeOffsetNoContent() - { - JsonTextReader reader = new JsonTextReader(new StringReader(@"")); + [Test] + public void ReadAsDateTimeOffsetNoContent() + { + JsonTextReader reader = new JsonTextReader(new StringReader(@"")); - Assert.IsNull(reader.ReadAsDateTimeOffset()); - Assert.AreEqual(JsonToken.None, reader.TokenType); - } + Assert.IsNull(reader.ReadAsDateTimeOffset()); + Assert.AreEqual(JsonToken.None, reader.TokenType); + } #endif - [Test] - public void ReadAsDecimalBadContent() - { - JsonTextReader reader = new JsonTextReader(new StringReader(@"new Date()")); - - ExceptionAssert.Throws( - "Error reading decimal. Unexpected token: StartConstructor. Path '', line 1, position 9.", - () => + [Test] + public void ReadAsDecimalBadContent() { - reader.ReadAsDecimal(); - }); - } + JsonTextReader reader = new JsonTextReader(new StringReader(@"new Date()")); - [Test] - public void ReadAsBytesBadContent() - { - JsonTextReader reader = new JsonTextReader(new StringReader(@"new Date()")); + ExceptionAssert.Throws( + "Error reading decimal. Unexpected token: StartConstructor. Path '', line 1, position 9.", + () => { reader.ReadAsDecimal(); }); + } - ExceptionAssert.Throws( - "Error reading bytes. Unexpected token: StartConstructor. Path '', line 1, position 9.", - () => + [Test] + public void ReadAsBytesBadContent() { - reader.ReadAsBytes(); - }); - } + JsonTextReader reader = new JsonTextReader(new StringReader(@"new Date()")); + + ExceptionAssert.Throws( + "Error reading bytes. Unexpected token: StartConstructor. Path '', line 1, position 9.", + () => { reader.ReadAsBytes(); }); + } #if !NET20 - [Test] - public void ReadAsDateTimeOffsetBadContent() - { - JsonTextReader reader = new JsonTextReader(new StringReader(@"new Date()")); - - ExceptionAssert.Throws( - "Error reading date. Unexpected token: StartConstructor. Path '', line 1, position 9.", - () => + [Test] + public void ReadAsDateTimeOffsetBadContent() { - reader.ReadAsDateTimeOffset(); - }); - } + JsonTextReader reader = new JsonTextReader(new StringReader(@"new Date()")); + + ExceptionAssert.Throws( + "Error reading date. Unexpected token: StartConstructor. Path '', line 1, position 9.", + () => { reader.ReadAsDateTimeOffset(); }); + } #endif - [Test] - public void ReadAsBytesIntegerArrayWithComments() - { - JsonTextReader reader = new JsonTextReader(new StringReader(@"[/*hi*/1/*hi*/,2/*hi*/]")); - - byte[] data = reader.ReadAsBytes(); - Assert.AreEqual(2, data.Length); - Assert.AreEqual(1, data[0]); - Assert.AreEqual(2, data[1]); - } - - [Test] - public void ReadAsBytesIntegerArrayWithNoEnd() - { - JsonTextReader reader = new JsonTextReader(new StringReader(@"[1")); - - ExceptionAssert.Throws( - "Unexpected end when reading bytes. Path '[0]', line 1, position 2.", - () => + [Test] + public void ReadAsBytesIntegerArrayWithComments() { - reader.ReadAsBytes(); - }); - } + JsonTextReader reader = new JsonTextReader(new StringReader(@"[/*hi*/1/*hi*/,2/*hi*/]")); - [Test] - public void ReadAsBytesArrayWithBadContent() - { - JsonTextReader reader = new JsonTextReader(new StringReader(@"[1.0]")); + byte[] data = reader.ReadAsBytes(); + Assert.AreEqual(2, data.Length); + Assert.AreEqual(1, data[0]); + Assert.AreEqual(2, data[1]); + } - ExceptionAssert.Throws( - "Unexpected token when reading bytes: Float. Path '[0]', line 1, position 4.", - () => + [Test] + public void ReadAsBytesIntegerArrayWithNoEnd() { - reader.ReadAsBytes(); - }); - } + JsonTextReader reader = new JsonTextReader(new StringReader(@"[1")); - [Test] - public void ReadUnicode() - { - string json = @"{""Message"":""Hi,I\u0092ve send you smth""}"; + ExceptionAssert.Throws( + "Unexpected end when reading bytes. Path '[0]', line 1, position 2.", + () => { reader.ReadAsBytes(); }); + } - JsonTextReader reader = new JsonTextReader(new StringReader(json)); + [Test] + public void ReadAsBytesArrayWithBadContent() + { + JsonTextReader reader = new JsonTextReader(new StringReader(@"[1.0]")); + + ExceptionAssert.Throws( + "Unexpected token when reading bytes: Float. Path '[0]', line 1, position 4.", + () => { reader.ReadAsBytes(); }); + } + + [Test] + public void ReadUnicode() + { + string json = @"{""Message"":""Hi,I\u0092ve send you smth""}"; + + JsonTextReader reader = new JsonTextReader(new StringReader(json)); #if DEBUG - reader.SetCharBuffer(new char[5]); + reader.SetCharBuffer(new char[5]); #endif - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("Message", reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("Message", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual(@"Hi,I" + '\u0092' + "ve send you smth", reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual(@"Hi,I" + '\u0092' + "ve send you smth", reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - Assert.IsFalse(reader.Read()); - } + Assert.IsFalse(reader.Read()); + } - [Test] - public void ReadHexidecimalWithAllLetters() - { - string json = @"{""text"":0xabcdef12345}"; + [Test] + public void ReadHexidecimalWithAllLetters() + { + string json = @"{""text"":0xabcdef12345}"; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); + JsonTextReader reader = new JsonTextReader(new StringReader(json)); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.AreEqual(11806310474565, reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); + Assert.AreEqual(11806310474565, reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - } + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + } #if !NET20 - [Test] - public void ReadAsDateTimeOffset() - { - string json = "{\"Offset\":\"\\/Date(946663200000+0600)\\/\"}"; - - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - - reader.ReadAsDateTimeOffset(); - Assert.AreEqual(JsonToken.Date, reader.TokenType); - Assert.AreEqual(typeof(DateTimeOffset), reader.ValueType); - Assert.AreEqual(new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(6)), reader.Value); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - } - - [Test] - public void ReadAsDateTimeOffsetNegative() - { - string json = @"{""Offset"":""\/Date(946706400000-0600)\/""}"; - - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - - reader.ReadAsDateTimeOffset(); - Assert.AreEqual(JsonToken.Date, reader.TokenType); - Assert.AreEqual(typeof(DateTimeOffset), reader.ValueType); - Assert.AreEqual(new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(-6)), reader.Value); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - } - - [Test] - public void ReadAsDateTimeOffsetBadString() - { - string json = @"{""Offset"":""blablahbla""}"; - - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - - ExceptionAssert.Throws( - "Could not convert string to DateTimeOffset: blablahbla. Path 'Offset', line 1, position 22.", - () => + [Test] + public void ReadAsDateTimeOffset() { - reader.ReadAsDateTimeOffset(); - }); - } + string json = "{\"Offset\":\"\\/Date(946663200000+0600)\\/\"}"; - [Test] - public void ReadAsDateTimeOffsetHoursOnly() - { - string json = "{\"Offset\":\"\\/Date(946663200000+06)\\/\"}"; + JsonTextReader reader = new JsonTextReader(new StringReader(json)); - JsonTextReader reader = new JsonTextReader(new StringReader(json)); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + reader.ReadAsDateTimeOffset(); + Assert.AreEqual(JsonToken.Date, reader.TokenType); + Assert.AreEqual(typeof(DateTimeOffset), reader.ValueType); + Assert.AreEqual(new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(6)), reader.Value); - reader.ReadAsDateTimeOffset(); - Assert.AreEqual(JsonToken.Date, reader.TokenType); - Assert.AreEqual(typeof(DateTimeOffset), reader.ValueType); - Assert.AreEqual(new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(6)), reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + } - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - } + [Test] + public void ReadAsDateTimeOffsetNegative() + { + string json = @"{""Offset"":""\/Date(946706400000-0600)\/""}"; - [Test] - public void ReadAsDateTimeOffsetWithMinutes() - { - string json = @"{""Offset"":""\/Date(946708260000-0631)\/""}"; + JsonTextReader reader = new JsonTextReader(new StringReader(json)); - JsonTextReader reader = new JsonTextReader(new StringReader(json)); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + reader.ReadAsDateTimeOffset(); + Assert.AreEqual(JsonToken.Date, reader.TokenType); + Assert.AreEqual(typeof(DateTimeOffset), reader.ValueType); + Assert.AreEqual(new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(-6)), reader.Value); - reader.ReadAsDateTimeOffset(); - Assert.AreEqual(JsonToken.Date, reader.TokenType); - Assert.AreEqual(typeof(DateTimeOffset), reader.ValueType); - Assert.AreEqual(new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(-6).Add(TimeSpan.FromMinutes(-31))), reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + } - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - } + [Test] + public void ReadAsDateTimeOffsetBadString() + { + string json = @"{""Offset"":""blablahbla""}"; - [Test] - public void ReadAsDateTimeOffsetIsoDate() - { - string json = @"{""Offset"":""2011-08-01T21:25Z""}"; + JsonTextReader reader = new JsonTextReader(new StringReader(json)); - JsonTextReader reader = new JsonTextReader(new StringReader(json)); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + ExceptionAssert.Throws( + "Could not convert string to DateTimeOffset: blablahbla. Path 'Offset', line 1, position 22.", + () => { reader.ReadAsDateTimeOffset(); }); + } - reader.ReadAsDateTimeOffset(); - Assert.AreEqual(JsonToken.Date, reader.TokenType); - Assert.AreEqual(typeof(DateTimeOffset), reader.ValueType); - Assert.AreEqual(new DateTimeOffset(new DateTime(2011, 8, 1, 21, 25, 0, DateTimeKind.Utc), TimeSpan.Zero), reader.Value); + [Test] + public void ReadAsDateTimeOffsetHoursOnly() + { + string json = "{\"Offset\":\"\\/Date(946663200000+06)\\/\"}"; - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - } + JsonTextReader reader = new JsonTextReader(new StringReader(json)); - [Test] - public void ReadAsDateTimeOffsetUnitedStatesDate() - { - string json = @"{""Offset"":""1/30/2011""}"; + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - reader.Culture = new CultureInfo("en-US"); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + reader.ReadAsDateTimeOffset(); + Assert.AreEqual(JsonToken.Date, reader.TokenType); + Assert.AreEqual(typeof(DateTimeOffset), reader.ValueType); + Assert.AreEqual(new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(6)), reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + } - reader.ReadAsDateTimeOffset(); - Assert.AreEqual(JsonToken.Date, reader.TokenType); - Assert.AreEqual(typeof(DateTimeOffset), reader.ValueType); + [Test] + public void ReadAsDateTimeOffsetWithMinutes() + { + string json = @"{""Offset"":""\/Date(946708260000-0631)\/""}"; - DateTimeOffset dt = (DateTimeOffset)reader.Value; - Assert.AreEqual(new DateTime(2011, 1, 30, 0, 0, 0, DateTimeKind.Unspecified), dt.DateTime); + JsonTextReader reader = new JsonTextReader(new StringReader(json)); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - } + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - [Test] - public void ReadAsDateTimeOffsetNewZealandDate() - { - string json = @"{""Offset"":""30/1/2011""}"; + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - reader.Culture = new CultureInfo("en-NZ"); + reader.ReadAsDateTimeOffset(); + Assert.AreEqual(JsonToken.Date, reader.TokenType); + Assert.AreEqual(typeof(DateTimeOffset), reader.ValueType); + Assert.AreEqual(new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(-6).Add(TimeSpan.FromMinutes(-31))), reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + } - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + [Test] + public void ReadAsDateTimeOffsetIsoDate() + { + string json = @"{""Offset"":""2011-08-01T21:25Z""}"; - reader.ReadAsDateTimeOffset(); - Assert.AreEqual(JsonToken.Date, reader.TokenType); - Assert.AreEqual(typeof(DateTimeOffset), reader.ValueType); + JsonTextReader reader = new JsonTextReader(new StringReader(json)); - DateTimeOffset dt = (DateTimeOffset)reader.Value; - Assert.AreEqual(new DateTime(2011, 1, 30, 0, 0, 0, DateTimeKind.Unspecified), dt.DateTime); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - } + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + + reader.ReadAsDateTimeOffset(); + Assert.AreEqual(JsonToken.Date, reader.TokenType); + Assert.AreEqual(typeof(DateTimeOffset), reader.ValueType); + Assert.AreEqual(new DateTimeOffset(new DateTime(2011, 8, 1, 21, 25, 0, DateTimeKind.Utc), TimeSpan.Zero), reader.Value); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + } + + [Test] + public void ReadAsDateTimeOffsetUnitedStatesDate() + { + string json = @"{""Offset"":""1/30/2011""}"; + + JsonTextReader reader = new JsonTextReader(new StringReader(json)); + reader.Culture = new CultureInfo("en-US"); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + + reader.ReadAsDateTimeOffset(); + Assert.AreEqual(JsonToken.Date, reader.TokenType); + Assert.AreEqual(typeof(DateTimeOffset), reader.ValueType); + + DateTimeOffset dt = (DateTimeOffset)reader.Value; + Assert.AreEqual(new DateTime(2011, 1, 30, 0, 0, 0, DateTimeKind.Unspecified), dt.DateTime); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + } + + [Test] + public void ReadAsDateTimeOffsetNewZealandDate() + { + string json = @"{""Offset"":""30/1/2011""}"; + + JsonTextReader reader = new JsonTextReader(new StringReader(json)); + reader.Culture = new CultureInfo("en-NZ"); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + + reader.ReadAsDateTimeOffset(); + Assert.AreEqual(JsonToken.Date, reader.TokenType); + Assert.AreEqual(typeof(DateTimeOffset), reader.ValueType); + + DateTimeOffset dt = (DateTimeOffset)reader.Value; + Assert.AreEqual(new DateTime(2011, 1, 30, 0, 0, 0, DateTimeKind.Unspecified), dt.DateTime); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + } #endif - [Test] - public void ReadAsDecimalInt() - { - string json = @"{""Name"":1}"; - - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - - reader.ReadAsDecimal(); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual(typeof(decimal), reader.ValueType); - Assert.AreEqual(1m, reader.Value); - } - - [Test] - public void ReadAsIntDecimal() - { - string json = @"{""Name"": 1.1}"; - - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - - ExceptionAssert.Throws( - "Input string was not in a correct format.", - () => + [Test] + public void ReadAsDecimalInt() { - reader.ReadAsInt32(); - }); - } + string json = @"{""Name"":1}"; - [Test] - public void MatchWithInsufficentCharacters() - { - JsonTextReader reader = new JsonTextReader(new StringReader(@"nul")); + JsonTextReader reader = new JsonTextReader(new StringReader(json)); - ExceptionAssert.Throws( - "Error parsing null value. Path '', line 0, position 0.", - () => - { - reader.Read(); - }); - } + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - [Test] - public void MatchWithWrongCharacters() - { - JsonTextReader reader = new JsonTextReader(new StringReader(@"nulz")); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - ExceptionAssert.Throws( - "Error parsing null value. Path '', line 0, position 0.", - () => - { - reader.Read(); - }); - } + reader.ReadAsDecimal(); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual(typeof(decimal), reader.ValueType); + Assert.AreEqual(1m, reader.Value); + } - [Test] - public void MatchWithNoTrailingSeperator() - { - JsonTextReader reader = new JsonTextReader(new StringReader(@"nullz")); + [Test] + public void ReadAsIntDecimal() + { + string json = @"{""Name"": 1.1}"; - ExceptionAssert.Throws( - "Error parsing null value. Path '', line 1, position 4.", - () => - { - reader.Read(); - }); - } + JsonTextReader reader = new JsonTextReader(new StringReader(json)); - [Test] - public void UnclosedComment() - { - JsonTextReader reader = new JsonTextReader(new StringReader(@"/* sdf")); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - ExceptionAssert.Throws( - "Unexpected end while parsing comment. Path '', line 1, position 6.", - () => - { - reader.Read(); - }); - } + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - [Test] - public void BadCommentStart() - { - JsonTextReader reader = new JsonTextReader(new StringReader(@"/sdf")); + ExceptionAssert.Throws( + "Input string was not in a correct format.", + () => { reader.ReadAsInt32(); }); + } - ExceptionAssert.Throws( - "Error parsing comment. Expected: *, got s. Path '', line 1, position 1.", - () => - { - reader.Read(); - }); - } + [Test] + public void MatchWithInsufficentCharacters() + { + JsonTextReader reader = new JsonTextReader(new StringReader(@"nul")); - [Test] - public void ReadAsDecimal() - { - string json = @"{""decimal"":-7.92281625142643E+28}"; + ExceptionAssert.Throws( + "Error parsing null value. Path '', line 0, position 0.", + () => { reader.Read(); }); + } - JsonTextReader reader = new JsonTextReader(new StringReader(json)); + [Test] + public void MatchWithWrongCharacters() + { + JsonTextReader reader = new JsonTextReader(new StringReader(@"nulz")); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + ExceptionAssert.Throws( + "Error parsing null value. Path '', line 0, position 0.", + () => { reader.Read(); }); + } - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + [Test] + public void MatchWithNoTrailingSeperator() + { + JsonTextReader reader = new JsonTextReader(new StringReader(@"nullz")); - decimal? d = reader.ReadAsDecimal(); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual(typeof(decimal), reader.ValueType); - Assert.AreEqual(-79228162514264300000000000000m, d); + ExceptionAssert.Throws( + "Error parsing null value. Path '', line 1, position 4.", + () => { reader.Read(); }); + } - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - } + [Test] + public void UnclosedComment() + { + JsonTextReader reader = new JsonTextReader(new StringReader(@"/* sdf")); - [Test] - public void ReadAsDecimalFrench() - { - string json = @"{""decimal"":""9,99""}"; + ExceptionAssert.Throws( + "Unexpected end while parsing comment. Path '', line 1, position 6.", + () => { reader.Read(); }); + } - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - reader.Culture = new CultureInfo("fr-FR"); + [Test] + public void BadCommentStart() + { + JsonTextReader reader = new JsonTextReader(new StringReader(@"/sdf")); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + ExceptionAssert.Throws( + "Error parsing comment. Expected: *, got s. Path '', line 1, position 1.", + () => { reader.Read(); }); + } - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + [Test] + public void ReadAsDecimal() + { + string json = @"{""decimal"":-7.92281625142643E+28}"; - decimal? d = reader.ReadAsDecimal(); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual(typeof(decimal), reader.ValueType); - Assert.AreEqual(9.99m, d); + JsonTextReader reader = new JsonTextReader(new StringReader(json)); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - } + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - [Test] - public void ReadBufferOnControlChar() - { - string json = @"[ + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + + decimal? d = reader.ReadAsDecimal(); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual(typeof(decimal), reader.ValueType); + Assert.AreEqual(-79228162514264300000000000000m, d); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + } + + [Test] + public void ReadAsDecimalFrench() + { + string json = @"{""decimal"":""9,99""}"; + + JsonTextReader reader = new JsonTextReader(new StringReader(json)); + reader.Culture = new CultureInfo("fr-FR"); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + + decimal? d = reader.ReadAsDecimal(); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual(typeof(decimal), reader.ValueType); + Assert.AreEqual(9.99m, d); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + } + + [Test] + public void ReadBufferOnControlChar() + { + string json = @"[ { ""Name"": ""Jim"", ""BirthDate"": ""\/Date(978048000000)\/"", @@ -2164,24 +2091,24 @@ bye", reader.Value); } ]"; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); + JsonTextReader reader = new JsonTextReader(new StringReader(json)); #if DEBUG - reader.SetCharBuffer(new char[5]); + reader.SetCharBuffer(new char[5]); #endif - for (int i = 0; i < 13; i++) - { - reader.Read(); - } + for (int i = 0; i < 13; i++) + { + reader.Read(); + } - Assert.IsTrue(reader.Read()); - Assert.AreEqual(new DateTime(631136448000000000), reader.Value); - } + Assert.IsTrue(reader.Read()); + Assert.AreEqual(new DateTime(631136448000000000), reader.Value); + } - [Test] - public void ReadBufferOnEndComment() - { - string json = @"/*comment*/ { /*comment*/ + [Test] + public void ReadBufferOnEndComment() + { + string json = @"/*comment*/ { /*comment*/ ""Name"": /*comment*/ ""Apple"" /*comment*/, /*comment*/ ""ExpiryDate"": ""\/Date(1230422400000)\/"", ""Price"": 3.99, @@ -2192,814 +2119,790 @@ bye", reader.Value); /*comment*/ ] /*comment*/ } /*comment*/"; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); + JsonTextReader reader = new JsonTextReader(new StringReader(json)); #if DEBUG - reader.SetCharBuffer(new char[5]); + reader.SetCharBuffer(new char[5]); #endif - for (int i = 0; i < 26; i++) - { - Assert.IsTrue(reader.Read()); - } + for (int i = 0; i < 26; i++) + { + Assert.IsTrue(reader.Read()); + } - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Comment, reader.TokenType); - - Assert.IsFalse(reader.Read()); - } - - [Test] - public void ParseNullStringConstructor() - { - string json = "new Date\0()"; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); -#if DEBUG - reader.SetCharBuffer(new char[7]); -#endif - - Assert.IsTrue(reader.Read()); - Assert.AreEqual("Date", reader.Value); - Assert.AreEqual(JsonToken.StartConstructor, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndConstructor, reader.TokenType); - } - - [Test] - public void ParseLineFeedDelimitedConstructor() - { - string json = "new Date\n()"; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual("Date", reader.Value); - Assert.AreEqual(JsonToken.StartConstructor, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndConstructor, reader.TokenType); - } - - [Test] - public void ParseArrayWithMissingValues() - { - string json = "[,,, \n\r\n \0 \r , , ]"; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Undefined, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Undefined, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Undefined, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Undefined, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Undefined, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - } - - [Test] - public void ParseBooleanWithNoExtraContent() - { - string json = "[true "; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - - Assert.IsTrue(reader.Read()); - Assert.IsTrue(reader.Read()); - Assert.IsFalse(reader.Read()); - } - - [Test] - public void ParseConstructorWithUnexpectedEnd() - { - string json = "new Dat"; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - - ExceptionAssert.Throws( - "Unexpected end while parsing constructor. Path '', line 1, position 7.", - () => - { - reader.Read(); - }); - } - - [Test] - public void ParseConstructorWithUnexpectedCharacter() - { - string json = "new Date !"; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - - ExceptionAssert.Throws( - "Unexpected character while parsing constructor: !. Path '', line 1, position 9.", - () => - { - reader.Read(); - }); - } - - [Test] - public void ParseObjectWithNoEnd() - { - string json = "{hi:1, "; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - - Assert.IsTrue(reader.Read()); - Assert.IsTrue(reader.Read()); - Assert.IsTrue(reader.Read()); - Assert.IsFalse(reader.Read()); - } - - [Test] - public void ParseEmptyArray() - { - string json = "[]"; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - } - - [Test] - public void ParseEmptyObject() - { - string json = "{}"; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - } - - [Test] - public void ParseIncompleteCommentSeperator() - { - JsonTextReader reader = new JsonTextReader(new StringReader("true/")); - - ExceptionAssert.Throws( - "Error parsing boolean value. Path '', line 1, position 4.", - () => - { - reader.Read(); - }); - } - - [Test] - public void ParseEmptyConstructor() - { - string json = "new Date()"; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartConstructor, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndConstructor, reader.TokenType); - } - - [Test] - public void ParseConstructorWithBadCharacter() - { - string json = "new Date,()"; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - - ExceptionAssert.Throws( - "Unexpected character while parsing constructor: ,. Path '', line 1, position 8.", - () => - { Assert.IsTrue(reader.Read()); - }); - } + Assert.AreEqual(JsonToken.Comment, reader.TokenType); - [Test] - public void ParseContentDelimitedByNonStandardWhitespace() - { - string json = "\x00a0{\x00a0'h\x00a0i\x00a0'\x00a0:\x00a0[\x00a0true\x00a0,\x00a0new\x00a0Date\x00a0(\x00a0)\x00a0]\x00a0/*\x00a0comment\x00a0*/\x00a0}\x00a0"; - JsonTextReader reader = new JsonTextReader(new StreamReader(new SlowStream(json, new UTF8Encoding(false), 1))); + Assert.IsFalse(reader.Read()); + } - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + [Test] + public void ParseNullStringConstructor() + { + string json = "new Date\0()"; + JsonTextReader reader = new JsonTextReader(new StringReader(json)); +#if DEBUG + reader.SetCharBuffer(new char[7]); +#endif - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Boolean, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartConstructor, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual("Date", reader.Value); + Assert.AreEqual(JsonToken.StartConstructor, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndConstructor, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndConstructor, reader.TokenType); + } - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + [Test] + public void ParseLineFeedDelimitedConstructor() + { + string json = "new Date\n()"; + JsonTextReader reader = new JsonTextReader(new StringReader(json)); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Comment, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual("Date", reader.Value); + Assert.AreEqual(JsonToken.StartConstructor, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndConstructor, reader.TokenType); + } - Assert.IsFalse(reader.Read()); - } - - [Test] - public void ReadContentDelimitedByComments() - { - string json = @"/*comment*/{/*comment*/Name:/*comment*/true/*comment*/,/*comment*/ + [Test] + public void ParseArrayWithMissingValues() + { + string json = "[,,, \n\r\n \0 \r , , ]"; + JsonTextReader reader = new JsonTextReader(new StringReader(json)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Undefined, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Undefined, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Undefined, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Undefined, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Undefined, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + } + + [Test] + public void ParseBooleanWithNoExtraContent() + { + string json = "[true "; + JsonTextReader reader = new JsonTextReader(new StringReader(json)); + + Assert.IsTrue(reader.Read()); + Assert.IsTrue(reader.Read()); + Assert.IsFalse(reader.Read()); + } + + [Test] + public void ParseConstructorWithUnexpectedEnd() + { + string json = "new Dat"; + JsonTextReader reader = new JsonTextReader(new StringReader(json)); + + ExceptionAssert.Throws( + "Unexpected end while parsing constructor. Path '', line 1, position 7.", + () => { reader.Read(); }); + } + + [Test] + public void ParseConstructorWithUnexpectedCharacter() + { + string json = "new Date !"; + JsonTextReader reader = new JsonTextReader(new StringReader(json)); + + ExceptionAssert.Throws( + "Unexpected character while parsing constructor: !. Path '', line 1, position 9.", + () => { reader.Read(); }); + } + + [Test] + public void ParseObjectWithNoEnd() + { + string json = "{hi:1, "; + JsonTextReader reader = new JsonTextReader(new StringReader(json)); + + Assert.IsTrue(reader.Read()); + Assert.IsTrue(reader.Read()); + Assert.IsTrue(reader.Read()); + Assert.IsFalse(reader.Read()); + } + + [Test] + public void ParseEmptyArray() + { + string json = "[]"; + JsonTextReader reader = new JsonTextReader(new StringReader(json)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + } + + [Test] + public void ParseEmptyObject() + { + string json = "{}"; + JsonTextReader reader = new JsonTextReader(new StringReader(json)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + } + + [Test] + public void ParseIncompleteCommentSeperator() + { + JsonTextReader reader = new JsonTextReader(new StringReader("true/")); + + ExceptionAssert.Throws( + "Error parsing boolean value. Path '', line 1, position 4.", + () => { reader.Read(); }); + } + + [Test] + public void ParseEmptyConstructor() + { + string json = "new Date()"; + JsonTextReader reader = new JsonTextReader(new StringReader(json)); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartConstructor, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndConstructor, reader.TokenType); + } + + [Test] + public void ParseConstructorWithBadCharacter() + { + string json = "new Date,()"; + JsonTextReader reader = new JsonTextReader(new StringReader(json)); + + ExceptionAssert.Throws( + "Unexpected character while parsing constructor: ,. Path '', line 1, position 8.", + () => { Assert.IsTrue(reader.Read()); }); + } + + [Test] + public void ParseContentDelimitedByNonStandardWhitespace() + { + string json = "\x00a0{\x00a0'h\x00a0i\x00a0'\x00a0:\x00a0[\x00a0true\x00a0,\x00a0new\x00a0Date\x00a0(\x00a0)\x00a0]\x00a0/*\x00a0comment\x00a0*/\x00a0}\x00a0"; + JsonTextReader reader = new JsonTextReader(new StreamReader(new SlowStream(json, new UTF8Encoding(false), 1))); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Boolean, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartConstructor, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndConstructor, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Comment, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + + Assert.IsFalse(reader.Read()); + } + + [Test] + public void ReadContentDelimitedByComments() + { + string json = @"/*comment*/{/*comment*/Name:/*comment*/true/*comment*/,/*comment*/ ""ExpiryDate"":/*comment*/new " + StringUtils.LineFeed + -@"Date + @"Date (/*comment*/null/*comment*/), ""Price"": 3.99, ""Sizes"":/*comment*/[/*comment*/ ""Small""/*comment*/]/*comment*/}/*comment*/"; - JsonTextReader reader = new JsonTextReader(new StreamReader(new SlowStream(json, new UTF8Encoding(false), 1))); + JsonTextReader reader = new JsonTextReader(new StreamReader(new SlowStream(json, new UTF8Encoding(false), 1))); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Comment, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Comment, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("Name", reader.Value); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Comment, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Boolean, reader.TokenType); - Assert.AreEqual(true, reader.Value); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Comment, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Comment, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("ExpiryDate", reader.Value); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Comment, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartConstructor, reader.TokenType); - Assert.AreEqual(5, reader.LineNumber); - Assert.AreEqual("Date", reader.Value); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Comment, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Null, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Comment, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndConstructor, reader.TokenType); - } - - [Test] - public void ParseOctalNumber() - { - string json = @"010"; - - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - - reader.ReadAsDecimal(); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual(8m, reader.Value); - } - - [Test] - public void ParseHexNumber() - { - string json = @"0x20"; - - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - - reader.ReadAsDecimal(); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual(32m, reader.Value); - } - - [Test] - public void ParseNumbers() - { - string json = @"[0,1,2 , 3]"; - - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - - reader.Read(); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - - reader.Read(); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); - - reader.Read(); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); - - reader.Read(); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); - - reader.Read(); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); - - reader.Read(); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - } - - [Test] - public void UnexpectedEndTokenWhenParsingOddEndToken() - { - JsonReader reader = new JsonTextReader(new StringReader(@"{}}")); - Assert.IsTrue(reader.Read()); - Assert.IsTrue(reader.Read()); - - ExceptionAssert.Throws( - "Additional text encountered after finished reading JSON content: }. Path '', line 1, position 2.", - () => - { - reader.Read(); - }); - } - - [Test] - public void ScientificNotation() - { - double d; - - d = Convert.ToDouble("6.0221418e23", CultureInfo.InvariantCulture); - Console.WriteLine(d.ToString(new CultureInfo("fr-FR"))); - Console.WriteLine(d.ToString("0.#############################################################################")); - - //CultureInfo info = CultureInfo.GetCultureInfo("fr-FR"); - //Console.WriteLine(info.NumberFormat.NumberDecimalSeparator); - - string json = @"[0e-10,0E-10,0.25e-5,0.3e10,6.0221418e23]"; - - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - - reader.Read(); - - reader.Read(); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual(0d, reader.Value); - - reader.Read(); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual(0d, reader.Value); - - reader.Read(); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual(0.0000025d, reader.Value); - - reader.Read(); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual(3000000000d, reader.Value); - - reader.Read(); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual(602214180000000000000000d, reader.Value); - - reader.Read(); - - - reader = new JsonTextReader(new StringReader(json)); - - reader.Read(); - - reader.ReadAsDecimal(); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual(0m, reader.Value); - - reader.ReadAsDecimal(); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual(0m, reader.Value); - - reader.ReadAsDecimal(); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual(0.0000025m, reader.Value); - - reader.ReadAsDecimal(); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual(3000000000m, reader.Value); - - reader.ReadAsDecimal(); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual(602214180000000000000000m, reader.Value); - - reader.Read(); - } - - [Test] - public void MaxDepth() - { - string json = "[[]]"; - - JsonTextReader reader = new JsonTextReader(new StringReader(json)) - { - MaxDepth = 1 - }; - - Assert.IsTrue(reader.Read()); - - ExceptionAssert.Throws( - "The reader's MaxDepth of 1 has been exceeded. Path '[0]', line 1, position 2.", - () => - { Assert.IsTrue(reader.Read()); - }); - } + Assert.AreEqual(JsonToken.Comment, reader.TokenType); - [Test] - public void MaxDepthDoesNotRecursivelyError() - { - string json = "[[[[]]],[[]]]"; + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - JsonTextReader reader = new JsonTextReader(new StringReader(json)) - { - MaxDepth = 1 - }; + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Comment, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(0, reader.Depth); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("Name", reader.Value); - ExceptionAssert.Throws( - "The reader's MaxDepth of 1 has been exceeded. Path '[0]', line 1, position 2.", - () => + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Comment, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Boolean, reader.TokenType); + Assert.AreEqual(true, reader.Value); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Comment, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Comment, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("ExpiryDate", reader.Value); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Comment, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartConstructor, reader.TokenType); + Assert.AreEqual(5, reader.LineNumber); + Assert.AreEqual("Date", reader.Value); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Comment, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Null, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Comment, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndConstructor, reader.TokenType); + } + + [Test] + public void ParseOctalNumber() { - Assert.IsTrue(reader.Read()); - }); - Assert.AreEqual(1, reader.Depth); + string json = @"010"; - Assert.IsTrue(reader.Read()); - Assert.AreEqual(2, reader.Depth); + JsonTextReader reader = new JsonTextReader(new StringReader(json)); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(3, reader.Depth); + reader.ReadAsDecimal(); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual(8m, reader.Value); + } - Assert.IsTrue(reader.Read()); - Assert.AreEqual(3, reader.Depth); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(2, reader.Depth); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(1, reader.Depth); - - ExceptionAssert.Throws( - "The reader's MaxDepth of 1 has been exceeded. Path '[1]', line 1, position 9.", - () => + [Test] + public void ParseHexNumber() { - Assert.IsTrue(reader.Read()); - }); - Assert.AreEqual(1, reader.Depth); + string json = @"0x20"; - Assert.IsTrue(reader.Read()); - Assert.AreEqual(2, reader.Depth); + JsonTextReader reader = new JsonTextReader(new StringReader(json)); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(2, reader.Depth); + reader.ReadAsDecimal(); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual(32m, reader.Value); + } - Assert.IsTrue(reader.Read()); - Assert.AreEqual(1, reader.Depth); + [Test] + public void ParseNumbers() + { + string json = @"[0,1,2 , 3]"; - Assert.IsTrue(reader.Read()); - Assert.AreEqual(0, reader.Depth); + JsonTextReader reader = new JsonTextReader(new StringReader(json)); - Assert.IsFalse(reader.Read()); - } + reader.Read(); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - [Test] - public void ReadingFromSlowStream() - { - string json = "[false, true, true, false, 'test!', 1.11, 0e-10, 0E-10, 0.25e-5, 0.3e10, 6.0221418e23, 'Purple\\r \\n monkey\\'s:\\tdishwasher']"; + reader.Read(); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); - JsonTextReader reader = new JsonTextReader(new StreamReader(new SlowStream(json, new UTF8Encoding(false), 1))); + reader.Read(); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.IsTrue(reader.Read()); + reader.Read(); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(false, reader.Value); + reader.Read(); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Boolean, reader.TokenType); - Assert.AreEqual(true, reader.Value); + reader.Read(); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + } - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Boolean, reader.TokenType); - Assert.AreEqual(true, reader.Value); + [Test] + public void UnexpectedEndTokenWhenParsingOddEndToken() + { + JsonReader reader = new JsonTextReader(new StringReader(@"{}}")); + Assert.IsTrue(reader.Read()); + Assert.IsTrue(reader.Read()); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Boolean, reader.TokenType); - Assert.AreEqual(false, reader.Value); + ExceptionAssert.Throws( + "Additional text encountered after finished reading JSON content: }. Path '', line 1, position 2.", + () => { reader.Read(); }); + } - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("test!", reader.Value); + [Test] + public void ScientificNotation() + { + double d; - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual(1.11d, reader.Value); + d = Convert.ToDouble("6.0221418e23", CultureInfo.InvariantCulture); + Console.WriteLine(d.ToString(new CultureInfo("fr-FR"))); + Console.WriteLine(d.ToString("0.#############################################################################")); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual(0d, reader.Value); + //CultureInfo info = CultureInfo.GetCultureInfo("fr-FR"); + //Console.WriteLine(info.NumberFormat.NumberDecimalSeparator); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual(0d, reader.Value); + string json = @"[0e-10,0E-10,0.25e-5,0.3e10,6.0221418e23]"; - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual(0.0000025d, reader.Value); + JsonTextReader reader = new JsonTextReader(new StringReader(json)); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual(3000000000d, reader.Value); + reader.Read(); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual(602214180000000000000000d, reader.Value); + reader.Read(); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual(0d, reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual(reader.Value, "Purple\r \n monkey's:\tdishwasher"); + reader.Read(); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual(0d, reader.Value); - Assert.IsTrue(reader.Read()); - } + reader.Read(); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual(0.0000025d, reader.Value); - [Test] - public void DateParseHandling() - { - string json = @"[""1970-01-01T00:00:00Z"",""\/Date(0)\/""]"; + reader.Read(); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual(3000000000d, reader.Value); - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - reader.DateParseHandling = Json.DateParseHandling.DateTime; + reader.Read(); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual(602214180000000000000000d, reader.Value); - Assert.IsTrue(reader.Read()); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc), reader.Value); - Assert.AreEqual(typeof(DateTime), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc), reader.Value); - Assert.AreEqual(typeof(DateTime), reader.ValueType); - Assert.IsTrue(reader.Read()); + reader.Read(); + + + reader = new JsonTextReader(new StringReader(json)); + + reader.Read(); + + reader.ReadAsDecimal(); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual(0m, reader.Value); + + reader.ReadAsDecimal(); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual(0m, reader.Value); + + reader.ReadAsDecimal(); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual(0.0000025m, reader.Value); + + reader.ReadAsDecimal(); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual(3000000000m, reader.Value); + + reader.ReadAsDecimal(); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual(602214180000000000000000m, reader.Value); + + reader.Read(); + } + + [Test] + public void MaxDepth() + { + string json = "[[]]"; + + JsonTextReader reader = new JsonTextReader(new StringReader(json)) + { + MaxDepth = 1 + }; + + Assert.IsTrue(reader.Read()); + + ExceptionAssert.Throws( + "The reader's MaxDepth of 1 has been exceeded. Path '[0]', line 1, position 2.", + () => { Assert.IsTrue(reader.Read()); }); + } + + [Test] + public void MaxDepthDoesNotRecursivelyError() + { + string json = "[[[[]]],[[]]]"; + + JsonTextReader reader = new JsonTextReader(new StringReader(json)) + { + MaxDepth = 1 + }; + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(0, reader.Depth); + + ExceptionAssert.Throws( + "The reader's MaxDepth of 1 has been exceeded. Path '[0]', line 1, position 2.", + () => { Assert.IsTrue(reader.Read()); }); + Assert.AreEqual(1, reader.Depth); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(2, reader.Depth); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(3, reader.Depth); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(3, reader.Depth); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(2, reader.Depth); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(1, reader.Depth); + + ExceptionAssert.Throws( + "The reader's MaxDepth of 1 has been exceeded. Path '[1]', line 1, position 9.", + () => { Assert.IsTrue(reader.Read()); }); + Assert.AreEqual(1, reader.Depth); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(2, reader.Depth); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(2, reader.Depth); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(1, reader.Depth); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(0, reader.Depth); + + Assert.IsFalse(reader.Read()); + } + + [Test] + public void ReadingFromSlowStream() + { + string json = "[false, true, true, false, 'test!', 1.11, 0e-10, 0E-10, 0.25e-5, 0.3e10, 6.0221418e23, 'Purple\\r \\n monkey\\'s:\\tdishwasher']"; + + JsonTextReader reader = new JsonTextReader(new StreamReader(new SlowStream(json, new UTF8Encoding(false), 1))); + + Assert.IsTrue(reader.Read()); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(false, reader.Value); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Boolean, reader.TokenType); + Assert.AreEqual(true, reader.Value); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Boolean, reader.TokenType); + Assert.AreEqual(true, reader.Value); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Boolean, reader.TokenType); + Assert.AreEqual(false, reader.Value); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("test!", reader.Value); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual(1.11d, reader.Value); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual(0d, reader.Value); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual(0d, reader.Value); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual(0.0000025d, reader.Value); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual(3000000000d, reader.Value); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual(602214180000000000000000d, reader.Value); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual(reader.Value, "Purple\r \n monkey's:\tdishwasher"); + + Assert.IsTrue(reader.Read()); + } + + [Test] + public void DateParseHandling() + { + string json = @"[""1970-01-01T00:00:00Z"",""\/Date(0)\/""]"; + + JsonTextReader reader = new JsonTextReader(new StringReader(json)); + reader.DateParseHandling = Json.DateParseHandling.DateTime; + + Assert.IsTrue(reader.Read()); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc), reader.Value); + Assert.AreEqual(typeof(DateTime), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc), reader.Value); + Assert.AreEqual(typeof(DateTime), reader.ValueType); + Assert.IsTrue(reader.Read()); #if !NET20 - reader = new JsonTextReader(new StringReader(json)); - reader.DateParseHandling = Json.DateParseHandling.DateTimeOffset; + reader = new JsonTextReader(new StringReader(json)); + reader.DateParseHandling = Json.DateParseHandling.DateTimeOffset; - Assert.IsTrue(reader.Read()); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(new DateTimeOffset(DateTimeUtils.InitialJavaScriptDateTicks, TimeSpan.Zero), reader.Value); - Assert.AreEqual(typeof(DateTimeOffset), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(new DateTimeOffset(DateTimeUtils.InitialJavaScriptDateTicks, TimeSpan.Zero), reader.Value); - Assert.AreEqual(typeof(DateTimeOffset), reader.ValueType); - Assert.IsTrue(reader.Read()); + Assert.IsTrue(reader.Read()); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(new DateTimeOffset(DateTimeUtils.InitialJavaScriptDateTicks, TimeSpan.Zero), reader.Value); + Assert.AreEqual(typeof(DateTimeOffset), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(new DateTimeOffset(DateTimeUtils.InitialJavaScriptDateTicks, TimeSpan.Zero), reader.Value); + Assert.AreEqual(typeof(DateTimeOffset), reader.ValueType); + Assert.IsTrue(reader.Read()); #endif - reader = new JsonTextReader(new StringReader(json)); - reader.DateParseHandling = Json.DateParseHandling.None; + reader = new JsonTextReader(new StringReader(json)); + reader.DateParseHandling = Json.DateParseHandling.None; - Assert.IsTrue(reader.Read()); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(@"1970-01-01T00:00:00Z", reader.Value); - Assert.AreEqual(typeof(string), reader.ValueType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(@"/Date(0)/", reader.Value); - Assert.AreEqual(typeof(string), reader.ValueType); - Assert.IsTrue(reader.Read()); + Assert.IsTrue(reader.Read()); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(@"1970-01-01T00:00:00Z", reader.Value); + Assert.AreEqual(typeof(string), reader.ValueType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(@"/Date(0)/", reader.Value); + Assert.AreEqual(typeof(string), reader.ValueType); + Assert.IsTrue(reader.Read()); #if !NET20 - reader = new JsonTextReader(new StringReader(json)); - reader.DateParseHandling = Json.DateParseHandling.DateTime; + reader = new JsonTextReader(new StringReader(json)); + reader.DateParseHandling = Json.DateParseHandling.DateTime; - Assert.IsTrue(reader.Read()); - reader.ReadAsDateTimeOffset(); - Assert.AreEqual(new DateTimeOffset(DateTimeUtils.InitialJavaScriptDateTicks, TimeSpan.Zero), reader.Value); - Assert.AreEqual(typeof(DateTimeOffset), reader.ValueType); - reader.ReadAsDateTimeOffset(); - Assert.AreEqual(new DateTimeOffset(DateTimeUtils.InitialJavaScriptDateTicks, TimeSpan.Zero), reader.Value); - Assert.AreEqual(typeof(DateTimeOffset), reader.ValueType); - Assert.IsTrue(reader.Read()); + Assert.IsTrue(reader.Read()); + reader.ReadAsDateTimeOffset(); + Assert.AreEqual(new DateTimeOffset(DateTimeUtils.InitialJavaScriptDateTicks, TimeSpan.Zero), reader.Value); + Assert.AreEqual(typeof(DateTimeOffset), reader.ValueType); + reader.ReadAsDateTimeOffset(); + Assert.AreEqual(new DateTimeOffset(DateTimeUtils.InitialJavaScriptDateTicks, TimeSpan.Zero), reader.Value); + Assert.AreEqual(typeof(DateTimeOffset), reader.ValueType); + Assert.IsTrue(reader.Read()); - reader = new JsonTextReader(new StringReader(json)); - reader.DateParseHandling = Json.DateParseHandling.DateTimeOffset; + reader = new JsonTextReader(new StringReader(json)); + reader.DateParseHandling = Json.DateParseHandling.DateTimeOffset; - Assert.IsTrue(reader.Read()); - reader.ReadAsDateTime(); - Assert.AreEqual(new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc), reader.Value); - Assert.AreEqual(typeof(DateTime), reader.ValueType); - reader.ReadAsDateTime(); - Assert.AreEqual(new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc), reader.Value); - Assert.AreEqual(typeof(DateTime), reader.ValueType); - Assert.IsTrue(reader.Read()); + Assert.IsTrue(reader.Read()); + reader.ReadAsDateTime(); + Assert.AreEqual(new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc), reader.Value); + Assert.AreEqual(typeof(DateTime), reader.ValueType); + reader.ReadAsDateTime(); + Assert.AreEqual(new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc), reader.Value); + Assert.AreEqual(typeof(DateTime), reader.ValueType); + Assert.IsTrue(reader.Read()); #endif + } + + [Test] + public void ResetJsonTextReaderErrorCount() + { + ToggleReaderError toggleReaderError = new ToggleReaderError(new StringReader("{'first':1,'second':2,'third':3}")); + JsonTextReader jsonTextReader = new JsonTextReader(toggleReaderError); + + Assert.IsTrue(jsonTextReader.Read()); + + toggleReaderError.Error = true; + + ExceptionAssert.Throws( + "Read error", + () => jsonTextReader.Read()); + ExceptionAssert.Throws( + "Read error", + () => jsonTextReader.Read()); + + toggleReaderError.Error = false; + + Assert.IsTrue(jsonTextReader.Read()); + Assert.AreEqual("first", jsonTextReader.Value); + + toggleReaderError.Error = true; + + ExceptionAssert.Throws( + "Read error", + () => jsonTextReader.Read()); + + toggleReaderError.Error = false; + + Assert.IsTrue(jsonTextReader.Read()); + Assert.AreEqual(1L, jsonTextReader.Value); + + toggleReaderError.Error = true; + + ExceptionAssert.Throws( + "Read error", + () => jsonTextReader.Read()); + ExceptionAssert.Throws( + "Read error", + () => jsonTextReader.Read()); + ExceptionAssert.Throws( + "Read error", + () => jsonTextReader.Read()); + + toggleReaderError.Error = false; + + //a reader use to skip to the end after 3 errors in a row + //Assert.IsFalse(jsonTextReader.Read()); + } + + [Test] + public void WriteReadBoundaryDecimals() + { + StringWriter sw = new StringWriter(); + JsonTextWriter writer = new JsonTextWriter(sw); + + writer.WriteStartArray(); + writer.WriteValue(decimal.MaxValue); + writer.WriteValue(decimal.MinValue); + writer.WriteEndArray(); + + string json = sw.ToString(); + + StringReader sr = new StringReader(json); + JsonTextReader reader = new JsonTextReader(sr); + + Assert.IsTrue(reader.Read()); + + decimal? max = reader.ReadAsDecimal(); + Assert.AreEqual(decimal.MaxValue, max); + + decimal? min = reader.ReadAsDecimal(); + Assert.AreEqual(decimal.MinValue, min); + + Assert.IsTrue(reader.Read()); + } } - [Test] - public void ResetJsonTextReaderErrorCount() + public class ToggleReaderError : TextReader { - ToggleReaderError toggleReaderError = new ToggleReaderError(new StringReader("{'first':1,'second':2,'third':3}")); - JsonTextReader jsonTextReader = new JsonTextReader(toggleReaderError); + private readonly TextReader _inner; - Assert.IsTrue(jsonTextReader.Read()); + public bool Error { get; set; } - toggleReaderError.Error = true; + public ToggleReaderError(TextReader inner) + { + _inner = inner; + } - ExceptionAssert.Throws( - "Read error", - () => jsonTextReader.Read()); - ExceptionAssert.Throws( - "Read error", - () => jsonTextReader.Read()); + public override int Read(char[] buffer, int index, int count) + { + if (Error) + throw new Exception("Read error"); - toggleReaderError.Error = false; - - Assert.IsTrue(jsonTextReader.Read()); - Assert.AreEqual("first", jsonTextReader.Value); - - toggleReaderError.Error = true; - - ExceptionAssert.Throws( - "Read error", - () => jsonTextReader.Read()); - - toggleReaderError.Error = false; - - Assert.IsTrue(jsonTextReader.Read()); - Assert.AreEqual(1L, jsonTextReader.Value); - - toggleReaderError.Error = true; - - ExceptionAssert.Throws( - "Read error", - () => jsonTextReader.Read()); - ExceptionAssert.Throws( - "Read error", - () => jsonTextReader.Read()); - ExceptionAssert.Throws( - "Read error", - () => jsonTextReader.Read()); - - toggleReaderError.Error = false; - - //a reader use to skip to the end after 3 errors in a row - //Assert.IsFalse(jsonTextReader.Read()); + return _inner.Read(buffer, index, 1); + } } - [Test] - public void WriteReadBoundaryDecimals() + public class SlowStream : Stream { - StringWriter sw = new StringWriter(); - JsonTextWriter writer = new JsonTextWriter(sw); + private byte[] bytes; + private int totalBytesRead; + private int bytesPerRead; - writer.WriteStartArray(); - writer.WriteValue(decimal.MaxValue); - writer.WriteValue(decimal.MinValue); - writer.WriteEndArray(); + public SlowStream(byte[] content, int bytesPerRead) + { + bytes = content; + totalBytesRead = 0; + this.bytesPerRead = bytesPerRead; + } - string json = sw.ToString(); + public SlowStream(string content, Encoding encoding, int bytesPerRead) + : this(encoding.GetBytes(content), bytesPerRead) + { + } - StringReader sr = new StringReader(json); - JsonTextReader reader = new JsonTextReader(sr); + public override bool CanRead + { + get { return true; } + } - Assert.IsTrue(reader.Read()); + public override bool CanSeek + { + get { return false; } + } - decimal? max = reader.ReadAsDecimal(); - Assert.AreEqual(decimal.MaxValue, max); + public override bool CanWrite + { + get { return false; } + } - decimal? min = reader.ReadAsDecimal(); - Assert.AreEqual(decimal.MinValue, min); + public override void Flush() + { + } - Assert.IsTrue(reader.Read()); + public override long Length + { + get { throw new NotSupportedException(); } + } + + public override long Position + { + get { throw new NotSupportedException(); } + set { throw new NotSupportedException(); } + } + + public override int Read(byte[] buffer, int offset, int count) + { + int toReturn = Math.Min(count, bytesPerRead); + toReturn = Math.Min(toReturn, bytes.Length - totalBytesRead); + if (toReturn > 0) + { + Array.Copy(bytes, totalBytesRead, buffer, offset, toReturn); + } + + totalBytesRead += toReturn; + return toReturn; + } + + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotSupportedException(); + } + + public override void SetLength(long value) + { + throw new NotSupportedException(); + } + + public override void Write(byte[] buffer, int offset, int count) + { + throw new NotSupportedException(); + } } - } - - public class ToggleReaderError : TextReader - { - private readonly TextReader _inner; - - public bool Error { get; set; } - - public ToggleReaderError(TextReader inner) - { - _inner = inner; - } - - public override int Read(char[] buffer, int index, int count) - { - if (Error) - throw new Exception("Read error"); - - return _inner.Read(buffer, index, 1); - } - } - - public class SlowStream : Stream - { - byte[] bytes; - int totalBytesRead; - int bytesPerRead; - - public SlowStream(byte[] content, int bytesPerRead) - { - this.bytes = content; - this.totalBytesRead = 0; - this.bytesPerRead = bytesPerRead; - } - - public SlowStream(string content, Encoding encoding, int bytesPerRead) - : this(encoding.GetBytes(content), bytesPerRead) - { - } - - public override bool CanRead - { - get { return true; } - } - - public override bool CanSeek - { - get { return false; } - } - - public override bool CanWrite - { - get { return false; } - } - - public override void Flush() - { - } - - public override long Length - { - get { throw new NotSupportedException(); } - } - - public override long Position - { - get { throw new NotSupportedException(); } - set { throw new NotSupportedException(); } - } - - public override int Read(byte[] buffer, int offset, int count) - { - int toReturn = Math.Min(count, this.bytesPerRead); - toReturn = Math.Min(toReturn, this.bytes.Length - this.totalBytesRead); - if (toReturn > 0) - { - Array.Copy(this.bytes, this.totalBytesRead, buffer, offset, toReturn); - } - - this.totalBytesRead += toReturn; - return toReturn; - } - - public override long Seek(long offset, SeekOrigin origin) - { - throw new NotSupportedException(); - } - - public override void SetLength(long value) - { - throw new NotSupportedException(); - } - - public override void Write(byte[] buffer, int offset, int count) - { - throw new NotSupportedException(); - } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs b/Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs index e62a2218..a92283b7 100644 --- a/Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs +++ b/Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs @@ -49,233 +49,233 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Tests { - [TestFixture] - public class JsonTextWriterTest : TestFixtureBase - { - [Test] - public void QuoteNameAndStrings() + [TestFixture] + public class JsonTextWriterTest : TestFixtureBase { - StringBuilder sb = new StringBuilder(); - StringWriter sw = new StringWriter(sb); - JsonTextWriter writer = new JsonTextWriter(sw) { QuoteName = false }; + [Test] + public void QuoteNameAndStrings() + { + StringBuilder sb = new StringBuilder(); + StringWriter sw = new StringWriter(sb); + JsonTextWriter writer = new JsonTextWriter(sw) { QuoteName = false }; - writer.WriteStartObject(); + writer.WriteStartObject(); - writer.WritePropertyName("name"); - writer.WriteValue("value"); + writer.WritePropertyName("name"); + writer.WriteValue("value"); - writer.WriteEndObject(); - writer.Flush(); + writer.WriteEndObject(); + writer.Flush(); - Assert.AreEqual(@"{name:""value""}", sb.ToString()); - } + Assert.AreEqual(@"{name:""value""}", sb.ToString()); + } - [Test] - public void CloseOutput() - { - MemoryStream ms = new MemoryStream(); - JsonTextWriter writer = new JsonTextWriter(new StreamWriter(ms)); + [Test] + public void CloseOutput() + { + MemoryStream ms = new MemoryStream(); + JsonTextWriter writer = new JsonTextWriter(new StreamWriter(ms)); - Assert.IsTrue(ms.CanRead); - writer.Close(); - Assert.IsFalse(ms.CanRead); + Assert.IsTrue(ms.CanRead); + writer.Close(); + Assert.IsFalse(ms.CanRead); - ms = new MemoryStream(); - writer = new JsonTextWriter(new StreamWriter(ms)) { CloseOutput = false }; + ms = new MemoryStream(); + writer = new JsonTextWriter(new StreamWriter(ms)) { CloseOutput = false }; - Assert.IsTrue(ms.CanRead); - writer.Close(); - Assert.IsTrue(ms.CanRead); - } + Assert.IsTrue(ms.CanRead); + writer.Close(); + Assert.IsTrue(ms.CanRead); + } #if !(PORTABLE || NETFX_CORE) - [Test] - public void WriteIConvertable() - { - var sw = new StringWriter(); - JsonTextWriter writer = new JsonTextWriter(sw); - writer.WriteValue(new ConvertibleInt(1)); + [Test] + public void WriteIConvertable() + { + var sw = new StringWriter(); + JsonTextWriter writer = new JsonTextWriter(sw); + writer.WriteValue(new ConvertibleInt(1)); - Assert.AreEqual("1", sw.ToString()); - } + Assert.AreEqual("1", sw.ToString()); + } #endif - - [Test] - public void ValueFormatting() - { - StringBuilder sb = new StringBuilder(); - StringWriter sw = new StringWriter(sb); - using (JsonWriter jsonWriter = new JsonTextWriter(sw)) - { - jsonWriter.WriteStartArray(); - jsonWriter.WriteValue('@'); - jsonWriter.WriteValue("\r\n\t\f\b?{\\r\\n\"\'"); - jsonWriter.WriteValue(true); - jsonWriter.WriteValue(10); - jsonWriter.WriteValue(10.99); - jsonWriter.WriteValue(0.99); - jsonWriter.WriteValue(0.000000000000000001d); - jsonWriter.WriteValue(0.000000000000000001m); - jsonWriter.WriteValue((string)null); - jsonWriter.WriteValue((object)null); - jsonWriter.WriteValue("This is a string."); - jsonWriter.WriteNull(); - jsonWriter.WriteUndefined(); - jsonWriter.WriteEndArray(); - } + [Test] + public void ValueFormatting() + { + StringBuilder sb = new StringBuilder(); + StringWriter sw = new StringWriter(sb); - string expected = @"[""@"",""\r\n\t\f\b?{\\r\\n\""'"",true,10,10.99,0.99,1E-18,0.000000000000000001,null,null,""This is a string."",null,undefined]"; - string result = sb.ToString(); + using (JsonWriter jsonWriter = new JsonTextWriter(sw)) + { + jsonWriter.WriteStartArray(); + jsonWriter.WriteValue('@'); + jsonWriter.WriteValue("\r\n\t\f\b?{\\r\\n\"\'"); + jsonWriter.WriteValue(true); + jsonWriter.WriteValue(10); + jsonWriter.WriteValue(10.99); + jsonWriter.WriteValue(0.99); + jsonWriter.WriteValue(0.000000000000000001d); + jsonWriter.WriteValue(0.000000000000000001m); + jsonWriter.WriteValue((string)null); + jsonWriter.WriteValue((object)null); + jsonWriter.WriteValue("This is a string."); + jsonWriter.WriteNull(); + jsonWriter.WriteUndefined(); + jsonWriter.WriteEndArray(); + } - Console.WriteLine("ValueFormatting"); - Console.WriteLine(result); + string expected = @"[""@"",""\r\n\t\f\b?{\\r\\n\""'"",true,10,10.99,0.99,1E-18,0.000000000000000001,null,null,""This is a string."",null,undefined]"; + string result = sb.ToString(); - Assert.AreEqual(expected, result); - } + Console.WriteLine("ValueFormatting"); + Console.WriteLine(result); - [Test] - public void NullableValueFormatting() - { - StringWriter sw = new StringWriter(); - using (JsonTextWriter jsonWriter = new JsonTextWriter(sw)) - { - jsonWriter.WriteStartArray(); - jsonWriter.WriteValue((char?)null); - jsonWriter.WriteValue((char?)'c'); - jsonWriter.WriteValue((bool?)null); - jsonWriter.WriteValue((bool?)true); - jsonWriter.WriteValue((byte?)null); - jsonWriter.WriteValue((byte?)1); - jsonWriter.WriteValue((sbyte?)null); - jsonWriter.WriteValue((sbyte?)1); - jsonWriter.WriteValue((short?)null); - jsonWriter.WriteValue((short?)1); - jsonWriter.WriteValue((ushort?)null); - jsonWriter.WriteValue((ushort?)1); - jsonWriter.WriteValue((int?)null); - jsonWriter.WriteValue((int?)1); - jsonWriter.WriteValue((uint?)null); - jsonWriter.WriteValue((uint?)1); - jsonWriter.WriteValue((long?)null); - jsonWriter.WriteValue((long?)1); - jsonWriter.WriteValue((ulong?)null); - jsonWriter.WriteValue((ulong?)1); - jsonWriter.WriteValue((double?)null); - jsonWriter.WriteValue((double?)1.1); - jsonWriter.WriteValue((float?)null); - jsonWriter.WriteValue((float?)1.1); - jsonWriter.WriteValue((decimal?)null); - jsonWriter.WriteValue((decimal?)1.1m); - jsonWriter.WriteValue((DateTime?)null); - jsonWriter.WriteValue((DateTime?)new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc)); + Assert.AreEqual(expected, result); + } + + [Test] + public void NullableValueFormatting() + { + StringWriter sw = new StringWriter(); + using (JsonTextWriter jsonWriter = new JsonTextWriter(sw)) + { + jsonWriter.WriteStartArray(); + jsonWriter.WriteValue((char?)null); + jsonWriter.WriteValue((char?)'c'); + jsonWriter.WriteValue((bool?)null); + jsonWriter.WriteValue((bool?)true); + jsonWriter.WriteValue((byte?)null); + jsonWriter.WriteValue((byte?)1); + jsonWriter.WriteValue((sbyte?)null); + jsonWriter.WriteValue((sbyte?)1); + jsonWriter.WriteValue((short?)null); + jsonWriter.WriteValue((short?)1); + jsonWriter.WriteValue((ushort?)null); + jsonWriter.WriteValue((ushort?)1); + jsonWriter.WriteValue((int?)null); + jsonWriter.WriteValue((int?)1); + jsonWriter.WriteValue((uint?)null); + jsonWriter.WriteValue((uint?)1); + jsonWriter.WriteValue((long?)null); + jsonWriter.WriteValue((long?)1); + jsonWriter.WriteValue((ulong?)null); + jsonWriter.WriteValue((ulong?)1); + jsonWriter.WriteValue((double?)null); + jsonWriter.WriteValue((double?)1.1); + jsonWriter.WriteValue((float?)null); + jsonWriter.WriteValue((float?)1.1); + jsonWriter.WriteValue((decimal?)null); + jsonWriter.WriteValue((decimal?)1.1m); + jsonWriter.WriteValue((DateTime?)null); + jsonWriter.WriteValue((DateTime?)new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc)); #if !NET20 - jsonWriter.WriteValue((DateTimeOffset?)null); - jsonWriter.WriteValue((DateTimeOffset?)new DateTimeOffset(DateTimeUtils.InitialJavaScriptDateTicks, TimeSpan.Zero)); + jsonWriter.WriteValue((DateTimeOffset?)null); + jsonWriter.WriteValue((DateTimeOffset?)new DateTimeOffset(DateTimeUtils.InitialJavaScriptDateTicks, TimeSpan.Zero)); #endif - jsonWriter.WriteEndArray(); - } + jsonWriter.WriteEndArray(); + } - string json = sw.ToString(); - string expected; + string json = sw.ToString(); + string expected; #if !NET20 - expected = @"[null,""c"",null,true,null,1,null,1,null,1,null,1,null,1,null,1,null,1,null,1,null,1.1,null,1.1,null,1.1,null,""1970-01-01T00:00:00Z"",null,""1970-01-01T00:00:00+00:00""]"; + expected = @"[null,""c"",null,true,null,1,null,1,null,1,null,1,null,1,null,1,null,1,null,1,null,1.1,null,1.1,null,1.1,null,""1970-01-01T00:00:00Z"",null,""1970-01-01T00:00:00+00:00""]"; #else expected = @"[null,""c"",null,true,null,1,null,1,null,1,null,1,null,1,null,1,null,1,null,1,null,1.1,null,1.1,null,1.1,null,""1970-01-01T00:00:00Z""]"; #endif - Assert.AreEqual(expected, json); - } + Assert.AreEqual(expected, json); + } - [Test] - public void WriteValueObjectWithNullable() - { - StringWriter sw = new StringWriter(); - using (JsonTextWriter jsonWriter = new JsonTextWriter(sw)) - { - char? value = 'c'; - - jsonWriter.WriteStartArray(); - jsonWriter.WriteValue((object)value); - jsonWriter.WriteEndArray(); - } - - string json = sw.ToString(); - string expected = @"[""c""]"; - - Assert.AreEqual(expected, json); - } - - [Test] - public void WriteValueObjectWithUnsupportedValue() - { - ExceptionAssert.Throws( - @"Unsupported type: System.Version. Use the JsonSerializer class to get the object's JSON representation. Path ''.", - () => + [Test] + public void WriteValueObjectWithNullable() { - StringWriter sw = new StringWriter(); - using (JsonTextWriter jsonWriter = new JsonTextWriter(sw)) - { - jsonWriter.WriteStartArray(); - jsonWriter.WriteValue(new Version(1, 1, 1, 1)); - jsonWriter.WriteEndArray(); - } - }); - } + StringWriter sw = new StringWriter(); + using (JsonTextWriter jsonWriter = new JsonTextWriter(sw)) + { + char? value = 'c'; - [Test] - public void StringEscaping() - { - StringBuilder sb = new StringBuilder(); - StringWriter sw = new StringWriter(sb); + jsonWriter.WriteStartArray(); + jsonWriter.WriteValue((object)value); + jsonWriter.WriteEndArray(); + } - using (JsonWriter jsonWriter = new JsonTextWriter(sw)) - { - jsonWriter.WriteStartArray(); - jsonWriter.WriteValue(@"""These pretzels are making me thirsty!"""); - jsonWriter.WriteValue("Jeff's house was burninated."); - jsonWriter.WriteValue(@"1. You don't talk about fight club. + string json = sw.ToString(); + string expected = @"[""c""]"; + + Assert.AreEqual(expected, json); + } + + [Test] + public void WriteValueObjectWithUnsupportedValue() + { + ExceptionAssert.Throws( + @"Unsupported type: System.Version. Use the JsonSerializer class to get the object's JSON representation. Path ''.", + () => + { + StringWriter sw = new StringWriter(); + using (JsonTextWriter jsonWriter = new JsonTextWriter(sw)) + { + jsonWriter.WriteStartArray(); + jsonWriter.WriteValue(new Version(1, 1, 1, 1)); + jsonWriter.WriteEndArray(); + } + }); + } + + [Test] + public void StringEscaping() + { + StringBuilder sb = new StringBuilder(); + StringWriter sw = new StringWriter(sb); + + using (JsonWriter jsonWriter = new JsonTextWriter(sw)) + { + jsonWriter.WriteStartArray(); + jsonWriter.WriteValue(@"""These pretzels are making me thirsty!"""); + jsonWriter.WriteValue("Jeff's house was burninated."); + jsonWriter.WriteValue(@"1. You don't talk about fight club. 2. You don't talk about fight club."); - jsonWriter.WriteValue("35% of\t statistics\n are made\r up."); - jsonWriter.WriteEndArray(); - } + jsonWriter.WriteValue("35% of\t statistics\n are made\r up."); + jsonWriter.WriteEndArray(); + } - string expected = @"[""\""These pretzels are making me thirsty!\"""",""Jeff's house was burninated."",""1. You don't talk about fight club.\r\n2. You don't talk about fight club."",""35% of\t statistics\n are made\r up.""]"; - string result = sb.ToString(); + string expected = @"[""\""These pretzels are making me thirsty!\"""",""Jeff's house was burninated."",""1. You don't talk about fight club.\r\n2. You don't talk about fight club."",""35% of\t statistics\n are made\r up.""]"; + string result = sb.ToString(); - Console.WriteLine("StringEscaping"); - Console.WriteLine(result); + Console.WriteLine("StringEscaping"); + Console.WriteLine(result); - Assert.AreEqual(expected, result); - } + Assert.AreEqual(expected, result); + } - [Test] - public void WriteEnd() - { - StringBuilder sb = new StringBuilder(); - StringWriter sw = new StringWriter(sb); + [Test] + public void WriteEnd() + { + StringBuilder sb = new StringBuilder(); + StringWriter sw = new StringWriter(sb); - using (JsonWriter jsonWriter = new JsonTextWriter(sw)) - { - jsonWriter.Formatting = Formatting.Indented; + using (JsonWriter jsonWriter = new JsonTextWriter(sw)) + { + jsonWriter.Formatting = Formatting.Indented; - jsonWriter.WriteStartObject(); - jsonWriter.WritePropertyName("CPU"); - jsonWriter.WriteValue("Intel"); - jsonWriter.WritePropertyName("PSU"); - jsonWriter.WriteValue("500W"); - jsonWriter.WritePropertyName("Drives"); - jsonWriter.WriteStartArray(); - jsonWriter.WriteValue("DVD read/writer"); - jsonWriter.WriteComment("(broken)"); - jsonWriter.WriteValue("500 gigabyte hard drive"); - jsonWriter.WriteValue("200 gigabype hard drive"); - jsonWriter.WriteEndObject(); - Assert.AreEqual(WriteState.Start, jsonWriter.WriteState); - } + jsonWriter.WriteStartObject(); + jsonWriter.WritePropertyName("CPU"); + jsonWriter.WriteValue("Intel"); + jsonWriter.WritePropertyName("PSU"); + jsonWriter.WriteValue("500W"); + jsonWriter.WritePropertyName("Drives"); + jsonWriter.WriteStartArray(); + jsonWriter.WriteValue("DVD read/writer"); + jsonWriter.WriteComment("(broken)"); + jsonWriter.WriteValue("500 gigabyte hard drive"); + jsonWriter.WriteValue("200 gigabype hard drive"); + jsonWriter.WriteEndObject(); + Assert.AreEqual(WriteState.Start, jsonWriter.WriteState); + } - string expected = @"{ + string expected = @"{ ""CPU"": ""Intel"", ""PSU"": ""500W"", ""Drives"": [ @@ -285,36 +285,36 @@ namespace Newtonsoft.Json.Tests ""200 gigabype hard drive"" ] }"; - string result = sb.ToString(); + string result = sb.ToString(); - Assert.AreEqual(expected, result); - } + Assert.AreEqual(expected, result); + } - [Test] - public void CloseWithRemainingContent() - { - StringBuilder sb = new StringBuilder(); - StringWriter sw = new StringWriter(sb); + [Test] + public void CloseWithRemainingContent() + { + StringBuilder sb = new StringBuilder(); + StringWriter sw = new StringWriter(sb); - using (JsonWriter jsonWriter = new JsonTextWriter(sw)) - { - jsonWriter.Formatting = Formatting.Indented; + using (JsonWriter jsonWriter = new JsonTextWriter(sw)) + { + jsonWriter.Formatting = Formatting.Indented; - jsonWriter.WriteStartObject(); - jsonWriter.WritePropertyName("CPU"); - jsonWriter.WriteValue("Intel"); - jsonWriter.WritePropertyName("PSU"); - jsonWriter.WriteValue("500W"); - jsonWriter.WritePropertyName("Drives"); - jsonWriter.WriteStartArray(); - jsonWriter.WriteValue("DVD read/writer"); - jsonWriter.WriteComment("(broken)"); - jsonWriter.WriteValue("500 gigabyte hard drive"); - jsonWriter.WriteValue("200 gigabype hard drive"); - jsonWriter.Close(); - } + jsonWriter.WriteStartObject(); + jsonWriter.WritePropertyName("CPU"); + jsonWriter.WriteValue("Intel"); + jsonWriter.WritePropertyName("PSU"); + jsonWriter.WriteValue("500W"); + jsonWriter.WritePropertyName("Drives"); + jsonWriter.WriteStartArray(); + jsonWriter.WriteValue("DVD read/writer"); + jsonWriter.WriteComment("(broken)"); + jsonWriter.WriteValue("500 gigabyte hard drive"); + jsonWriter.WriteValue("200 gigabype hard drive"); + jsonWriter.Close(); + } - string expected = @"{ + string expected = @"{ ""CPU"": ""Intel"", ""PSU"": ""500W"", ""Drives"": [ @@ -324,49 +324,49 @@ namespace Newtonsoft.Json.Tests ""200 gigabype hard drive"" ] }"; - string result = sb.ToString(); + string result = sb.ToString(); - Assert.AreEqual(expected, result); - } + Assert.AreEqual(expected, result); + } - [Test] - public void Indenting() - { - StringBuilder sb = new StringBuilder(); - StringWriter sw = new StringWriter(sb); + [Test] + public void Indenting() + { + StringBuilder sb = new StringBuilder(); + StringWriter sw = new StringWriter(sb); - using (JsonWriter jsonWriter = new JsonTextWriter(sw)) - { - jsonWriter.Formatting = Formatting.Indented; + using (JsonWriter jsonWriter = new JsonTextWriter(sw)) + { + jsonWriter.Formatting = Formatting.Indented; - jsonWriter.WriteStartObject(); - jsonWriter.WritePropertyName("CPU"); - jsonWriter.WriteValue("Intel"); - jsonWriter.WritePropertyName("PSU"); - jsonWriter.WriteValue("500W"); - jsonWriter.WritePropertyName("Drives"); - jsonWriter.WriteStartArray(); - jsonWriter.WriteValue("DVD read/writer"); - jsonWriter.WriteComment("(broken)"); - jsonWriter.WriteValue("500 gigabyte hard drive"); - jsonWriter.WriteValue("200 gigabype hard drive"); - jsonWriter.WriteEnd(); - jsonWriter.WriteEndObject(); - Assert.AreEqual(WriteState.Start, jsonWriter.WriteState); - } + jsonWriter.WriteStartObject(); + jsonWriter.WritePropertyName("CPU"); + jsonWriter.WriteValue("Intel"); + jsonWriter.WritePropertyName("PSU"); + jsonWriter.WriteValue("500W"); + jsonWriter.WritePropertyName("Drives"); + jsonWriter.WriteStartArray(); + jsonWriter.WriteValue("DVD read/writer"); + jsonWriter.WriteComment("(broken)"); + jsonWriter.WriteValue("500 gigabyte hard drive"); + jsonWriter.WriteValue("200 gigabype hard drive"); + jsonWriter.WriteEnd(); + jsonWriter.WriteEndObject(); + Assert.AreEqual(WriteState.Start, jsonWriter.WriteState); + } - // { - // "CPU": "Intel", - // "PSU": "500W", - // "Drives": [ - // "DVD read/writer" - // /*(broken)*/, - // "500 gigabyte hard drive", - // "200 gigabype hard drive" - // ] - // } + // { + // "CPU": "Intel", + // "PSU": "500W", + // "Drives": [ + // "DVD read/writer" + // /*(broken)*/, + // "500 gigabyte hard drive", + // "200 gigabype hard drive" + // ] + // } - string expected = @"{ + string expected = @"{ ""CPU"": ""Intel"", ""PSU"": ""500W"", ""Drives"": [ @@ -376,78 +376,78 @@ namespace Newtonsoft.Json.Tests ""200 gigabype hard drive"" ] }"; - string result = sb.ToString(); + string result = sb.ToString(); - Assert.AreEqual(expected, result); - } + Assert.AreEqual(expected, result); + } - [Test] - public void State() - { - StringBuilder sb = new StringBuilder(); - StringWriter sw = new StringWriter(sb); + [Test] + public void State() + { + StringBuilder sb = new StringBuilder(); + StringWriter sw = new StringWriter(sb); - using (JsonWriter jsonWriter = new JsonTextWriter(sw)) - { - Assert.AreEqual(WriteState.Start, jsonWriter.WriteState); + using (JsonWriter jsonWriter = new JsonTextWriter(sw)) + { + Assert.AreEqual(WriteState.Start, jsonWriter.WriteState); - jsonWriter.WriteStartObject(); - Assert.AreEqual(WriteState.Object, jsonWriter.WriteState); - Assert.AreEqual("", jsonWriter.Path); + jsonWriter.WriteStartObject(); + Assert.AreEqual(WriteState.Object, jsonWriter.WriteState); + Assert.AreEqual("", jsonWriter.Path); - jsonWriter.WritePropertyName("CPU"); - Assert.AreEqual(WriteState.Property, jsonWriter.WriteState); - Assert.AreEqual("CPU", jsonWriter.Path); + jsonWriter.WritePropertyName("CPU"); + Assert.AreEqual(WriteState.Property, jsonWriter.WriteState); + Assert.AreEqual("CPU", jsonWriter.Path); - jsonWriter.WriteValue("Intel"); - Assert.AreEqual(WriteState.Object, jsonWriter.WriteState); - Assert.AreEqual("CPU", jsonWriter.Path); + jsonWriter.WriteValue("Intel"); + Assert.AreEqual(WriteState.Object, jsonWriter.WriteState); + Assert.AreEqual("CPU", jsonWriter.Path); - jsonWriter.WritePropertyName("Drives"); - Assert.AreEqual(WriteState.Property, jsonWriter.WriteState); - Assert.AreEqual("Drives", jsonWriter.Path); + jsonWriter.WritePropertyName("Drives"); + Assert.AreEqual(WriteState.Property, jsonWriter.WriteState); + Assert.AreEqual("Drives", jsonWriter.Path); - jsonWriter.WriteStartArray(); - Assert.AreEqual(WriteState.Array, jsonWriter.WriteState); + jsonWriter.WriteStartArray(); + Assert.AreEqual(WriteState.Array, jsonWriter.WriteState); - jsonWriter.WriteValue("DVD read/writer"); - Assert.AreEqual(WriteState.Array, jsonWriter.WriteState); - Assert.AreEqual("Drives[0]", jsonWriter.Path); + jsonWriter.WriteValue("DVD read/writer"); + Assert.AreEqual(WriteState.Array, jsonWriter.WriteState); + Assert.AreEqual("Drives[0]", jsonWriter.Path); - jsonWriter.WriteEnd(); - Assert.AreEqual(WriteState.Object, jsonWriter.WriteState); - Assert.AreEqual("Drives", jsonWriter.Path); + jsonWriter.WriteEnd(); + Assert.AreEqual(WriteState.Object, jsonWriter.WriteState); + Assert.AreEqual("Drives", jsonWriter.Path); - jsonWriter.WriteEndObject(); - Assert.AreEqual(WriteState.Start, jsonWriter.WriteState); - Assert.AreEqual("", jsonWriter.Path); - } - } + jsonWriter.WriteEndObject(); + Assert.AreEqual(WriteState.Start, jsonWriter.WriteState); + Assert.AreEqual("", jsonWriter.Path); + } + } - [Test] - public void FloatingPointNonFiniteNumbers_Symbol() - { - StringBuilder sb = new StringBuilder(); - StringWriter sw = new StringWriter(sb); + [Test] + public void FloatingPointNonFiniteNumbers_Symbol() + { + StringBuilder sb = new StringBuilder(); + StringWriter sw = new StringWriter(sb); - using (JsonWriter jsonWriter = new JsonTextWriter(sw)) - { - jsonWriter.Formatting = Formatting.Indented; - jsonWriter.FloatFormatHandling = FloatFormatHandling.Symbol; + using (JsonWriter jsonWriter = new JsonTextWriter(sw)) + { + jsonWriter.Formatting = Formatting.Indented; + jsonWriter.FloatFormatHandling = FloatFormatHandling.Symbol; - jsonWriter.WriteStartArray(); - jsonWriter.WriteValue(double.NaN); - jsonWriter.WriteValue(double.PositiveInfinity); - jsonWriter.WriteValue(double.NegativeInfinity); - jsonWriter.WriteValue(float.NaN); - jsonWriter.WriteValue(float.PositiveInfinity); - jsonWriter.WriteValue(float.NegativeInfinity); - jsonWriter.WriteEndArray(); + jsonWriter.WriteStartArray(); + jsonWriter.WriteValue(double.NaN); + jsonWriter.WriteValue(double.PositiveInfinity); + jsonWriter.WriteValue(double.NegativeInfinity); + jsonWriter.WriteValue(float.NaN); + jsonWriter.WriteValue(float.PositiveInfinity); + jsonWriter.WriteValue(float.NegativeInfinity); + jsonWriter.WriteEndArray(); - jsonWriter.Flush(); - } + jsonWriter.Flush(); + } - string expected = @"[ + string expected = @"[ NaN, Infinity, -Infinity, @@ -455,41 +455,41 @@ namespace Newtonsoft.Json.Tests Infinity, -Infinity ]"; - string result = sb.ToString(); + string result = sb.ToString(); - Assert.AreEqual(expected, result); - } + Assert.AreEqual(expected, result); + } - [Test] - public void FloatingPointNonFiniteNumbers_Zero() - { - StringBuilder sb = new StringBuilder(); - StringWriter sw = new StringWriter(sb); + [Test] + public void FloatingPointNonFiniteNumbers_Zero() + { + StringBuilder sb = new StringBuilder(); + StringWriter sw = new StringWriter(sb); - using (JsonWriter jsonWriter = new JsonTextWriter(sw)) - { - jsonWriter.Formatting = Formatting.Indented; - jsonWriter.FloatFormatHandling = FloatFormatHandling.DefaultValue; + using (JsonWriter jsonWriter = new JsonTextWriter(sw)) + { + jsonWriter.Formatting = Formatting.Indented; + jsonWriter.FloatFormatHandling = FloatFormatHandling.DefaultValue; - jsonWriter.WriteStartArray(); - jsonWriter.WriteValue(double.NaN); - jsonWriter.WriteValue(double.PositiveInfinity); - jsonWriter.WriteValue(double.NegativeInfinity); - jsonWriter.WriteValue(float.NaN); - jsonWriter.WriteValue(float.PositiveInfinity); - jsonWriter.WriteValue(float.NegativeInfinity); - jsonWriter.WriteValue((double?)double.NaN); - jsonWriter.WriteValue((double?)double.PositiveInfinity); - jsonWriter.WriteValue((double?)double.NegativeInfinity); - jsonWriter.WriteValue((float?)float.NaN); - jsonWriter.WriteValue((float?)float.PositiveInfinity); - jsonWriter.WriteValue((float?)float.NegativeInfinity); - jsonWriter.WriteEndArray(); + jsonWriter.WriteStartArray(); + jsonWriter.WriteValue(double.NaN); + jsonWriter.WriteValue(double.PositiveInfinity); + jsonWriter.WriteValue(double.NegativeInfinity); + jsonWriter.WriteValue(float.NaN); + jsonWriter.WriteValue(float.PositiveInfinity); + jsonWriter.WriteValue(float.NegativeInfinity); + jsonWriter.WriteValue((double?)double.NaN); + jsonWriter.WriteValue((double?)double.PositiveInfinity); + jsonWriter.WriteValue((double?)double.NegativeInfinity); + jsonWriter.WriteValue((float?)float.NaN); + jsonWriter.WriteValue((float?)float.PositiveInfinity); + jsonWriter.WriteValue((float?)float.NegativeInfinity); + jsonWriter.WriteEndArray(); - jsonWriter.Flush(); - } + jsonWriter.Flush(); + } - string expected = @"[ + string expected = @"[ 0.0, 0.0, 0.0, @@ -503,35 +503,35 @@ namespace Newtonsoft.Json.Tests null, null ]"; - string result = sb.ToString(); + string result = sb.ToString(); - Assert.AreEqual(expected, result); - } + Assert.AreEqual(expected, result); + } - [Test] - public void FloatingPointNonFiniteNumbers_String() - { - StringBuilder sb = new StringBuilder(); - StringWriter sw = new StringWriter(sb); + [Test] + public void FloatingPointNonFiniteNumbers_String() + { + StringBuilder sb = new StringBuilder(); + StringWriter sw = new StringWriter(sb); - using (JsonWriter jsonWriter = new JsonTextWriter(sw)) - { - jsonWriter.Formatting = Formatting.Indented; - jsonWriter.FloatFormatHandling = FloatFormatHandling.String; + using (JsonWriter jsonWriter = new JsonTextWriter(sw)) + { + jsonWriter.Formatting = Formatting.Indented; + jsonWriter.FloatFormatHandling = FloatFormatHandling.String; - jsonWriter.WriteStartArray(); - jsonWriter.WriteValue(double.NaN); - jsonWriter.WriteValue(double.PositiveInfinity); - jsonWriter.WriteValue(double.NegativeInfinity); - jsonWriter.WriteValue(float.NaN); - jsonWriter.WriteValue(float.PositiveInfinity); - jsonWriter.WriteValue(float.NegativeInfinity); - jsonWriter.WriteEndArray(); + jsonWriter.WriteStartArray(); + jsonWriter.WriteValue(double.NaN); + jsonWriter.WriteValue(double.PositiveInfinity); + jsonWriter.WriteValue(double.NegativeInfinity); + jsonWriter.WriteValue(float.NaN); + jsonWriter.WriteValue(float.PositiveInfinity); + jsonWriter.WriteValue(float.NegativeInfinity); + jsonWriter.WriteEndArray(); - jsonWriter.Flush(); - } + jsonWriter.Flush(); + } - string expected = @"[ + string expected = @"[ ""NaN"", ""Infinity"", ""-Infinity"", @@ -539,36 +539,36 @@ namespace Newtonsoft.Json.Tests ""Infinity"", ""-Infinity"" ]"; - string result = sb.ToString(); + string result = sb.ToString(); - Assert.AreEqual(expected, result); - } + Assert.AreEqual(expected, result); + } - [Test] - public void FloatingPointNonFiniteNumbers_QuoteChar() - { - StringBuilder sb = new StringBuilder(); - StringWriter sw = new StringWriter(sb); + [Test] + public void FloatingPointNonFiniteNumbers_QuoteChar() + { + StringBuilder sb = new StringBuilder(); + StringWriter sw = new StringWriter(sb); - using (JsonTextWriter jsonWriter = new JsonTextWriter(sw)) - { - jsonWriter.Formatting = Formatting.Indented; - jsonWriter.FloatFormatHandling = FloatFormatHandling.String; - jsonWriter.QuoteChar = '\''; + using (JsonTextWriter jsonWriter = new JsonTextWriter(sw)) + { + jsonWriter.Formatting = Formatting.Indented; + jsonWriter.FloatFormatHandling = FloatFormatHandling.String; + jsonWriter.QuoteChar = '\''; - jsonWriter.WriteStartArray(); - jsonWriter.WriteValue(double.NaN); - jsonWriter.WriteValue(double.PositiveInfinity); - jsonWriter.WriteValue(double.NegativeInfinity); - jsonWriter.WriteValue(float.NaN); - jsonWriter.WriteValue(float.PositiveInfinity); - jsonWriter.WriteValue(float.NegativeInfinity); - jsonWriter.WriteEndArray(); + jsonWriter.WriteStartArray(); + jsonWriter.WriteValue(double.NaN); + jsonWriter.WriteValue(double.PositiveInfinity); + jsonWriter.WriteValue(double.NegativeInfinity); + jsonWriter.WriteValue(float.NaN); + jsonWriter.WriteValue(float.PositiveInfinity); + jsonWriter.WriteValue(float.NegativeInfinity); + jsonWriter.WriteEndArray(); - jsonWriter.Flush(); - } + jsonWriter.Flush(); + } - string expected = @"[ + string expected = @"[ 'NaN', 'Infinity', '-Infinity', @@ -576,212 +576,212 @@ namespace Newtonsoft.Json.Tests 'Infinity', '-Infinity' ]"; - string result = sb.ToString(); + string result = sb.ToString(); - Assert.AreEqual(expected, result); - } + Assert.AreEqual(expected, result); + } - [Test] - public void WriteRawInStart() - { - StringBuilder sb = new StringBuilder(); - StringWriter sw = new StringWriter(sb); + [Test] + public void WriteRawInStart() + { + StringBuilder sb = new StringBuilder(); + StringWriter sw = new StringWriter(sb); - using (JsonWriter jsonWriter = new JsonTextWriter(sw)) - { - jsonWriter.Formatting = Formatting.Indented; - jsonWriter.FloatFormatHandling = FloatFormatHandling.Symbol; + using (JsonWriter jsonWriter = new JsonTextWriter(sw)) + { + jsonWriter.Formatting = Formatting.Indented; + jsonWriter.FloatFormatHandling = FloatFormatHandling.Symbol; - jsonWriter.WriteRaw("[1,2,3,4,5]"); - jsonWriter.WriteWhitespace(" "); - jsonWriter.WriteStartArray(); - jsonWriter.WriteValue(double.NaN); - jsonWriter.WriteEndArray(); - } + jsonWriter.WriteRaw("[1,2,3,4,5]"); + jsonWriter.WriteWhitespace(" "); + jsonWriter.WriteStartArray(); + jsonWriter.WriteValue(double.NaN); + jsonWriter.WriteEndArray(); + } - string expected = @"[1,2,3,4,5] [ + string expected = @"[1,2,3,4,5] [ NaN ]"; - string result = sb.ToString(); + string result = sb.ToString(); - Assert.AreEqual(expected, result); - } + Assert.AreEqual(expected, result); + } - [Test] - public void WriteRawInArray() - { - StringBuilder sb = new StringBuilder(); - StringWriter sw = new StringWriter(sb); + [Test] + public void WriteRawInArray() + { + StringBuilder sb = new StringBuilder(); + StringWriter sw = new StringWriter(sb); - using (JsonWriter jsonWriter = new JsonTextWriter(sw)) - { - jsonWriter.Formatting = Formatting.Indented; - jsonWriter.FloatFormatHandling = FloatFormatHandling.Symbol; + using (JsonWriter jsonWriter = new JsonTextWriter(sw)) + { + jsonWriter.Formatting = Formatting.Indented; + jsonWriter.FloatFormatHandling = FloatFormatHandling.Symbol; - jsonWriter.WriteStartArray(); - jsonWriter.WriteValue(double.NaN); - jsonWriter.WriteRaw(",[1,2,3,4,5]"); - jsonWriter.WriteRaw(",[1,2,3,4,5]"); - jsonWriter.WriteValue(float.NaN); - jsonWriter.WriteEndArray(); - } + jsonWriter.WriteStartArray(); + jsonWriter.WriteValue(double.NaN); + jsonWriter.WriteRaw(",[1,2,3,4,5]"); + jsonWriter.WriteRaw(",[1,2,3,4,5]"); + jsonWriter.WriteValue(float.NaN); + jsonWriter.WriteEndArray(); + } - string expected = @"[ + string expected = @"[ NaN,[1,2,3,4,5],[1,2,3,4,5], NaN ]"; - string result = sb.ToString(); + string result = sb.ToString(); - Assert.AreEqual(expected, result); - } - - [Test] - public void WriteRawInObject() - { - StringBuilder sb = new StringBuilder(); - StringWriter sw = new StringWriter(sb); - - using (JsonWriter jsonWriter = new JsonTextWriter(sw)) - { - jsonWriter.Formatting = Formatting.Indented; - - jsonWriter.WriteStartObject(); - jsonWriter.WriteRaw(@"""PropertyName"":[1,2,3,4,5]"); - jsonWriter.WriteEnd(); - } - - string expected = @"{""PropertyName"":[1,2,3,4,5]}"; - string result = sb.ToString(); - - Assert.AreEqual(expected, result); - } - - [Test] - public void WriteToken() - { - JsonTextReader reader = new JsonTextReader(new StringReader("[1,2,3,4,5]")); - reader.Read(); - reader.Read(); - - StringWriter sw = new StringWriter(); - JsonTextWriter writer = new JsonTextWriter(sw); - writer.WriteToken(reader); - - Assert.AreEqual("1", sw.ToString()); - } - - [Test] - public void WriteRawValue() - { - StringBuilder sb = new StringBuilder(); - StringWriter sw = new StringWriter(sb); - - using (JsonWriter jsonWriter = new JsonTextWriter(sw)) - { - int i = 0; - string rawJson = "[1,2]"; - - jsonWriter.WriteStartObject(); - - while (i < 3) - { - jsonWriter.WritePropertyName("d" + i); - jsonWriter.WriteRawValue(rawJson); - - i++; + Assert.AreEqual(expected, result); } - jsonWriter.WriteEndObject(); - } + [Test] + public void WriteRawInObject() + { + StringBuilder sb = new StringBuilder(); + StringWriter sw = new StringWriter(sb); - Assert.AreEqual(@"{""d0"":[1,2],""d1"":[1,2],""d2"":[1,2]}", sb.ToString()); - } + using (JsonWriter jsonWriter = new JsonTextWriter(sw)) + { + jsonWriter.Formatting = Formatting.Indented; - [Test] - public void WriteObjectNestedInConstructor() - { - StringBuilder sb = new StringBuilder(); - StringWriter sw = new StringWriter(sb); + jsonWriter.WriteStartObject(); + jsonWriter.WriteRaw(@"""PropertyName"":[1,2,3,4,5]"); + jsonWriter.WriteEnd(); + } - using (JsonWriter jsonWriter = new JsonTextWriter(sw)) - { - jsonWriter.WriteStartObject(); - jsonWriter.WritePropertyName("con"); + string expected = @"{""PropertyName"":[1,2,3,4,5]}"; + string result = sb.ToString(); - jsonWriter.WriteStartConstructor("Ext.data.JsonStore"); - jsonWriter.WriteStartObject(); - jsonWriter.WritePropertyName("aa"); - jsonWriter.WriteValue("aa"); - jsonWriter.WriteEndObject(); - jsonWriter.WriteEndConstructor(); + Assert.AreEqual(expected, result); + } - jsonWriter.WriteEndObject(); - } + [Test] + public void WriteToken() + { + JsonTextReader reader = new JsonTextReader(new StringReader("[1,2,3,4,5]")); + reader.Read(); + reader.Read(); - Assert.AreEqual(@"{""con"":new Ext.data.JsonStore({""aa"":""aa""})}", sb.ToString()); - } + StringWriter sw = new StringWriter(); + JsonTextWriter writer = new JsonTextWriter(sw); + writer.WriteToken(reader); - [Test] - public void WriteFloatingPointNumber() - { - StringBuilder sb = new StringBuilder(); - StringWriter sw = new StringWriter(sb); + Assert.AreEqual("1", sw.ToString()); + } - using (JsonWriter jsonWriter = new JsonTextWriter(sw)) - { - jsonWriter.FloatFormatHandling = FloatFormatHandling.Symbol; - - jsonWriter.WriteStartArray(); + [Test] + public void WriteRawValue() + { + StringBuilder sb = new StringBuilder(); + StringWriter sw = new StringWriter(sb); - jsonWriter.WriteValue(0.0); - jsonWriter.WriteValue(0f); - jsonWriter.WriteValue(0.1); - jsonWriter.WriteValue(1.0); - jsonWriter.WriteValue(1.000001); - jsonWriter.WriteValue(0.000001); - jsonWriter.WriteValue(double.Epsilon); - jsonWriter.WriteValue(double.PositiveInfinity); - jsonWriter.WriteValue(double.NegativeInfinity); - jsonWriter.WriteValue(double.NaN); - jsonWriter.WriteValue(double.MaxValue); - jsonWriter.WriteValue(double.MinValue); - jsonWriter.WriteValue(float.PositiveInfinity); - jsonWriter.WriteValue(float.NegativeInfinity); - jsonWriter.WriteValue(float.NaN); + using (JsonWriter jsonWriter = new JsonTextWriter(sw)) + { + int i = 0; + string rawJson = "[1,2]"; - jsonWriter.WriteEndArray(); - } + jsonWriter.WriteStartObject(); - Assert.AreEqual(@"[0.0,0.0,0.1,1.0,1.000001,1E-06,4.94065645841247E-324,Infinity,-Infinity,NaN,1.7976931348623157E+308,-1.7976931348623157E+308,Infinity,-Infinity,NaN]", sb.ToString()); - } + while (i < 3) + { + jsonWriter.WritePropertyName("d" + i); + jsonWriter.WriteRawValue(rawJson); - [Test] - public void WriteIntegerNumber() - { - StringBuilder sb = new StringBuilder(); - StringWriter sw = new StringWriter(sb); + i++; + } - using (JsonWriter jsonWriter = new JsonTextWriter(sw) { Formatting = Formatting.Indented }) - { - jsonWriter.WriteStartArray(); + jsonWriter.WriteEndObject(); + } - jsonWriter.WriteValue(int.MaxValue); - jsonWriter.WriteValue(int.MinValue); - jsonWriter.WriteValue(0); - jsonWriter.WriteValue(-0); - jsonWriter.WriteValue(9L); - jsonWriter.WriteValue(9UL); - jsonWriter.WriteValue(long.MaxValue); - jsonWriter.WriteValue(long.MinValue); - jsonWriter.WriteValue(ulong.MaxValue); - jsonWriter.WriteValue(ulong.MinValue); + Assert.AreEqual(@"{""d0"":[1,2],""d1"":[1,2],""d2"":[1,2]}", sb.ToString()); + } - jsonWriter.WriteEndArray(); - } + [Test] + public void WriteObjectNestedInConstructor() + { + StringBuilder sb = new StringBuilder(); + StringWriter sw = new StringWriter(sb); - Console.WriteLine(sb.ToString()); + using (JsonWriter jsonWriter = new JsonTextWriter(sw)) + { + jsonWriter.WriteStartObject(); + jsonWriter.WritePropertyName("con"); - Assert.AreEqual(@"[ + jsonWriter.WriteStartConstructor("Ext.data.JsonStore"); + jsonWriter.WriteStartObject(); + jsonWriter.WritePropertyName("aa"); + jsonWriter.WriteValue("aa"); + jsonWriter.WriteEndObject(); + jsonWriter.WriteEndConstructor(); + + jsonWriter.WriteEndObject(); + } + + Assert.AreEqual(@"{""con"":new Ext.data.JsonStore({""aa"":""aa""})}", sb.ToString()); + } + + [Test] + public void WriteFloatingPointNumber() + { + StringBuilder sb = new StringBuilder(); + StringWriter sw = new StringWriter(sb); + + using (JsonWriter jsonWriter = new JsonTextWriter(sw)) + { + jsonWriter.FloatFormatHandling = FloatFormatHandling.Symbol; + + jsonWriter.WriteStartArray(); + + jsonWriter.WriteValue(0.0); + jsonWriter.WriteValue(0f); + jsonWriter.WriteValue(0.1); + jsonWriter.WriteValue(1.0); + jsonWriter.WriteValue(1.000001); + jsonWriter.WriteValue(0.000001); + jsonWriter.WriteValue(double.Epsilon); + jsonWriter.WriteValue(double.PositiveInfinity); + jsonWriter.WriteValue(double.NegativeInfinity); + jsonWriter.WriteValue(double.NaN); + jsonWriter.WriteValue(double.MaxValue); + jsonWriter.WriteValue(double.MinValue); + jsonWriter.WriteValue(float.PositiveInfinity); + jsonWriter.WriteValue(float.NegativeInfinity); + jsonWriter.WriteValue(float.NaN); + + jsonWriter.WriteEndArray(); + } + + Assert.AreEqual(@"[0.0,0.0,0.1,1.0,1.000001,1E-06,4.94065645841247E-324,Infinity,-Infinity,NaN,1.7976931348623157E+308,-1.7976931348623157E+308,Infinity,-Infinity,NaN]", sb.ToString()); + } + + [Test] + public void WriteIntegerNumber() + { + StringBuilder sb = new StringBuilder(); + StringWriter sw = new StringWriter(sb); + + using (JsonWriter jsonWriter = new JsonTextWriter(sw) { Formatting = Formatting.Indented }) + { + jsonWriter.WriteStartArray(); + + jsonWriter.WriteValue(int.MaxValue); + jsonWriter.WriteValue(int.MinValue); + jsonWriter.WriteValue(0); + jsonWriter.WriteValue(-0); + jsonWriter.WriteValue(9L); + jsonWriter.WriteValue(9UL); + jsonWriter.WriteValue(long.MaxValue); + jsonWriter.WriteValue(long.MinValue); + jsonWriter.WriteValue(ulong.MaxValue); + jsonWriter.WriteValue(ulong.MinValue); + + jsonWriter.WriteEndArray(); + } + + Console.WriteLine(sb.ToString()); + + Assert.AreEqual(@"[ 2147483647, -2147483648, 0, @@ -793,198 +793,198 @@ namespace Newtonsoft.Json.Tests 18446744073709551615, 0 ]", sb.ToString()); - } + } - [Test] - public void BadWriteEndArray() - { - ExceptionAssert.Throws( - "No token to close. Path ''.", - () => + [Test] + public void BadWriteEndArray() { - StringBuilder sb = new StringBuilder(); - StringWriter sw = new StringWriter(sb); + ExceptionAssert.Throws( + "No token to close. Path ''.", + () => + { + StringBuilder sb = new StringBuilder(); + StringWriter sw = new StringWriter(sb); - using (JsonWriter jsonWriter = new JsonTextWriter(sw)) - { - jsonWriter.WriteStartArray(); + using (JsonWriter jsonWriter = new JsonTextWriter(sw)) + { + jsonWriter.WriteStartArray(); - jsonWriter.WriteValue(0.0); + jsonWriter.WriteValue(0.0); - jsonWriter.WriteEndArray(); - jsonWriter.WriteEndArray(); - } - }); - } + jsonWriter.WriteEndArray(); + jsonWriter.WriteEndArray(); + } + }); + } - [Test] - public void InvalidQuoteChar() - { - ExceptionAssert.Throws( - @"Invalid JavaScript string quote character. Valid quote characters are ' and "".", - () => + [Test] + public void InvalidQuoteChar() { - StringBuilder sb = new StringBuilder(); - StringWriter sw = new StringWriter(sb); + ExceptionAssert.Throws( + @"Invalid JavaScript string quote character. Valid quote characters are ' and "".", + () => + { + StringBuilder sb = new StringBuilder(); + StringWriter sw = new StringWriter(sb); - using (JsonTextWriter jsonWriter = new JsonTextWriter(sw)) - { - jsonWriter.Formatting = Formatting.Indented; - jsonWriter.QuoteChar = '*'; - } - }); - } + using (JsonTextWriter jsonWriter = new JsonTextWriter(sw)) + { + jsonWriter.Formatting = Formatting.Indented; + jsonWriter.QuoteChar = '*'; + } + }); + } - [Test] - public void Indentation() - { - StringBuilder sb = new StringBuilder(); - StringWriter sw = new StringWriter(sb); + [Test] + public void Indentation() + { + StringBuilder sb = new StringBuilder(); + StringWriter sw = new StringWriter(sb); - using (JsonTextWriter jsonWriter = new JsonTextWriter(sw)) - { - jsonWriter.Formatting = Formatting.Indented; - jsonWriter.FloatFormatHandling = FloatFormatHandling.Symbol; + using (JsonTextWriter jsonWriter = new JsonTextWriter(sw)) + { + jsonWriter.Formatting = Formatting.Indented; + jsonWriter.FloatFormatHandling = FloatFormatHandling.Symbol; - Assert.AreEqual(Formatting.Indented, jsonWriter.Formatting); + Assert.AreEqual(Formatting.Indented, jsonWriter.Formatting); - jsonWriter.Indentation = 5; - Assert.AreEqual(5, jsonWriter.Indentation); - jsonWriter.IndentChar = '_'; - Assert.AreEqual('_', jsonWriter.IndentChar); - jsonWriter.QuoteName = true; - Assert.AreEqual(true, jsonWriter.QuoteName); - jsonWriter.QuoteChar = '\''; - Assert.AreEqual('\'', jsonWriter.QuoteChar); + jsonWriter.Indentation = 5; + Assert.AreEqual(5, jsonWriter.Indentation); + jsonWriter.IndentChar = '_'; + Assert.AreEqual('_', jsonWriter.IndentChar); + jsonWriter.QuoteName = true; + Assert.AreEqual(true, jsonWriter.QuoteName); + jsonWriter.QuoteChar = '\''; + Assert.AreEqual('\'', jsonWriter.QuoteChar); - jsonWriter.WriteStartObject(); - jsonWriter.WritePropertyName("propertyName"); - jsonWriter.WriteValue(double.NaN); - jsonWriter.WriteEndObject(); - } + jsonWriter.WriteStartObject(); + jsonWriter.WritePropertyName("propertyName"); + jsonWriter.WriteValue(double.NaN); + jsonWriter.WriteEndObject(); + } - string expected = @"{ + string expected = @"{ _____'propertyName': NaN }"; - string result = sb.ToString(); + string result = sb.ToString(); - Assert.AreEqual(expected, result); - } + Assert.AreEqual(expected, result); + } - [Test] - public void WriteSingleBytes() - { - StringBuilder sb = new StringBuilder(); - StringWriter sw = new StringWriter(sb); + [Test] + public void WriteSingleBytes() + { + StringBuilder sb = new StringBuilder(); + StringWriter sw = new StringWriter(sb); - string text = "Hello world."; - byte[] data = Encoding.UTF8.GetBytes(text); + string text = "Hello world."; + byte[] data = Encoding.UTF8.GetBytes(text); - using (JsonTextWriter jsonWriter = new JsonTextWriter(sw)) - { - jsonWriter.Formatting = Formatting.Indented; - Assert.AreEqual(Formatting.Indented, jsonWriter.Formatting); + using (JsonTextWriter jsonWriter = new JsonTextWriter(sw)) + { + jsonWriter.Formatting = Formatting.Indented; + Assert.AreEqual(Formatting.Indented, jsonWriter.Formatting); - jsonWriter.WriteValue(data); - } + jsonWriter.WriteValue(data); + } - string expected = @"""SGVsbG8gd29ybGQu"""; - string result = sb.ToString(); + string expected = @"""SGVsbG8gd29ybGQu"""; + string result = sb.ToString(); - Assert.AreEqual(expected, result); + Assert.AreEqual(expected, result); - byte[] d2 = Convert.FromBase64String(result.Trim('"')); + byte[] d2 = Convert.FromBase64String(result.Trim('"')); - Assert.AreEqual(text, Encoding.UTF8.GetString(d2, 0, d2.Length)); - } + Assert.AreEqual(text, Encoding.UTF8.GetString(d2, 0, d2.Length)); + } - [Test] - public void WriteBytesInArray() - { - StringBuilder sb = new StringBuilder(); - StringWriter sw = new StringWriter(sb); + [Test] + public void WriteBytesInArray() + { + StringBuilder sb = new StringBuilder(); + StringWriter sw = new StringWriter(sb); - string text = "Hello world."; - byte[] data = Encoding.UTF8.GetBytes(text); + string text = "Hello world."; + byte[] data = Encoding.UTF8.GetBytes(text); - using (JsonTextWriter jsonWriter = new JsonTextWriter(sw)) - { - jsonWriter.Formatting = Formatting.Indented; - Assert.AreEqual(Formatting.Indented, jsonWriter.Formatting); + using (JsonTextWriter jsonWriter = new JsonTextWriter(sw)) + { + jsonWriter.Formatting = Formatting.Indented; + Assert.AreEqual(Formatting.Indented, jsonWriter.Formatting); - jsonWriter.WriteStartArray(); - jsonWriter.WriteValue(data); - jsonWriter.WriteValue(data); - jsonWriter.WriteValue((object)data); - jsonWriter.WriteValue((byte[])null); - jsonWriter.WriteValue((Uri)null); - jsonWriter.WriteEndArray(); - } + jsonWriter.WriteStartArray(); + jsonWriter.WriteValue(data); + jsonWriter.WriteValue(data); + jsonWriter.WriteValue((object)data); + jsonWriter.WriteValue((byte[])null); + jsonWriter.WriteValue((Uri)null); + jsonWriter.WriteEndArray(); + } - string expected = @"[ + string expected = @"[ ""SGVsbG8gd29ybGQu"", ""SGVsbG8gd29ybGQu"", ""SGVsbG8gd29ybGQu"", null, null ]"; - string result = sb.ToString(); + string result = sb.ToString(); - Assert.AreEqual(expected, result); - } + Assert.AreEqual(expected, result); + } - [Test] - public void Path() - { - StringBuilder sb = new StringBuilder(); - StringWriter sw = new StringWriter(sb); + [Test] + public void Path() + { + StringBuilder sb = new StringBuilder(); + StringWriter sw = new StringWriter(sb); - string text = "Hello world."; - byte[] data = Encoding.UTF8.GetBytes(text); + string text = "Hello world."; + byte[] data = Encoding.UTF8.GetBytes(text); - using (JsonTextWriter writer = new JsonTextWriter(sw)) - { - writer.Formatting = Formatting.Indented; + using (JsonTextWriter writer = new JsonTextWriter(sw)) + { + writer.Formatting = Formatting.Indented; - writer.WriteStartArray(); - Assert.AreEqual("", writer.Path); - writer.WriteStartObject(); - Assert.AreEqual("[0]", writer.Path); - writer.WritePropertyName("Property1"); - Assert.AreEqual("[0].Property1", writer.Path); - writer.WriteStartArray(); - Assert.AreEqual("[0].Property1", writer.Path); - writer.WriteValue(1); - Assert.AreEqual("[0].Property1[0]", writer.Path); - writer.WriteStartArray(); - Assert.AreEqual("[0].Property1[1]", writer.Path); - writer.WriteStartArray(); - Assert.AreEqual("[0].Property1[1][0]", writer.Path); - writer.WriteStartArray(); - Assert.AreEqual("[0].Property1[1][0][0]", writer.Path); - writer.WriteEndObject(); - Assert.AreEqual("[0]", writer.Path); - writer.WriteStartObject(); - Assert.AreEqual("[1]", writer.Path); - writer.WritePropertyName("Property2"); - Assert.AreEqual("[1].Property2", writer.Path); - writer.WriteStartConstructor("Constructor1"); - Assert.AreEqual("[1].Property2", writer.Path); - writer.WriteNull(); - Assert.AreEqual("[1].Property2[0]", writer.Path); - writer.WriteStartArray(); - Assert.AreEqual("[1].Property2[1]", writer.Path); - writer.WriteValue(1); - Assert.AreEqual("[1].Property2[1][0]", writer.Path); - writer.WriteEnd(); - Assert.AreEqual("[1].Property2[1]", writer.Path); - writer.WriteEndObject(); - Assert.AreEqual("[1]", writer.Path); - writer.WriteEndArray(); - Assert.AreEqual("", writer.Path); - } + writer.WriteStartArray(); + Assert.AreEqual("", writer.Path); + writer.WriteStartObject(); + Assert.AreEqual("[0]", writer.Path); + writer.WritePropertyName("Property1"); + Assert.AreEqual("[0].Property1", writer.Path); + writer.WriteStartArray(); + Assert.AreEqual("[0].Property1", writer.Path); + writer.WriteValue(1); + Assert.AreEqual("[0].Property1[0]", writer.Path); + writer.WriteStartArray(); + Assert.AreEqual("[0].Property1[1]", writer.Path); + writer.WriteStartArray(); + Assert.AreEqual("[0].Property1[1][0]", writer.Path); + writer.WriteStartArray(); + Assert.AreEqual("[0].Property1[1][0][0]", writer.Path); + writer.WriteEndObject(); + Assert.AreEqual("[0]", writer.Path); + writer.WriteStartObject(); + Assert.AreEqual("[1]", writer.Path); + writer.WritePropertyName("Property2"); + Assert.AreEqual("[1].Property2", writer.Path); + writer.WriteStartConstructor("Constructor1"); + Assert.AreEqual("[1].Property2", writer.Path); + writer.WriteNull(); + Assert.AreEqual("[1].Property2[0]", writer.Path); + writer.WriteStartArray(); + Assert.AreEqual("[1].Property2[1]", writer.Path); + writer.WriteValue(1); + Assert.AreEqual("[1].Property2[1][0]", writer.Path); + writer.WriteEnd(); + Assert.AreEqual("[1].Property2[1]", writer.Path); + writer.WriteEndObject(); + Assert.AreEqual("[1]", writer.Path); + writer.WriteEndArray(); + Assert.AreEqual("", writer.Path); + } - Assert.AreEqual(@"[ + Assert.AreEqual(@"[ { ""Property1"": [ 1, @@ -1004,154 +1004,154 @@ _____'propertyName': NaN ) } ]", sb.ToString()); - } - - [Test] - public void BuildStateArray() - { - JsonWriter.State[][] stateArray = JsonWriter.BuildStateArray(); - - var valueStates = JsonWriter.StateArrayTempate[7]; - - foreach (JsonToken valueToken in EnumUtils.GetValues(typeof(JsonToken))) - { - switch (valueToken) - { - case JsonToken.Integer: - case JsonToken.Float: - case JsonToken.String: - case JsonToken.Boolean: - case JsonToken.Null: - case JsonToken.Undefined: - case JsonToken.Date: - case JsonToken.Bytes: - Assert.AreEqual(valueStates, stateArray[(int)valueToken], "Error for " + valueToken + " states."); - break; } - } - } - [Test] - public void DateTimeZoneHandling() - { - StringWriter sw = new StringWriter(); - JsonTextWriter writer = new JsonTextWriter(sw) + [Test] + public void BuildStateArray() { - DateTimeZoneHandling = Json.DateTimeZoneHandling.Utc - }; + JsonWriter.State[][] stateArray = JsonWriter.BuildStateArray(); - writer.WriteValue(new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Unspecified)); + var valueStates = JsonWriter.StateArrayTempate[7]; - Assert.AreEqual(@"""2000-01-01T01:01:01Z""", sw.ToString()); - } + foreach (JsonToken valueToken in EnumUtils.GetValues(typeof(JsonToken))) + { + switch (valueToken) + { + case JsonToken.Integer: + case JsonToken.Float: + case JsonToken.String: + case JsonToken.Boolean: + case JsonToken.Null: + case JsonToken.Undefined: + case JsonToken.Date: + case JsonToken.Bytes: + Assert.AreEqual(valueStates, stateArray[(int)valueToken], "Error for " + valueToken + " states."); + break; + } + } + } - [Test] - public void HtmlStringEscapeHandling() - { - StringWriter sw = new StringWriter(); - JsonTextWriter writer = new JsonTextWriter(sw) - { - StringEscapeHandling = StringEscapeHandling.EscapeHtml - }; + [Test] + public void DateTimeZoneHandling() + { + StringWriter sw = new StringWriter(); + JsonTextWriter writer = new JsonTextWriter(sw) + { + DateTimeZoneHandling = Json.DateTimeZoneHandling.Utc + }; - string script = @""; + writer.WriteValue(new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Unspecified)); - writer.WriteValue(script); + Assert.AreEqual(@"""2000-01-01T01:01:01Z""", sw.ToString()); + } - string json = sw.ToString(); + [Test] + public void HtmlStringEscapeHandling() + { + StringWriter sw = new StringWriter(); + JsonTextWriter writer = new JsonTextWriter(sw) + { + StringEscapeHandling = StringEscapeHandling.EscapeHtml + }; - Assert.AreEqual(@"""\u003cscript type=\u0022text/javascript\u0022\u003ealert(\u0027hi\u0027);\u003c/script\u003e""", json); + string script = @""; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - - Assert.AreEqual(script, reader.ReadAsString()); + writer.WriteValue(script); - //Console.WriteLine(HttpUtility.HtmlEncode(script)); + string json = sw.ToString(); - //System.Web.Script.Serialization.JavaScriptSerializer s = new System.Web.Script.Serialization.JavaScriptSerializer(); - //Console.WriteLine(s.Serialize(new { html = script })); - } + Assert.AreEqual(@"""\u003cscript type=\u0022text/javascript\u0022\u003ealert(\u0027hi\u0027);\u003c/script\u003e""", json); - [Test] - public void NonAsciiStringEscapeHandling() - { - StringWriter sw = new StringWriter(); - JsonTextWriter writer = new JsonTextWriter(sw) - { - StringEscapeHandling = StringEscapeHandling.EscapeNonAscii - }; + JsonTextReader reader = new JsonTextReader(new StringReader(json)); - string unicode = "\u5f20"; + Assert.AreEqual(script, reader.ReadAsString()); - writer.WriteValue(unicode); + //Console.WriteLine(HttpUtility.HtmlEncode(script)); - string json = sw.ToString(); + //System.Web.Script.Serialization.JavaScriptSerializer s = new System.Web.Script.Serialization.JavaScriptSerializer(); + //Console.WriteLine(s.Serialize(new { html = script })); + } - Assert.AreEqual(8, json.Length); - Assert.AreEqual(@"""\u5f20""", json); + [Test] + public void NonAsciiStringEscapeHandling() + { + StringWriter sw = new StringWriter(); + JsonTextWriter writer = new JsonTextWriter(sw) + { + StringEscapeHandling = StringEscapeHandling.EscapeNonAscii + }; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); + string unicode = "\u5f20"; - Assert.AreEqual(unicode, reader.ReadAsString()); + writer.WriteValue(unicode); - sw = new StringWriter(); - writer = new JsonTextWriter(sw) - { - StringEscapeHandling = StringEscapeHandling.Default - }; + string json = sw.ToString(); - writer.WriteValue(unicode); + Assert.AreEqual(8, json.Length); + Assert.AreEqual(@"""\u5f20""", json); - json = sw.ToString(); + JsonTextReader reader = new JsonTextReader(new StringReader(json)); - Assert.AreEqual(3, json.Length); - Assert.AreEqual("\"\u5f20\"", json); - } + Assert.AreEqual(unicode, reader.ReadAsString()); - [Test] - public void WriteEndOnProperty() - { - StringWriter sw = new StringWriter(); - JsonTextWriter writer = new JsonTextWriter(sw); - writer.QuoteChar = '\''; + sw = new StringWriter(); + writer = new JsonTextWriter(sw) + { + StringEscapeHandling = StringEscapeHandling.Default + }; - writer.WriteStartObject(); - writer.WritePropertyName("Blah"); - writer.WriteEnd(); + writer.WriteValue(unicode); - Assert.AreEqual("{'Blah':null}", sw.ToString()); - } + json = sw.ToString(); + + Assert.AreEqual(3, json.Length); + Assert.AreEqual("\"\u5f20\"", json); + } + + [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()); + } #if !NET20 - [Test] - public void QuoteChar() - { - StringWriter sw = new StringWriter(); - JsonTextWriter writer = new JsonTextWriter(sw); - writer.Formatting = Formatting.Indented; - writer.QuoteChar = '\''; + [Test] + public void QuoteChar() + { + StringWriter sw = new StringWriter(); + JsonTextWriter writer = new JsonTextWriter(sw); + writer.Formatting = Formatting.Indented; + writer.QuoteChar = '\''; - writer.WriteStartArray(); + writer.WriteStartArray(); - writer.WriteValue(new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc)); - writer.WriteValue(new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero)); + writer.WriteValue(new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc)); + writer.WriteValue(new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero)); - writer.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat; - writer.WriteValue(new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc)); - writer.WriteValue(new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero)); + writer.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat; + writer.WriteValue(new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc)); + writer.WriteValue(new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero)); - writer.DateFormatString = "yyyy gg"; - writer.WriteValue(new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc)); - writer.WriteValue(new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero)); + writer.DateFormatString = "yyyy gg"; + writer.WriteValue(new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc)); + writer.WriteValue(new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero)); - writer.WriteValue(new byte[] { 1, 2, 3 }); - writer.WriteValue(TimeSpan.Zero); - writer.WriteValue(new Uri("http://www.google.com/")); - writer.WriteValue(Guid.Empty); + writer.WriteValue(new byte[] { 1, 2, 3 }); + writer.WriteValue(TimeSpan.Zero); + writer.WriteValue(new Uri("http://www.google.com/")); + writer.WriteValue(Guid.Empty); - writer.WriteEnd(); + writer.WriteEnd(); - Assert.AreEqual(@"[ + Assert.AreEqual(@"[ '2000-01-01T01:01:01Z', '2000-01-01T01:01:01+00:00', '\/Date(946688461000)\/', @@ -1163,382 +1163,382 @@ _____'propertyName': NaN 'http://www.google.com/', '00000000-0000-0000-0000-000000000000' ]", sw.ToString()); - } + } - [Test] - public void Culture() - { - StringWriter sw = new StringWriter(); - JsonTextWriter writer = new JsonTextWriter(sw); - writer.Formatting = Formatting.Indented; - writer.DateFormatString = "yyyy tt"; - writer.Culture = new CultureInfo("en-NZ"); - writer.QuoteChar = '\''; + [Test] + public void Culture() + { + StringWriter sw = new StringWriter(); + JsonTextWriter writer = new JsonTextWriter(sw); + writer.Formatting = Formatting.Indented; + writer.DateFormatString = "yyyy tt"; + writer.Culture = new CultureInfo("en-NZ"); + writer.QuoteChar = '\''; - writer.WriteStartArray(); + writer.WriteStartArray(); - writer.WriteValue(new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc)); - writer.WriteValue(new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero)); + writer.WriteValue(new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc)); + writer.WriteValue(new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero)); - writer.WriteEnd(); + writer.WriteEnd(); - Assert.AreEqual(@"[ + Assert.AreEqual(@"[ '2000 a.m.', '2000 a.m.' ]", sw.ToString()); - } + } #endif - [Test] - public void CompareNewStringEscapingWithOld() - { - Console.WriteLine("Started"); - - char c = (char) 0; - - do - { - if (c % 1000 == 0) - Console.WriteLine("Position: " + (int)c); - - StringWriter swNew = new StringWriter(); - char[] buffer = null; - JavaScriptUtils.WriteEscapedJavaScriptString(swNew, c.ToString(), '"', true, JavaScriptUtils.DoubleQuoteCharEscapeFlags, StringEscapeHandling.Default, ref buffer); - - StringWriter swOld = new StringWriter(); - WriteEscapedJavaScriptStringOld(swOld, c.ToString(), '"', true); - - string newText = swNew.ToString(); - string oldText = swOld.ToString(); - - if (newText != oldText) - throw new Exception("Difference for char '{0}' (value {1}). Old text: {2}, New text: {3}".FormatWith(CultureInfo.InvariantCulture, c, (int) c, oldText, newText)); - - c++; - } while (c != char.MaxValue); - - Console.WriteLine("Finished"); - } - - private const string EscapedUnicodeText = "!"; - - private static void WriteEscapedJavaScriptStringOld(TextWriter writer, string s, char delimiter, bool appendDelimiters) - { - // leading delimiter - if (appendDelimiters) - writer.Write(delimiter); - - if (s != null) - { - char[] chars = null; - char[] unicodeBuffer = null; - int lastWritePosition = 0; - - for (int i = 0; i < s.Length; i++) + [Test] + public void CompareNewStringEscapingWithOld() { - var c = s[i]; + Console.WriteLine("Started"); - // don't escape standard text/numbers except '\' and the text delimiter - if (c >= ' ' && c < 128 && c != '\\' && c != delimiter) - continue; + char c = (char)0; - string escapedValue; + do + { + if (c % 1000 == 0) + Console.WriteLine("Position: " + (int)c); - switch (c) - { - case '\t': - escapedValue = @"\t"; - break; - case '\n': - escapedValue = @"\n"; - break; - case '\r': - escapedValue = @"\r"; - break; - case '\f': - escapedValue = @"\f"; - break; - case '\b': - escapedValue = @"\b"; - break; - case '\\': - escapedValue = @"\\"; - break; - case '\u0085': // Next Line - escapedValue = @"\u0085"; - break; - case '\u2028': // Line Separator - escapedValue = @"\u2028"; - break; - case '\u2029': // Paragraph Separator - escapedValue = @"\u2029"; - break; - case '\'': - // this charater is being used as the delimiter - escapedValue = @"\'"; - break; - case '"': - // this charater is being used as the delimiter - escapedValue = "\\\""; - break; - default: - if (c <= '\u001f') - { - if (unicodeBuffer == null) - unicodeBuffer = new char[6]; + StringWriter swNew = new StringWriter(); + char[] buffer = null; + JavaScriptUtils.WriteEscapedJavaScriptString(swNew, c.ToString(), '"', true, JavaScriptUtils.DoubleQuoteCharEscapeFlags, StringEscapeHandling.Default, ref buffer); - StringUtils.ToCharAsUnicode(c, unicodeBuffer); + StringWriter swOld = new StringWriter(); + WriteEscapedJavaScriptStringOld(swOld, c.ToString(), '"', true); - // slightly hacky but it saves multiple conditions in if test - escapedValue = EscapedUnicodeText; - } - else - { - escapedValue = null; - } - break; - } + string newText = swNew.ToString(); + string oldText = swOld.ToString(); - if (escapedValue == null) - continue; + if (newText != oldText) + throw new Exception("Difference for char '{0}' (value {1}). Old text: {2}, New text: {3}".FormatWith(CultureInfo.InvariantCulture, c, (int)c, oldText, newText)); - if (i > lastWritePosition) - { - if (chars == null) - chars = s.ToCharArray(); + c++; + } while (c != char.MaxValue); - // write unchanged chars before writing escaped text - writer.Write(chars, lastWritePosition, i - lastWritePosition); - } - - lastWritePosition = i + 1; - if (!string.Equals(escapedValue, EscapedUnicodeText)) - writer.Write(escapedValue); - else - writer.Write(unicodeBuffer); + Console.WriteLine("Finished"); } - if (lastWritePosition == 0) + private const string EscapedUnicodeText = "!"; + + private static void WriteEscapedJavaScriptStringOld(TextWriter writer, string s, char delimiter, bool appendDelimiters) { - // no escaped text, write entire string - writer.Write(s); + // leading delimiter + if (appendDelimiters) + writer.Write(delimiter); + + if (s != null) + { + char[] chars = null; + char[] unicodeBuffer = null; + int lastWritePosition = 0; + + for (int i = 0; i < s.Length; i++) + { + var c = s[i]; + + // don't escape standard text/numbers except '\' and the text delimiter + if (c >= ' ' && c < 128 && c != '\\' && c != delimiter) + continue; + + string escapedValue; + + switch (c) + { + case '\t': + escapedValue = @"\t"; + break; + case '\n': + escapedValue = @"\n"; + break; + case '\r': + escapedValue = @"\r"; + break; + case '\f': + escapedValue = @"\f"; + break; + case '\b': + escapedValue = @"\b"; + break; + case '\\': + escapedValue = @"\\"; + break; + case '\u0085': // Next Line + escapedValue = @"\u0085"; + break; + case '\u2028': // Line Separator + escapedValue = @"\u2028"; + break; + case '\u2029': // Paragraph Separator + escapedValue = @"\u2029"; + break; + case '\'': + // this charater is being used as the delimiter + escapedValue = @"\'"; + break; + case '"': + // this charater is being used as the delimiter + escapedValue = "\\\""; + break; + default: + if (c <= '\u001f') + { + if (unicodeBuffer == null) + unicodeBuffer = new char[6]; + + StringUtils.ToCharAsUnicode(c, unicodeBuffer); + + // slightly hacky but it saves multiple conditions in if test + escapedValue = EscapedUnicodeText; + } + else + { + escapedValue = null; + } + break; + } + + if (escapedValue == null) + continue; + + if (i > lastWritePosition) + { + if (chars == null) + chars = s.ToCharArray(); + + // write unchanged chars before writing escaped text + writer.Write(chars, lastWritePosition, i - lastWritePosition); + } + + lastWritePosition = i + 1; + if (!string.Equals(escapedValue, EscapedUnicodeText)) + writer.Write(escapedValue); + else + writer.Write(unicodeBuffer); + } + + if (lastWritePosition == 0) + { + // no escaped text, write entire string + writer.Write(s); + } + else + { + if (chars == null) + chars = s.ToCharArray(); + + // write remaining text + writer.Write(chars, lastWritePosition, s.Length - lastWritePosition); + } + } + + // trailing delimiter + if (appendDelimiters) + writer.Write(delimiter); } - else + + [Test] + public void CustomJsonTextWriterTests() { - if (chars == null) - chars = s.ToCharArray(); + StringWriter sw = new StringWriter(); + CustomJsonTextWriter writer = new CustomJsonTextWriter(sw) { Formatting = Formatting.Indented }; + writer.WriteStartObject(); + Assert.AreEqual(WriteState.Object, writer.WriteState); + writer.WritePropertyName("Property1"); + Assert.AreEqual(WriteState.Property, writer.WriteState); + Assert.AreEqual("Property1", writer.Path); + writer.WriteNull(); + Assert.AreEqual(WriteState.Object, writer.WriteState); + writer.WriteEndObject(); + Assert.AreEqual(WriteState.Start, writer.WriteState); - // write remaining text - writer.Write(chars, lastWritePosition, s.Length - lastWritePosition); - } - } - - // trailing delimiter - if (appendDelimiters) - writer.Write(delimiter); - } - - [Test] - public void CustomJsonTextWriterTests() - { - StringWriter sw = new StringWriter(); - CustomJsonTextWriter writer = new CustomJsonTextWriter(sw) { Formatting = Formatting.Indented }; - writer.WriteStartObject(); - Assert.AreEqual(WriteState.Object, writer.WriteState); - writer.WritePropertyName("Property1"); - Assert.AreEqual(WriteState.Property, writer.WriteState); - Assert.AreEqual("Property1", writer.Path); - writer.WriteNull(); - Assert.AreEqual(WriteState.Object, writer.WriteState); - writer.WriteEndObject(); - Assert.AreEqual(WriteState.Start, writer.WriteState); - - Assert.AreEqual(@"{{{ + Assert.AreEqual(@"{{{ ""1ytreporP"": NULL!!! }}}", sw.ToString()); - } - - [Test] - public void QuoteDictionaryNames() - { - var d = new Dictionary - { - { "a", 1 }, - }; - var jsonSerializerSettings = new JsonSerializerSettings - { - Formatting = Formatting.Indented, - }; - var serializer = JsonSerializer.Create(jsonSerializerSettings); - using (var stringWriter = new StringWriter()) - { - using (var writer = new JsonTextWriter(stringWriter) { QuoteName = false }) - { - serializer.Serialize(writer, d); - writer.Close(); } - Assert.AreEqual(@"{ + [Test] + public void QuoteDictionaryNames() + { + var d = new Dictionary + { + { "a", 1 }, + }; + var jsonSerializerSettings = new JsonSerializerSettings + { + Formatting = Formatting.Indented, + }; + var serializer = JsonSerializer.Create(jsonSerializerSettings); + using (var stringWriter = new StringWriter()) + { + using (var writer = new JsonTextWriter(stringWriter) { QuoteName = false }) + { + serializer.Serialize(writer, d); + writer.Close(); + } + + Assert.AreEqual(@"{ a: 1 }", stringWriter.ToString()); - } + } + } } - } - public class CustomJsonTextWriter : JsonTextWriter - { - private readonly TextWriter _writer; - - public CustomJsonTextWriter(TextWriter textWriter) : base(textWriter) + public class CustomJsonTextWriter : JsonTextWriter { - _writer = textWriter; + private readonly TextWriter _writer; + + public CustomJsonTextWriter(TextWriter textWriter) : base(textWriter) + { + _writer = textWriter; + } + + public override void WritePropertyName(string name) + { + WritePropertyName(name, true); + } + + public override void WritePropertyName(string name, bool escape) + { + SetWriteState(JsonToken.PropertyName, name); + + if (QuoteName) + _writer.Write(QuoteChar); + + _writer.Write(new string(name.ToCharArray().Reverse().ToArray())); + + if (QuoteName) + _writer.Write(QuoteChar); + + _writer.Write(':'); + } + + public override void WriteNull() + { + SetWriteState(JsonToken.Null, null); + + _writer.Write("NULL!!!"); + } + + public override void WriteStartObject() + { + SetWriteState(JsonToken.StartObject, null); + + _writer.Write("{{{"); + } + + public override void WriteEndObject() + { + SetWriteState(JsonToken.EndObject, null); + } + + protected override void WriteEnd(JsonToken token) + { + if (token == JsonToken.EndObject) + _writer.Write("}}}"); + else + base.WriteEnd(token); + } } - public override void WritePropertyName(string name) - { - WritePropertyName(name, true); - } - - public override void WritePropertyName(string name, bool escape) - { - SetWriteState(JsonToken.PropertyName, name); - - if (QuoteName) - _writer.Write(QuoteChar); - - _writer.Write(new string(name.ToCharArray().Reverse().ToArray())); - - if (QuoteName) - _writer.Write(QuoteChar); - - _writer.Write(':'); - } - - public override void WriteNull() - { - SetWriteState(JsonToken.Null, null); - - _writer.Write("NULL!!!"); - } - - public override void WriteStartObject() - { - SetWriteState(JsonToken.StartObject, null); - - _writer.Write("{{{"); - } - - public override void WriteEndObject() - { - SetWriteState(JsonToken.EndObject, null); - } - - protected override void WriteEnd(JsonToken token) - { - if (token == JsonToken.EndObject) - _writer.Write("}}}"); - else - base.WriteEnd(token); - } - } - #if !(PORTABLE || NETFX_CORE) - public struct ConvertibleInt : IConvertible - { - private readonly int _value; - - public ConvertibleInt(int value) + public struct ConvertibleInt : IConvertible { - _value = value; - } + private readonly int _value; - public TypeCode GetTypeCode() - { - return TypeCode.Int32; - } + public ConvertibleInt(int value) + { + _value = value; + } - public bool ToBoolean(IFormatProvider provider) - { - throw new NotImplementedException(); - } + public TypeCode GetTypeCode() + { + return TypeCode.Int32; + } - public byte ToByte(IFormatProvider provider) - { - throw new NotImplementedException(); - } + public bool ToBoolean(IFormatProvider provider) + { + throw new NotImplementedException(); + } - public char ToChar(IFormatProvider provider) - { - throw new NotImplementedException(); - } + public byte ToByte(IFormatProvider provider) + { + throw new NotImplementedException(); + } - public DateTime ToDateTime(IFormatProvider provider) - { - throw new NotImplementedException(); - } + public char ToChar(IFormatProvider provider) + { + throw new NotImplementedException(); + } - public decimal ToDecimal(IFormatProvider provider) - { - throw new NotImplementedException(); - } + public DateTime ToDateTime(IFormatProvider provider) + { + throw new NotImplementedException(); + } - public double ToDouble(IFormatProvider provider) - { - throw new NotImplementedException(); - } + public decimal ToDecimal(IFormatProvider provider) + { + throw new NotImplementedException(); + } - public short ToInt16(IFormatProvider provider) - { - throw new NotImplementedException(); - } + public double ToDouble(IFormatProvider provider) + { + throw new NotImplementedException(); + } - public int ToInt32(IFormatProvider provider) - { - throw new NotImplementedException(); - } + public short ToInt16(IFormatProvider provider) + { + throw new NotImplementedException(); + } - public long ToInt64(IFormatProvider provider) - { - throw new NotImplementedException(); - } + public int ToInt32(IFormatProvider provider) + { + throw new NotImplementedException(); + } - public sbyte ToSByte(IFormatProvider provider) - { - throw new NotImplementedException(); - } + public long ToInt64(IFormatProvider provider) + { + throw new NotImplementedException(); + } - public float ToSingle(IFormatProvider provider) - { - throw new NotImplementedException(); - } + public sbyte ToSByte(IFormatProvider provider) + { + throw new NotImplementedException(); + } - public string ToString(IFormatProvider provider) - { - throw new NotImplementedException(); - } + public float ToSingle(IFormatProvider provider) + { + throw new NotImplementedException(); + } - public object ToType(Type conversionType, IFormatProvider provider) - { - if (conversionType == typeof(int)) - return _value; + public string ToString(IFormatProvider provider) + { + throw new NotImplementedException(); + } - throw new Exception("Type not supported: " + conversionType.FullName); - } + public object ToType(Type conversionType, IFormatProvider provider) + { + if (conversionType == typeof(int)) + return _value; - public ushort ToUInt16(IFormatProvider provider) - { - throw new NotImplementedException(); - } + throw new Exception("Type not supported: " + conversionType.FullName); + } - public uint ToUInt32(IFormatProvider provider) - { - throw new NotImplementedException(); - } + public ushort ToUInt16(IFormatProvider provider) + { + throw new NotImplementedException(); + } - public ulong ToUInt64(IFormatProvider provider) - { - throw new NotImplementedException(); + public uint ToUInt32(IFormatProvider provider) + { + throw new NotImplementedException(); + } + + public ulong ToUInt64(IFormatProvider provider) + { + throw new NotImplementedException(); + } } - } #endif } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/JsonValidatingReaderTests.cs b/Src/Newtonsoft.Json.Tests/JsonValidatingReaderTests.cs index 7167adf6..637ff8a5 100644 --- a/Src/Newtonsoft.Json.Tests/JsonValidatingReaderTests.cs +++ b/Src/Newtonsoft.Json.Tests/JsonValidatingReaderTests.cs @@ -49,23 +49,23 @@ using ValidationEventArgs = Newtonsoft.Json.Schema.ValidationEventArgs; namespace Newtonsoft.Json.Tests { - [TestFixture] - public class JsonValidatingReaderTests : TestFixtureBase - { - [Test] - public void CheckInnerReader() + [TestFixture] + public class JsonValidatingReaderTests : TestFixtureBase { - string json = "{'name':'James','hobbies':['pie','cake']}"; - JsonReader reader = new JsonTextReader(new StringReader(json)); + [Test] + public void CheckInnerReader() + { + string json = "{'name':'James','hobbies':['pie','cake']}"; + JsonReader reader = new JsonTextReader(new StringReader(json)); - JsonValidatingReader validatingReader = new JsonValidatingReader(reader); - Assert.AreEqual(reader, validatingReader.Reader); - } + JsonValidatingReader validatingReader = new JsonValidatingReader(reader); + Assert.AreEqual(reader, validatingReader.Reader); + } - [Test] - public void ValidateTypes() - { - string schemaJson = @"{ + [Test] + public void ValidateTypes() + { + string schemaJson = @"{ ""description"":""A person"", ""type"":""object"", ""properties"": @@ -79,194 +79,194 @@ namespace Newtonsoft.Json.Tests } }"; - string json = @"{'name':""James"",'hobbies':[""pie"",'cake']}"; + string json = @"{'name':""James"",'hobbies':[""pie"",'cake']}"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - JsonSchema schema = JsonSchema.Parse(schemaJson); - reader.Schema = schema; - Assert.AreEqual(schema, reader.Schema); - Assert.AreEqual(0, reader.Depth); - Assert.AreEqual("", reader.Path); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + JsonSchema schema = JsonSchema.Parse(schemaJson); + reader.Schema = schema; + Assert.AreEqual(schema, reader.Schema); + Assert.AreEqual(0, reader.Depth); + Assert.AreEqual("", reader.Path); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.AreEqual("", reader.Path); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.AreEqual("", reader.Path); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("name", reader.Value.ToString()); - Assert.AreEqual("name", reader.Path); - Assert.AreEqual(1, reader.Depth); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("name", reader.Value.ToString()); + Assert.AreEqual("name", reader.Path); + Assert.AreEqual(1, reader.Depth); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("James", reader.Value.ToString()); - Assert.AreEqual(typeof (string), reader.ValueType); - Assert.AreEqual('"', reader.QuoteChar); - Assert.AreEqual("name", reader.Path); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("James", reader.Value.ToString()); + Assert.AreEqual(typeof(string), reader.ValueType); + Assert.AreEqual('"', reader.QuoteChar); + Assert.AreEqual("name", reader.Path); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("hobbies", reader.Value.ToString()); - Assert.AreEqual('\'', reader.QuoteChar); - Assert.AreEqual("hobbies", reader.Path); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("hobbies", reader.Value.ToString()); + Assert.AreEqual('\'', reader.QuoteChar); + Assert.AreEqual("hobbies", reader.Path); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - Assert.AreEqual("hobbies", reader.Path); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + Assert.AreEqual("hobbies", reader.Path); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("pie", reader.Value.ToString()); - Assert.AreEqual('"', reader.QuoteChar); - Assert.AreEqual("hobbies[0]", reader.Path); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("pie", reader.Value.ToString()); + Assert.AreEqual('"', reader.QuoteChar); + Assert.AreEqual("hobbies[0]", reader.Path); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("cake", reader.Value.ToString()); - Assert.AreEqual("hobbies[1]", reader.Path); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("cake", reader.Value.ToString()); + Assert.AreEqual("hobbies[1]", reader.Path); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - Assert.AreEqual("hobbies", reader.Path); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + Assert.AreEqual("hobbies", reader.Path); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - Assert.AreEqual("", reader.Path); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.AreEqual("", reader.Path); - Assert.IsFalse(reader.Read()); - - Assert.IsNull(validationEventArgs); - } + Assert.IsFalse(reader.Read()); - [Test] - public void ValidateUnrestrictedArray() - { - string schemaJson = @"{ + Assert.IsNull(validationEventArgs); + } + + [Test] + public void ValidateUnrestrictedArray() + { + string schemaJson = @"{ ""type"":""array"" }"; - string json = "['pie','cake',['nested1','nested2'],{'nestedproperty1':1.1,'nestedproperty2':[null]}]"; + string json = "['pie','cake',['nested1','nested2'],{'nestedproperty1':1.1,'nestedproperty2':[null]}]"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - reader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + reader.Schema = JsonSchema.Parse(schemaJson); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("pie", reader.Value.ToString()); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("pie", reader.Value.ToString()); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("cake", reader.Value.ToString()); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("cake", reader.Value.ToString()); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("nested1", reader.Value.ToString()); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("nested1", reader.Value.ToString()); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("nested2", reader.Value.ToString()); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("nested2", reader.Value.ToString()); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("nestedproperty1", reader.Value.ToString()); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("nestedproperty1", reader.Value.ToString()); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual(1.1, reader.Value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual(1.1, reader.Value); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("nestedproperty2", reader.Value.ToString()); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("nestedproperty2", reader.Value.ToString()); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Null, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Null, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - Assert.IsNull(validationEventArgs); - } + Assert.IsNull(validationEventArgs); + } - [Test] - public void StringLessThanMinimumLength() - { - string schemaJson = @"{ + [Test] + public void StringLessThanMinimumLength() + { + string schemaJson = @"{ ""type"":""string"", ""minLength"":5, ""maxLength"":50, }"; - string json = "'pie'"; + string json = "'pie'"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - reader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + reader.Schema = JsonSchema.Parse(schemaJson); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("String 'pie' is less than minimum length of 5. Line 1, position 5.", validationEventArgs.Message); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("String 'pie' is less than minimum length of 5. Line 1, position 5.", validationEventArgs.Message); - Assert.IsNotNull(validationEventArgs); - } + Assert.IsNotNull(validationEventArgs); + } - [Test] - public void StringGreaterThanMaximumLength() - { - string schemaJson = @"{ + [Test] + public void StringGreaterThanMaximumLength() + { + string schemaJson = @"{ ""type"":""string"", ""minLength"":5, ""maxLength"":10 }"; - string json = "'The quick brown fox jumps over the lazy dog.'"; + string json = "'The quick brown fox jumps over the lazy dog.'"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - reader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + reader.Schema = JsonSchema.Parse(schemaJson); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("String 'The quick brown fox jumps over the lazy dog.' exceeds maximum length of 10. Line 1, position 46.", validationEventArgs.Message); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("String 'The quick brown fox jumps over the lazy dog.' exceeds maximum length of 10. Line 1, position 46.", validationEventArgs.Message); - Assert.IsNotNull(validationEventArgs); - } + Assert.IsNotNull(validationEventArgs); + } - [Test] - public void StringIsNotInEnum() - { - string schemaJson = @"{ + [Test] + public void StringIsNotInEnum() + { + string schemaJson = @"{ ""type"":""array"", ""items"":{ ""type"":""string"", @@ -275,173 +275,173 @@ namespace Newtonsoft.Json.Tests ""maxItems"":3 }"; - string json = "['one','two','THREE']"; + string json = "['one','two','THREE']"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - reader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + reader.Schema = JsonSchema.Parse(schemaJson); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual(null, validationEventArgs); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual(null, validationEventArgs); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual(@"Value ""THREE"" is not defined in enum. Line 1, position 20.", validationEventArgs.Message); - Assert.AreEqual("[2]", validationEventArgs.Path); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual(@"Value ""THREE"" is not defined in enum. Line 1, position 20.", validationEventArgs.Message); + Assert.AreEqual("[2]", validationEventArgs.Path); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - Assert.IsNotNull(validationEventArgs); - } + Assert.IsNotNull(validationEventArgs); + } - [Test] - public void StringDoesNotMatchPattern() - { - string schemaJson = @"{ + [Test] + public void StringDoesNotMatchPattern() + { + string schemaJson = @"{ ""type"":""string"", ""pattern"":""foo"" }"; - string json = "'The quick brown fox jumps over the lazy dog.'"; + string json = "'The quick brown fox jumps over the lazy dog.'"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - reader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + reader.Schema = JsonSchema.Parse(schemaJson); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("String 'The quick brown fox jumps over the lazy dog.' does not match regex pattern 'foo'. Line 1, position 46.", validationEventArgs.Message); - Assert.AreEqual("", validationEventArgs.Path); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("String 'The quick brown fox jumps over the lazy dog.' does not match regex pattern 'foo'. Line 1, position 46.", validationEventArgs.Message); + Assert.AreEqual("", validationEventArgs.Path); - Assert.IsNotNull(validationEventArgs); - } + Assert.IsNotNull(validationEventArgs); + } - [Test] - public void IntegerGreaterThanMaximumValue() - { - string schemaJson = @"{ + [Test] + public void IntegerGreaterThanMaximumValue() + { + string schemaJson = @"{ ""type"":""integer"", ""maximum"":5 }"; - string json = "10"; + string json = "10"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - reader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + reader.Schema = JsonSchema.Parse(schemaJson); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.AreEqual("Integer 10 exceeds maximum value of 5. Line 1, position 2.", validationEventArgs.Message); - Assert.AreEqual("", validationEventArgs.Path); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); + Assert.AreEqual("Integer 10 exceeds maximum value of 5. Line 1, position 2.", validationEventArgs.Message); + Assert.AreEqual("", validationEventArgs.Path); - Assert.IsNotNull(validationEventArgs); - } + Assert.IsNotNull(validationEventArgs); + } #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE || PORTABLE40) - [Test] - public void IntegerGreaterThanMaximumValue_BigInteger() - { - string schemaJson = @"{ + [Test] + public void IntegerGreaterThanMaximumValue_BigInteger() + { + string schemaJson = @"{ ""type"":""integer"", ""maximum"":5 }"; - string json = "99999999999999999999999999999999999999999999999999999999999999999999"; + string json = "99999999999999999999999999999999999999999999999999999999999999999999"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - reader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + reader.Schema = JsonSchema.Parse(schemaJson); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.AreEqual("Integer 99999999999999999999999999999999999999999999999999999999999999999999 exceeds maximum value of 5. Line 1, position 68.", validationEventArgs.Message); - Assert.AreEqual("", validationEventArgs.Path); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); + Assert.AreEqual("Integer 99999999999999999999999999999999999999999999999999999999999999999999 exceeds maximum value of 5. Line 1, position 68.", validationEventArgs.Message); + Assert.AreEqual("", validationEventArgs.Path); - Assert.IsNotNull(validationEventArgs); - } + Assert.IsNotNull(validationEventArgs); + } - [Test] - public void IntegerLessThanMaximumValue_BigInteger() - { - string schemaJson = @"{ + [Test] + public void IntegerLessThanMaximumValue_BigInteger() + { + string schemaJson = @"{ ""type"":""integer"", ""minimum"":5 }"; - JValue v = new JValue(new BigInteger(1)); + JValue v = new JValue(new BigInteger(1)); - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - v.Validate(JsonSchema.Parse(schemaJson), (sender, args) => { validationEventArgs = args; }); + v.Validate(JsonSchema.Parse(schemaJson), (sender, args) => { validationEventArgs = args; }); - Assert.IsNotNull(validationEventArgs); - Assert.AreEqual("Integer 1 is less than minimum value of 5.", validationEventArgs.Message); - Assert.AreEqual("", validationEventArgs.Path); - } + Assert.IsNotNull(validationEventArgs); + Assert.AreEqual("Integer 1 is less than minimum value of 5.", validationEventArgs.Message); + Assert.AreEqual("", validationEventArgs.Path); + } #endif - [Test] - public void ThrowExceptionWhenNoValidationEventHandler() - { - ExceptionAssert.Throws("Integer 10 exceeds maximum value of 5. Line 1, position 2.", - () => - { - string schemaJson = @"{ + [Test] + public void ThrowExceptionWhenNoValidationEventHandler() + { + ExceptionAssert.Throws("Integer 10 exceeds maximum value of 5. Line 1, position 2.", + () => + { + string schemaJson = @"{ ""type"":""integer"", ""maximum"":5 }"; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader("10"))); - reader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader("10"))); + reader.Schema = JsonSchema.Parse(schemaJson); - Assert.IsTrue(reader.Read()); - }); - } + Assert.IsTrue(reader.Read()); + }); + } - [Test] - public void IntegerLessThanMinimumValue() - { - string schemaJson = @"{ + [Test] + public void IntegerLessThanMinimumValue() + { + string schemaJson = @"{ ""type"":""integer"", ""minimum"":5 }"; - string json = "1"; + string json = "1"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - reader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + reader.Schema = JsonSchema.Parse(schemaJson); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.AreEqual("Integer 1 is less than minimum value of 5. Line 1, position 1.", validationEventArgs.Message); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); + Assert.AreEqual("Integer 1 is less than minimum value of 5. Line 1, position 1.", validationEventArgs.Message); - Assert.IsNotNull(validationEventArgs); - } + Assert.IsNotNull(validationEventArgs); + } - [Test] - public void IntegerIsNotInEnum() - { - string schemaJson = @"{ + [Test] + public void IntegerIsNotInEnum() + { + string schemaJson = @"{ ""type"":""array"", ""items"":{ ""type"":""integer"", @@ -450,85 +450,85 @@ namespace Newtonsoft.Json.Tests ""maxItems"":3 }"; - string json = "[1,2,3]"; + string json = "[1,2,3]"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - reader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + reader.Schema = JsonSchema.Parse(schemaJson); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.AreEqual(null, validationEventArgs); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); + Assert.AreEqual(null, validationEventArgs); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.AreEqual(@"Value 3 is not defined in enum. Line 1, position 6.", validationEventArgs.Message); - Assert.AreEqual("[2]", validationEventArgs.Path); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); + Assert.AreEqual(@"Value 3 is not defined in enum. Line 1, position 6.", validationEventArgs.Message); + Assert.AreEqual("[2]", validationEventArgs.Path); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - Assert.IsNotNull(validationEventArgs); - } + Assert.IsNotNull(validationEventArgs); + } - [Test] - public void FloatGreaterThanMaximumValue() - { - string schemaJson = @"{ + [Test] + public void FloatGreaterThanMaximumValue() + { + string schemaJson = @"{ ""type"":""number"", ""maximum"":5 }"; - string json = "10.0"; + string json = "10.0"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - reader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + reader.Schema = JsonSchema.Parse(schemaJson); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual("Float 10.0 exceeds maximum value of 5. Line 1, position 4.", validationEventArgs.Message); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual("Float 10.0 exceeds maximum value of 5. Line 1, position 4.", validationEventArgs.Message); - Assert.IsNotNull(validationEventArgs); - } + Assert.IsNotNull(validationEventArgs); + } - [Test] - public void FloatLessThanMinimumValue() - { - string schemaJson = @"{ + [Test] + public void FloatLessThanMinimumValue() + { + string schemaJson = @"{ ""type"":""number"", ""minimum"":5 }"; - string json = "1.1"; + string json = "1.1"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - reader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + reader.Schema = JsonSchema.Parse(schemaJson); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual("Float 1.1 is less than minimum value of 5. Line 1, position 3.", validationEventArgs.Message); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual("Float 1.1 is less than minimum value of 5. Line 1, position 3.", validationEventArgs.Message); - Assert.IsNotNull(validationEventArgs); - } + Assert.IsNotNull(validationEventArgs); + } - [Test] - public void FloatIsNotInEnum() - { - string schemaJson = @"{ + [Test] + public void FloatIsNotInEnum() + { + string schemaJson = @"{ ""type"":""array"", ""items"":{ ""type"":""number"", @@ -537,39 +537,39 @@ namespace Newtonsoft.Json.Tests ""maxItems"":3 }"; - string json = "[1.1,2.2,3.0]"; + string json = "[1.1,2.2,3.0]"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - reader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + reader.Schema = JsonSchema.Parse(schemaJson); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual(null, validationEventArgs); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual(null, validationEventArgs); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual(@"Value 3.0 is not defined in enum. Line 1, position 12.", validationEventArgs.Message); - Assert.AreEqual("[2]", validationEventArgs.Path); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual(@"Value 3.0 is not defined in enum. Line 1, position 12.", validationEventArgs.Message); + Assert.AreEqual("[2]", validationEventArgs.Path); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - Assert.IsNotNull(validationEventArgs); - } + Assert.IsNotNull(validationEventArgs); + } - [Test] - public void FloatDivisibleBy() - { - string schemaJson = @"{ + [Test] + public void FloatDivisibleBy() + { + string schemaJson = @"{ ""type"":""array"", ""items"":{ ""type"":""number"", @@ -577,40 +577,40 @@ namespace Newtonsoft.Json.Tests } }"; - string json = "[1.1,2.2,4.001]"; + string json = "[1.1,2.2,4.001]"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - reader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + reader.Schema = JsonSchema.Parse(schemaJson); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual(null, validationEventArgs); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual(null, validationEventArgs); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual(@"Float 4.001 is not evenly divisible by 0.1. Line 1, position 14.", validationEventArgs.Message); - Assert.AreEqual("[2]", validationEventArgs.Path); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual(@"Float 4.001 is not evenly divisible by 0.1. Line 1, position 14.", validationEventArgs.Message); + Assert.AreEqual("[2]", validationEventArgs.Path); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - Assert.IsNotNull(validationEventArgs); - } + Assert.IsNotNull(validationEventArgs); + } #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE || PORTABLE40) - [Test] - public void BigIntegerDivisibleBy_Success() - { - string schemaJson = @"{ + [Test] + public void BigIntegerDivisibleBy_Success() + { + string schemaJson = @"{ ""type"":""array"", ""items"":{ ""type"":""number"", @@ -618,29 +618,29 @@ namespace Newtonsoft.Json.Tests } }"; - string json = "[999999999999999999999999999999999999999999999999999999998]"; + string json = "[999999999999999999999999999999999999999999999999999999998]"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - reader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + reader.Schema = JsonSchema.Parse(schemaJson); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.IsNull(validationEventArgs); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); + Assert.IsNull(validationEventArgs); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - } + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + } - [Test] - public void BigIntegerDivisibleBy_Failure() - { - string schemaJson = @"{ + [Test] + public void BigIntegerDivisibleBy_Failure() + { + string schemaJson = @"{ ""type"":""array"", ""items"":{ ""type"":""number"", @@ -648,32 +648,32 @@ namespace Newtonsoft.Json.Tests } }"; - string json = "[999999999999999999999999999999999999999999999999999999999]"; + string json = "[999999999999999999999999999999999999999999999999999999999]"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - reader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + reader.Schema = JsonSchema.Parse(schemaJson); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.AreEqual(@"Integer 999999999999999999999999999999999999999999999999999999999 is not evenly divisible by 2. Line 1, position 58.", validationEventArgs.Message); - Assert.AreEqual("[0]", validationEventArgs.Path); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); + Assert.AreEqual(@"Integer 999999999999999999999999999999999999999999999999999999999 is not evenly divisible by 2. Line 1, position 58.", validationEventArgs.Message); + Assert.AreEqual("[0]", validationEventArgs.Path); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - Assert.IsNotNull(validationEventArgs); - } + Assert.IsNotNull(validationEventArgs); + } - [Test] - public void BigIntegerDivisibleBy_Fraction() - { - string schemaJson = @"{ + [Test] + public void BigIntegerDivisibleBy_Fraction() + { + string schemaJson = @"{ ""type"":""array"", ""items"":{ ""type"":""number"", @@ -681,31 +681,31 @@ namespace Newtonsoft.Json.Tests } }"; - string json = "[999999999999999999999999999999999999999999999999999999999]"; + string json = "[999999999999999999999999999999999999999999999999999999999]"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - reader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + reader.Schema = JsonSchema.Parse(schemaJson); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.IsNotNull(validationEventArgs); - Assert.AreEqual(@"Integer 999999999999999999999999999999999999999999999999999999999 is not evenly divisible by 1.1. Line 1, position 58.", validationEventArgs.Message); - Assert.AreEqual("[0]", validationEventArgs.Path); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); + Assert.IsNotNull(validationEventArgs); + Assert.AreEqual(@"Integer 999999999999999999999999999999999999999999999999999999999 is not evenly divisible by 1.1. Line 1, position 58.", validationEventArgs.Message); + Assert.AreEqual("[0]", validationEventArgs.Path); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - } + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + } - [Test] - public void BigIntegerDivisibleBy_FractionWithZeroValue() - { - string schemaJson = @"{ + [Test] + public void BigIntegerDivisibleBy_FractionWithZeroValue() + { + string schemaJson = @"{ ""type"":""array"", ""items"":{ ""type"":""number"", @@ -713,50 +713,50 @@ namespace Newtonsoft.Json.Tests } }"; - JArray a = new JArray(new JValue(new BigInteger(0))); + JArray a = new JArray(new JValue(new BigInteger(0))); - ValidationEventArgs validationEventArgs = null; + ValidationEventArgs validationEventArgs = null; - a.Validate(JsonSchema.Parse(schemaJson), (sender, args) => { validationEventArgs = args; }); + a.Validate(JsonSchema.Parse(schemaJson), (sender, args) => { validationEventArgs = args; }); - Assert.IsNull(validationEventArgs); - } + Assert.IsNull(validationEventArgs); + } #endif - [Test] - public void IntValidForNumber() - { - string schemaJson = @"{ + [Test] + public void IntValidForNumber() + { + string schemaJson = @"{ ""type"":""array"", ""items"":{ ""type"":""number"" } }"; - string json = "[1]"; + string json = "[1]"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - reader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + reader.Schema = JsonSchema.Parse(schemaJson); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - Assert.IsNull(validationEventArgs); - } + Assert.IsNull(validationEventArgs); + } - [Test] - public void NullNotInEnum() - { - string schemaJson = @"{ + [Test] + public void NullNotInEnum() + { + string schemaJson = @"{ ""type"":""array"", ""items"":{ ""type"":""null"", @@ -765,32 +765,32 @@ namespace Newtonsoft.Json.Tests ""maxItems"":3 }"; - string json = "[null]"; + string json = "[null]"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - reader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + reader.Schema = JsonSchema.Parse(schemaJson); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Null, reader.TokenType); - Assert.AreEqual(@"Value null is not defined in enum. Line 1, position 5.", validationEventArgs.Message); - Assert.AreEqual("[0]", validationEventArgs.Path); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Null, reader.TokenType); + Assert.AreEqual(@"Value null is not defined in enum. Line 1, position 5.", validationEventArgs.Message); + Assert.AreEqual("[0]", validationEventArgs.Path); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - Assert.IsNotNull(validationEventArgs); - } + Assert.IsNotNull(validationEventArgs); + } - [Test] - public void BooleanNotInEnum() - { - string schemaJson = @"{ + [Test] + public void BooleanNotInEnum() + { + string schemaJson = @"{ ""type"":""array"", ""items"":{ ""type"":""boolean"", @@ -799,127 +799,127 @@ namespace Newtonsoft.Json.Tests ""maxItems"":3 }"; - string json = "[true,false]"; + string json = "[true,false]"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - reader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + reader.Schema = JsonSchema.Parse(schemaJson); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Boolean, reader.TokenType); - Assert.AreEqual(null, validationEventArgs); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Boolean, reader.TokenType); + Assert.AreEqual(null, validationEventArgs); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Boolean, reader.TokenType); - Assert.AreEqual(@"Value false is not defined in enum. Line 1, position 11.", validationEventArgs.Message); - Assert.AreEqual("[1]", validationEventArgs.Path); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Boolean, reader.TokenType); + Assert.AreEqual(@"Value false is not defined in enum. Line 1, position 11.", validationEventArgs.Message); + Assert.AreEqual("[1]", validationEventArgs.Path); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - Assert.IsNotNull(validationEventArgs); - } + Assert.IsNotNull(validationEventArgs); + } - [Test] - public void ArrayCountGreaterThanMaximumItems() - { - string schemaJson = @"{ + [Test] + public void ArrayCountGreaterThanMaximumItems() + { + string schemaJson = @"{ ""type"":""array"", ""minItems"":2, ""maxItems"":3 }"; - string json = "[null,null,null,null]"; + string json = "[null,null,null,null]"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - reader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + reader.Schema = JsonSchema.Parse(schemaJson); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Null, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Null, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Null, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Null, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Null, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Null, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Null, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Null, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - Assert.AreEqual("Array item count 4 exceeds maximum count of 3. Line 1, position 21.", validationEventArgs.Message); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + Assert.AreEqual("Array item count 4 exceeds maximum count of 3. Line 1, position 21.", validationEventArgs.Message); - Assert.IsNotNull(validationEventArgs); - } + Assert.IsNotNull(validationEventArgs); + } - [Test] - public void ArrayCountLessThanMinimumItems() - { - string schemaJson = @"{ + [Test] + public void ArrayCountLessThanMinimumItems() + { + string schemaJson = @"{ ""type"":""array"", ""minItems"":2, ""maxItems"":3 }"; - string json = "[null]"; + string json = "[null]"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - reader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + reader.Schema = JsonSchema.Parse(schemaJson); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Null, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Null, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - Assert.AreEqual("Array item count 1 is less than minimum count of 2. Line 1, position 6.", validationEventArgs.Message); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + Assert.AreEqual("Array item count 1 is less than minimum count of 2. Line 1, position 6.", validationEventArgs.Message); - Assert.IsNotNull(validationEventArgs); - } + Assert.IsNotNull(validationEventArgs); + } - [Test] - public void InvalidDataType() - { - string schemaJson = @"{ + [Test] + public void InvalidDataType() + { + string schemaJson = @"{ ""type"":""string"", ""minItems"":2, ""maxItems"":3, ""items"":{} }"; - string json = "[null,null,null,null]"; + string json = "[null,null,null,null]"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - reader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + reader.Schema = JsonSchema.Parse(schemaJson); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - Assert.AreEqual(@"Invalid type. Expected String but got Array. Line 1, position 1.", validationEventArgs.Message); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + Assert.AreEqual(@"Invalid type. Expected String but got Array. Line 1, position 1.", validationEventArgs.Message); - Assert.IsNotNull(validationEventArgs); - } + Assert.IsNotNull(validationEventArgs); + } - [Test] - public void StringDisallowed() - { - string schemaJson = @"{ + [Test] + public void StringDisallowed() + { + string schemaJson = @"{ ""type"":""array"", ""items"":{ ""disallow"":[""number""] @@ -927,35 +927,35 @@ namespace Newtonsoft.Json.Tests ""maxItems"":3 }"; - string json = "['pie',1.1]"; + string json = "['pie',1.1]"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - reader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + reader.Schema = JsonSchema.Parse(schemaJson); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual(null, validationEventArgs); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual(null, validationEventArgs); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual(@"Type Float is disallowed. Line 1, position 10.", validationEventArgs.Message); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual(@"Type Float is disallowed. Line 1, position 10.", validationEventArgs.Message); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - Assert.IsNotNull(validationEventArgs); - } + Assert.IsNotNull(validationEventArgs); + } - [Test] - public void MissingRequiredProperties() - { - string schemaJson = @"{ + [Test] + public void MissingRequiredProperties() + { + string schemaJson = @"{ ""description"":""A person"", ""type"":""object"", ""properties"": @@ -966,38 +966,38 @@ namespace Newtonsoft.Json.Tests } }"; - string json = "{'name':'James'}"; + string json = "{'name':'James'}"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - reader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + reader.Schema = JsonSchema.Parse(schemaJson); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("name", reader.Value.ToString()); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("name", reader.Value.ToString()); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("James", reader.Value.ToString()); - Assert.AreEqual(null, validationEventArgs); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("James", reader.Value.ToString()); + Assert.AreEqual(null, validationEventArgs); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - Assert.AreEqual("Required properties are missing from object: hobbies, age. Line 1, position 16.", validationEventArgs.Message); - Assert.AreEqual("", validationEventArgs.Path); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.AreEqual("Required properties are missing from object: hobbies, age. Line 1, position 16.", validationEventArgs.Message); + Assert.AreEqual("", validationEventArgs.Path); - Assert.IsNotNull(validationEventArgs); - } + Assert.IsNotNull(validationEventArgs); + } - [Test] - public void MissingNonRequiredProperties() - { - string schemaJson = @"{ + [Test] + public void MissingNonRequiredProperties() + { + string schemaJson = @"{ ""description"":""A person"", ""type"":""object"", ""properties"": @@ -1008,36 +1008,36 @@ namespace Newtonsoft.Json.Tests } }"; - string json = "{'name':'James'}"; + string json = "{'name':'James'}"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - reader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + reader.Schema = JsonSchema.Parse(schemaJson); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("name", reader.Value.ToString()); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("name", reader.Value.ToString()); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("James", reader.Value.ToString()); - Assert.IsNull(validationEventArgs); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("James", reader.Value.ToString()); + Assert.IsNull(validationEventArgs); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - Assert.IsNull(validationEventArgs); - } + Assert.IsNull(validationEventArgs); + } - [Test] - public void DisableAdditionalProperties() - { - string schemaJson = @"{ + [Test] + public void DisableAdditionalProperties() + { + string schemaJson = @"{ ""description"":""A person"", ""type"":""object"", ""properties"": @@ -1047,54 +1047,54 @@ namespace Newtonsoft.Json.Tests ""additionalProperties"":false }"; - string json = "{'name':'James','additionalProperty1':null,'additionalProperty2':null}"; + string json = "{'name':'James','additionalProperty1':null,'additionalProperty2':null}"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - reader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + reader.Schema = JsonSchema.Parse(schemaJson); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("name", reader.Value.ToString()); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("name", reader.Value.ToString()); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("James", reader.Value.ToString()); - Assert.AreEqual(null, validationEventArgs); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("James", reader.Value.ToString()); + Assert.AreEqual(null, validationEventArgs); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("additionalProperty1", reader.Value.ToString()); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("additionalProperty1", reader.Value.ToString()); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Null, reader.TokenType); - Assert.AreEqual(null, reader.Value); - Assert.AreEqual("Property 'additionalProperty1' has not been defined and the schema does not allow additional properties. Line 1, position 38.", validationEventArgs.Message); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Null, reader.TokenType); + Assert.AreEqual(null, reader.Value); + Assert.AreEqual("Property 'additionalProperty1' has not been defined and the schema does not allow additional properties. Line 1, position 38.", validationEventArgs.Message); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("additionalProperty2", reader.Value.ToString()); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("additionalProperty2", reader.Value.ToString()); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Null, reader.TokenType); - Assert.AreEqual(null, reader.Value); - Assert.AreEqual("Property 'additionalProperty2' has not been defined and the schema does not allow additional properties. Line 1, position 65.", validationEventArgs.Message); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Null, reader.TokenType); + Assert.AreEqual(null, reader.Value); + Assert.AreEqual("Property 'additionalProperty2' has not been defined and the schema does not allow additional properties. Line 1, position 65.", validationEventArgs.Message); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - Assert.IsNotNull(validationEventArgs); - } + Assert.IsNotNull(validationEventArgs); + } - [Test] - public void ExtendsStringGreaterThanMaximumLength() - { - string schemaJson = @"{ + [Test] + public void ExtendsStringGreaterThanMaximumLength() + { + string schemaJson = @"{ ""extends"":{ ""type"":""string"", ""minLength"":5, @@ -1103,30 +1103,30 @@ namespace Newtonsoft.Json.Tests ""maxLength"":9 }"; - List errors = new List(); - string json = "'The quick brown fox jumps over the lazy dog.'"; + List errors = new List(); + string json = "'The quick brown fox jumps over the lazy dog.'"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => + { + validationEventArgs = args; + errors.Add(validationEventArgs.Message); + }; + reader.Schema = JsonSchema.Parse(schemaJson); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual(1, errors.Count); + Assert.AreEqual("String 'The quick brown fox jumps over the lazy dog.' exceeds maximum length of 9. Line 1, position 46.", errors[0]); + + Assert.IsNotNull(validationEventArgs); + } + + private JsonSchema GetExtendedSchema() { - validationEventArgs = args; - errors.Add(validationEventArgs.Message); - }; - reader.Schema = JsonSchema.Parse(schemaJson); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual(1, errors.Count); - Assert.AreEqual("String 'The quick brown fox jumps over the lazy dog.' exceeds maximum length of 9. Line 1, position 46.", errors[0]); - - Assert.IsNotNull(validationEventArgs); - } - - private JsonSchema GetExtendedSchema() - { - string first = @"{ + string first = @"{ ""id"":""first"", ""type"":""object"", ""properties"": @@ -1136,7 +1136,7 @@ namespace Newtonsoft.Json.Tests ""additionalProperties"":{} }"; - string second = @"{ + string second = @"{ ""id"":""second"", ""type"":""object"", ""extends"":{""$ref"":""first""}, @@ -1147,134 +1147,134 @@ namespace Newtonsoft.Json.Tests ""additionalProperties"":false }"; - JsonSchemaResolver resolver = new JsonSchemaResolver(); - JsonSchema firstSchema = JsonSchema.Parse(first, resolver); - JsonSchema secondSchema = JsonSchema.Parse(second, resolver); + JsonSchemaResolver resolver = new JsonSchemaResolver(); + JsonSchema firstSchema = JsonSchema.Parse(first, resolver); + JsonSchema secondSchema = JsonSchema.Parse(second, resolver); - return secondSchema; - } + return secondSchema; + } - [Test] - public void ExtendsDisallowAdditionProperties() - { - string json = "{'firstproperty':'blah','secondproperty':'blah2','additional':'blah3','additional2':'blah4'}"; + [Test] + public void ExtendsDisallowAdditionProperties() + { + string json = "{'firstproperty':'blah','secondproperty':'blah2','additional':'blah3','additional2':'blah4'}"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - reader.Schema = GetExtendedSchema(); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + reader.Schema = GetExtendedSchema(); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("firstproperty", reader.Value.ToString()); - Assert.AreEqual(null, validationEventArgs); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("firstproperty", reader.Value.ToString()); + Assert.AreEqual(null, validationEventArgs); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("blah", reader.Value.ToString()); - Assert.AreEqual(null, validationEventArgs); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("blah", reader.Value.ToString()); + Assert.AreEqual(null, validationEventArgs); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("secondproperty", reader.Value.ToString()); - Assert.AreEqual(null, validationEventArgs); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("secondproperty", reader.Value.ToString()); + Assert.AreEqual(null, validationEventArgs); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("blah2", reader.Value.ToString()); - Assert.AreEqual(null, validationEventArgs); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("blah2", reader.Value.ToString()); + Assert.AreEqual(null, validationEventArgs); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("additional", reader.Value.ToString()); - Assert.AreEqual("Property 'additional' has not been defined and the schema does not allow additional properties. Line 1, position 62.", validationEventArgs.Message); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("additional", reader.Value.ToString()); + Assert.AreEqual("Property 'additional' has not been defined and the schema does not allow additional properties. Line 1, position 62.", validationEventArgs.Message); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("blah3", reader.Value.ToString()); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("blah3", reader.Value.ToString()); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("additional2", reader.Value.ToString()); - Assert.AreEqual("Property 'additional2' has not been defined and the schema does not allow additional properties. Line 1, position 84.", validationEventArgs.Message); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("additional2", reader.Value.ToString()); + Assert.AreEqual("Property 'additional2' has not been defined and the schema does not allow additional properties. Line 1, position 84.", validationEventArgs.Message); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("blah4", reader.Value.ToString()); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("blah4", reader.Value.ToString()); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - Assert.IsFalse(reader.Read()); - } + Assert.IsFalse(reader.Read()); + } - [Test] - public void ExtendsMissingRequiredProperties() - { - string json = "{}"; + [Test] + public void ExtendsMissingRequiredProperties() + { + string json = "{}"; - List errors = new List(); + List errors = new List(); - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { errors.Add(args.Message); }; - reader.Schema = GetExtendedSchema(); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { errors.Add(args.Message); }; + reader.Schema = GetExtendedSchema(); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - Assert.AreEqual(1, errors.Count); - Assert.AreEqual("Required properties are missing from object: secondproperty, firstproperty. Line 1, position 2.", errors[0]); - } + Assert.AreEqual(1, errors.Count); + Assert.AreEqual("Required properties are missing from object: secondproperty, firstproperty. Line 1, position 2.", errors[0]); + } - [Test] - public void NoAdditionalItems() - { - string schemaJson = @"{ + [Test] + public void NoAdditionalItems() + { + string schemaJson = @"{ ""type"":""array"", ""items"": [{""type"":""string""},{""type"":""integer""}], ""additionalItems"": false }"; - string json = @"[1, 'a', null]"; + string json = @"[1, 'a', null]"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - reader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + reader.Schema = JsonSchema.Parse(schemaJson); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.AreEqual("Invalid type. Expected String but got Integer. Line 1, position 2.", validationEventArgs.Message); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); + Assert.AreEqual("Invalid type. Expected String but got Integer. Line 1, position 2.", validationEventArgs.Message); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("Invalid type. Expected Integer but got String. Line 1, position 7.", validationEventArgs.Message); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("Invalid type. Expected Integer but got String. Line 1, position 7.", validationEventArgs.Message); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Null, reader.TokenType); - Assert.AreEqual("Index 3 has not been defined and the schema does not allow additional items. Line 1, position 13.", validationEventArgs.Message); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Null, reader.TokenType); + Assert.AreEqual("Index 3 has not been defined and the schema does not allow additional items. Line 1, position 13.", validationEventArgs.Message); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - Assert.IsFalse(reader.Read()); - } + Assert.IsFalse(reader.Read()); + } - [Test] - public void PatternPropertiesNoAdditionalProperties() - { - string schemaJson = @"{ + [Test] + public void PatternPropertiesNoAdditionalProperties() + { + string schemaJson = @"{ ""type"":""object"", ""patternProperties"": { ""hi"": {""type"":""string""}, @@ -1283,61 +1283,61 @@ namespace Newtonsoft.Json.Tests ""additionalProperties"": false }"; - string json = @"{ + string json = @"{ ""hi"": ""A string!"", ""hide"": ""A string!"", ""ho"": 1, ""hey"": ""A string!"" }"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - reader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + reader.Schema = JsonSchema.Parse(schemaJson); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual(null, validationEventArgs); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual(null, validationEventArgs); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual(null, validationEventArgs); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual(null, validationEventArgs); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual(null, validationEventArgs); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual(null, validationEventArgs); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.AreEqual("Invalid type. Expected String but got Integer. Line 4, position 10.", validationEventArgs.Message); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); + Assert.AreEqual("Invalid type. Expected String but got Integer. Line 4, position 10.", validationEventArgs.Message); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("Property 'hey' has not been defined and the schema does not allow additional properties. Line 5, position 9.", validationEventArgs.Message); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("Property 'hey' has not been defined and the schema does not allow additional properties. Line 5, position 9.", validationEventArgs.Message); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - Assert.IsFalse(reader.Read()); - } + Assert.IsFalse(reader.Read()); + } - [Test] - public void ExtendedComplex() - { - string first = @"{ + [Test] + public void ExtendedComplex() + { + string first = @"{ ""id"":""first"", ""type"":""object"", ""properties"": @@ -1355,7 +1355,7 @@ namespace Newtonsoft.Json.Tests ""additionalProperties"":{} }"; - string second = @"{ + string second = @"{ ""id"":""second"", ""type"":""object"", ""extends"":{""$ref"":""first""}, @@ -1382,13 +1382,13 @@ namespace Newtonsoft.Json.Tests ""additionalProperties"":false }"; - JsonSchemaResolver resolver = new JsonSchemaResolver(); - JsonSchema firstSchema = JsonSchema.Parse(first, resolver); - JsonSchema secondSchema = JsonSchema.Parse(second, resolver); + JsonSchemaResolver resolver = new JsonSchemaResolver(); + JsonSchema firstSchema = JsonSchema.Parse(first, resolver); + JsonSchema secondSchema = JsonSchema.Parse(second, resolver); - JsonSchemaModelBuilder modelBuilder = new JsonSchemaModelBuilder(); + JsonSchemaModelBuilder modelBuilder = new JsonSchemaModelBuilder(); - string json = @"{ + string json = @"{ 'firstproperty':'blahblahblahblahblahblah', 'secondproperty':'secasecasecasecaseca', 'thirdproperty':{ @@ -1397,85 +1397,85 @@ namespace Newtonsoft.Json.Tests } }"; - Json.Schema.ValidationEventArgs validationEventArgs = null; - List errors = new List(); + Json.Schema.ValidationEventArgs validationEventArgs = null; + List errors = new List(); - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => + { + validationEventArgs = args; + errors.Add(validationEventArgs.Path + " - " + validationEventArgs.Message); + }; + reader.Schema = secondSchema; + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("firstproperty", reader.Value.ToString()); + Assert.AreEqual(null, validationEventArgs); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("blahblahblahblahblahblah", reader.Value.ToString()); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("secondproperty", reader.Value.ToString()); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("secasecasecasecaseca", reader.Value.ToString()); + Assert.AreEqual(1, errors.Count); + Assert.AreEqual("secondproperty - String 'secasecasecasecaseca' exceeds maximum length of 10. Line 3, position 42.", errors[0]); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("thirdproperty", reader.Value.ToString()); + Assert.AreEqual(1, errors.Count); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.AreEqual(1, errors.Count); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("thirdproperty_firstproperty", reader.Value.ToString()); + Assert.AreEqual(1, errors.Count); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("aaa", reader.Value.ToString()); + Assert.AreEqual(4, errors.Count); + Assert.AreEqual("thirdproperty.thirdproperty_firstproperty - String 'aaa' is less than minimum length of 7. Line 5, position 40.", errors[1]); + Assert.AreEqual("thirdproperty.thirdproperty_firstproperty - String 'aaa' does not match regex pattern 'hi'. Line 5, position 40.", errors[2]); + Assert.AreEqual("thirdproperty.thirdproperty_firstproperty - String 'aaa' does not match regex pattern 'hi2u'. Line 5, position 40.", errors[3]); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + Assert.AreEqual("additional", reader.Value.ToString()); + Assert.AreEqual(4, errors.Count); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + Assert.AreEqual("three", reader.Value.ToString()); + Assert.AreEqual(5, errors.Count); + Assert.AreEqual("thirdproperty.additional - String 'three' is less than minimum length of 6. Line 6, position 25.", errors[4]); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + + Assert.IsFalse(reader.Read()); + } + + [Test] + public void DuplicateErrorsTest() { - validationEventArgs = args; - errors.Add(validationEventArgs.Path + " - " + validationEventArgs.Message); - }; - reader.Schema = secondSchema; - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("firstproperty", reader.Value.ToString()); - Assert.AreEqual(null, validationEventArgs); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("blahblahblahblahblahblah", reader.Value.ToString()); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("secondproperty", reader.Value.ToString()); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("secasecasecasecaseca", reader.Value.ToString()); - Assert.AreEqual(1, errors.Count); - Assert.AreEqual("secondproperty - String 'secasecasecasecaseca' exceeds maximum length of 10. Line 3, position 42.", errors[0]); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("thirdproperty", reader.Value.ToString()); - Assert.AreEqual(1, errors.Count); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.AreEqual(1, errors.Count); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("thirdproperty_firstproperty", reader.Value.ToString()); - Assert.AreEqual(1, errors.Count); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("aaa", reader.Value.ToString()); - Assert.AreEqual(4, errors.Count); - Assert.AreEqual("thirdproperty.thirdproperty_firstproperty - String 'aaa' is less than minimum length of 7. Line 5, position 40.", errors[1]); - Assert.AreEqual("thirdproperty.thirdproperty_firstproperty - String 'aaa' does not match regex pattern 'hi'. Line 5, position 40.", errors[2]); - Assert.AreEqual("thirdproperty.thirdproperty_firstproperty - String 'aaa' does not match regex pattern 'hi2u'. Line 5, position 40.", errors[3]); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.AreEqual("additional", reader.Value.ToString()); - Assert.AreEqual(4, errors.Count); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - Assert.AreEqual("three", reader.Value.ToString()); - Assert.AreEqual(5, errors.Count); - Assert.AreEqual("thirdproperty.additional - String 'three' is less than minimum length of 6. Line 6, position 25.", errors[4]); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - - Assert.IsFalse(reader.Read()); - } - - [Test] - public void DuplicateErrorsTest() - { - string schema = @"{ + string schema = @"{ ""id"":""ErrorDemo.Database"", ""properties"":{ ""ErrorDemoDatabase"":{ @@ -1533,7 +1533,7 @@ namespace Newtonsoft.Json.Tests } }"; - string json = @"{ + string json = @"{ ""ErrorDemoDatabase"":{ ""URL"":""localhost:3164"", ""Version"":""1.0"", @@ -1575,117 +1575,114 @@ namespace Newtonsoft.Json.Tests } }"; - IList validationEventArgs = new List(); + IList validationEventArgs = new List(); - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs.Add(args); }; + reader.Schema = JsonSchema.Parse(schema); + + while (reader.Read()) + { + } + + Assert.AreEqual(1, validationEventArgs.Count); + } + + [Test] + public void ReadAsBytes() { - validationEventArgs.Add(args); - }; - reader.Schema = JsonSchema.Parse(schema); + JsonSchema s = new JsonSchemaGenerator().Generate(typeof(byte[])); - while (reader.Read()) - { - } + byte[] data = Encoding.UTF8.GetBytes("Hello world"); - Assert.AreEqual(1, validationEventArgs.Count); - } + JsonReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(@"""" + Convert.ToBase64String(data) + @""""))) + { + Schema = s + }; + byte[] bytes = reader.ReadAsBytes(); - [Test] - public void ReadAsBytes() - { - JsonSchema s = new JsonSchemaGenerator().Generate(typeof (byte[])); + CollectionAssert.AreEquivalent(data, bytes); + } - byte[] data = Encoding.UTF8.GetBytes("Hello world"); - - JsonReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(@"""" + Convert.ToBase64String(data) + @""""))) + [Test] + public void ReadAsInt32() { - Schema = s - }; - byte[] bytes = reader.ReadAsBytes(); + JsonSchema s = new JsonSchemaGenerator().Generate(typeof(int)); - CollectionAssert.AreEquivalent(data, bytes); - } + JsonReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(@"1"))) + { + Schema = s + }; + int? i = reader.ReadAsInt32(); - [Test] - public void ReadAsInt32() - { - JsonSchema s = new JsonSchemaGenerator().Generate(typeof (int)); + Assert.AreEqual(1, i); + } - JsonReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(@"1"))) + [Test] + public void ReadAsInt32Failure() { - Schema = s - }; - int? i = reader.ReadAsInt32(); + ExceptionAssert.Throws("Integer 5 exceeds maximum value of 2. Line 1, position 1.", + () => + { + JsonSchema s = new JsonSchemaGenerator().Generate(typeof(int)); + s.Maximum = 2; - Assert.AreEqual(1, i); - } + JsonReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(@"5"))) + { + Schema = s + }; + reader.ReadAsInt32(); + }); + } - [Test] - public void ReadAsInt32Failure() - { - ExceptionAssert.Throws("Integer 5 exceeds maximum value of 2. Line 1, position 1.", - () => - { - JsonSchema s = new JsonSchemaGenerator().Generate(typeof(int)); - s.Maximum = 2; - - JsonReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(@"5"))) + [Test] + public void ReadAsDecimal() { - Schema = s - }; - reader.ReadAsInt32(); - }); - } + JsonSchema s = new JsonSchemaGenerator().Generate(typeof(decimal)); - [Test] - public void ReadAsDecimal() - { - JsonSchema s = new JsonSchemaGenerator().Generate(typeof (decimal)); + JsonReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(@"1.5"))) + { + Schema = s + }; + decimal? d = reader.ReadAsDecimal(); - JsonReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(@"1.5"))) + Assert.AreEqual(1.5m, d); + } + + [Test] + public void ReadAsDecimalFailure() { - Schema = s - }; - decimal? d = reader.ReadAsDecimal(); + ExceptionAssert.Throws("Float 5.5 is not evenly divisible by 1. Line 1, position 3.", + () => + { + JsonSchema s = new JsonSchemaGenerator().Generate(typeof(decimal)); + s.DivisibleBy = 1; - Assert.AreEqual(1.5m, d); - } + JsonReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(@"5.5"))) + { + Schema = s + }; + reader.ReadAsDecimal(); + }); + } - [Test] - public void ReadAsDecimalFailure() - { - ExceptionAssert.Throws("Float 5.5 is not evenly divisible by 1. Line 1, position 3.", - () => - { - JsonSchema s = new JsonSchemaGenerator().Generate(typeof(decimal)); - s.DivisibleBy = 1; - - JsonReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(@"5.5"))) + [Test] + public void ReadAsInt32FromSerializer() { - Schema = s - }; - reader.ReadAsDecimal(); - }); - } + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader("[1,2,3]"))); + reader.Schema = new JsonSchemaGenerator().Generate(typeof(int[])); + int[] values = new JsonSerializer().Deserialize(reader); - [Test] - public void ReadAsInt32FromSerializer() - { - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader("[1,2,3]"))); - reader.Schema = new JsonSchemaGenerator().Generate(typeof(int[])); - int[] values = new JsonSerializer().Deserialize(reader); + Assert.AreEqual(3, values.Length); + Assert.AreEqual(1, values[0]); + Assert.AreEqual(2, values[1]); + Assert.AreEqual(3, values[2]); + } - Assert.AreEqual(3, values.Length); - Assert.AreEqual(1, values[0]); - Assert.AreEqual(2, values[1]); - Assert.AreEqual(3, values[2]); - } - - [Test] - public void ReadAsInt32InArray() - { - string schemaJson = @"{ + [Test] + public void ReadAsInt32InArray() + { + string schemaJson = @"{ ""type"":""array"", ""items"":{ ""type"":""integer"" @@ -1693,35 +1690,35 @@ namespace Newtonsoft.Json.Tests ""maxItems"":1 }"; - string json = "[1,2]"; + string json = "[1,2]"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - reader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + reader.Schema = JsonSchema.Parse(schemaJson); - reader.Read(); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + reader.Read(); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - reader.ReadAsInt32(); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.AreEqual(null, validationEventArgs); + reader.ReadAsInt32(); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); + Assert.AreEqual(null, validationEventArgs); - reader.ReadAsInt32(); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.AreEqual(null, validationEventArgs); + reader.ReadAsInt32(); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); + Assert.AreEqual(null, validationEventArgs); - reader.ReadAsInt32(); - Assert.AreEqual(JsonToken.EndArray, reader.TokenType); - Assert.AreEqual("Array item count 2 exceeds maximum count of 1. Line 1, position 5.", validationEventArgs.Message); - Assert.AreEqual("", validationEventArgs.Path); - } + reader.ReadAsInt32(); + Assert.AreEqual(JsonToken.EndArray, reader.TokenType); + Assert.AreEqual("Array item count 2 exceeds maximum count of 1. Line 1, position 5.", validationEventArgs.Message); + Assert.AreEqual("", validationEventArgs.Path); + } - [Test] - public void ReadAsInt32InArrayIncomplete() - { - string schemaJson = @"{ + [Test] + public void ReadAsInt32InArrayIncomplete() + { + string schemaJson = @"{ ""type"":""array"", ""items"":{ ""type"":""integer"" @@ -1729,28 +1726,28 @@ namespace Newtonsoft.Json.Tests ""maxItems"":1 }"; - string json = "[1,2"; + string json = "[1,2"; - Json.Schema.ValidationEventArgs validationEventArgs = null; + Json.Schema.ValidationEventArgs validationEventArgs = null; - JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); - reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; - reader.Schema = JsonSchema.Parse(schemaJson); + JsonValidatingReader reader = new JsonValidatingReader(new JsonTextReader(new StringReader(json))); + reader.ValidationEventHandler += (sender, args) => { validationEventArgs = args; }; + reader.Schema = JsonSchema.Parse(schemaJson); - reader.Read(); - Assert.AreEqual(JsonToken.StartArray, reader.TokenType); + reader.Read(); + Assert.AreEqual(JsonToken.StartArray, reader.TokenType); - reader.ReadAsInt32(); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.AreEqual(null, validationEventArgs); + reader.ReadAsInt32(); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); + Assert.AreEqual(null, validationEventArgs); - reader.ReadAsInt32(); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.AreEqual(null, validationEventArgs); + reader.ReadAsInt32(); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); + Assert.AreEqual(null, validationEventArgs); - reader.ReadAsInt32(); - Assert.AreEqual(JsonToken.None, reader.TokenType); - Assert.AreEqual(null, validationEventArgs); + reader.ReadAsInt32(); + Assert.AreEqual(JsonToken.None, reader.TokenType); + Assert.AreEqual(null, validationEventArgs); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Linq/ComponentModel/BindingTests.cs b/Src/Newtonsoft.Json.Tests/Linq/ComponentModel/BindingTests.cs index 3fd6268d..a05efac8 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/ComponentModel/BindingTests.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/ComponentModel/BindingTests.cs @@ -30,46 +30,47 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Linq.ComponentModel { - [TestFixture] - public class BindingTests : TestFixtureBase - { - [Test] - public void DataBinderEval() + [TestFixture] + public class BindingTests : TestFixtureBase { - JObject o = new JObject( - new JProperty("First", "String!"), - new JProperty("Second", 12345.6789m), - new JProperty("Third", new JArray( - 1, - 2, - 3, - 4, - 5, - new JObject( - new JProperty("Fourth", "String!"), - new JProperty("Fifth", new JObject( - new JProperty("Sixth", "String!"))))))); + [Test] + public void DataBinderEval() + { + JObject o = new JObject( + new JProperty("First", "String!"), + new JProperty("Second", 12345.6789m), + new JProperty("Third", new JArray( + 1, + 2, + 3, + 4, + 5, + new JObject( + new JProperty("Fourth", "String!"), + new JProperty("Fifth", new JObject( + new JProperty("Sixth", "String!"))))))); - object value; + object value; - value = (string)DataBinder.Eval(o, "First.Value"); - Assert.AreEqual(value, (string)o["First"]); + value = (string)DataBinder.Eval(o, "First.Value"); + Assert.AreEqual(value, (string)o["First"]); - value = DataBinder.Eval(o, "Second.Value"); - Assert.AreEqual(value, (decimal)o["Second"]); + value = DataBinder.Eval(o, "Second.Value"); + Assert.AreEqual(value, (decimal)o["Second"]); - value = DataBinder.Eval(o, "Third"); - Assert.AreEqual(value, o["Third"]); + value = DataBinder.Eval(o, "Third"); + Assert.AreEqual(value, o["Third"]); - value = DataBinder.Eval(o, "Third[0].Value"); - Assert.AreEqual((int)value, (int)o["Third"][0]); + value = DataBinder.Eval(o, "Third[0].Value"); + Assert.AreEqual((int)value, (int)o["Third"][0]); - value = DataBinder.Eval(o, "Third[5].Fourth.Value"); - Assert.AreEqual(value, (string)o["Third"][5]["Fourth"]); + value = DataBinder.Eval(o, "Third[5].Fourth.Value"); + Assert.AreEqual(value, (string)o["Third"][5]["Fourth"]); - value = DataBinder.Eval(o, "Third[5].Fifth.Sixth.Value"); - Assert.AreEqual(value, (string)o["Third"][5]["Fifth"]["Sixth"]); + value = DataBinder.Eval(o, "Third[5].Fifth.Sixth.Value"); + Assert.AreEqual(value, (string)o["Third"][5]["Fifth"]["Sixth"]); + } } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Linq/ComponentModel/JPropertyDescriptorTests.cs b/Src/Newtonsoft.Json.Tests/Linq/ComponentModel/JPropertyDescriptorTests.cs index eaec5565..a9c4643a 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/ComponentModel/JPropertyDescriptorTests.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/ComponentModel/JPropertyDescriptorTests.cs @@ -29,59 +29,60 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Linq.ComponentModel { - [TestFixture] - public class JPropertyDescriptorTests : TestFixtureBase - { - [Test] - public void GetValue() + [TestFixture] + public class JPropertyDescriptorTests : TestFixtureBase { - JObject o = JObject.Parse("{prop1:'12345!',prop2:[1,'two','III']}"); + [Test] + public void GetValue() + { + JObject o = JObject.Parse("{prop1:'12345!',prop2:[1,'two','III']}"); - JPropertyDescriptor prop1 = new JPropertyDescriptor("prop1", typeof(string)); - JPropertyDescriptor prop2 = new JPropertyDescriptor("prop2", typeof(JArray)); + JPropertyDescriptor prop1 = new JPropertyDescriptor("prop1", typeof(string)); + JPropertyDescriptor prop2 = new JPropertyDescriptor("prop2", typeof(JArray)); - Assert.AreEqual("12345!", ((JValue) prop1.GetValue(o)).Value); - Assert.AreEqual(o["prop2"], prop2.GetValue(o)); + Assert.AreEqual("12345!", ((JValue)prop1.GetValue(o)).Value); + Assert.AreEqual(o["prop2"], prop2.GetValue(o)); + } + + [Test] + public void SetValue() + { + JObject o = JObject.Parse("{prop1:'12345!'}"); + + JPropertyDescriptor propertyDescriptor1 = new JPropertyDescriptor("prop1", typeof(string)); + + propertyDescriptor1.SetValue(o, "54321!"); + + Assert.AreEqual("54321!", (string)o["prop1"]); + } + + [Test] + public void ResetValue() + { + JObject o = JObject.Parse("{prop1:'12345!'}"); + + JPropertyDescriptor propertyDescriptor1 = new JPropertyDescriptor("prop1", typeof(string)); + propertyDescriptor1.ResetValue(o); + + Assert.AreEqual("12345!", (string)o["prop1"]); + } + + [Test] + public void IsReadOnly() + { + JPropertyDescriptor propertyDescriptor1 = new JPropertyDescriptor("prop1", typeof(string)); + + Assert.AreEqual(false, propertyDescriptor1.IsReadOnly); + } + + [Test] + public void PropertyType() + { + JPropertyDescriptor propertyDescriptor1 = new JPropertyDescriptor("prop1", typeof(string)); + + Assert.AreEqual(typeof(string), propertyDescriptor1.PropertyType); + } } - - [Test] - public void SetValue() - { - JObject o = JObject.Parse("{prop1:'12345!'}"); - - JPropertyDescriptor propertyDescriptor1 = new JPropertyDescriptor("prop1", typeof(string)); - - propertyDescriptor1.SetValue(o, "54321!"); - - Assert.AreEqual("54321!", (string)o["prop1"]); - } - - [Test] - public void ResetValue() - { - JObject o = JObject.Parse("{prop1:'12345!'}"); - - JPropertyDescriptor propertyDescriptor1 = new JPropertyDescriptor("prop1", typeof(string)); - propertyDescriptor1.ResetValue(o); - - Assert.AreEqual("12345!", (string)o["prop1"]); - } - - [Test] - public void IsReadOnly() - { - JPropertyDescriptor propertyDescriptor1 = new JPropertyDescriptor("prop1", typeof(string)); - - Assert.AreEqual(false, propertyDescriptor1.IsReadOnly); - } - - [Test] - public void PropertyType() - { - JPropertyDescriptor propertyDescriptor1 = new JPropertyDescriptor("prop1", typeof(string)); - - Assert.AreEqual(typeof(string), propertyDescriptor1.PropertyType); - } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Linq/DynamicTests.cs b/Src/Newtonsoft.Json.Tests/Linq/DynamicTests.cs index a8ca0041..13e55202 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/DynamicTests.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/DynamicTests.cs @@ -45,805 +45,806 @@ using System.Globalization; namespace Newtonsoft.Json.Tests.Linq { - [TestFixture] - public class DynamicTests : TestFixtureBase - { - [Test] - public void JObjectPropertyNames() + [TestFixture] + public class DynamicTests : TestFixtureBase { - JObject o = new JObject( - new JProperty("ChildValue", "blah blah")); - - dynamic d = o; - - d.First = "A value!"; - - Assert.AreEqual(new JValue("A value!"), d.First); - Assert.AreEqual("A value!", (string)d.First); - - d.First = null; - Assert.AreEqual(JTokenType.Null, d.First.Type); - - Assert.IsTrue(d.Remove("First")); - Assert.IsNull(d.First); - - JValue v1 = d.ChildValue; - JValue v2 = d["ChildValue"]; - Assert.AreEqual(v1, v2); - - JValue newValue1 = new JValue("Blah blah"); - d.NewValue = newValue1; - JValue newValue2 = d.NewValue; - - Assert.IsTrue(ReferenceEquals(newValue1, newValue2)); - } - - [Test] - public void JObjectCount() - { - JObject o = new JObject(); - - dynamic d = o; - - long? c1 = d.Count; - - o["Count"] = 99; - - long? c2 = d.Count; - - Assert.AreEqual(null, c1); - Assert.AreEqual(99, c2); - } - - [Test] - public void JObjectEnumerator() - { - JObject o = new JObject( - new JProperty("ChildValue", "blah blah")); - - dynamic d = o; - - foreach (JProperty value in d) - { - Assert.AreEqual("ChildValue", value.Name); - Assert.AreEqual("blah blah", (string)value.Value); - } - - foreach (dynamic value in d) - { - Assert.AreEqual("ChildValue", value.Name); - Assert.AreEqual("blah blah", (string)value.Value); - } - } - - [Test] - public void JObjectPropertyNameWithJArray() - { - JObject o = new JObject( - new JProperty("ChildValue", "blah blah")); - - dynamic d = o; - - d.First = new JArray(); - d.First.Add("Hi"); - - Assert.AreEqual(1, d.First.Count); - } - - [Test] - public void JObjectPropertyNameWithNonToken() - { - ExceptionAssert.Throws( - "Could not determine JSON object type for type System.String[].", - () => + [Test] + public void JObjectPropertyNames() { - dynamic d = new JObject(); + JObject o = new JObject( + new JProperty("ChildValue", "blah blah")); - d.First = new[] { "One", "II", "3" }; - }); - } + dynamic d = o; - [Test] - public void JObjectMethods() - { - JObject o = new JObject( - new JProperty("ChildValue", "blah blah")); + d.First = "A value!"; - dynamic d = o; + Assert.AreEqual(new JValue("A value!"), d.First); + Assert.AreEqual("A value!", (string)d.First); - d.Add("NewValue", 1); + d.First = null; + Assert.AreEqual(JTokenType.Null, d.First.Type); - object count = d.Count; + Assert.IsTrue(d.Remove("First")); + Assert.IsNull(d.First); - Assert.IsNull(count); - Assert.IsNull(d["Count"]); + JValue v1 = d.ChildValue; + JValue v2 = d["ChildValue"]; + Assert.AreEqual(v1, v2); - JToken v; - Assert.IsTrue(d.TryGetValue("ChildValue", out v)); - Assert.AreEqual("blah blah", (string)v); - } + JValue newValue1 = new JValue("Blah blah"); + d.NewValue = newValue1; + JValue newValue2 = d.NewValue; - [Test] - public void JValueEquals() - { - JObject o = new JObject( - new JProperty("Null", new JValue(null, JTokenType.Null)), - new JProperty("Integer", new JValue(1)), - new JProperty("Float", new JValue(1.1d)), - new JProperty("Decimal", new JValue(1.1m)), - new JProperty("DateTime", new JValue(new DateTime(2000, 12, 29, 23, 51, 10, DateTimeKind.Utc))), - new JProperty("Boolean", new JValue(true)), - new JProperty("String", new JValue("A string lol!")), - new JProperty("Bytes", new JValue(Encoding.UTF8.GetBytes("A string lol!"))), - new JProperty("Uri", new Uri("http://json.codeplex.com/")), - new JProperty("Guid", new Guid("EA27FE1D-0D80-44F2-BF34-4654156FA7AF")), - new JProperty("TimeSpan", TimeSpan.FromDays(1)) + Assert.IsTrue(ReferenceEquals(newValue1, newValue2)); + } + + [Test] + public void JObjectCount() + { + JObject o = new JObject(); + + dynamic d = o; + + long? c1 = d.Count; + + o["Count"] = 99; + + long? c2 = d.Count; + + Assert.AreEqual(null, c1); + Assert.AreEqual(99, c2); + } + + [Test] + public void JObjectEnumerator() + { + JObject o = new JObject( + new JProperty("ChildValue", "blah blah")); + + dynamic d = o; + + foreach (JProperty value in d) + { + Assert.AreEqual("ChildValue", value.Name); + Assert.AreEqual("blah blah", (string)value.Value); + } + + foreach (dynamic value in d) + { + Assert.AreEqual("ChildValue", value.Name); + Assert.AreEqual("blah blah", (string)value.Value); + } + } + + [Test] + public void JObjectPropertyNameWithJArray() + { + JObject o = new JObject( + new JProperty("ChildValue", "blah blah")); + + dynamic d = o; + + d.First = new JArray(); + d.First.Add("Hi"); + + Assert.AreEqual(1, d.First.Count); + } + + [Test] + public void JObjectPropertyNameWithNonToken() + { + ExceptionAssert.Throws( + "Could not determine JSON object type for type System.String[].", + () => + { + dynamic d = new JObject(); + + d.First = new[] { "One", "II", "3" }; + }); + } + + [Test] + public void JObjectMethods() + { + JObject o = new JObject( + new JProperty("ChildValue", "blah blah")); + + dynamic d = o; + + d.Add("NewValue", 1); + + object count = d.Count; + + Assert.IsNull(count); + Assert.IsNull(d["Count"]); + + JToken v; + Assert.IsTrue(d.TryGetValue("ChildValue", out v)); + Assert.AreEqual("blah blah", (string)v); + } + + [Test] + public void JValueEquals() + { + JObject o = new JObject( + new JProperty("Null", new JValue(null, JTokenType.Null)), + new JProperty("Integer", new JValue(1)), + new JProperty("Float", new JValue(1.1d)), + new JProperty("Decimal", new JValue(1.1m)), + new JProperty("DateTime", new JValue(new DateTime(2000, 12, 29, 23, 51, 10, DateTimeKind.Utc))), + new JProperty("Boolean", new JValue(true)), + new JProperty("String", new JValue("A string lol!")), + new JProperty("Bytes", new JValue(Encoding.UTF8.GetBytes("A string lol!"))), + new JProperty("Uri", new Uri("http://json.codeplex.com/")), + new JProperty("Guid", new Guid("EA27FE1D-0D80-44F2-BF34-4654156FA7AF")), + new JProperty("TimeSpan", TimeSpan.FromDays(1)) #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE) - ,new JProperty("BigInteger", BigInteger.Parse("1")) + , new JProperty("BigInteger", BigInteger.Parse("1")) #endif - ); + ); - dynamic d = o; + dynamic d = o; - Assert.IsTrue(d.Null == d.Null); - Assert.IsTrue(d.Null == null); - Assert.IsTrue(d.Null == new JValue(null, JTokenType.Null)); - Assert.IsFalse(d.Null == 1); + Assert.IsTrue(d.Null == d.Null); + Assert.IsTrue(d.Null == null); + Assert.IsTrue(d.Null == new JValue(null, JTokenType.Null)); + Assert.IsFalse(d.Null == 1); - Assert.IsTrue(d.Integer == d.Integer); - Assert.IsTrue(d.Integer > 0); - Assert.IsTrue(d.Integer > 0.0m); - Assert.IsTrue(d.Integer > 0.0f); - Assert.IsTrue(d.Integer > null); - Assert.IsTrue(d.Integer >= null); - Assert.IsTrue(d.Integer == 1); - Assert.IsTrue(d.Integer == 1m); - Assert.IsTrue(d.Integer != 1.1f); - Assert.IsTrue(d.Integer != 1.1d); + Assert.IsTrue(d.Integer == d.Integer); + Assert.IsTrue(d.Integer > 0); + Assert.IsTrue(d.Integer > 0.0m); + Assert.IsTrue(d.Integer > 0.0f); + Assert.IsTrue(d.Integer > null); + Assert.IsTrue(d.Integer >= null); + Assert.IsTrue(d.Integer == 1); + Assert.IsTrue(d.Integer == 1m); + Assert.IsTrue(d.Integer != 1.1f); + Assert.IsTrue(d.Integer != 1.1d); - Assert.IsTrue(d.Decimal == d.Decimal); - Assert.IsTrue(d.Decimal > 0); - Assert.IsTrue(d.Decimal > 0.0m); - Assert.IsTrue(d.Decimal > 0.0f); - Assert.IsTrue(d.Decimal > null); - Assert.IsTrue(d.Decimal >= null); - Assert.IsTrue(d.Decimal == 1.1); - Assert.IsTrue(d.Decimal == 1.1m); - Assert.IsTrue(d.Decimal != 1.0f); - Assert.IsTrue(d.Decimal != 1.0d); + Assert.IsTrue(d.Decimal == d.Decimal); + Assert.IsTrue(d.Decimal > 0); + Assert.IsTrue(d.Decimal > 0.0m); + Assert.IsTrue(d.Decimal > 0.0f); + Assert.IsTrue(d.Decimal > null); + Assert.IsTrue(d.Decimal >= null); + Assert.IsTrue(d.Decimal == 1.1); + Assert.IsTrue(d.Decimal == 1.1m); + Assert.IsTrue(d.Decimal != 1.0f); + Assert.IsTrue(d.Decimal != 1.0d); #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE) - Assert.IsTrue(d.Decimal > new BigInteger(0)); + Assert.IsTrue(d.Decimal > new BigInteger(0)); #endif - Assert.IsTrue(d.Float == d.Float); - Assert.IsTrue(d.Float > 0); - Assert.IsTrue(d.Float > 0.0m); - Assert.IsTrue(d.Float > 0.0f); - Assert.IsTrue(d.Float > null); - Assert.IsTrue(d.Float >= null); - Assert.IsTrue(d.Float < 2); - Assert.IsTrue(d.Float <= 1.1); - Assert.IsTrue(d.Float == 1.1); - Assert.IsTrue(d.Float == 1.1m); - Assert.IsTrue(d.Float != 1.0f); - Assert.IsTrue(d.Float != 1.0d); + Assert.IsTrue(d.Float == d.Float); + Assert.IsTrue(d.Float > 0); + Assert.IsTrue(d.Float > 0.0m); + Assert.IsTrue(d.Float > 0.0f); + Assert.IsTrue(d.Float > null); + Assert.IsTrue(d.Float >= null); + Assert.IsTrue(d.Float < 2); + Assert.IsTrue(d.Float <= 1.1); + Assert.IsTrue(d.Float == 1.1); + Assert.IsTrue(d.Float == 1.1m); + Assert.IsTrue(d.Float != 1.0f); + Assert.IsTrue(d.Float != 1.0d); #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE) - Assert.IsTrue(d.Float > new BigInteger(0)); + Assert.IsTrue(d.Float > new BigInteger(0)); #endif #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE) - Assert.IsTrue(d.BigInteger == d.BigInteger); - Assert.IsTrue(d.BigInteger > 0); - Assert.IsTrue(d.BigInteger > 0.0m); - Assert.IsTrue(d.BigInteger > 0.0f); - Assert.IsTrue(d.BigInteger > null); - Assert.IsTrue(d.BigInteger >= null); - Assert.IsTrue(d.BigInteger < 2); - Assert.IsTrue(d.BigInteger <= 1.1); - Assert.IsTrue(d.BigInteger == 1); - Assert.IsTrue(d.BigInteger == 1m); - Assert.IsTrue(d.BigInteger != 1.1f); - Assert.IsTrue(d.BigInteger != 1.1d); + Assert.IsTrue(d.BigInteger == d.BigInteger); + Assert.IsTrue(d.BigInteger > 0); + Assert.IsTrue(d.BigInteger > 0.0m); + Assert.IsTrue(d.BigInteger > 0.0f); + Assert.IsTrue(d.BigInteger > null); + Assert.IsTrue(d.BigInteger >= null); + Assert.IsTrue(d.BigInteger < 2); + Assert.IsTrue(d.BigInteger <= 1.1); + Assert.IsTrue(d.BigInteger == 1); + Assert.IsTrue(d.BigInteger == 1m); + Assert.IsTrue(d.BigInteger != 1.1f); + Assert.IsTrue(d.BigInteger != 1.1d); #endif - Assert.IsTrue(d.Bytes == d.Bytes); - Assert.IsTrue(d.Bytes == Encoding.UTF8.GetBytes("A string lol!")); - Assert.IsTrue(d.Bytes == new JValue(Encoding.UTF8.GetBytes("A string lol!"))); + Assert.IsTrue(d.Bytes == d.Bytes); + Assert.IsTrue(d.Bytes == Encoding.UTF8.GetBytes("A string lol!")); + Assert.IsTrue(d.Bytes == new JValue(Encoding.UTF8.GetBytes("A string lol!"))); - Assert.IsTrue(d.Uri == d.Uri); - Assert.IsTrue(d.Uri == new Uri("http://json.codeplex.com/")); - Assert.IsTrue(d.Uri > new Uri("http://abc.org/")); - Assert.IsTrue(d.Uri >= new Uri("http://abc.com/")); - Assert.IsTrue(d.Uri > null); - Assert.IsTrue(d.Uri >= null); + Assert.IsTrue(d.Uri == d.Uri); + Assert.IsTrue(d.Uri == new Uri("http://json.codeplex.com/")); + Assert.IsTrue(d.Uri > new Uri("http://abc.org/")); + Assert.IsTrue(d.Uri >= new Uri("http://abc.com/")); + Assert.IsTrue(d.Uri > null); + Assert.IsTrue(d.Uri >= null); - Assert.IsTrue(d.Guid == d.Guid); - Assert.IsTrue(d.Guid == new Guid("EA27FE1D-0D80-44F2-BF34-4654156FA7AF")); - Assert.IsTrue(d.Guid > new Guid("AAAAAAAA-0D80-44F2-BF34-4654156FA7AF")); - Assert.IsTrue(d.Guid >= new Guid("AAAAAAAA-0D80-44F2-BF34-4654156FA7AF")); - Assert.IsTrue(d.Guid > null); - Assert.IsTrue(d.Guid >= null); + Assert.IsTrue(d.Guid == d.Guid); + Assert.IsTrue(d.Guid == new Guid("EA27FE1D-0D80-44F2-BF34-4654156FA7AF")); + Assert.IsTrue(d.Guid > new Guid("AAAAAAAA-0D80-44F2-BF34-4654156FA7AF")); + Assert.IsTrue(d.Guid >= new Guid("AAAAAAAA-0D80-44F2-BF34-4654156FA7AF")); + Assert.IsTrue(d.Guid > null); + Assert.IsTrue(d.Guid >= null); - Assert.IsTrue(d.TimeSpan == d.TimeSpan); - Assert.IsTrue(d.TimeSpan == TimeSpan.FromDays(1)); - Assert.IsTrue(d.TimeSpan > TimeSpan.FromHours(1)); - Assert.IsTrue(d.TimeSpan >= TimeSpan.FromHours(1)); - Assert.IsTrue(d.TimeSpan > null); - Assert.IsTrue(d.TimeSpan >= null); - } + Assert.IsTrue(d.TimeSpan == d.TimeSpan); + Assert.IsTrue(d.TimeSpan == TimeSpan.FromDays(1)); + Assert.IsTrue(d.TimeSpan > TimeSpan.FromHours(1)); + Assert.IsTrue(d.TimeSpan >= TimeSpan.FromHours(1)); + Assert.IsTrue(d.TimeSpan > null); + Assert.IsTrue(d.TimeSpan >= null); + } - [Test] - public void JValueAddition() - { - JObject o = new JObject( - new JProperty("Null", new JValue(null, JTokenType.Null)), - new JProperty("Integer", new JValue(1)), - new JProperty("Float", new JValue(1.1d)), - new JProperty("Decimal", new JValue(1.1m)), - new JProperty("DateTime", new JValue(new DateTime(2000, 12, 29, 23, 51, 10, DateTimeKind.Utc))), - new JProperty("Boolean", new JValue(true)), - new JProperty("String", new JValue("A string lol!")), - new JProperty("Bytes", new JValue(Encoding.UTF8.GetBytes("A string lol!"))), - new JProperty("Uri", new Uri("http://json.codeplex.com/")), - new JProperty("Guid", new Guid("EA27FE1D-0D80-44F2-BF34-4654156FA7AF")), - new JProperty("TimeSpan", TimeSpan.FromDays(1)) + [Test] + public void JValueAddition() + { + JObject o = new JObject( + new JProperty("Null", new JValue(null, JTokenType.Null)), + new JProperty("Integer", new JValue(1)), + new JProperty("Float", new JValue(1.1d)), + new JProperty("Decimal", new JValue(1.1m)), + new JProperty("DateTime", new JValue(new DateTime(2000, 12, 29, 23, 51, 10, DateTimeKind.Utc))), + new JProperty("Boolean", new JValue(true)), + new JProperty("String", new JValue("A string lol!")), + new JProperty("Bytes", new JValue(Encoding.UTF8.GetBytes("A string lol!"))), + new JProperty("Uri", new Uri("http://json.codeplex.com/")), + new JProperty("Guid", new Guid("EA27FE1D-0D80-44F2-BF34-4654156FA7AF")), + new JProperty("TimeSpan", TimeSpan.FromDays(1)) #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE) - ,new JProperty("BigInteger", new BigInteger(100)) + , new JProperty("BigInteger", new BigInteger(100)) #endif - ); + ); - dynamic d = o; - dynamic r; + dynamic d = o; + dynamic r; - #region Add - r = d.String + " LAMO!"; - Assert.AreEqual("A string lol! LAMO!", (string)r); - r += " gg"; - Assert.AreEqual("A string lol! LAMO! gg", (string)r); + #region Add + r = d.String + " LAMO!"; + Assert.AreEqual("A string lol! LAMO!", (string)r); + r += " gg"; + Assert.AreEqual("A string lol! LAMO! gg", (string)r); - r = d.String + null; - Assert.AreEqual("A string lol!", (string)r); - r += null; - Assert.AreEqual("A string lol!", (string)r); + r = d.String + null; + Assert.AreEqual("A string lol!", (string)r); + r += null; + Assert.AreEqual("A string lol!", (string)r); - r = d.Integer + 1; - Assert.AreEqual(2, (int)r); - r += 2; - Assert.AreEqual(4, (int)r); + r = d.Integer + 1; + Assert.AreEqual(2, (int)r); + r += 2; + Assert.AreEqual(4, (int)r); - r = d.Integer + 1.1; - Assert.AreEqual(2.1, (double)r); - r += 2; - Assert.AreEqual(4.1, (double)r); + r = d.Integer + 1.1; + Assert.AreEqual(2.1, (double)r); + r += 2; + Assert.AreEqual(4.1, (double)r); - r = d.Integer + 1.1d; - Assert.AreEqual(2.1m, (decimal)r); - r += 2; - Assert.AreEqual(4.1m, (decimal)r); + r = d.Integer + 1.1d; + Assert.AreEqual(2.1m, (decimal)r); + r += 2; + Assert.AreEqual(4.1m, (decimal)r); - r = d.Integer + null; - Assert.AreEqual(null, r.Value); - r += 2; - Assert.AreEqual(null, r.Value); + r = d.Integer + null; + Assert.AreEqual(null, r.Value); + r += 2; + Assert.AreEqual(null, r.Value); - r = d.Float + 1; - Assert.AreEqual(2.1d, (double)r); - r += 2; - Assert.AreEqual(4.1d, (double)r); + r = d.Float + 1; + Assert.AreEqual(2.1d, (double)r); + r += 2; + Assert.AreEqual(4.1d, (double)r); - r = d.Float + 1.1; - Assert.AreEqual(2.2d, (double)r); - r += 2; - Assert.AreEqual(4.2d, (double)r); + r = d.Float + 1.1; + Assert.AreEqual(2.2d, (double)r); + r += 2; + Assert.AreEqual(4.2d, (double)r); - r = d.Float + 1.1d; - Assert.AreEqual(2.2m, (decimal)r); - r += 2; - Assert.AreEqual(4.2m, (decimal)r); + r = d.Float + 1.1d; + Assert.AreEqual(2.2m, (decimal)r); + r += 2; + Assert.AreEqual(4.2m, (decimal)r); - r = d.Float + null; - Assert.AreEqual(null, r.Value); - r += 2; - Assert.AreEqual(null, r.Value); + r = d.Float + null; + Assert.AreEqual(null, r.Value); + r += 2; + Assert.AreEqual(null, r.Value); - r = d.Decimal + 1; - Assert.AreEqual(2.1m, (decimal)r); - r += 2; - Assert.AreEqual(4.1m, (decimal)r); + r = d.Decimal + 1; + Assert.AreEqual(2.1m, (decimal)r); + r += 2; + Assert.AreEqual(4.1m, (decimal)r); - r = d.Decimal + 1.1; - Assert.AreEqual(2.2m, (decimal)r); - r += 2; - Assert.AreEqual(4.2m, (decimal)r); + r = d.Decimal + 1.1; + Assert.AreEqual(2.2m, (decimal)r); + r += 2; + Assert.AreEqual(4.2m, (decimal)r); - r = d.Decimal + 1.1d; - Assert.AreEqual(2.2m, (decimal)r); - r += 2; - Assert.AreEqual(4.2m, (decimal)r); + r = d.Decimal + 1.1d; + Assert.AreEqual(2.2m, (decimal)r); + r += 2; + Assert.AreEqual(4.2m, (decimal)r); - r = d.Decimal + null; - Assert.AreEqual(null, r.Value); - r += 2; - Assert.AreEqual(null, r.Value); + r = d.Decimal + null; + Assert.AreEqual(null, r.Value); + r += 2; + Assert.AreEqual(null, r.Value); #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE) - r = d.BigInteger + null; - Assert.AreEqual(null, r.Value); - r += 2; - Assert.AreEqual(null, r.Value); + r = d.BigInteger + null; + Assert.AreEqual(null, r.Value); + r += 2; + Assert.AreEqual(null, r.Value); - r = d.BigInteger + 1; - Assert.AreEqual(101, (int)r); - r += 2; - Assert.AreEqual(103, (int)r); + r = d.BigInteger + 1; + Assert.AreEqual(101, (int)r); + r += 2; + Assert.AreEqual(103, (int)r); - r = d.BigInteger + 1.1d; - Assert.AreEqual(101m, (decimal)r); - r += 2; - Assert.AreEqual(103m, (decimal)r); + r = d.BigInteger + 1.1d; + Assert.AreEqual(101m, (decimal)r); + r += 2; + Assert.AreEqual(103m, (decimal)r); #endif - #endregion + #endregion - #region Subtract - r = d.Integer - 1; - Assert.AreEqual(0, (int)r); - r -= 2; - Assert.AreEqual(-2, (int)r); + #region Subtract + r = d.Integer - 1; + Assert.AreEqual(0, (int)r); + r -= 2; + Assert.AreEqual(-2, (int)r); - r = d.Integer - 1.1; - Assert.AreEqual(-0.1d, (double)r, 0.00001); - r -= 2; - Assert.AreEqual(-2.1d, (double)r); + r = d.Integer - 1.1; + Assert.AreEqual(-0.1d, (double)r, 0.00001); + r -= 2; + Assert.AreEqual(-2.1d, (double)r); - r = d.Integer - 1.1d; - Assert.AreEqual(-0.1m, (decimal)r); - r -= 2; - Assert.AreEqual(-2.1m, (decimal)r); + r = d.Integer - 1.1d; + Assert.AreEqual(-0.1m, (decimal)r); + r -= 2; + Assert.AreEqual(-2.1m, (decimal)r); - r = d.Integer - null; - Assert.AreEqual(null, r.Value); - r -= 2; - Assert.AreEqual(null, r.Value); + r = d.Integer - null; + Assert.AreEqual(null, r.Value); + r -= 2; + Assert.AreEqual(null, r.Value); - r = d.Float - 1; - Assert.AreEqual(0.1d, (double)r, 0.00001); - r -= 2; - Assert.AreEqual(-1.9d, (double)r); + r = d.Float - 1; + Assert.AreEqual(0.1d, (double)r, 0.00001); + r -= 2; + Assert.AreEqual(-1.9d, (double)r); - r = d.Float - 1.1; - Assert.AreEqual(0d, (double)r); - r -= 2; - Assert.AreEqual(-2d, (double)r); + r = d.Float - 1.1; + Assert.AreEqual(0d, (double)r); + r -= 2; + Assert.AreEqual(-2d, (double)r); - r = d.Float - 1.1d; - Assert.AreEqual(0m, (decimal)r); - r -= 2; - Assert.AreEqual(-2m, (decimal)r); + r = d.Float - 1.1d; + Assert.AreEqual(0m, (decimal)r); + r -= 2; + Assert.AreEqual(-2m, (decimal)r); - r = d.Float - null; - Assert.AreEqual(null, r.Value); - r -= 2; - Assert.AreEqual(null, r.Value); + r = d.Float - null; + Assert.AreEqual(null, r.Value); + r -= 2; + Assert.AreEqual(null, r.Value); - r = d.Decimal - 1; - Assert.AreEqual(0.1m, (decimal)r); - r -= 2; - Assert.AreEqual(-1.9m, (decimal)r); + r = d.Decimal - 1; + Assert.AreEqual(0.1m, (decimal)r); + r -= 2; + Assert.AreEqual(-1.9m, (decimal)r); - r = d.Decimal - 1.1; - Assert.AreEqual(0m, (decimal)r); - r -= 2; - Assert.AreEqual(-2m, (decimal)r); + r = d.Decimal - 1.1; + Assert.AreEqual(0m, (decimal)r); + r -= 2; + Assert.AreEqual(-2m, (decimal)r); - r = d.Decimal - 1.1d; - Assert.AreEqual(0m, (decimal)r); - r -= 2; - Assert.AreEqual(-2m, (decimal)r); + r = d.Decimal - 1.1d; + Assert.AreEqual(0m, (decimal)r); + r -= 2; + Assert.AreEqual(-2m, (decimal)r); - r = d.Decimal - null; - Assert.AreEqual(null, r.Value); - r -= 2; - Assert.AreEqual(null, r.Value); + r = d.Decimal - null; + Assert.AreEqual(null, r.Value); + r -= 2; + Assert.AreEqual(null, r.Value); #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE) - r = d.BigInteger - null; - Assert.AreEqual(null, r.Value); - r -= 2; - Assert.AreEqual(null, r.Value); + r = d.BigInteger - null; + Assert.AreEqual(null, r.Value); + r -= 2; + Assert.AreEqual(null, r.Value); - r = d.BigInteger - 1.1d; - Assert.AreEqual(99m, (decimal)r); - r -= 2; - Assert.AreEqual(97m, (decimal)r); + r = d.BigInteger - 1.1d; + Assert.AreEqual(99m, (decimal)r); + r -= 2; + Assert.AreEqual(97m, (decimal)r); #endif - #endregion + #endregion - #region Multiply - r = d.Integer * 1; - Assert.AreEqual(1, (int)r); - r *= 2; - Assert.AreEqual(2, (int)r); + #region Multiply + r = d.Integer * 1; + Assert.AreEqual(1, (int)r); + r *= 2; + Assert.AreEqual(2, (int)r); - r = d.Integer * 1.1; - Assert.AreEqual(1.1d, (double)r); - r *= 2; - Assert.AreEqual(2.2d, (double)r); + r = d.Integer * 1.1; + Assert.AreEqual(1.1d, (double)r); + r *= 2; + Assert.AreEqual(2.2d, (double)r); - r = d.Integer * 1.1d; - Assert.AreEqual(1.1m, (decimal)r); - r *= 2; - Assert.AreEqual(2.2m, (decimal)r); + r = d.Integer * 1.1d; + Assert.AreEqual(1.1m, (decimal)r); + r *= 2; + Assert.AreEqual(2.2m, (decimal)r); - r = d.Integer * null; - Assert.AreEqual(null, r.Value); - r *= 2; - Assert.AreEqual(null, r.Value); + r = d.Integer * null; + Assert.AreEqual(null, r.Value); + r *= 2; + Assert.AreEqual(null, r.Value); - r = d.Float * 1; - Assert.AreEqual(1.1d, (double)r); - r *= 2; - Assert.AreEqual(2.2d, (double)r); + r = d.Float * 1; + Assert.AreEqual(1.1d, (double)r); + r *= 2; + Assert.AreEqual(2.2d, (double)r); - r = d.Float * 1.1; - Assert.AreEqual(1.21d, (double)r, 0.00001); - r *= 2; - Assert.AreEqual(2.42d, (double)r, 0.00001); + r = d.Float * 1.1; + Assert.AreEqual(1.21d, (double)r, 0.00001); + r *= 2; + Assert.AreEqual(2.42d, (double)r, 0.00001); - r = d.Float * 1.1d; - Assert.AreEqual(1.21m, (decimal)r); - r *= 2; - Assert.AreEqual(2.42m, (decimal)r); + r = d.Float * 1.1d; + Assert.AreEqual(1.21m, (decimal)r); + r *= 2; + Assert.AreEqual(2.42m, (decimal)r); - r = d.Float * null; - Assert.AreEqual(null, r.Value); - r *= 2; - Assert.AreEqual(null, r.Value); + r = d.Float * null; + Assert.AreEqual(null, r.Value); + r *= 2; + Assert.AreEqual(null, r.Value); - r = d.Decimal * 1; - Assert.AreEqual(1.1m, (decimal)r); - r *= 2; - Assert.AreEqual(2.2m, (decimal)r); + r = d.Decimal * 1; + Assert.AreEqual(1.1m, (decimal)r); + r *= 2; + Assert.AreEqual(2.2m, (decimal)r); - r = d.Decimal * 1.1; - Assert.AreEqual(1.21m, (decimal)r); - r *= 2; - Assert.AreEqual(2.42m, (decimal)r); + r = d.Decimal * 1.1; + Assert.AreEqual(1.21m, (decimal)r); + r *= 2; + Assert.AreEqual(2.42m, (decimal)r); - r = d.Decimal * 1.1d; - Assert.AreEqual(1.21m, (decimal)r); - r *= 2; - Assert.AreEqual(2.42m, (decimal)r); + r = d.Decimal * 1.1d; + Assert.AreEqual(1.21m, (decimal)r); + r *= 2; + Assert.AreEqual(2.42m, (decimal)r); - r = d.Decimal * null; - Assert.AreEqual(null, r.Value); - r *= 2; - Assert.AreEqual(null, r.Value); + r = d.Decimal * null; + Assert.AreEqual(null, r.Value); + r *= 2; + Assert.AreEqual(null, r.Value); #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE) - r = d.BigInteger * 1.1d; - Assert.AreEqual(100m, (decimal)r); - r *= 2; - Assert.AreEqual(200m, (decimal)r); + r = d.BigInteger * 1.1d; + Assert.AreEqual(100m, (decimal)r); + r *= 2; + Assert.AreEqual(200m, (decimal)r); - r = d.BigInteger * null; - Assert.AreEqual(null, r.Value); - r *= 2; - Assert.AreEqual(null, r.Value); + r = d.BigInteger * null; + Assert.AreEqual(null, r.Value); + r *= 2; + Assert.AreEqual(null, r.Value); #endif - #endregion + #endregion - #region Divide - r = d.Integer / 1; - Assert.AreEqual(1, (int)r); - r /= 2; - Assert.AreEqual(0, (int)r); + #region Divide + r = d.Integer / 1; + Assert.AreEqual(1, (int)r); + r /= 2; + Assert.AreEqual(0, (int)r); - r = d.Integer / 1.1; - Assert.AreEqual(0.9090909090909091d, (double)r); - r /= 2; - Assert.AreEqual(0.454545454545455d, (double)r, 0.00001); + r = d.Integer / 1.1; + Assert.AreEqual(0.9090909090909091d, (double)r); + r /= 2; + Assert.AreEqual(0.454545454545455d, (double)r, 0.00001); - r = d.Integer / 1.1d; - Assert.AreEqual(0.909090909090909m, (decimal)r); - r /= 2; - Assert.AreEqual(0.454545454545454m, (decimal)r); + r = d.Integer / 1.1d; + Assert.AreEqual(0.909090909090909m, (decimal)r); + r /= 2; + Assert.AreEqual(0.454545454545454m, (decimal)r); - r = d.Integer / null; - Assert.AreEqual(null, r.Value); - r /= 2; - Assert.AreEqual(null, r.Value); + r = d.Integer / null; + Assert.AreEqual(null, r.Value); + r /= 2; + Assert.AreEqual(null, r.Value); - r = d.Float / 1; - Assert.AreEqual(1.1d, (double)r); - r /= 2; - Assert.AreEqual(0.55d, (double)r); + r = d.Float / 1; + Assert.AreEqual(1.1d, (double)r); + r /= 2; + Assert.AreEqual(0.55d, (double)r); - r = d.Float / 1.1; - Assert.AreEqual(1d, (double)r, 0.00001); - r /= 2; - Assert.AreEqual(0.5d, (double)r, 0.00001); + r = d.Float / 1.1; + Assert.AreEqual(1d, (double)r, 0.00001); + r /= 2; + Assert.AreEqual(0.5d, (double)r, 0.00001); - r = d.Float / 1.1d; - Assert.AreEqual(1m, (decimal)r); - r /= 2; - Assert.AreEqual(0.5m, (decimal)r); + r = d.Float / 1.1d; + Assert.AreEqual(1m, (decimal)r); + r /= 2; + Assert.AreEqual(0.5m, (decimal)r); - r = d.Float / null; - Assert.AreEqual(null, r.Value); - r /= 2; - Assert.AreEqual(null, r.Value); + r = d.Float / null; + Assert.AreEqual(null, r.Value); + r /= 2; + Assert.AreEqual(null, r.Value); - r = d.Decimal / 1; - Assert.AreEqual(1.1m, (decimal)r); - r /= 2; - Assert.AreEqual(0.55m, (decimal)r); + r = d.Decimal / 1; + Assert.AreEqual(1.1m, (decimal)r); + r /= 2; + Assert.AreEqual(0.55m, (decimal)r); - r = d.Decimal / 1.1; - Assert.AreEqual(1m, (decimal)r); - r /= 2; - Assert.AreEqual(0.5m, (decimal)r); + r = d.Decimal / 1.1; + Assert.AreEqual(1m, (decimal)r); + r /= 2; + Assert.AreEqual(0.5m, (decimal)r); - r = d.Decimal / 1.1d; - Assert.AreEqual(1m, (decimal)r); - r /= 2; - Assert.AreEqual(0.5m, (decimal)r); + r = d.Decimal / 1.1d; + Assert.AreEqual(1m, (decimal)r); + r /= 2; + Assert.AreEqual(0.5m, (decimal)r); - r = d.Decimal / null; - Assert.AreEqual(null, r.Value); - r /= 2; - Assert.AreEqual(null, r.Value); + r = d.Decimal / null; + Assert.AreEqual(null, r.Value); + r /= 2; + Assert.AreEqual(null, r.Value); #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE) - r = d.BigInteger / 1.1d; - Assert.AreEqual(100m, (decimal)r); - r /= 2; - Assert.AreEqual(50m, (decimal)r); + r = d.BigInteger / 1.1d; + Assert.AreEqual(100m, (decimal)r); + r /= 2; + Assert.AreEqual(50m, (decimal)r); - r = d.BigInteger / null; - Assert.AreEqual(null, r.Value); - r /= 2; - Assert.AreEqual(null, r.Value); + r = d.BigInteger / null; + Assert.AreEqual(null, r.Value); + r /= 2; + Assert.AreEqual(null, r.Value); #endif - #endregion - } + #endregion + } - [Test] - public void JValueToString() - { - JObject o = new JObject( - new JProperty("Null", new JValue(null, JTokenType.Null)), - new JProperty("Integer", new JValue(1)), - new JProperty("Float", new JValue(1.1)), - new JProperty("DateTime", new JValue(new DateTime(2000, 12, 29, 23, 51, 10, DateTimeKind.Utc))), - new JProperty("Boolean", new JValue(true)), - new JProperty("String", new JValue("A string lol!")), - new JProperty("Bytes", new JValue(Encoding.UTF8.GetBytes("A string lol!"))), - new JProperty("Uri", new Uri("http://json.codeplex.com/")), - new JProperty("Guid", new Guid("EA27FE1D-0D80-44F2-BF34-4654156FA7AF")), - new JProperty("TimeSpan", TimeSpan.FromDays(1)) + [Test] + public void JValueToString() + { + JObject o = new JObject( + new JProperty("Null", new JValue(null, JTokenType.Null)), + new JProperty("Integer", new JValue(1)), + new JProperty("Float", new JValue(1.1)), + new JProperty("DateTime", new JValue(new DateTime(2000, 12, 29, 23, 51, 10, DateTimeKind.Utc))), + new JProperty("Boolean", new JValue(true)), + new JProperty("String", new JValue("A string lol!")), + new JProperty("Bytes", new JValue(Encoding.UTF8.GetBytes("A string lol!"))), + new JProperty("Uri", new Uri("http://json.codeplex.com/")), + new JProperty("Guid", new Guid("EA27FE1D-0D80-44F2-BF34-4654156FA7AF")), + new JProperty("TimeSpan", TimeSpan.FromDays(1)) #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE) - ,new JProperty("BigInteger", new BigInteger(100)) + , new JProperty("BigInteger", new BigInteger(100)) #endif - ); + ); - dynamic d = o; + dynamic d = o; - Assert.AreEqual("", d.Null.ToString()); - Assert.AreEqual("1", d.Integer.ToString()); - Assert.AreEqual("1.1", d.Float.ToString(CultureInfo.InvariantCulture)); - Assert.AreEqual("12/29/2000 23:51:10", d.DateTime.ToString(null, CultureInfo.InvariantCulture)); - Assert.AreEqual("True", d.Boolean.ToString()); - Assert.AreEqual("A string lol!", d.String.ToString()); - Assert.AreEqual("System.Byte[]", d.Bytes.ToString()); - Assert.AreEqual("http://json.codeplex.com/", d.Uri.ToString()); - Assert.AreEqual("ea27fe1d-0d80-44f2-bf34-4654156fa7af", d.Guid.ToString()); - Assert.AreEqual("1.00:00:00", d.TimeSpan.ToString()); + Assert.AreEqual("", d.Null.ToString()); + Assert.AreEqual("1", d.Integer.ToString()); + Assert.AreEqual("1.1", d.Float.ToString(CultureInfo.InvariantCulture)); + Assert.AreEqual("12/29/2000 23:51:10", d.DateTime.ToString(null, CultureInfo.InvariantCulture)); + Assert.AreEqual("True", d.Boolean.ToString()); + Assert.AreEqual("A string lol!", d.String.ToString()); + Assert.AreEqual("System.Byte[]", d.Bytes.ToString()); + Assert.AreEqual("http://json.codeplex.com/", d.Uri.ToString()); + Assert.AreEqual("ea27fe1d-0d80-44f2-bf34-4654156fa7af", d.Guid.ToString()); + Assert.AreEqual("1.00:00:00", d.TimeSpan.ToString()); #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE) - Assert.AreEqual("100", d.BigInteger.ToString()); + Assert.AreEqual("100", d.BigInteger.ToString()); #endif - } + } - [Test] - public void JObjectGetDynamicPropertyNames() - { - JObject o = new JObject( - new JProperty("ChildValue", "blah blah"), - new JProperty("Hello Joe", null)); + [Test] + public void JObjectGetDynamicPropertyNames() + { + JObject o = new JObject( + new JProperty("ChildValue", "blah blah"), + new JProperty("Hello Joe", null)); - dynamic d = o; + dynamic d = o; - List memberNames = o.GetDynamicMemberNames().ToList(); + List memberNames = o.GetDynamicMemberNames().ToList(); - Assert.AreEqual(2, memberNames.Count); - Assert.AreEqual("ChildValue", memberNames[0]); - Assert.AreEqual("Hello Joe", memberNames[1]); + Assert.AreEqual(2, memberNames.Count); + Assert.AreEqual("ChildValue", memberNames[0]); + Assert.AreEqual("Hello Joe", memberNames[1]); - o = new JObject( - new JProperty("ChildValue1", "blah blah"), - new JProperty("Hello Joe1", null)); + o = new JObject( + new JProperty("ChildValue1", "blah blah"), + new JProperty("Hello Joe1", null)); - d = o; + d = o; - memberNames = o.GetDynamicMemberNames().ToList(); + memberNames = o.GetDynamicMemberNames().ToList(); - Assert.AreEqual(2, memberNames.Count); - Assert.AreEqual("ChildValue1", memberNames[0]); - Assert.AreEqual("Hello Joe1", memberNames[1]); - } + Assert.AreEqual(2, memberNames.Count); + Assert.AreEqual("ChildValue1", memberNames[0]); + Assert.AreEqual("Hello Joe1", memberNames[1]); + } - [Test] - public void JValueConvert() - { - AssertValueConverted(true); - AssertValueConverted(true); - AssertValueConverted(false); - AssertValueConverted(null); - AssertValueConverted("true", true); - AssertValueConverted(null); - AssertValueConverted(Encoding.UTF8.GetBytes("blah")); - AssertValueConverted(new DateTime(2000, 12, 20, 23, 59, 2, DateTimeKind.Utc)); - AssertValueConverted(new DateTime(2000, 12, 20, 23, 59, 2, DateTimeKind.Utc)); - AssertValueConverted(null); - AssertValueConverted(new DateTimeOffset(2000, 12, 20, 23, 59, 2, TimeSpan.FromHours(1))); - AssertValueConverted(new DateTimeOffset(2000, 12, 20, 23, 59, 2, TimeSpan.FromHours(1))); - AssertValueConverted(null); - AssertValueConverted(99.9m); - AssertValueConverted(99.9m); - AssertValueConverted(1m); - AssertValueConverted(1.1f, 1.1m); - AssertValueConverted("1.1", 1.1m); - AssertValueConverted(99.9); - AssertValueConverted(99.9d); - AssertValueConverted(99.9d); - AssertValueConverted(99.9f); - AssertValueConverted(99.9f); - AssertValueConverted(int.MinValue); - AssertValueConverted(int.MinValue); - AssertValueConverted(long.MaxValue); - AssertValueConverted(long.MaxValue); - AssertValueConverted(short.MaxValue); - AssertValueConverted(short.MaxValue); - AssertValueConverted("blah"); - AssertValueConverted(null); - AssertValueConverted(1, "1"); - AssertValueConverted(uint.MinValue); - AssertValueConverted(uint.MinValue); - AssertValueConverted("1", (uint)1); - AssertValueConverted(ulong.MaxValue); - AssertValueConverted(ulong.MaxValue); - AssertValueConverted(ushort.MinValue); - AssertValueConverted(ushort.MinValue); - AssertValueConverted(null); - AssertValueConverted(TimeSpan.FromDays(1)); - AssertValueConverted(TimeSpan.FromDays(1)); - AssertValueConverted(null); - AssertValueConverted(new Guid("60304274-CD13-4060-B38C-057C8557AB54")); - AssertValueConverted(new Guid("60304274-CD13-4060-B38C-057C8557AB54")); - AssertValueConverted(null); - AssertValueConverted(new Uri("http://json.codeplex.com/")); - AssertValueConverted(null); + [Test] + public void JValueConvert() + { + AssertValueConverted(true); + AssertValueConverted(true); + AssertValueConverted(false); + AssertValueConverted(null); + AssertValueConverted("true", true); + AssertValueConverted(null); + AssertValueConverted(Encoding.UTF8.GetBytes("blah")); + AssertValueConverted(new DateTime(2000, 12, 20, 23, 59, 2, DateTimeKind.Utc)); + AssertValueConverted(new DateTime(2000, 12, 20, 23, 59, 2, DateTimeKind.Utc)); + AssertValueConverted(null); + AssertValueConverted(new DateTimeOffset(2000, 12, 20, 23, 59, 2, TimeSpan.FromHours(1))); + AssertValueConverted(new DateTimeOffset(2000, 12, 20, 23, 59, 2, TimeSpan.FromHours(1))); + AssertValueConverted(null); + AssertValueConverted(99.9m); + AssertValueConverted(99.9m); + AssertValueConverted(1m); + AssertValueConverted(1.1f, 1.1m); + AssertValueConverted("1.1", 1.1m); + AssertValueConverted(99.9); + AssertValueConverted(99.9d); + AssertValueConverted(99.9d); + AssertValueConverted(99.9f); + AssertValueConverted(99.9f); + AssertValueConverted(int.MinValue); + AssertValueConverted(int.MinValue); + AssertValueConverted(long.MaxValue); + AssertValueConverted(long.MaxValue); + AssertValueConverted(short.MaxValue); + AssertValueConverted(short.MaxValue); + AssertValueConverted("blah"); + AssertValueConverted(null); + AssertValueConverted(1, "1"); + AssertValueConverted(uint.MinValue); + AssertValueConverted(uint.MinValue); + AssertValueConverted("1", (uint)1); + AssertValueConverted(ulong.MaxValue); + AssertValueConverted(ulong.MaxValue); + AssertValueConverted(ushort.MinValue); + AssertValueConverted(ushort.MinValue); + AssertValueConverted(null); + AssertValueConverted(TimeSpan.FromDays(1)); + AssertValueConverted(TimeSpan.FromDays(1)); + AssertValueConverted(null); + AssertValueConverted(new Guid("60304274-CD13-4060-B38C-057C8557AB54")); + AssertValueConverted(new Guid("60304274-CD13-4060-B38C-057C8557AB54")); + AssertValueConverted(null); + AssertValueConverted(new Uri("http://json.codeplex.com/")); + AssertValueConverted(null); #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE) - AssertValueConverted(new BigInteger(100)); - AssertValueConverted(null); + AssertValueConverted(new BigInteger(100)); + AssertValueConverted(null); #endif - } + } - private static void AssertValueConverted(object value) - { - AssertValueConverted(value, value); - } + private static void AssertValueConverted(object value) + { + AssertValueConverted(value, value); + } - private static void AssertValueConverted(object value, object expected) - { - JValue v = new JValue(value); - dynamic d = v; + private static void AssertValueConverted(object value, object expected) + { + JValue v = new JValue(value); + dynamic d = v; - T t = d; - Assert.AreEqual(expected, t); - } + T t = d; + Assert.AreEqual(expected, t); + } - [Test] - public void DynamicSerializerExample() - { - dynamic value = new DynamicDictionary(); + [Test] + public void DynamicSerializerExample() + { + dynamic value = new DynamicDictionary(); - value.Name = "Arine Admin"; - value.Enabled = true; - value.Roles = new[] {"Admin", "User"}; + value.Name = "Arine Admin"; + value.Enabled = true; + value.Roles = new[] { "Admin", "User" }; - string json = JsonConvert.SerializeObject(value, Formatting.Indented); - // { - // "Name": "Arine Admin", - // "Enabled": true, - // "Roles": [ - // "Admin", - // "User" - // ] - // } + string json = JsonConvert.SerializeObject(value, Formatting.Indented); + // { + // "Name": "Arine Admin", + // "Enabled": true, + // "Roles": [ + // "Admin", + // "User" + // ] + // } - dynamic newValue = JsonConvert.DeserializeObject(json); + dynamic newValue = JsonConvert.DeserializeObject(json); - string role = newValue.Roles[0]; - // Admin - } + string role = newValue.Roles[0]; + // Admin + } - [Test] - public void DynamicLinqExample() - { - JObject oldAndBusted = new JObject(); - oldAndBusted["Name"] = "Arnie Admin"; - oldAndBusted["Enabled"] = true; - oldAndBusted["Roles"] = new JArray(new[] { "Admin", "User" }); + [Test] + public void DynamicLinqExample() + { + JObject oldAndBusted = new JObject(); + oldAndBusted["Name"] = "Arnie Admin"; + oldAndBusted["Enabled"] = true; + oldAndBusted["Roles"] = new JArray(new[] { "Admin", "User" }); - string oldRole = (string) oldAndBusted["Roles"][0]; - // Admin + string oldRole = (string)oldAndBusted["Roles"][0]; + // Admin - dynamic newHotness = new JObject(); - newHotness.Name = "Arnie Admin"; - newHotness.Enabled = true; - newHotness.Roles = new JArray(new[] { "Admin", "User" }); + dynamic newHotness = new JObject(); + newHotness.Name = "Arnie Admin"; + newHotness.Enabled = true; + newHotness.Roles = new JArray(new[] { "Admin", "User" }); - string newRole = newHotness.Roles[0]; - // Admin - } + string newRole = newHotness.Roles[0]; + // Admin + } - [Test] - public void ImprovedDynamicLinqExample() - { - dynamic product = new JObject(); - product.ProductName = "Elbow Grease"; - product.Enabled = true; - product.Price = 4.90m; - product.StockCount = 9000; - product.StockValue = 44100; + [Test] + public void ImprovedDynamicLinqExample() + { + dynamic product = new JObject(); + product.ProductName = "Elbow Grease"; + product.Enabled = true; + product.Price = 4.90m; + product.StockCount = 9000; + product.StockValue = 44100; - // All Elbow Grease must go sale! - // 50% off price + // All Elbow Grease must go sale! + // 50% off price - product.Price = product.Price / 2; - product.StockValue = product.StockCount * product.Price; - product.ProductName = product.ProductName + " (SALE)"; + product.Price = product.Price / 2; + product.StockValue = product.StockCount * product.Price; + product.ProductName = product.ProductName + " (SALE)"; - string json = product.ToString(); - // { - // "ProductName": "Elbow Grease (SALE)", - // "Enabled": true, - // "Price": 2.45, - // "StockCount": 9000, - // "StockValue": 22050.00 - // } + string json = product.ToString(); + // { + // "ProductName": "Elbow Grease (SALE)", + // "Enabled": true, + // "Price": 2.45, + // "StockCount": 9000, + // "StockValue": 22050.00 + // } - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""ProductName"": ""Elbow Grease (SALE)"", ""Enabled"": true, ""Price"": 2.45, ""StockCount"": 9000, ""StockValue"": 22050.00 }", json); + } } - } - public class DynamicDictionary : DynamicObject - { - private readonly IDictionary _values = new Dictionary(); - - public override IEnumerable GetDynamicMemberNames() + public class DynamicDictionary : DynamicObject { - return _values.Keys; - } + private readonly IDictionary _values = new Dictionary(); - public override bool TryGetMember(GetMemberBinder binder, out object result) - { - result = _values[binder.Name]; - return true; - } + public override IEnumerable GetDynamicMemberNames() + { + return _values.Keys; + } - public override bool TrySetMember(SetMemberBinder binder, object value) - { - _values[binder.Name] = value; - return true; + public override bool TryGetMember(GetMemberBinder binder, out object result) + { + result = _values[binder.Name]; + return true; + } + + public override bool TrySetMember(SetMemberBinder binder, object value) + { + _values[binder.Name] = value; + return true; + } } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Linq/JArrayTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JArrayTests.cs index 54bee3ef..a2a09476 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/JArrayTests.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/JArrayTests.cs @@ -38,410 +38,383 @@ using Newtonsoft.Json.Linq; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json.Tests.Linq { - [TestFixture] - public class JArrayTests : TestFixtureBase - { - [Test] - public void RemoveSpecificAndRemoveSelf() + [TestFixture] + public class JArrayTests : TestFixtureBase { - JObject o = new JObject - { - {"results", new JArray(1, 2, 3, 4)} - }; + [Test] + public void RemoveSpecificAndRemoveSelf() + { + JObject o = new JObject + { + { "results", new JArray(1, 2, 3, 4) } + }; - JArray a = (JArray)o["results"]; + JArray a = (JArray)o["results"]; - var last = a.Last(); + var last = a.Last(); - Assert.IsTrue(a.Remove(last)); + Assert.IsTrue(a.Remove(last)); - last = a.Last(); - last.Remove(); + last = a.Last(); + last.Remove(); - Assert.AreEqual(2, a.Count); - } + Assert.AreEqual(2, a.Count); + } - [Test] - public void Clear() - { - JArray a = new JArray {1}; - Assert.AreEqual(1, a.Count); + [Test] + public void Clear() + { + JArray a = new JArray { 1 }; + Assert.AreEqual(1, a.Count); - a.Clear(); - Assert.AreEqual(0, a.Count); - } + a.Clear(); + Assert.AreEqual(0, a.Count); + } - [Test] - public void AddToSelf() - { - JArray a = new JArray(); - a.Add(a); + [Test] + public void AddToSelf() + { + JArray a = new JArray(); + a.Add(a); - Assert.IsFalse(ReferenceEquals(a[0], a)); - } + Assert.IsFalse(ReferenceEquals(a[0], a)); + } - [Test] - public void Contains() - { - JValue v = new JValue(1); + [Test] + public void Contains() + { + JValue v = new JValue(1); - JArray a = new JArray {v}; + JArray a = new JArray { v }; - Assert.AreEqual(false, a.Contains(new JValue(2))); - Assert.AreEqual(false, a.Contains(new JValue(1))); - Assert.AreEqual(false, a.Contains(null)); - Assert.AreEqual(true, a.Contains(v)); - } + Assert.AreEqual(false, a.Contains(new JValue(2))); + Assert.AreEqual(false, a.Contains(new JValue(1))); + Assert.AreEqual(false, a.Contains(null)); + Assert.AreEqual(true, a.Contains(v)); + } - [Test] - public void GenericCollectionCopyTo() - { - JArray j = new JArray(); - j.Add(new JValue(1)); - j.Add(new JValue(2)); - j.Add(new JValue(3)); - Assert.AreEqual(3, j.Count); + [Test] + public void GenericCollectionCopyTo() + { + JArray j = new JArray(); + j.Add(new JValue(1)); + j.Add(new JValue(2)); + j.Add(new JValue(3)); + Assert.AreEqual(3, j.Count); - JToken[] a = new JToken[5]; + JToken[] a = new JToken[5]; - ((ICollection) j).CopyTo(a, 1); + ((ICollection)j).CopyTo(a, 1); - Assert.AreEqual(null, a[0]); + Assert.AreEqual(null, a[0]); - Assert.AreEqual(1, (int) a[1]); + Assert.AreEqual(1, (int)a[1]); - Assert.AreEqual(2, (int) a[2]); + Assert.AreEqual(2, (int)a[2]); - Assert.AreEqual(3, (int) a[3]); + Assert.AreEqual(3, (int)a[3]); - Assert.AreEqual(null, a[4]); + Assert.AreEqual(null, a[4]); + } - } + [Test] + public void GenericCollectionCopyToNullArrayShouldThrow() + { + JArray j = new JArray(); - [Test] - public void GenericCollectionCopyToNullArrayShouldThrow() - { - JArray j = new JArray(); - - ExceptionAssert.Throws( - @"Value cannot be null. + ExceptionAssert.Throws( + @"Value cannot be null. Parameter name: array", - () => - { - ((ICollection) j).CopyTo(null, 0); - }); - } + () => { ((ICollection)j).CopyTo(null, 0); }); + } - [Test] - public void GenericCollectionCopyToNegativeArrayIndexShouldThrow() - { - JArray j = new JArray(); + [Test] + public void GenericCollectionCopyToNegativeArrayIndexShouldThrow() + { + JArray j = new JArray(); - ExceptionAssert.Throws( - @"arrayIndex is less than 0. + ExceptionAssert.Throws( + @"arrayIndex is less than 0. Parameter name: arrayIndex", - () => - { - ((ICollection) j).CopyTo(new JToken[1], -1); - }); - } + () => { ((ICollection)j).CopyTo(new JToken[1], -1); }); + } - [Test] - public void GenericCollectionCopyToArrayIndexEqualGreaterToArrayLengthShouldThrow() - { - JArray j = new JArray(); - - ExceptionAssert.Throws( - @"arrayIndex is equal to or greater than the length of array.", - () => - { - ((ICollection) j).CopyTo(new JToken[1], 1); - }); - } - - [Test] - public void GenericCollectionCopyToInsufficientArrayCapacity() - { - JArray j = new JArray(); - j.Add(new JValue(1)); - j.Add(new JValue(2)); - j.Add(new JValue(3)); - - ExceptionAssert.Throws( - @"The number of elements in the source JObject is greater than the available space from arrayIndex to the end of the destination array.", - () => + [Test] + public void GenericCollectionCopyToArrayIndexEqualGreaterToArrayLengthShouldThrow() { - ((ICollection)j).CopyTo(new JToken[3], 1); - }); - } + JArray j = new JArray(); - [Test] - public void Remove() - { - JValue v = new JValue(1); - JArray j = new JArray(); - j.Add(v); + ExceptionAssert.Throws( + @"arrayIndex is equal to or greater than the length of array.", + () => { ((ICollection)j).CopyTo(new JToken[1], 1); }); + } - Assert.AreEqual(1, j.Count); + [Test] + public void GenericCollectionCopyToInsufficientArrayCapacity() + { + JArray j = new JArray(); + j.Add(new JValue(1)); + j.Add(new JValue(2)); + j.Add(new JValue(3)); - Assert.AreEqual(false, j.Remove(new JValue(1))); - Assert.AreEqual(false, j.Remove(null)); - Assert.AreEqual(true, j.Remove(v)); - Assert.AreEqual(false, j.Remove(v)); + ExceptionAssert.Throws( + @"The number of elements in the source JObject is greater than the available space from arrayIndex to the end of the destination array.", + () => { ((ICollection)j).CopyTo(new JToken[3], 1); }); + } - Assert.AreEqual(0, j.Count); - } + [Test] + public void Remove() + { + JValue v = new JValue(1); + JArray j = new JArray(); + j.Add(v); - [Test] - public void IndexOf() - { - JValue v1 = new JValue(1); - JValue v2 = new JValue(1); - JValue v3 = new JValue(1); + Assert.AreEqual(1, j.Count); - JArray j = new JArray(); + Assert.AreEqual(false, j.Remove(new JValue(1))); + Assert.AreEqual(false, j.Remove(null)); + Assert.AreEqual(true, j.Remove(v)); + Assert.AreEqual(false, j.Remove(v)); - j.Add(v1); - Assert.AreEqual(0, j.IndexOf(v1)); + Assert.AreEqual(0, j.Count); + } - j.Add(v2); - Assert.AreEqual(0, j.IndexOf(v1)); - Assert.AreEqual(1, j.IndexOf(v2)); + [Test] + public void IndexOf() + { + JValue v1 = new JValue(1); + JValue v2 = new JValue(1); + JValue v3 = new JValue(1); - j.AddFirst(v3); - Assert.AreEqual(1, j.IndexOf(v1)); - Assert.AreEqual(2, j.IndexOf(v2)); - Assert.AreEqual(0, j.IndexOf(v3)); + JArray j = new JArray(); - v3.Remove(); - Assert.AreEqual(0, j.IndexOf(v1)); - Assert.AreEqual(1, j.IndexOf(v2)); - Assert.AreEqual(-1, j.IndexOf(v3)); - } + j.Add(v1); + Assert.AreEqual(0, j.IndexOf(v1)); - [Test] - public void RemoveAt() - { - JValue v1 = new JValue(1); - JValue v2 = new JValue(1); - JValue v3 = new JValue(1); + j.Add(v2); + Assert.AreEqual(0, j.IndexOf(v1)); + Assert.AreEqual(1, j.IndexOf(v2)); - JArray j = new JArray(); + j.AddFirst(v3); + Assert.AreEqual(1, j.IndexOf(v1)); + Assert.AreEqual(2, j.IndexOf(v2)); + Assert.AreEqual(0, j.IndexOf(v3)); - j.Add(v1); - j.Add(v2); - j.Add(v3); + v3.Remove(); + Assert.AreEqual(0, j.IndexOf(v1)); + Assert.AreEqual(1, j.IndexOf(v2)); + Assert.AreEqual(-1, j.IndexOf(v3)); + } - Assert.AreEqual(true, j.Contains(v1)); - j.RemoveAt(0); - Assert.AreEqual(false, j.Contains(v1)); + [Test] + public void RemoveAt() + { + JValue v1 = new JValue(1); + JValue v2 = new JValue(1); + JValue v3 = new JValue(1); - Assert.AreEqual(true, j.Contains(v3)); - j.RemoveAt(1); - Assert.AreEqual(false, j.Contains(v3)); + JArray j = new JArray(); - Assert.AreEqual(1, j.Count); - } + j.Add(v1); + j.Add(v2); + j.Add(v3); - [Test] - public void RemoveAtOutOfRangeIndexShouldError() - { - JArray j = new JArray(); - - ExceptionAssert.Throws( - @"Index is equal to or greater than Count. -Parameter name: index", - () => - { + Assert.AreEqual(true, j.Contains(v1)); j.RemoveAt(0); - }); - } + Assert.AreEqual(false, j.Contains(v1)); - [Test] - public void RemoveAtNegativeIndexShouldError() - { - JArray j = new JArray(); + Assert.AreEqual(true, j.Contains(v3)); + j.RemoveAt(1); + Assert.AreEqual(false, j.Contains(v3)); - ExceptionAssert.Throws( - @"Index is less than 0. -Parameter name: index", - () => - { - j.RemoveAt(-1); - }); - } + Assert.AreEqual(1, j.Count); + } - [Test] - public void Insert() - { - JValue v1 = new JValue(1); - JValue v2 = new JValue(2); - JValue v3 = new JValue(3); - JValue v4 = new JValue(4); - - JArray j = new JArray(); - - j.Add(v1); - j.Add(v2); - j.Add(v3); - j.Insert(1, v4); - - Assert.AreEqual(0, j.IndexOf(v1)); - Assert.AreEqual(1, j.IndexOf(v4)); - Assert.AreEqual(2, j.IndexOf(v2)); - Assert.AreEqual(3, j.IndexOf(v3)); - } - - [Test] - public void AddFirstAddedTokenShouldBeFirst() - { - JValue v1 = new JValue(1); - JValue v2 = new JValue(2); - JValue v3 = new JValue(3); - - JArray j = new JArray(); - Assert.AreEqual(null, j.First); - Assert.AreEqual(null, j.Last); - - j.AddFirst(v1); - Assert.AreEqual(v1, j.First); - Assert.AreEqual(v1, j.Last); - - j.AddFirst(v2); - Assert.AreEqual(v2, j.First); - Assert.AreEqual(v1, j.Last); - - j.AddFirst(v3); - Assert.AreEqual(v3, j.First); - Assert.AreEqual(v1, j.Last); - } - - [Test] - public void InsertShouldInsertAtZeroIndex() - { - JValue v1 = new JValue(1); - JValue v2 = new JValue(2); - - JArray j = new JArray(); - - j.Insert(0, v1); - Assert.AreEqual(0, j.IndexOf(v1)); - - j.Insert(0, v2); - Assert.AreEqual(1, j.IndexOf(v1)); - Assert.AreEqual(0, j.IndexOf(v2)); - } - - [Test] - public void InsertNull() - { - JArray j = new JArray(); - j.Insert(0, null); - - Assert.AreEqual(null, ((JValue) j[0]).Value); - } - - [Test] - public void InsertNegativeIndexShouldThrow() - { - JArray j = new JArray(); - - ExceptionAssert.Throws( - @"Index was out of range. Must be non-negative and less than the size of the collection. -Parameter name: index", - () => + [Test] + public void RemoveAtOutOfRangeIndexShouldError() { - j.Insert(-1, new JValue(1)); - }); - } + JArray j = new JArray(); - [Test] - public void InsertOutOfRangeIndexShouldThrow() - { - JArray j = new JArray(); - - ExceptionAssert.Throws( - @"Index must be within the bounds of the List. + ExceptionAssert.Throws( + @"Index is equal to or greater than Count. Parameter name: index", - () => - { - j.Insert(2, new JValue(1)); - }); - } + () => { j.RemoveAt(0); }); + } - [Test] - public void Item() - { - JValue v1 = new JValue(1); - JValue v2 = new JValue(2); - JValue v3 = new JValue(3); - JValue v4 = new JValue(4); - - JArray j = new JArray(); - - j.Add(v1); - j.Add(v2); - j.Add(v3); - - j[1] = v4; - - Assert.AreEqual(null, v2.Parent); - Assert.AreEqual(-1, j.IndexOf(v2)); - Assert.AreEqual(j, v4.Parent); - Assert.AreEqual(1, j.IndexOf(v4)); - } - - [Test] - public void Parse_ShouldThrowOnUnexpectedToken() - { - string json = @"{""prop"":""value""}"; - - ExceptionAssert.Throws( - "Error reading JArray from JsonReader. Current JsonReader item is not an array: StartObject. Path '', line 1, position 1.", - () => - { - JArray.Parse(json); - }); - } - - public class ListItemFields - { - public string ListItemText { get; set; } - public object ListItemValue { get; set; } - } - - [Test] - public void ArrayOrder() - { - string itemZeroText = "Zero text"; - - IEnumerable t = new List + [Test] + public void RemoveAtNegativeIndexShouldError() { - new ListItemFields {ListItemText = "First", ListItemValue = 1}, - new ListItemFields {ListItemText = "Second", ListItemValue = 2}, - new ListItemFields {ListItemText = "Third", ListItemValue = 3} - }; + JArray j = new JArray(); - JObject optionValues = - new JObject( - new JProperty("options", + ExceptionAssert.Throws( + @"Index is less than 0. +Parameter name: index", + () => { j.RemoveAt(-1); }); + } + + [Test] + public void Insert() + { + JValue v1 = new JValue(1); + JValue v2 = new JValue(2); + JValue v3 = new JValue(3); + JValue v4 = new JValue(4); + + JArray j = new JArray(); + + j.Add(v1); + j.Add(v2); + j.Add(v3); + j.Insert(1, v4); + + Assert.AreEqual(0, j.IndexOf(v1)); + Assert.AreEqual(1, j.IndexOf(v4)); + Assert.AreEqual(2, j.IndexOf(v2)); + Assert.AreEqual(3, j.IndexOf(v3)); + } + + [Test] + public void AddFirstAddedTokenShouldBeFirst() + { + JValue v1 = new JValue(1); + JValue v2 = new JValue(2); + JValue v3 = new JValue(3); + + JArray j = new JArray(); + Assert.AreEqual(null, j.First); + Assert.AreEqual(null, j.Last); + + j.AddFirst(v1); + Assert.AreEqual(v1, j.First); + Assert.AreEqual(v1, j.Last); + + j.AddFirst(v2); + Assert.AreEqual(v2, j.First); + Assert.AreEqual(v1, j.Last); + + j.AddFirst(v3); + Assert.AreEqual(v3, j.First); + Assert.AreEqual(v1, j.Last); + } + + [Test] + public void InsertShouldInsertAtZeroIndex() + { + JValue v1 = new JValue(1); + JValue v2 = new JValue(2); + + JArray j = new JArray(); + + j.Insert(0, v1); + Assert.AreEqual(0, j.IndexOf(v1)); + + j.Insert(0, v2); + Assert.AreEqual(1, j.IndexOf(v1)); + Assert.AreEqual(0, j.IndexOf(v2)); + } + + [Test] + public void InsertNull() + { + JArray j = new JArray(); + j.Insert(0, null); + + Assert.AreEqual(null, ((JValue)j[0]).Value); + } + + [Test] + public void InsertNegativeIndexShouldThrow() + { + JArray j = new JArray(); + + ExceptionAssert.Throws( + @"Index was out of range. Must be non-negative and less than the size of the collection. +Parameter name: index", + () => { j.Insert(-1, new JValue(1)); }); + } + + [Test] + public void InsertOutOfRangeIndexShouldThrow() + { + JArray j = new JArray(); + + ExceptionAssert.Throws( + @"Index must be within the bounds of the List. +Parameter name: index", + () => { j.Insert(2, new JValue(1)); }); + } + + [Test] + public void Item() + { + JValue v1 = new JValue(1); + JValue v2 = new JValue(2); + JValue v3 = new JValue(3); + JValue v4 = new JValue(4); + + JArray j = new JArray(); + + j.Add(v1); + j.Add(v2); + j.Add(v3); + + j[1] = v4; + + Assert.AreEqual(null, v2.Parent); + Assert.AreEqual(-1, j.IndexOf(v2)); + Assert.AreEqual(j, v4.Parent); + Assert.AreEqual(1, j.IndexOf(v4)); + } + + [Test] + public void Parse_ShouldThrowOnUnexpectedToken() + { + string json = @"{""prop"":""value""}"; + + ExceptionAssert.Throws( + "Error reading JArray from JsonReader. Current JsonReader item is not an array: StartObject. Path '', line 1, position 1.", + () => { JArray.Parse(json); }); + } + + public class ListItemFields + { + public string ListItemText { get; set; } + public object ListItemValue { get; set; } + } + + [Test] + public void ArrayOrder() + { + string itemZeroText = "Zero text"; + + IEnumerable t = new List + { + new ListItemFields { ListItemText = "First", ListItemValue = 1 }, + new ListItemFields { ListItemText = "Second", ListItemValue = 2 }, + new ListItemFields { ListItemText = "Third", ListItemValue = 3 } + }; + + JObject optionValues = + new JObject( + new JProperty("options", new JArray( - new JObject( - new JProperty("text", itemZeroText), - new JProperty("value", "0")), - from r in t - orderby r.ListItemValue - select new JObject( - new JProperty("text", r.ListItemText), - new JProperty("value", r.ListItemValue.ToString()))))); + new JObject( + new JProperty("text", itemZeroText), + new JProperty("value", "0")), + from r in t + orderby r.ListItemValue + select new JObject( + new JProperty("text", r.ListItemText), + new JProperty("value", r.ListItemValue.ToString()))))); - string result = "myOptions = " + optionValues.ToString(); + string result = "myOptions = " + optionValues.ToString(); - Assert.AreEqual(@"myOptions = { + Assert.AreEqual(@"myOptions = { ""options"": [ { ""text"": ""Zero text"", @@ -461,141 +434,135 @@ Parameter name: index", } ] }", result); - } + } - [Test] - public void Iterate() - { - JArray a = new JArray(1, 2, 3, 4, 5); + [Test] + public void Iterate() + { + JArray a = new JArray(1, 2, 3, 4, 5); - int i = 1; - foreach (JToken token in a) - { - Assert.AreEqual(i, (int) token); - i++; - } - } + int i = 1; + foreach (JToken token in a) + { + Assert.AreEqual(i, (int)token); + i++; + } + } #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - [Test] - public void ITypedListGetItemProperties() - { - JProperty p1 = new JProperty("Test1", 1); - JProperty p2 = new JProperty("Test2", "Two"); - ITypedList a = new JArray(new JObject(p1, p2)); + [Test] + public void ITypedListGetItemProperties() + { + JProperty p1 = new JProperty("Test1", 1); + JProperty p2 = new JProperty("Test2", "Two"); + ITypedList a = new JArray(new JObject(p1, p2)); - PropertyDescriptorCollection propertyDescriptors = a.GetItemProperties(null); - Assert.IsNotNull(propertyDescriptors); - Assert.AreEqual(2, propertyDescriptors.Count); - Assert.AreEqual("Test1", propertyDescriptors[0].Name); - Assert.AreEqual("Test2", propertyDescriptors[1].Name); - } + PropertyDescriptorCollection propertyDescriptors = a.GetItemProperties(null); + Assert.IsNotNull(propertyDescriptors); + Assert.AreEqual(2, propertyDescriptors.Count); + Assert.AreEqual("Test1", propertyDescriptors[0].Name); + Assert.AreEqual("Test2", propertyDescriptors[1].Name); + } #endif - [Test] - public void AddArrayToSelf() - { - JArray a = new JArray(1, 2); - a.Add(a); - - Assert.AreEqual(3, a.Count); - Assert.AreEqual(1, (int) a[0]); - Assert.AreEqual(2, (int) a[1]); - Assert.AreNotSame(a, a[2]); - } - - [Test] - public void SetValueWithInvalidIndex() - { - ExceptionAssert.Throws( - @"Set JArray values with invalid key value: ""badvalue"". Array position index expected.", - () => + [Test] + public void AddArrayToSelf() { - JArray a = new JArray(); - a["badvalue"] = new JValue(3); - }); - } + JArray a = new JArray(1, 2); + a.Add(a); - [Test] - public void SetValue() - { - object key = 0; + Assert.AreEqual(3, a.Count); + Assert.AreEqual(1, (int)a[0]); + Assert.AreEqual(2, (int)a[1]); + Assert.AreNotSame(a, a[2]); + } - JArray a = new JArray((object) null); - a[key] = new JValue(3); - - Assert.AreEqual(3, (int) a[key]); - } - - [Test] - public void ReplaceAll() - { - JArray a = new JArray(new[] {1, 2, 3}); - Assert.AreEqual(3, a.Count); - Assert.AreEqual(1, (int) a[0]); - Assert.AreEqual(2, (int) a[1]); - Assert.AreEqual(3, (int) a[2]); - - a.ReplaceAll(1); - Assert.AreEqual(1, a.Count); - Assert.AreEqual(1, (int) a[0]); - } - - [Test] - public void ParseIncomplete() - { - ExceptionAssert.Throws( - "Unexpected end of content while loading JArray. Path '[0]', line 1, position 2.", - () => + [Test] + public void SetValueWithInvalidIndex() { - JArray.Parse("[1"); - }); - } + ExceptionAssert.Throws( + @"Set JArray values with invalid key value: ""badvalue"". Array position index expected.", + () => + { + JArray a = new JArray(); + a["badvalue"] = new JValue(3); + }); + } - [Test] - public void InsertAddEnd() - { - JArray array = new JArray(); - array.Insert(0, 123); - array.Insert(1, 456); + [Test] + public void SetValue() + { + object key = 0; - Assert.AreEqual(2, array.Count); - Assert.AreEqual(123, (int) array[0]); - Assert.AreEqual(456, (int) array[1]); - } + JArray a = new JArray((object)null); + a[key] = new JValue(3); - [Test] - public void ParseAdditionalContent() - { - string json = @"[ + Assert.AreEqual(3, (int)a[key]); + } + + [Test] + public void ReplaceAll() + { + JArray a = new JArray(new[] { 1, 2, 3 }); + Assert.AreEqual(3, a.Count); + Assert.AreEqual(1, (int)a[0]); + Assert.AreEqual(2, (int)a[1]); + Assert.AreEqual(3, (int)a[2]); + + a.ReplaceAll(1); + Assert.AreEqual(1, a.Count); + Assert.AreEqual(1, (int)a[0]); + } + + [Test] + public void ParseIncomplete() + { + ExceptionAssert.Throws( + "Unexpected end of content while loading JArray. Path '[0]', line 1, position 2.", + () => { JArray.Parse("[1"); }); + } + + [Test] + public void InsertAddEnd() + { + JArray array = new JArray(); + array.Insert(0, 123); + array.Insert(1, 456); + + Assert.AreEqual(2, array.Count); + Assert.AreEqual(123, (int)array[0]); + Assert.AreEqual(456, (int)array[1]); + } + + [Test] + public void ParseAdditionalContent() + { + string json = @"[ ""Small"", ""Medium"", ""Large"" ], 987987"; - ExceptionAssert.Throws( - "Additional text encountered after finished reading JSON content: ,. Path '', line 5, position 2.", - () => - { - JArray.Parse(json); - }); + ExceptionAssert.Throws( + "Additional text encountered after finished reading JSON content: ,. Path '', line 5, position 2.", + () => { JArray.Parse(json); }); + } + + [Test] + public void ToListOnEmptyArray() + { + string json = @"{""decks"":[]}"; + + JArray decks = (JArray)JObject.Parse(json)["decks"]; + IList l = decks.ToList(); + Assert.AreEqual(0, l.Count); + + json = @"{""decks"":[1]}"; + + decks = (JArray)JObject.Parse(json)["decks"]; + l = decks.ToList(); + Assert.AreEqual(1, l.Count); + } } - - [Test] - public void ToListOnEmptyArray() - { - string json = @"{""decks"":[]}"; - - JArray decks = (JArray)JObject.Parse(json)["decks"]; - IList l = decks.ToList(); - Assert.AreEqual(0, l.Count); - - json = @"{""decks"":[1]}"; - - decks = (JArray)JObject.Parse(json)["decks"]; - l = decks.ToList(); - Assert.AreEqual(1, l.Count); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Linq/JConstructorTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JConstructorTests.cs index 6d7e4375..a205e78c 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/JConstructorTests.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/JConstructorTests.cs @@ -38,70 +38,71 @@ using System.IO; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json.Tests.Linq { - [TestFixture] - public class JConstructorTests : TestFixtureBase - { - [Test] - public void Load() + [TestFixture] + public class JConstructorTests : TestFixtureBase { - JsonReader reader = new JsonTextReader(new StringReader("new Date(123)")); - reader.Read(); + [Test] + public void Load() + { + JsonReader reader = new JsonTextReader(new StringReader("new Date(123)")); + reader.Read(); - JConstructor constructor = JConstructor.Load(reader); - Assert.AreEqual("Date", constructor.Name); - Assert.IsTrue(JToken.DeepEquals(new JValue(123), constructor.Values().ElementAt(0))); + JConstructor constructor = JConstructor.Load(reader); + Assert.AreEqual("Date", constructor.Name); + Assert.IsTrue(JToken.DeepEquals(new JValue(123), constructor.Values().ElementAt(0))); + } + + [Test] + public void CreateWithMultiValue() + { + JConstructor constructor = new JConstructor("Test", new List { 1, 2, 3 }); + Assert.AreEqual("Test", constructor.Name); + Assert.AreEqual(3, constructor.Children().Count()); + Assert.AreEqual(1, (int)constructor.Children().ElementAt(0)); + Assert.AreEqual(2, (int)constructor.Children().ElementAt(1)); + Assert.AreEqual(3, (int)constructor.Children().ElementAt(2)); + } + + [Test] + public void Iterate() + { + JConstructor c = new JConstructor("MrConstructor", 1, 2, 3, 4, 5); + + int i = 1; + foreach (JToken token in c) + { + Assert.AreEqual(i, (int)token); + i++; + } + } + + [Test] + public void SetValueWithInvalidIndex() + { + ExceptionAssert.Throws(@"Set JConstructor values with invalid key value: ""badvalue"". Argument position index expected.", + () => + { + JConstructor c = new JConstructor(); + c["badvalue"] = new JValue(3); + }); + } + + [Test] + public void SetValue() + { + object key = 0; + + JConstructor c = new JConstructor(); + c.Name = "con"; + c.Add(null); + c[key] = new JValue(3); + + Assert.AreEqual(3, (int)c[key]); + } } - - [Test] - public void CreateWithMultiValue() - { - JConstructor constructor = new JConstructor("Test", new List { 1, 2, 3 }); - Assert.AreEqual("Test", constructor.Name); - Assert.AreEqual(3, constructor.Children().Count()); - Assert.AreEqual(1, (int)constructor.Children().ElementAt(0)); - Assert.AreEqual(2, (int)constructor.Children().ElementAt(1)); - Assert.AreEqual(3, (int)constructor.Children().ElementAt(2)); - } - - [Test] - public void Iterate() - { - JConstructor c = new JConstructor("MrConstructor", 1, 2, 3, 4, 5); - - int i = 1; - foreach (JToken token in c) - { - Assert.AreEqual(i, (int)token); - i++; - } - } - - [Test] - public void SetValueWithInvalidIndex() - { - ExceptionAssert.Throws(@"Set JConstructor values with invalid key value: ""badvalue"". Argument position index expected.", - () => - { - JConstructor c = new JConstructor(); - c["badvalue"] = new JValue(3); - }); - } - - [Test] - public void SetValue() - { - object key = 0; - - JConstructor c = new JConstructor(); - c.Name = "con"; - c.Add(null); - c[key] = new JValue(3); - - Assert.AreEqual(3, (int)c[key]); - } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs index 5ac84a4a..5a3eddae 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs @@ -54,476 +54,473 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Tests.Linq { - [TestFixture] - public class JObjectTests : TestFixtureBase - { - [Test] - public void WritePropertyWithNoValue() + [TestFixture] + public class JObjectTests : TestFixtureBase { - var o = new JObject(); - o.Add(new JProperty("novalue")); + [Test] + public void WritePropertyWithNoValue() + { + var o = new JObject(); + o.Add(new JProperty("novalue")); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""novalue"": null }", o.ToString()); - } + } - [Test] - public void Keys() - { - var o = new JObject(); - var d = (IDictionary) o; - - Assert.AreEqual(0, d.Keys.Count); - - o["value"] = true; - - Assert.AreEqual(1, d.Keys.Count); - } - - [Test] - public void TryGetValue() - { - JObject o = new JObject(); - o.Add("PropertyNameValue", new JValue(1)); - Assert.AreEqual(1, o.Children().Count()); - - JToken t; - Assert.AreEqual(false, o.TryGetValue("sdf", out t)); - Assert.AreEqual(null, t); - - Assert.AreEqual(false, o.TryGetValue(null, out t)); - Assert.AreEqual(null, t); - - Assert.AreEqual(true, o.TryGetValue("PropertyNameValue", out t)); - Assert.AreEqual(true, JToken.DeepEquals(new JValue(1), t)); - } - - [Test] - public void DictionaryItemShouldSet() - { - JObject o = new JObject(); - o["PropertyNameValue"] = new JValue(1); - Assert.AreEqual(1, o.Children().Count()); - - JToken t; - Assert.AreEqual(true, o.TryGetValue("PropertyNameValue", out t)); - Assert.AreEqual(true, JToken.DeepEquals(new JValue(1), t)); - - o["PropertyNameValue"] = new JValue(2); - Assert.AreEqual(1, o.Children().Count()); - - Assert.AreEqual(true, o.TryGetValue("PropertyNameValue", out t)); - Assert.AreEqual(true, JToken.DeepEquals(new JValue(2), t)); - - o["PropertyNameValue"] = null; - Assert.AreEqual(1, o.Children().Count()); - - Assert.AreEqual(true, o.TryGetValue("PropertyNameValue", out t)); - Assert.AreEqual(true, JToken.DeepEquals(new JValue((object)null), t)); - } - - [Test] - public void Remove() - { - JObject o = new JObject(); - o.Add("PropertyNameValue", new JValue(1)); - Assert.AreEqual(1, o.Children().Count()); - - Assert.AreEqual(false, o.Remove("sdf")); - Assert.AreEqual(false, o.Remove(null)); - Assert.AreEqual(true, o.Remove("PropertyNameValue")); - - Assert.AreEqual(0, o.Children().Count()); - } - - [Test] - public void GenericCollectionRemove() - { - JValue v = new JValue(1); - JObject o = new JObject(); - o.Add("PropertyNameValue", v); - Assert.AreEqual(1, o.Children().Count()); - - Assert.AreEqual(false, ((ICollection>)o).Remove(new KeyValuePair("PropertyNameValue1", new JValue(1)))); - Assert.AreEqual(false, ((ICollection>)o).Remove(new KeyValuePair("PropertyNameValue", new JValue(2)))); - Assert.AreEqual(false, ((ICollection>)o).Remove(new KeyValuePair("PropertyNameValue", new JValue(1)))); - Assert.AreEqual(true, ((ICollection>)o).Remove(new KeyValuePair("PropertyNameValue", v))); - - Assert.AreEqual(0, o.Children().Count()); - } - - [Test] - public void DuplicatePropertyNameShouldThrow() - { - ExceptionAssert.Throws( - "Can not add property PropertyNameValue to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object.", - () => + [Test] + public void Keys() { - JObject o = new JObject(); - o.Add("PropertyNameValue", null); - o.Add("PropertyNameValue", null); - }); - } + var o = new JObject(); + var d = (IDictionary)o; - [Test] - public void GenericDictionaryAdd() - { - JObject o = new JObject(); + Assert.AreEqual(0, d.Keys.Count); - o.Add("PropertyNameValue", new JValue(1)); - Assert.AreEqual(1, (int)o["PropertyNameValue"]); + o["value"] = true; - o.Add("PropertyNameValue1", null); - Assert.AreEqual(null, ((JValue)o["PropertyNameValue1"]).Value); + Assert.AreEqual(1, d.Keys.Count); + } - Assert.AreEqual(2, o.Children().Count()); - } + [Test] + public void TryGetValue() + { + JObject o = new JObject(); + o.Add("PropertyNameValue", new JValue(1)); + Assert.AreEqual(1, o.Children().Count()); - [Test] - public void GenericCollectionAdd() - { - JObject o = new JObject(); - ((ICollection>)o).Add(new KeyValuePair("PropertyNameValue", new JValue(1))); + JToken t; + Assert.AreEqual(false, o.TryGetValue("sdf", out t)); + Assert.AreEqual(null, t); - Assert.AreEqual(1, (int)o["PropertyNameValue"]); - Assert.AreEqual(1, o.Children().Count()); - } + Assert.AreEqual(false, o.TryGetValue(null, out t)); + Assert.AreEqual(null, t); - [Test] - public void GenericCollectionClear() - { - JObject o = new JObject(); - o.Add("PropertyNameValue", new JValue(1)); - Assert.AreEqual(1, o.Children().Count()); + Assert.AreEqual(true, o.TryGetValue("PropertyNameValue", out t)); + Assert.AreEqual(true, JToken.DeepEquals(new JValue(1), t)); + } - JProperty p = (JProperty)o.Children().ElementAt(0); + [Test] + public void DictionaryItemShouldSet() + { + JObject o = new JObject(); + o["PropertyNameValue"] = new JValue(1); + Assert.AreEqual(1, o.Children().Count()); - ((ICollection>)o).Clear(); - Assert.AreEqual(0, o.Children().Count()); + JToken t; + Assert.AreEqual(true, o.TryGetValue("PropertyNameValue", out t)); + Assert.AreEqual(true, JToken.DeepEquals(new JValue(1), t)); - Assert.AreEqual(null, p.Parent); - } + o["PropertyNameValue"] = new JValue(2); + Assert.AreEqual(1, o.Children().Count()); - [Test] - public void GenericCollectionContains() - { - JValue v = new JValue(1); - JObject o = new JObject(); - o.Add("PropertyNameValue", v); - Assert.AreEqual(1, o.Children().Count()); + Assert.AreEqual(true, o.TryGetValue("PropertyNameValue", out t)); + Assert.AreEqual(true, JToken.DeepEquals(new JValue(2), t)); - bool contains = ((ICollection>)o).Contains(new KeyValuePair("PropertyNameValue", new JValue(1))); - Assert.AreEqual(false, contains); + o["PropertyNameValue"] = null; + Assert.AreEqual(1, o.Children().Count()); - contains = ((ICollection>)o).Contains(new KeyValuePair("PropertyNameValue", v)); - Assert.AreEqual(true, contains); + Assert.AreEqual(true, o.TryGetValue("PropertyNameValue", out t)); + Assert.AreEqual(true, JToken.DeepEquals(new JValue((object)null), t)); + } - contains = ((ICollection>)o).Contains(new KeyValuePair("PropertyNameValue", new JValue(2))); - Assert.AreEqual(false, contains); + [Test] + public void Remove() + { + JObject o = new JObject(); + o.Add("PropertyNameValue", new JValue(1)); + Assert.AreEqual(1, o.Children().Count()); - contains = ((ICollection>)o).Contains(new KeyValuePair("PropertyNameValue1", new JValue(1))); - Assert.AreEqual(false, contains); + Assert.AreEqual(false, o.Remove("sdf")); + Assert.AreEqual(false, o.Remove(null)); + Assert.AreEqual(true, o.Remove("PropertyNameValue")); - contains = ((ICollection>)o).Contains(default(KeyValuePair)); - Assert.AreEqual(false, contains); - } + Assert.AreEqual(0, o.Children().Count()); + } - [Test] - public void GenericDictionaryContains() - { - JObject o = new JObject(); - o.Add("PropertyNameValue", new JValue(1)); - Assert.AreEqual(1, o.Children().Count()); + [Test] + public void GenericCollectionRemove() + { + JValue v = new JValue(1); + JObject o = new JObject(); + o.Add("PropertyNameValue", v); + Assert.AreEqual(1, o.Children().Count()); - bool contains = ((IDictionary)o).ContainsKey("PropertyNameValue"); - Assert.AreEqual(true, contains); - } + Assert.AreEqual(false, ((ICollection>)o).Remove(new KeyValuePair("PropertyNameValue1", new JValue(1)))); + Assert.AreEqual(false, ((ICollection>)o).Remove(new KeyValuePair("PropertyNameValue", new JValue(2)))); + Assert.AreEqual(false, ((ICollection>)o).Remove(new KeyValuePair("PropertyNameValue", new JValue(1)))); + Assert.AreEqual(true, ((ICollection>)o).Remove(new KeyValuePair("PropertyNameValue", v))); - [Test] - public void GenericCollectionCopyTo() - { - JObject o = new JObject(); - o.Add("PropertyNameValue", new JValue(1)); - o.Add("PropertyNameValue2", new JValue(2)); - o.Add("PropertyNameValue3", new JValue(3)); - Assert.AreEqual(3, o.Children().Count()); + Assert.AreEqual(0, o.Children().Count()); + } - KeyValuePair[] a = new KeyValuePair[5]; + [Test] + public void DuplicatePropertyNameShouldThrow() + { + ExceptionAssert.Throws( + "Can not add property PropertyNameValue to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object.", + () => + { + JObject o = new JObject(); + o.Add("PropertyNameValue", null); + o.Add("PropertyNameValue", null); + }); + } - ((ICollection>)o).CopyTo(a, 1); + [Test] + public void GenericDictionaryAdd() + { + JObject o = new JObject(); - Assert.AreEqual(default(KeyValuePair), a[0]); - - Assert.AreEqual("PropertyNameValue", a[1].Key); - Assert.AreEqual(1, (int)a[1].Value); + o.Add("PropertyNameValue", new JValue(1)); + Assert.AreEqual(1, (int)o["PropertyNameValue"]); - Assert.AreEqual("PropertyNameValue2", a[2].Key); - Assert.AreEqual(2, (int)a[2].Value); + o.Add("PropertyNameValue1", null); + Assert.AreEqual(null, ((JValue)o["PropertyNameValue1"]).Value); - Assert.AreEqual("PropertyNameValue3", a[3].Key); - Assert.AreEqual(3, (int)a[3].Value); + Assert.AreEqual(2, o.Children().Count()); + } - Assert.AreEqual(default(KeyValuePair), a[4]); - } + [Test] + public void GenericCollectionAdd() + { + JObject o = new JObject(); + ((ICollection>)o).Add(new KeyValuePair("PropertyNameValue", new JValue(1))); - [Test] - public void GenericCollectionCopyToNullArrayShouldThrow() - { - ExceptionAssert.Throws( - @"Value cannot be null. + Assert.AreEqual(1, (int)o["PropertyNameValue"]); + Assert.AreEqual(1, o.Children().Count()); + } + + [Test] + public void GenericCollectionClear() + { + JObject o = new JObject(); + o.Add("PropertyNameValue", new JValue(1)); + Assert.AreEqual(1, o.Children().Count()); + + JProperty p = (JProperty)o.Children().ElementAt(0); + + ((ICollection>)o).Clear(); + Assert.AreEqual(0, o.Children().Count()); + + Assert.AreEqual(null, p.Parent); + } + + [Test] + public void GenericCollectionContains() + { + JValue v = new JValue(1); + JObject o = new JObject(); + o.Add("PropertyNameValue", v); + Assert.AreEqual(1, o.Children().Count()); + + bool contains = ((ICollection>)o).Contains(new KeyValuePair("PropertyNameValue", new JValue(1))); + Assert.AreEqual(false, contains); + + contains = ((ICollection>)o).Contains(new KeyValuePair("PropertyNameValue", v)); + Assert.AreEqual(true, contains); + + contains = ((ICollection>)o).Contains(new KeyValuePair("PropertyNameValue", new JValue(2))); + Assert.AreEqual(false, contains); + + contains = ((ICollection>)o).Contains(new KeyValuePair("PropertyNameValue1", new JValue(1))); + Assert.AreEqual(false, contains); + + contains = ((ICollection>)o).Contains(default(KeyValuePair)); + Assert.AreEqual(false, contains); + } + + [Test] + public void GenericDictionaryContains() + { + JObject o = new JObject(); + o.Add("PropertyNameValue", new JValue(1)); + Assert.AreEqual(1, o.Children().Count()); + + bool contains = ((IDictionary)o).ContainsKey("PropertyNameValue"); + Assert.AreEqual(true, contains); + } + + [Test] + public void GenericCollectionCopyTo() + { + JObject o = new JObject(); + o.Add("PropertyNameValue", new JValue(1)); + o.Add("PropertyNameValue2", new JValue(2)); + o.Add("PropertyNameValue3", new JValue(3)); + Assert.AreEqual(3, o.Children().Count()); + + KeyValuePair[] a = new KeyValuePair[5]; + + ((ICollection>)o).CopyTo(a, 1); + + Assert.AreEqual(default(KeyValuePair), a[0]); + + Assert.AreEqual("PropertyNameValue", a[1].Key); + Assert.AreEqual(1, (int)a[1].Value); + + Assert.AreEqual("PropertyNameValue2", a[2].Key); + Assert.AreEqual(2, (int)a[2].Value); + + Assert.AreEqual("PropertyNameValue3", a[3].Key); + Assert.AreEqual(3, (int)a[3].Value); + + Assert.AreEqual(default(KeyValuePair), a[4]); + } + + [Test] + public void GenericCollectionCopyToNullArrayShouldThrow() + { + ExceptionAssert.Throws( + @"Value cannot be null. Parameter name: array", - () => - { - JObject o = new JObject(); - ((ICollection>)o).CopyTo(null, 0); - }); - } + () => + { + JObject o = new JObject(); + ((ICollection>)o).CopyTo(null, 0); + }); + } - [Test] - public void GenericCollectionCopyToNegativeArrayIndexShouldThrow() - { - ExceptionAssert.Throws( - @"arrayIndex is less than 0. + [Test] + public void GenericCollectionCopyToNegativeArrayIndexShouldThrow() + { + ExceptionAssert.Throws( + @"arrayIndex is less than 0. Parameter name: arrayIndex", - () => + () => + { + JObject o = new JObject(); + ((ICollection>)o).CopyTo(new KeyValuePair[1], -1); + }); + } + + [Test] + public void GenericCollectionCopyToArrayIndexEqualGreaterToArrayLengthShouldThrow() { - JObject o = new JObject(); - ((ICollection>)o).CopyTo(new KeyValuePair[1], -1); - }); - } + ExceptionAssert.Throws( + @"arrayIndex is equal to or greater than the length of array.", + () => + { + JObject o = new JObject(); + ((ICollection>)o).CopyTo(new KeyValuePair[1], 1); + }); + } - [Test] - public void GenericCollectionCopyToArrayIndexEqualGreaterToArrayLengthShouldThrow() - { - ExceptionAssert.Throws( - @"arrayIndex is equal to or greater than the length of array.", - () => + [Test] + public void GenericCollectionCopyToInsufficientArrayCapacity() { - JObject o = new JObject(); - ((ICollection>)o).CopyTo(new KeyValuePair[1], 1); - }); - } + ExceptionAssert.Throws( + @"The number of elements in the source JObject is greater than the available space from arrayIndex to the end of the destination array.", + () => + { + JObject o = new JObject(); + o.Add("PropertyNameValue", new JValue(1)); + o.Add("PropertyNameValue2", new JValue(2)); + o.Add("PropertyNameValue3", new JValue(3)); - [Test] - public void GenericCollectionCopyToInsufficientArrayCapacity() - { - ExceptionAssert.Throws( - @"The number of elements in the source JObject is greater than the available space from arrayIndex to the end of the destination array.", - () => + ((ICollection>)o).CopyTo(new KeyValuePair[3], 1); + }); + } + + [Test] + public void FromObjectRaw() { - JObject o = new JObject(); - o.Add("PropertyNameValue", new JValue(1)); - o.Add("PropertyNameValue2", new JValue(2)); - o.Add("PropertyNameValue3", new JValue(3)); + PersonRaw raw = new PersonRaw + { + FirstName = "FirstNameValue", + RawContent = new JRaw("[1,2,3,4,5]"), + LastName = "LastNameValue" + }; - ((ICollection>)o).CopyTo(new KeyValuePair[3], 1); - }); - } + JObject o = JObject.FromObject(raw); - [Test] - public void FromObjectRaw() - { - PersonRaw raw = new PersonRaw - { - FirstName = "FirstNameValue", - RawContent = new JRaw("[1,2,3,4,5]"), - LastName = "LastNameValue" - }; + Assert.AreEqual("FirstNameValue", (string)o["first_name"]); + Assert.AreEqual(JTokenType.Raw, ((JValue)o["RawContent"]).Type); + Assert.AreEqual("[1,2,3,4,5]", (string)o["RawContent"]); + Assert.AreEqual("LastNameValue", (string)o["last_name"]); + } - JObject o = JObject.FromObject(raw); - - Assert.AreEqual("FirstNameValue", (string)o["first_name"]); - Assert.AreEqual(JTokenType.Raw, ((JValue)o["RawContent"]).Type); - Assert.AreEqual("[1,2,3,4,5]", (string)o["RawContent"]); - Assert.AreEqual("LastNameValue", (string)o["last_name"]); - } - - [Test] - public void JTokenReader() - { - PersonRaw raw = new PersonRaw - { - FirstName = "FirstNameValue", - RawContent = new JRaw("[1,2,3,4,5]"), - LastName = "LastNameValue" - }; - - JObject o = JObject.FromObject(raw); - - JsonReader reader = new JTokenReader(o); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.Raw, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.String, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - - Assert.IsFalse(reader.Read()); - } - - [Test] - public void DeserializeFromRaw() - { - PersonRaw raw = new PersonRaw - { - FirstName = "FirstNameValue", - RawContent = new JRaw("[1,2,3,4,5]"), - LastName = "LastNameValue" - }; - - JObject o = JObject.FromObject(raw); - - JsonReader reader = new JTokenReader(o); - JsonSerializer serializer = new JsonSerializer(); - raw = (PersonRaw)serializer.Deserialize(reader, typeof(PersonRaw)); - - Assert.AreEqual("FirstNameValue", raw.FirstName); - Assert.AreEqual("LastNameValue", raw.LastName); - Assert.AreEqual("[1,2,3,4,5]", raw.RawContent.Value); - } - - [Test] - public void Parse_ShouldThrowOnUnexpectedToken() - { - ExceptionAssert.Throws("Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray. Path '', line 1, position 1.", - () => + [Test] + public void JTokenReader() { - string json = @"[""prop""]"; - JObject.Parse(json); - }); - } + PersonRaw raw = new PersonRaw + { + FirstName = "FirstNameValue", + RawContent = new JRaw("[1,2,3,4,5]"), + LastName = "LastNameValue" + }; - [Test] - public void ParseJavaScriptDate() - { - string json = @"[new Date(1207285200000)]"; + JObject o = JObject.FromObject(raw); - JArray a = (JArray)JsonConvert.DeserializeObject(json); - JValue v = (JValue)a[0]; + JsonReader reader = new JTokenReader(o); - Assert.AreEqual(DateTimeUtils.ConvertJavaScriptTicksToDateTime(1207285200000), (DateTime)v); - } + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - [Test] - public void GenericValueCast() - { - string json = @"{""foo"":true}"; - JObject o = (JObject)JsonConvert.DeserializeObject(json); - bool? value = o.Value("foo"); - Assert.AreEqual(true, value); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - json = @"{""foo"":null}"; - o = (JObject)JsonConvert.DeserializeObject(json); - value = o.Value("foo"); - Assert.AreEqual(null, value); - } + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); - [Test] - public void Blog() - { - ExceptionAssert.Throws( - "Invalid property identifier character: ]. Path 'name', line 3, position 5.", - () => + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.Raw, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.String, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + + Assert.IsFalse(reader.Read()); + } + + [Test] + public void DeserializeFromRaw() { - JObject.Parse(@"{ + PersonRaw raw = new PersonRaw + { + FirstName = "FirstNameValue", + RawContent = new JRaw("[1,2,3,4,5]"), + LastName = "LastNameValue" + }; + + JObject o = JObject.FromObject(raw); + + JsonReader reader = new JTokenReader(o); + JsonSerializer serializer = new JsonSerializer(); + raw = (PersonRaw)serializer.Deserialize(reader, typeof(PersonRaw)); + + Assert.AreEqual("FirstNameValue", raw.FirstName); + Assert.AreEqual("LastNameValue", raw.LastName); + Assert.AreEqual("[1,2,3,4,5]", raw.RawContent.Value); + } + + [Test] + public void Parse_ShouldThrowOnUnexpectedToken() + { + ExceptionAssert.Throws("Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray. Path '', line 1, position 1.", + () => + { + string json = @"[""prop""]"; + JObject.Parse(json); + }); + } + + [Test] + public void ParseJavaScriptDate() + { + string json = @"[new Date(1207285200000)]"; + + JArray a = (JArray)JsonConvert.DeserializeObject(json); + JValue v = (JValue)a[0]; + + Assert.AreEqual(DateTimeUtils.ConvertJavaScriptTicksToDateTime(1207285200000), (DateTime)v); + } + + [Test] + public void GenericValueCast() + { + string json = @"{""foo"":true}"; + JObject o = (JObject)JsonConvert.DeserializeObject(json); + bool? value = o.Value("foo"); + Assert.AreEqual(true, value); + + json = @"{""foo"":null}"; + o = (JObject)JsonConvert.DeserializeObject(json); + value = o.Value("foo"); + Assert.AreEqual(null, value); + } + + [Test] + public void Blog() + { + ExceptionAssert.Throws( + "Invalid property identifier character: ]. Path 'name', line 3, position 5.", + () => { JObject.Parse(@"{ ""name"": ""James"", ]!#$THIS IS: BAD JSON![{}}}}] - }"); - }); - } + }"); }); + } - [Test] - public void RawChildValues() - { - JObject o = new JObject(); - o["val1"] = new JRaw("1"); - o["val2"] = new JRaw("1"); + [Test] + public void RawChildValues() + { + JObject o = new JObject(); + o["val1"] = new JRaw("1"); + o["val2"] = new JRaw("1"); - string json = o.ToString(); + string json = o.ToString(); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""val1"": 1, ""val2"": 1 }", json); - } + } - [Test] - public void Iterate() - { - JObject o = new JObject(); - o.Add("PropertyNameValue1", new JValue(1)); - o.Add("PropertyNameValue2", new JValue(2)); + [Test] + public void Iterate() + { + JObject o = new JObject(); + o.Add("PropertyNameValue1", new JValue(1)); + o.Add("PropertyNameValue2", new JValue(2)); - JToken t = o; + JToken t = o; - int i = 1; - foreach (JProperty property in t) - { - Assert.AreEqual("PropertyNameValue" + i, property.Name); - Assert.AreEqual(i, (int)property.Value); + int i = 1; + foreach (JProperty property in t) + { + Assert.AreEqual("PropertyNameValue" + i, property.Name); + Assert.AreEqual(i, (int)property.Value); - i++; - } - } + i++; + } + } - [Test] - public void KeyValuePairIterate() - { - JObject o = new JObject(); - o.Add("PropertyNameValue1", new JValue(1)); - o.Add("PropertyNameValue2", new JValue(2)); + [Test] + public void KeyValuePairIterate() + { + JObject o = new JObject(); + o.Add("PropertyNameValue1", new JValue(1)); + o.Add("PropertyNameValue2", new JValue(2)); - int i = 1; - foreach (KeyValuePair pair in o) - { - Assert.AreEqual("PropertyNameValue" + i, pair.Key); - Assert.AreEqual(i, (int)pair.Value); + int i = 1; + foreach (KeyValuePair pair in o) + { + Assert.AreEqual("PropertyNameValue" + i, pair.Key); + Assert.AreEqual(i, (int)pair.Value); - i++; - } - } + i++; + } + } - [Test] - public void WriteObjectNullStringValue() - { - string s = null; - JValue v = new JValue(s); - Assert.AreEqual(null, v.Value); - Assert.AreEqual(JTokenType.String, v.Type); + [Test] + public void WriteObjectNullStringValue() + { + string s = null; + JValue v = new JValue(s); + Assert.AreEqual(null, v.Value); + Assert.AreEqual(JTokenType.String, v.Type); - JObject o = new JObject(); - o["title"] = v; + JObject o = new JObject(); + o["title"] = v; - string output = o.ToString(); - - Assert.AreEqual(@"{ + string output = o.ToString(); + + Assert.AreEqual(@"{ ""title"": null }", output); - } + } - [Test] - public void Example() - { - string json = @"{ + [Test] + public void Example() + { + string json = @"{ ""Name"": ""Apple"", ""Expiry"": new Date(1230422400000), ""Price"": 3.99, @@ -534,24 +531,24 @@ Parameter name: arrayIndex", ] }"; - JObject o = JObject.Parse(json); + JObject o = JObject.Parse(json); - string name = (string)o["Name"]; - // Apple + string name = (string)o["Name"]; + // Apple - JArray sizes = (JArray)o["Sizes"]; + JArray sizes = (JArray)o["Sizes"]; - string smallest = (string)sizes[0]; - // Small + string smallest = (string)sizes[0]; + // Small - Console.WriteLine(name); - Console.WriteLine(smallest); - } + Console.WriteLine(name); + Console.WriteLine(smallest); + } - [Test] - public void DeserializeClassManually() - { - string jsonText = @"{ + [Test] + public void DeserializeClassManually() + { + string jsonText = @"{ ""short"": { ""original"":""http://www.foo.com/"", @@ -564,39 +561,39 @@ Parameter name: arrayIndex", } }"; - JObject json = JObject.Parse(jsonText); + JObject json = JObject.Parse(jsonText); - Shortie shortie = new Shortie - { - Original = (string)json["short"]["original"], - Short = (string)json["short"]["short"], - Error = new ShortieException - { - Code = (int)json["short"]["error"]["code"], - ErrorMessage = (string)json["short"]["error"]["msg"] - } - }; + Shortie shortie = new Shortie + { + Original = (string)json["short"]["original"], + Short = (string)json["short"]["short"], + Error = new ShortieException + { + Code = (int)json["short"]["error"]["code"], + ErrorMessage = (string)json["short"]["error"]["msg"] + } + }; - Console.WriteLine(shortie.Original); - // http://www.foo.com/ + Console.WriteLine(shortie.Original); + // http://www.foo.com/ - Console.WriteLine(shortie.Error.ErrorMessage); - // No action taken + Console.WriteLine(shortie.Error.ErrorMessage); + // No action taken - Assert.AreEqual("http://www.foo.com/", shortie.Original); - Assert.AreEqual("krehqk", shortie.Short); - Assert.AreEqual(null, shortie.Shortened); - Assert.AreEqual(0, shortie.Error.Code); - Assert.AreEqual("No action taken", shortie.Error.ErrorMessage); - } + Assert.AreEqual("http://www.foo.com/", shortie.Original); + Assert.AreEqual("krehqk", shortie.Short); + Assert.AreEqual(null, shortie.Shortened); + Assert.AreEqual(0, shortie.Error.Code); + Assert.AreEqual("No action taken", shortie.Error.ErrorMessage); + } - [Test] - public void JObjectContainingHtml() - { - JObject o = new JObject(); - o["rc"] = new JValue(200); - o["m"] = new JValue(""); - o["o"] = new JValue(@"
+ [Test] + public void JObjectContainingHtml() + { + JObject o = new JObject(); + o["rc"] = new JValue(200); + o["m"] = new JValue(""); + o["o"] = new JValue(@"
asdf
0 @@ -610,887 +607,887 @@ Parameter name: arrayIndex",
"); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""rc"": 200, ""m"": """", ""o"": ""
\r\n
\r\n asdf
\r\n 0\r\n
\r\n
\r\n

\r\n 444444444\r\n

\r\n
\r\n
\r\n
\r\n
"" }", o.ToString()); - } + } - [Test] - public void ImplicitValueConversions() - { - JObject moss = new JObject(); - moss["FirstName"] = new JValue("Maurice"); - moss["LastName"] = new JValue("Moss"); - moss["BirthDate"] = new JValue(new DateTime(1977, 12, 30)); - moss["Department"] = new JValue("IT"); - moss["JobTitle"] = new JValue("Support"); + [Test] + public void ImplicitValueConversions() + { + JObject moss = new JObject(); + moss["FirstName"] = new JValue("Maurice"); + moss["LastName"] = new JValue("Moss"); + moss["BirthDate"] = new JValue(new DateTime(1977, 12, 30)); + moss["Department"] = new JValue("IT"); + moss["JobTitle"] = new JValue("Support"); - Console.WriteLine(moss.ToString()); - //{ - // "FirstName": "Maurice", - // "LastName": "Moss", - // "BirthDate": "\/Date(252241200000+1300)\/", - // "Department": "IT", - // "JobTitle": "Support" - //} + Console.WriteLine(moss.ToString()); + //{ + // "FirstName": "Maurice", + // "LastName": "Moss", + // "BirthDate": "\/Date(252241200000+1300)\/", + // "Department": "IT", + // "JobTitle": "Support" + //} - JObject jen = new JObject(); - jen["FirstName"] = "Jen"; - jen["LastName"] = "Barber"; - jen["BirthDate"] = new DateTime(1978, 3, 15); - jen["Department"] = "IT"; - jen["JobTitle"] = "Manager"; + JObject jen = new JObject(); + jen["FirstName"] = "Jen"; + jen["LastName"] = "Barber"; + jen["BirthDate"] = new DateTime(1978, 3, 15); + jen["Department"] = "IT"; + jen["JobTitle"] = "Manager"; - Console.WriteLine(jen.ToString()); - //{ - // "FirstName": "Jen", - // "LastName": "Barber", - // "BirthDate": "\/Date(258721200000+1300)\/", - // "Department": "IT", - // "JobTitle": "Manager" - //} - } + Console.WriteLine(jen.ToString()); + //{ + // "FirstName": "Jen", + // "LastName": "Barber", + // "BirthDate": "\/Date(258721200000+1300)\/", + // "Department": "IT", + // "JobTitle": "Manager" + //} + } - [Test] - public void ReplaceJPropertyWithJPropertyWithSameName() - { - JProperty p1 = new JProperty("Test1", 1); - JProperty p2 = new JProperty("Test2", "Two"); + [Test] + public void ReplaceJPropertyWithJPropertyWithSameName() + { + JProperty p1 = new JProperty("Test1", 1); + JProperty p2 = new JProperty("Test2", "Two"); - JObject o = new JObject(p1, p2); - IList l = o; - Assert.AreEqual(p1, l[0]); - Assert.AreEqual(p2, l[1]); + JObject o = new JObject(p1, p2); + IList l = o; + Assert.AreEqual(p1, l[0]); + Assert.AreEqual(p2, l[1]); - JProperty p3 = new JProperty("Test1", "III"); + JProperty p3 = new JProperty("Test1", "III"); - p1.Replace(p3); - Assert.AreEqual(null, p1.Parent); - Assert.AreEqual(l, p3.Parent); + p1.Replace(p3); + Assert.AreEqual(null, p1.Parent); + Assert.AreEqual(l, p3.Parent); - Assert.AreEqual(p3, l[0]); - Assert.AreEqual(p2, l[1]); + Assert.AreEqual(p3, l[0]); + Assert.AreEqual(p2, l[1]); - Assert.AreEqual(2, l.Count); - Assert.AreEqual(2, o.Properties().Count()); + Assert.AreEqual(2, l.Count); + Assert.AreEqual(2, o.Properties().Count()); - JProperty p4 = new JProperty("Test4", "IV"); + JProperty p4 = new JProperty("Test4", "IV"); - p2.Replace(p4); - Assert.AreEqual(null, p2.Parent); - Assert.AreEqual(l, p4.Parent); + p2.Replace(p4); + Assert.AreEqual(null, p2.Parent); + Assert.AreEqual(l, p4.Parent); - Assert.AreEqual(p3, l[0]); - Assert.AreEqual(p4, l[1]); - } + Assert.AreEqual(p3, l[0]); + Assert.AreEqual(p4, l[1]); + } #if !(SILVERLIGHT || NET20 || NETFX_CORE || PORTABLE || PORTABLE40) - [Test] - public void PropertyChanging() - { - object changing = null; - object changed = null; - int changingCount = 0; - int changedCount = 0; - - JObject o = new JObject(); - o.PropertyChanging += (sender, args) => + [Test] + public void PropertyChanging() { - JObject s = (JObject) sender; - changing = (s[args.PropertyName] != null) ? ((JValue)s[args.PropertyName]).Value : null; - changingCount++; - }; - o.PropertyChanged += (sender, args) => - { - JObject s = (JObject)sender; - changed = (s[args.PropertyName] != null) ? ((JValue)s[args.PropertyName]).Value : null; - changedCount++; - }; + object changing = null; + object changed = null; + int changingCount = 0; + int changedCount = 0; - o["StringValue"] = "value1"; - Assert.AreEqual(null, changing); - Assert.AreEqual("value1", changed); - Assert.AreEqual("value1", (string)o["StringValue"]); - Assert.AreEqual(1, changingCount); - Assert.AreEqual(1, changedCount); + JObject o = new JObject(); + o.PropertyChanging += (sender, args) => + { + JObject s = (JObject)sender; + changing = (s[args.PropertyName] != null) ? ((JValue)s[args.PropertyName]).Value : null; + changingCount++; + }; + o.PropertyChanged += (sender, args) => + { + JObject s = (JObject)sender; + changed = (s[args.PropertyName] != null) ? ((JValue)s[args.PropertyName]).Value : null; + changedCount++; + }; - o["StringValue"] = "value1"; - Assert.AreEqual(1, changingCount); - Assert.AreEqual(1, changedCount); + o["StringValue"] = "value1"; + Assert.AreEqual(null, changing); + Assert.AreEqual("value1", changed); + Assert.AreEqual("value1", (string)o["StringValue"]); + Assert.AreEqual(1, changingCount); + Assert.AreEqual(1, changedCount); - o["StringValue"] = "value2"; - Assert.AreEqual("value1", changing); - Assert.AreEqual("value2", changed); - Assert.AreEqual("value2", (string)o["StringValue"]); - Assert.AreEqual(2, changingCount); - Assert.AreEqual(2, changedCount); + o["StringValue"] = "value1"; + Assert.AreEqual(1, changingCount); + Assert.AreEqual(1, changedCount); - o["StringValue"] = null; - Assert.AreEqual("value2", changing); - Assert.AreEqual(null, changed); - Assert.AreEqual(null, (string)o["StringValue"]); - Assert.AreEqual(3, changingCount); - Assert.AreEqual(3, changedCount); + o["StringValue"] = "value2"; + Assert.AreEqual("value1", changing); + Assert.AreEqual("value2", changed); + Assert.AreEqual("value2", (string)o["StringValue"]); + Assert.AreEqual(2, changingCount); + Assert.AreEqual(2, changedCount); - o["NullValue"] = null; - Assert.AreEqual(null, changing); - Assert.AreEqual(null, changed); - Assert.AreEqual(new JValue((object)null), o["NullValue"]); - Assert.AreEqual(4, changingCount); - Assert.AreEqual(4, changedCount); + o["StringValue"] = null; + Assert.AreEqual("value2", changing); + Assert.AreEqual(null, changed); + Assert.AreEqual(null, (string)o["StringValue"]); + Assert.AreEqual(3, changingCount); + Assert.AreEqual(3, changedCount); - o["NullValue"] = null; - Assert.AreEqual(4, changingCount); - Assert.AreEqual(4, changedCount); - } + o["NullValue"] = null; + Assert.AreEqual(null, changing); + Assert.AreEqual(null, changed); + Assert.AreEqual(new JValue((object)null), o["NullValue"]); + Assert.AreEqual(4, changingCount); + Assert.AreEqual(4, changedCount); + + o["NullValue"] = null; + Assert.AreEqual(4, changingCount); + Assert.AreEqual(4, changedCount); + } #endif - [Test] - public void PropertyChanged() - { - object changed = null; - int changedCount = 0; - - JObject o = new JObject(); - o.PropertyChanged += (sender, args) => - { - JObject s = (JObject)sender; - changed = (s[args.PropertyName] != null) ? ((JValue)s[args.PropertyName]).Value : null; - changedCount++; - }; - - o["StringValue"] = "value1"; - Assert.AreEqual("value1", changed); - Assert.AreEqual("value1", (string)o["StringValue"]); - Assert.AreEqual(1, changedCount); - - o["StringValue"] = "value1"; - Assert.AreEqual(1, changedCount); - - o["StringValue"] = "value2"; - Assert.AreEqual("value2", changed); - Assert.AreEqual("value2", (string)o["StringValue"]); - Assert.AreEqual(2, changedCount); - - o["StringValue"] = null; - Assert.AreEqual(null, changed); - Assert.AreEqual(null, (string)o["StringValue"]); - Assert.AreEqual(3, changedCount); - - o["NullValue"] = null; - Assert.AreEqual(null, changed); - Assert.AreEqual(new JValue((object)null), o["NullValue"]); - Assert.AreEqual(4, changedCount); - - o["NullValue"] = null; - Assert.AreEqual(4, changedCount); - } - - [Test] - public void IListContains() - { - JProperty p = new JProperty("Test", 1); - IList l = new JObject(p); - - Assert.IsTrue(l.Contains(p)); - Assert.IsFalse(l.Contains(new JProperty("Test", 1))); - } - - [Test] - public void IListIndexOf() - { - JProperty p = new JProperty("Test", 1); - IList l = new JObject(p); - - Assert.AreEqual(0, l.IndexOf(p)); - Assert.AreEqual(-1, l.IndexOf(new JProperty("Test", 1))); - } - - [Test] - public void IListClear() - { - JProperty p = new JProperty("Test", 1); - IList l = new JObject(p); - - Assert.AreEqual(1, l.Count); - - l.Clear(); - - Assert.AreEqual(0, l.Count); - } - - [Test] - public void IListCopyTo() - { - JProperty p1 = new JProperty("Test1", 1); - JProperty p2 = new JProperty("Test2", "Two"); - IList l = new JObject(p1, p2); - - object[] a = new object[l.Count]; - - l.CopyTo(a, 0); - - Assert.AreEqual(p1, a[0]); - Assert.AreEqual(p2, a[1]); - } - - [Test] - public void IListAdd() - { - JProperty p1 = new JProperty("Test1", 1); - JProperty p2 = new JProperty("Test2", "Two"); - IList l = new JObject(p1, p2); - - JProperty p3 = new JProperty("Test3", "III"); - - l.Add(p3); - - Assert.AreEqual(3, l.Count); - Assert.AreEqual(p3, l[2]); - } - - [Test] - public void IListAddBadToken() - { - ExceptionAssert.Throws( - "Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject.", - () => - { - JProperty p1 = new JProperty("Test1", 1); - JProperty p2 = new JProperty("Test2", "Two"); - IList l = new JObject(p1, p2); - - l.Add(new JValue("Bad!")); - }); - } - - [Test] - public void IListAddBadValue() - { - ExceptionAssert.Throws( - "Argument is not a JToken.", - () => - { - JProperty p1 = new JProperty("Test1", 1); - JProperty p2 = new JProperty("Test2", "Two"); - IList l = new JObject(p1, p2); - - l.Add("Bad!"); - }); - } - - [Test] - public void IListAddPropertyWithExistingName() - { - ExceptionAssert.Throws( - "Can not add property Test2 to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object.", - () => - { - JProperty p1 = new JProperty("Test1", 1); - JProperty p2 = new JProperty("Test2", "Two"); - IList l = new JObject(p1, p2); - - JProperty p3 = new JProperty("Test2", "II"); - - l.Add(p3); - }); - } - - [Test] - public void IListRemove() - { - JProperty p1 = new JProperty("Test1", 1); - JProperty p2 = new JProperty("Test2", "Two"); - IList l = new JObject(p1, p2); - - JProperty p3 = new JProperty("Test3", "III"); - - // won't do anything - l.Remove(p3); - Assert.AreEqual(2, l.Count); - - l.Remove(p1); - Assert.AreEqual(1, l.Count); - Assert.IsFalse(l.Contains(p1)); - Assert.IsTrue(l.Contains(p2)); - - l.Remove(p2); - Assert.AreEqual(0, l.Count); - Assert.IsFalse(l.Contains(p2)); - Assert.AreEqual(null, p2.Parent); - } - - [Test] - public void IListRemoveAt() - { - JProperty p1 = new JProperty("Test1", 1); - JProperty p2 = new JProperty("Test2", "Two"); - IList l = new JObject(p1, p2); - - // won't do anything - l.RemoveAt(0); - - l.Remove(p1); - Assert.AreEqual(1, l.Count); - - l.Remove(p2); - Assert.AreEqual(0, l.Count); - } - - [Test] - public void IListInsert() - { - JProperty p1 = new JProperty("Test1", 1); - JProperty p2 = new JProperty("Test2", "Two"); - IList l = new JObject(p1, p2); - - JProperty p3 = new JProperty("Test3", "III"); - - l.Insert(1, p3); - Assert.AreEqual(l, p3.Parent); - - Assert.AreEqual(p1, l[0]); - Assert.AreEqual(p3, l[1]); - Assert.AreEqual(p2, l[2]); - } - - [Test] - public void IListIsReadOnly() - { - IList l = new JObject(); - Assert.IsFalse(l.IsReadOnly); - } - - [Test] - public void IListIsFixedSize() - { - IList l = new JObject(); - Assert.IsFalse(l.IsFixedSize); - } - - [Test] - public void IListSetItem() - { - JProperty p1 = new JProperty("Test1", 1); - JProperty p2 = new JProperty("Test2", "Two"); - IList l = new JObject(p1, p2); - - JProperty p3 = new JProperty("Test3", "III"); - - l[0] = p3; - - Assert.AreEqual(p3, l[0]); - Assert.AreEqual(p2, l[1]); - } - - [Test] - public void IListSetItemAlreadyExists() - { - ExceptionAssert.Throws( - "Can not add property Test3 to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object.", - () => - { - JProperty p1 = new JProperty("Test1", 1); - JProperty p2 = new JProperty("Test2", "Two"); - IList l = new JObject(p1, p2); - - JProperty p3 = new JProperty("Test3", "III"); - - l[0] = p3; - l[1] = p3; - }); - } - - [Test] - public void IListSetItemInvalid() - { - ExceptionAssert.Throws( - @"Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject.", - () => - { - JProperty p1 = new JProperty("Test1", 1); - JProperty p2 = new JProperty("Test2", "Two"); - IList l = new JObject(p1, p2); - - l[0] = new JValue(true); - }); - } - - [Test] - public void IListSyncRoot() - { - JProperty p1 = new JProperty("Test1", 1); - JProperty p2 = new JProperty("Test2", "Two"); - IList l = new JObject(p1, p2); - - Assert.IsNotNull(l.SyncRoot); - } - - [Test] - public void IListIsSynchronized() - { - JProperty p1 = new JProperty("Test1", 1); - JProperty p2 = new JProperty("Test2", "Two"); - IList l = new JObject(p1, p2); - - Assert.IsFalse(l.IsSynchronized); - } - - [Test] - public void GenericListJTokenContains() - { - JProperty p = new JProperty("Test", 1); - IList l = new JObject(p); - - Assert.IsTrue(l.Contains(p)); - Assert.IsFalse(l.Contains(new JProperty("Test", 1))); - } - - [Test] - public void GenericListJTokenIndexOf() - { - JProperty p = new JProperty("Test", 1); - IList l = new JObject(p); - - Assert.AreEqual(0, l.IndexOf(p)); - Assert.AreEqual(-1, l.IndexOf(new JProperty("Test", 1))); - } - - [Test] - public void GenericListJTokenClear() - { - JProperty p = new JProperty("Test", 1); - IList l = new JObject(p); - - Assert.AreEqual(1, l.Count); - - l.Clear(); - - Assert.AreEqual(0, l.Count); - } - - [Test] - public void GenericListJTokenCopyTo() - { - JProperty p1 = new JProperty("Test1", 1); - JProperty p2 = new JProperty("Test2", "Two"); - IList l = new JObject(p1, p2); - - JToken[] a = new JToken[l.Count]; - - l.CopyTo(a, 0); - - Assert.AreEqual(p1, a[0]); - Assert.AreEqual(p2, a[1]); - } - - [Test] - public void GenericListJTokenAdd() - { - JProperty p1 = new JProperty("Test1", 1); - JProperty p2 = new JProperty("Test2", "Two"); - IList l = new JObject(p1, p2); - - JProperty p3 = new JProperty("Test3", "III"); - - l.Add(p3); - - Assert.AreEqual(3, l.Count); - Assert.AreEqual(p3, l[2]); - } - - [Test] - public void GenericListJTokenAddBadToken() - { - ExceptionAssert.Throws("Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject.", - () => - { - JProperty p1 = new JProperty("Test1", 1); - JProperty p2 = new JProperty("Test2", "Two"); - IList l = new JObject(p1, p2); - - l.Add(new JValue("Bad!")); - }); - } - - [Test] - public void GenericListJTokenAddBadValue() - { - ExceptionAssert.Throws("Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject.", - () => + [Test] + public void PropertyChanged() { - JProperty p1 = new JProperty("Test1", 1); - JProperty p2 = new JProperty("Test2", "Two"); - IList l = new JObject(p1, p2); + object changed = null; + int changedCount = 0; - // string is implicitly converted to JValue - l.Add("Bad!"); - }); - } + JObject o = new JObject(); + o.PropertyChanged += (sender, args) => + { + JObject s = (JObject)sender; + changed = (s[args.PropertyName] != null) ? ((JValue)s[args.PropertyName]).Value : null; + changedCount++; + }; - [Test] - public void GenericListJTokenAddPropertyWithExistingName() - { - ExceptionAssert.Throws("Can not add property Test2 to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object.", - () => + o["StringValue"] = "value1"; + Assert.AreEqual("value1", changed); + Assert.AreEqual("value1", (string)o["StringValue"]); + Assert.AreEqual(1, changedCount); + + o["StringValue"] = "value1"; + Assert.AreEqual(1, changedCount); + + o["StringValue"] = "value2"; + Assert.AreEqual("value2", changed); + Assert.AreEqual("value2", (string)o["StringValue"]); + Assert.AreEqual(2, changedCount); + + o["StringValue"] = null; + Assert.AreEqual(null, changed); + Assert.AreEqual(null, (string)o["StringValue"]); + Assert.AreEqual(3, changedCount); + + o["NullValue"] = null; + Assert.AreEqual(null, changed); + Assert.AreEqual(new JValue((object)null), o["NullValue"]); + Assert.AreEqual(4, changedCount); + + o["NullValue"] = null; + Assert.AreEqual(4, changedCount); + } + + [Test] + public void IListContains() { - JProperty p1 = new JProperty("Test1", 1); - JProperty p2 = new JProperty("Test2", "Two"); - IList l = new JObject(p1, p2); + JProperty p = new JProperty("Test", 1); + IList l = new JObject(p); - JProperty p3 = new JProperty("Test2", "II"); + Assert.IsTrue(l.Contains(p)); + Assert.IsFalse(l.Contains(new JProperty("Test", 1))); + } - l.Add(p3); - }); - } + [Test] + public void IListIndexOf() + { + JProperty p = new JProperty("Test", 1); + IList l = new JObject(p); - [Test] - public void GenericListJTokenRemove() - { - JProperty p1 = new JProperty("Test1", 1); - JProperty p2 = new JProperty("Test2", "Two"); - IList l = new JObject(p1, p2); + Assert.AreEqual(0, l.IndexOf(p)); + Assert.AreEqual(-1, l.IndexOf(new JProperty("Test", 1))); + } - JProperty p3 = new JProperty("Test3", "III"); + [Test] + public void IListClear() + { + JProperty p = new JProperty("Test", 1); + IList l = new JObject(p); - // won't do anything - Assert.IsFalse(l.Remove(p3)); - Assert.AreEqual(2, l.Count); + Assert.AreEqual(1, l.Count); - Assert.IsTrue(l.Remove(p1)); - Assert.AreEqual(1, l.Count); - Assert.IsFalse(l.Contains(p1)); - Assert.IsTrue(l.Contains(p2)); + l.Clear(); - Assert.IsTrue(l.Remove(p2)); - Assert.AreEqual(0, l.Count); - Assert.IsFalse(l.Contains(p2)); - Assert.AreEqual(null, p2.Parent); - } + Assert.AreEqual(0, l.Count); + } - [Test] - public void GenericListJTokenRemoveAt() - { - JProperty p1 = new JProperty("Test1", 1); - JProperty p2 = new JProperty("Test2", "Two"); - IList l = new JObject(p1, p2); + [Test] + public void IListCopyTo() + { + JProperty p1 = new JProperty("Test1", 1); + JProperty p2 = new JProperty("Test2", "Two"); + IList l = new JObject(p1, p2); - // won't do anything - l.RemoveAt(0); + object[] a = new object[l.Count]; - l.Remove(p1); - Assert.AreEqual(1, l.Count); + l.CopyTo(a, 0); - l.Remove(p2); - Assert.AreEqual(0, l.Count); - } + Assert.AreEqual(p1, a[0]); + Assert.AreEqual(p2, a[1]); + } - [Test] - public void GenericListJTokenInsert() - { - JProperty p1 = new JProperty("Test1", 1); - JProperty p2 = new JProperty("Test2", "Two"); - IList l = new JObject(p1, p2); + [Test] + public void IListAdd() + { + JProperty p1 = new JProperty("Test1", 1); + JProperty p2 = new JProperty("Test2", "Two"); + IList l = new JObject(p1, p2); - JProperty p3 = new JProperty("Test3", "III"); + JProperty p3 = new JProperty("Test3", "III"); - l.Insert(1, p3); - Assert.AreEqual(l, p3.Parent); + l.Add(p3); - Assert.AreEqual(p1, l[0]); - Assert.AreEqual(p3, l[1]); - Assert.AreEqual(p2, l[2]); - } + Assert.AreEqual(3, l.Count); + Assert.AreEqual(p3, l[2]); + } - [Test] - public void GenericListJTokenIsReadOnly() - { - IList l = new JObject(); - Assert.IsFalse(l.IsReadOnly); - } + [Test] + public void IListAddBadToken() + { + ExceptionAssert.Throws( + "Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject.", + () => + { + JProperty p1 = new JProperty("Test1", 1); + JProperty p2 = new JProperty("Test2", "Two"); + IList l = new JObject(p1, p2); - [Test] - public void GenericListJTokenSetItem() - { - JProperty p1 = new JProperty("Test1", 1); - JProperty p2 = new JProperty("Test2", "Two"); - IList l = new JObject(p1, p2); + l.Add(new JValue("Bad!")); + }); + } - JProperty p3 = new JProperty("Test3", "III"); + [Test] + public void IListAddBadValue() + { + ExceptionAssert.Throws( + "Argument is not a JToken.", + () => + { + JProperty p1 = new JProperty("Test1", 1); + JProperty p2 = new JProperty("Test2", "Two"); + IList l = new JObject(p1, p2); - l[0] = p3; + l.Add("Bad!"); + }); + } - Assert.AreEqual(p3, l[0]); - Assert.AreEqual(p2, l[1]); - } + [Test] + public void IListAddPropertyWithExistingName() + { + ExceptionAssert.Throws( + "Can not add property Test2 to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object.", + () => + { + JProperty p1 = new JProperty("Test1", 1); + JProperty p2 = new JProperty("Test2", "Two"); + IList l = new JObject(p1, p2); - [Test] - public void GenericListJTokenSetItemAlreadyExists() - { - ExceptionAssert.Throws("Can not add property Test3 to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object.", - () => - { - JProperty p1 = new JProperty("Test1", 1); - JProperty p2 = new JProperty("Test2", "Two"); - IList l = new JObject(p1, p2); + JProperty p3 = new JProperty("Test2", "II"); - JProperty p3 = new JProperty("Test3", "III"); + l.Add(p3); + }); + } - l[0] = p3; - l[1] = p3; - }); - } + [Test] + public void IListRemove() + { + JProperty p1 = new JProperty("Test1", 1); + JProperty p2 = new JProperty("Test2", "Two"); + IList l = new JObject(p1, p2); + + JProperty p3 = new JProperty("Test3", "III"); + + // won't do anything + l.Remove(p3); + Assert.AreEqual(2, l.Count); + + l.Remove(p1); + Assert.AreEqual(1, l.Count); + Assert.IsFalse(l.Contains(p1)); + Assert.IsTrue(l.Contains(p2)); + + l.Remove(p2); + Assert.AreEqual(0, l.Count); + Assert.IsFalse(l.Contains(p2)); + Assert.AreEqual(null, p2.Parent); + } + + [Test] + public void IListRemoveAt() + { + JProperty p1 = new JProperty("Test1", 1); + JProperty p2 = new JProperty("Test2", "Two"); + IList l = new JObject(p1, p2); + + // won't do anything + l.RemoveAt(0); + + l.Remove(p1); + Assert.AreEqual(1, l.Count); + + l.Remove(p2); + Assert.AreEqual(0, l.Count); + } + + [Test] + public void IListInsert() + { + JProperty p1 = new JProperty("Test1", 1); + JProperty p2 = new JProperty("Test2", "Two"); + IList l = new JObject(p1, p2); + + JProperty p3 = new JProperty("Test3", "III"); + + l.Insert(1, p3); + Assert.AreEqual(l, p3.Parent); + + Assert.AreEqual(p1, l[0]); + Assert.AreEqual(p3, l[1]); + Assert.AreEqual(p2, l[2]); + } + + [Test] + public void IListIsReadOnly() + { + IList l = new JObject(); + Assert.IsFalse(l.IsReadOnly); + } + + [Test] + public void IListIsFixedSize() + { + IList l = new JObject(); + Assert.IsFalse(l.IsFixedSize); + } + + [Test] + public void IListSetItem() + { + JProperty p1 = new JProperty("Test1", 1); + JProperty p2 = new JProperty("Test2", "Two"); + IList l = new JObject(p1, p2); + + JProperty p3 = new JProperty("Test3", "III"); + + l[0] = p3; + + Assert.AreEqual(p3, l[0]); + Assert.AreEqual(p2, l[1]); + } + + [Test] + public void IListSetItemAlreadyExists() + { + ExceptionAssert.Throws( + "Can not add property Test3 to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object.", + () => + { + JProperty p1 = new JProperty("Test1", 1); + JProperty p2 = new JProperty("Test2", "Two"); + IList l = new JObject(p1, p2); + + JProperty p3 = new JProperty("Test3", "III"); + + l[0] = p3; + l[1] = p3; + }); + } + + [Test] + public void IListSetItemInvalid() + { + ExceptionAssert.Throws( + @"Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject.", + () => + { + JProperty p1 = new JProperty("Test1", 1); + JProperty p2 = new JProperty("Test2", "Two"); + IList l = new JObject(p1, p2); + + l[0] = new JValue(true); + }); + } + + [Test] + public void IListSyncRoot() + { + JProperty p1 = new JProperty("Test1", 1); + JProperty p2 = new JProperty("Test2", "Two"); + IList l = new JObject(p1, p2); + + Assert.IsNotNull(l.SyncRoot); + } + + [Test] + public void IListIsSynchronized() + { + JProperty p1 = new JProperty("Test1", 1); + JProperty p2 = new JProperty("Test2", "Two"); + IList l = new JObject(p1, p2); + + Assert.IsFalse(l.IsSynchronized); + } + + [Test] + public void GenericListJTokenContains() + { + JProperty p = new JProperty("Test", 1); + IList l = new JObject(p); + + Assert.IsTrue(l.Contains(p)); + Assert.IsFalse(l.Contains(new JProperty("Test", 1))); + } + + [Test] + public void GenericListJTokenIndexOf() + { + JProperty p = new JProperty("Test", 1); + IList l = new JObject(p); + + Assert.AreEqual(0, l.IndexOf(p)); + Assert.AreEqual(-1, l.IndexOf(new JProperty("Test", 1))); + } + + [Test] + public void GenericListJTokenClear() + { + JProperty p = new JProperty("Test", 1); + IList l = new JObject(p); + + Assert.AreEqual(1, l.Count); + + l.Clear(); + + Assert.AreEqual(0, l.Count); + } + + [Test] + public void GenericListJTokenCopyTo() + { + JProperty p1 = new JProperty("Test1", 1); + JProperty p2 = new JProperty("Test2", "Two"); + IList l = new JObject(p1, p2); + + JToken[] a = new JToken[l.Count]; + + l.CopyTo(a, 0); + + Assert.AreEqual(p1, a[0]); + Assert.AreEqual(p2, a[1]); + } + + [Test] + public void GenericListJTokenAdd() + { + JProperty p1 = new JProperty("Test1", 1); + JProperty p2 = new JProperty("Test2", "Two"); + IList l = new JObject(p1, p2); + + JProperty p3 = new JProperty("Test3", "III"); + + l.Add(p3); + + Assert.AreEqual(3, l.Count); + Assert.AreEqual(p3, l[2]); + } + + [Test] + public void GenericListJTokenAddBadToken() + { + ExceptionAssert.Throws("Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject.", + () => + { + JProperty p1 = new JProperty("Test1", 1); + JProperty p2 = new JProperty("Test2", "Two"); + IList l = new JObject(p1, p2); + + l.Add(new JValue("Bad!")); + }); + } + + [Test] + public void GenericListJTokenAddBadValue() + { + ExceptionAssert.Throws("Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject.", + () => + { + JProperty p1 = new JProperty("Test1", 1); + JProperty p2 = new JProperty("Test2", "Two"); + IList l = new JObject(p1, p2); + + // string is implicitly converted to JValue + l.Add("Bad!"); + }); + } + + [Test] + public void GenericListJTokenAddPropertyWithExistingName() + { + ExceptionAssert.Throws("Can not add property Test2 to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object.", + () => + { + JProperty p1 = new JProperty("Test1", 1); + JProperty p2 = new JProperty("Test2", "Two"); + IList l = new JObject(p1, p2); + + JProperty p3 = new JProperty("Test2", "II"); + + l.Add(p3); + }); + } + + [Test] + public void GenericListJTokenRemove() + { + JProperty p1 = new JProperty("Test1", 1); + JProperty p2 = new JProperty("Test2", "Two"); + IList l = new JObject(p1, p2); + + JProperty p3 = new JProperty("Test3", "III"); + + // won't do anything + Assert.IsFalse(l.Remove(p3)); + Assert.AreEqual(2, l.Count); + + Assert.IsTrue(l.Remove(p1)); + Assert.AreEqual(1, l.Count); + Assert.IsFalse(l.Contains(p1)); + Assert.IsTrue(l.Contains(p2)); + + Assert.IsTrue(l.Remove(p2)); + Assert.AreEqual(0, l.Count); + Assert.IsFalse(l.Contains(p2)); + Assert.AreEqual(null, p2.Parent); + } + + [Test] + public void GenericListJTokenRemoveAt() + { + JProperty p1 = new JProperty("Test1", 1); + JProperty p2 = new JProperty("Test2", "Two"); + IList l = new JObject(p1, p2); + + // won't do anything + l.RemoveAt(0); + + l.Remove(p1); + Assert.AreEqual(1, l.Count); + + l.Remove(p2); + Assert.AreEqual(0, l.Count); + } + + [Test] + public void GenericListJTokenInsert() + { + JProperty p1 = new JProperty("Test1", 1); + JProperty p2 = new JProperty("Test2", "Two"); + IList l = new JObject(p1, p2); + + JProperty p3 = new JProperty("Test3", "III"); + + l.Insert(1, p3); + Assert.AreEqual(l, p3.Parent); + + Assert.AreEqual(p1, l[0]); + Assert.AreEqual(p3, l[1]); + Assert.AreEqual(p2, l[2]); + } + + [Test] + public void GenericListJTokenIsReadOnly() + { + IList l = new JObject(); + Assert.IsFalse(l.IsReadOnly); + } + + [Test] + public void GenericListJTokenSetItem() + { + JProperty p1 = new JProperty("Test1", 1); + JProperty p2 = new JProperty("Test2", "Two"); + IList l = new JObject(p1, p2); + + JProperty p3 = new JProperty("Test3", "III"); + + l[0] = p3; + + Assert.AreEqual(p3, l[0]); + Assert.AreEqual(p2, l[1]); + } + + [Test] + public void GenericListJTokenSetItemAlreadyExists() + { + ExceptionAssert.Throws("Can not add property Test3 to Newtonsoft.Json.Linq.JObject. Property with the same name already exists on object.", + () => + { + JProperty p1 = new JProperty("Test1", 1); + JProperty p2 = new JProperty("Test2", "Two"); + IList l = new JObject(p1, p2); + + JProperty p3 = new JProperty("Test3", "III"); + + l[0] = p3; + l[1] = p3; + }); + } #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - [Test] - public void IBindingListSortDirection() - { - IBindingList l = new JObject(); - Assert.AreEqual(ListSortDirection.Ascending, l.SortDirection); - } - - [Test] - public void IBindingListSortProperty() - { - IBindingList l = new JObject(); - Assert.AreEqual(null, l.SortProperty); - } - - [Test] - public void IBindingListSupportsChangeNotification() - { - IBindingList l = new JObject(); - Assert.AreEqual(true, l.SupportsChangeNotification); - } - - [Test] - public void IBindingListSupportsSearching() - { - IBindingList l = new JObject(); - Assert.AreEqual(false, l.SupportsSearching); - } - - [Test] - public void IBindingListSupportsSorting() - { - IBindingList l = new JObject(); - Assert.AreEqual(false, l.SupportsSorting); - } - - [Test] - public void IBindingListAllowEdit() - { - IBindingList l = new JObject(); - Assert.AreEqual(true, l.AllowEdit); - } - - [Test] - public void IBindingListAllowNew() - { - IBindingList l = new JObject(); - Assert.AreEqual(true, l.AllowNew); - } - - [Test] - public void IBindingListAllowRemove() - { - IBindingList l = new JObject(); - Assert.AreEqual(true, l.AllowRemove); - } - - [Test] - public void IBindingListAddIndex() - { - IBindingList l = new JObject(); - // do nothing - l.AddIndex(null); - } - - [Test] - public void IBindingListApplySort() - { - ExceptionAssert.Throws( - "Specified method is not supported.", - () => + [Test] + public void IBindingListSortDirection() { - IBindingList l = new JObject(); - l.ApplySort(null, ListSortDirection.Ascending); - }); - } + IBindingList l = new JObject(); + Assert.AreEqual(ListSortDirection.Ascending, l.SortDirection); + } - [Test] - public void IBindingListRemoveSort() - { - ExceptionAssert.Throws( - "Specified method is not supported.", - () => + [Test] + public void IBindingListSortProperty() { - IBindingList l = new JObject(); - l.RemoveSort(); - }); - } + IBindingList l = new JObject(); + Assert.AreEqual(null, l.SortProperty); + } - [Test] - public void IBindingListRemoveIndex() - { - IBindingList l = new JObject(); - // do nothing - l.RemoveIndex(null); - } - - [Test] - public void IBindingListFind() - { - ExceptionAssert.Throws( - "Specified method is not supported.", - () => + [Test] + public void IBindingListSupportsChangeNotification() { - IBindingList l = new JObject(); - l.Find(null, null); - }); - } + IBindingList l = new JObject(); + Assert.AreEqual(true, l.SupportsChangeNotification); + } - [Test] - public void IBindingListIsSorted() - { - IBindingList l = new JObject(); - Assert.AreEqual(false, l.IsSorted); - } - - [Test] - public void IBindingListAddNew() - { - ExceptionAssert.Throws( - "Could not determine new value to add to 'Newtonsoft.Json.Linq.JObject'.", - () => + [Test] + public void IBindingListSupportsSearching() { - IBindingList l = new JObject(); - l.AddNew(); - }); - } + IBindingList l = new JObject(); + Assert.AreEqual(false, l.SupportsSearching); + } - [Test] - public void IBindingListAddNewWithEvent() - { - JObject o = new JObject(); - o._addingNew += (s, e) => e.NewObject = new JProperty("Property!"); - - IBindingList l = o; - object newObject = l.AddNew(); - Assert.IsNotNull(newObject); - - JProperty p = (JProperty) newObject; - Assert.AreEqual("Property!", p.Name); - Assert.AreEqual(o, p.Parent); - } - - [Test] - public void ITypedListGetListName() - { - JProperty p1 = new JProperty("Test1", 1); - JProperty p2 = new JProperty("Test2", "Two"); - ITypedList l = new JObject(p1, p2); - - Assert.AreEqual(string.Empty, l.GetListName(null)); - } - - [Test] - public void ITypedListGetItemProperties() - { - JProperty p1 = new JProperty("Test1", 1); - JProperty p2 = new JProperty("Test2", "Two"); - ITypedList l = new JObject(p1, p2); - - PropertyDescriptorCollection propertyDescriptors = l.GetItemProperties(null); - Assert.IsNull(propertyDescriptors); - } - - [Test] - public void ListChanged() - { - JProperty p1 = new JProperty("Test1", 1); - JProperty p2 = new JProperty("Test2", "Two"); - JObject o = new JObject(p1, p2); - - ListChangedType? changedType = null; - int? index = null; - - o.ListChanged += (s, a) => + [Test] + public void IBindingListSupportsSorting() { - changedType = a.ListChangedType; - index = a.NewIndex; - }; + IBindingList l = new JObject(); + Assert.AreEqual(false, l.SupportsSorting); + } - JProperty p3 = new JProperty("Test3", "III"); + [Test] + public void IBindingListAllowEdit() + { + IBindingList l = new JObject(); + Assert.AreEqual(true, l.AllowEdit); + } - o.Add(p3); - Assert.AreEqual(changedType, ListChangedType.ItemAdded); - Assert.AreEqual(index, 2); - Assert.AreEqual(p3, ((IList)o)[index.Value]); + [Test] + public void IBindingListAllowNew() + { + IBindingList l = new JObject(); + Assert.AreEqual(true, l.AllowNew); + } - JProperty p4 = new JProperty("Test4", "IV"); + [Test] + public void IBindingListAllowRemove() + { + IBindingList l = new JObject(); + Assert.AreEqual(true, l.AllowRemove); + } - ((IList) o)[index.Value] = p4; - Assert.AreEqual(changedType, ListChangedType.ItemChanged); - Assert.AreEqual(index, 2); - Assert.AreEqual(p4, ((IList)o)[index.Value]); - Assert.IsFalse(((IList)o).Contains(p3)); - Assert.IsTrue(((IList)o).Contains(p4)); + [Test] + public void IBindingListAddIndex() + { + IBindingList l = new JObject(); + // do nothing + l.AddIndex(null); + } - o["Test1"] = 2; - Assert.AreEqual(changedType, ListChangedType.ItemChanged); - Assert.AreEqual(index, 0); - Assert.AreEqual(2, (int)o["Test1"]); - } + [Test] + public void IBindingListApplySort() + { + ExceptionAssert.Throws( + "Specified method is not supported.", + () => + { + IBindingList l = new JObject(); + l.ApplySort(null, ListSortDirection.Ascending); + }); + } + + [Test] + public void IBindingListRemoveSort() + { + ExceptionAssert.Throws( + "Specified method is not supported.", + () => + { + IBindingList l = new JObject(); + l.RemoveSort(); + }); + } + + [Test] + public void IBindingListRemoveIndex() + { + IBindingList l = new JObject(); + // do nothing + l.RemoveIndex(null); + } + + [Test] + public void IBindingListFind() + { + ExceptionAssert.Throws( + "Specified method is not supported.", + () => + { + IBindingList l = new JObject(); + l.Find(null, null); + }); + } + + [Test] + public void IBindingListIsSorted() + { + IBindingList l = new JObject(); + Assert.AreEqual(false, l.IsSorted); + } + + [Test] + public void IBindingListAddNew() + { + ExceptionAssert.Throws( + "Could not determine new value to add to 'Newtonsoft.Json.Linq.JObject'.", + () => + { + IBindingList l = new JObject(); + l.AddNew(); + }); + } + + [Test] + public void IBindingListAddNewWithEvent() + { + JObject o = new JObject(); + o._addingNew += (s, e) => e.NewObject = new JProperty("Property!"); + + IBindingList l = o; + object newObject = l.AddNew(); + Assert.IsNotNull(newObject); + + JProperty p = (JProperty)newObject; + Assert.AreEqual("Property!", p.Name); + Assert.AreEqual(o, p.Parent); + } + + [Test] + public void ITypedListGetListName() + { + JProperty p1 = new JProperty("Test1", 1); + JProperty p2 = new JProperty("Test2", "Two"); + ITypedList l = new JObject(p1, p2); + + Assert.AreEqual(string.Empty, l.GetListName(null)); + } + + [Test] + public void ITypedListGetItemProperties() + { + JProperty p1 = new JProperty("Test1", 1); + JProperty p2 = new JProperty("Test2", "Two"); + ITypedList l = new JObject(p1, p2); + + PropertyDescriptorCollection propertyDescriptors = l.GetItemProperties(null); + Assert.IsNull(propertyDescriptors); + } + + [Test] + public void ListChanged() + { + JProperty p1 = new JProperty("Test1", 1); + JProperty p2 = new JProperty("Test2", "Two"); + JObject o = new JObject(p1, p2); + + ListChangedType? changedType = null; + int? index = null; + + o.ListChanged += (s, a) => + { + changedType = a.ListChangedType; + index = a.NewIndex; + }; + + JProperty p3 = new JProperty("Test3", "III"); + + o.Add(p3); + Assert.AreEqual(changedType, ListChangedType.ItemAdded); + Assert.AreEqual(index, 2); + Assert.AreEqual(p3, ((IList)o)[index.Value]); + + JProperty p4 = new JProperty("Test4", "IV"); + + ((IList)o)[index.Value] = p4; + Assert.AreEqual(changedType, ListChangedType.ItemChanged); + Assert.AreEqual(index, 2); + Assert.AreEqual(p4, ((IList)o)[index.Value]); + Assert.IsFalse(((IList)o).Contains(p3)); + Assert.IsTrue(((IList)o).Contains(p4)); + + o["Test1"] = 2; + Assert.AreEqual(changedType, ListChangedType.ItemChanged); + Assert.AreEqual(index, 0); + Assert.AreEqual(2, (int)o["Test1"]); + } #endif #if SILVERLIGHT || !(NET20 || NET35 || PORTABLE40) - [Test] - public void CollectionChanged() - { - JProperty p1 = new JProperty("Test1", 1); - JProperty p2 = new JProperty("Test2", "Two"); - JObject o = new JObject(p1, p2); + [Test] + public void CollectionChanged() + { + JProperty p1 = new JProperty("Test1", 1); + JProperty p2 = new JProperty("Test2", "Two"); + JObject o = new JObject(p1, p2); - NotifyCollectionChangedAction? changedType = null; - int? index = null; + NotifyCollectionChangedAction? changedType = null; + int? index = null; - o._collectionChanged += (s, a) => - { - changedType = a.Action; - index = a.NewStartingIndex; - }; + o._collectionChanged += (s, a) => + { + changedType = a.Action; + index = a.NewStartingIndex; + }; - JProperty p3 = new JProperty("Test3", "III"); + JProperty p3 = new JProperty("Test3", "III"); - o.Add(p3); - Assert.AreEqual(changedType, NotifyCollectionChangedAction.Add); - Assert.AreEqual(index, 2); - Assert.AreEqual(p3, ((IList)o)[index.Value]); + o.Add(p3); + Assert.AreEqual(changedType, NotifyCollectionChangedAction.Add); + Assert.AreEqual(index, 2); + Assert.AreEqual(p3, ((IList)o)[index.Value]); - JProperty p4 = new JProperty("Test4", "IV"); + JProperty p4 = new JProperty("Test4", "IV"); - ((IList)o)[index.Value] = p4; - Assert.AreEqual(changedType, NotifyCollectionChangedAction.Replace); - Assert.AreEqual(index, 2); - Assert.AreEqual(p4, ((IList)o)[index.Value]); - Assert.IsFalse(((IList)o).Contains(p3)); - Assert.IsTrue(((IList)o).Contains(p4)); + ((IList)o)[index.Value] = p4; + Assert.AreEqual(changedType, NotifyCollectionChangedAction.Replace); + Assert.AreEqual(index, 2); + Assert.AreEqual(p4, ((IList)o)[index.Value]); + Assert.IsFalse(((IList)o).Contains(p3)); + Assert.IsTrue(((IList)o).Contains(p4)); - o["Test1"] = 2; - Assert.AreEqual(changedType, NotifyCollectionChangedAction.Replace); - Assert.AreEqual(index, 0); - Assert.AreEqual(2, (int)o["Test1"]); - } + o["Test1"] = 2; + Assert.AreEqual(changedType, NotifyCollectionChangedAction.Replace); + Assert.AreEqual(index, 0); + Assert.AreEqual(2, (int)o["Test1"]); + } #endif - [Test] - public void GetGeocodeAddress() - { - string json = @"{ + [Test] + public void GetGeocodeAddress() + { + string json = @"{ ""name"": ""Address: 435 North Mulford Road Rockford, IL 61107"", ""Status"": { ""code"": 200, @@ -1535,118 +1532,115 @@ Parameter name: arrayIndex", } ] }"; - JObject o = JObject.Parse(json); + JObject o = JObject.Parse(json); - string searchAddress = (string)o["Placemark"][0]["AddressDetails"]["Country"]["AdministrativeArea"]["SubAdministrativeArea"]["Locality"]["Thoroughfare"]["ThoroughfareName"]; - Assert.AreEqual("435 N Mulford Rd", searchAddress); - } + string searchAddress = (string)o["Placemark"][0]["AddressDetails"]["Country"]["AdministrativeArea"]["SubAdministrativeArea"]["Locality"]["Thoroughfare"]["ThoroughfareName"]; + Assert.AreEqual("435 N Mulford Rd", searchAddress); + } - [Test] - public void SetValueWithInvalidPropertyName() - { - ExceptionAssert.Throws("Set JObject values with invalid key value: 0. Object property name expected.", - () => + [Test] + public void SetValueWithInvalidPropertyName() { - JObject o = new JObject(); - o[0] = new JValue(3); - }); - } + ExceptionAssert.Throws("Set JObject values with invalid key value: 0. Object property name expected.", + () => + { + JObject o = new JObject(); + o[0] = new JValue(3); + }); + } - [Test] - public void SetValue() - { - object key = "TestKey"; + [Test] + public void SetValue() + { + object key = "TestKey"; - JObject o = new JObject(); - o[key] = new JValue(3); + JObject o = new JObject(); + o[key] = new JValue(3); - Assert.AreEqual(3, (int)o[key]); - } + Assert.AreEqual(3, (int)o[key]); + } - [Test] - public void ParseMultipleProperties() - { - string json = @"{ + [Test] + public void ParseMultipleProperties() + { + string json = @"{ ""Name"": ""Name1"", ""Name"": ""Name2"" }"; - JObject o = JObject.Parse(json); - string value = (string)o["Name"]; + JObject o = JObject.Parse(json); + string value = (string)o["Name"]; - Assert.AreEqual("Name2", value); - } + Assert.AreEqual("Name2", value); + } #if !(NETFX_CORE || PORTABLE || PORTABLE40) - [Test] - public void WriteObjectNullDBNullValue() - { - DBNull dbNull = DBNull.Value; - JValue v = new JValue(dbNull); - Assert.AreEqual(DBNull.Value, v.Value); - Assert.AreEqual(JTokenType.Null, v.Type); + [Test] + public void WriteObjectNullDBNullValue() + { + DBNull dbNull = DBNull.Value; + JValue v = new JValue(dbNull); + Assert.AreEqual(DBNull.Value, v.Value); + Assert.AreEqual(JTokenType.Null, v.Type); - JObject o = new JObject(); - o["title"] = v; + JObject o = new JObject(); + o["title"] = v; - string output = o.ToString(); - - Assert.AreEqual(@"{ + string output = o.ToString(); + + Assert.AreEqual(@"{ ""title"": null }", output); - } + } #endif - [Test] - public void InvalidValueCastExceptionMessage() - { - ExceptionAssert.Throws("Can not convert Object to String.", - () => + [Test] + public void InvalidValueCastExceptionMessage() { - string json = @"{ + ExceptionAssert.Throws("Can not convert Object to String.", + () => + { + string json = @"{ ""responseData"": {}, ""responseDetails"": null, ""responseStatus"": 200 }"; - JObject o = JObject.Parse(json); + JObject o = JObject.Parse(json); - string name = (string)o["responseData"]; - }); - } + string name = (string)o["responseData"]; + }); + } - [Test] - public void InvalidPropertyValueCastExceptionMessage() - { - ExceptionAssert.Throws("Can not convert Object to String.", - () => - { - string json = @"{ + [Test] + public void InvalidPropertyValueCastExceptionMessage() + { + ExceptionAssert.Throws("Can not convert Object to String.", + () => + { + string json = @"{ ""responseData"": {}, ""responseDetails"": null, ""responseStatus"": 200 }"; - JObject o = JObject.Parse(json); + JObject o = JObject.Parse(json); - string name = (string)o.Property("responseData"); - }); - } + string name = (string)o.Property("responseData"); + }); + } - [Test] - public void ParseIncomplete() - { - ExceptionAssert.Throws("Unexpected end of content while loading JObject. Path 'foo', line 1, position 6.", - () => + [Test] + public void ParseIncomplete() { - JObject.Parse("{ foo:"); - }); - } + ExceptionAssert.Throws("Unexpected end of content while loading JObject. Path 'foo', line 1, position 6.", + () => { JObject.Parse("{ foo:"); }); + } - [Test] - public void LoadFromNestedObject() - { - string jsonText = @"{ + [Test] + public void LoadFromNestedObject() + { + string jsonText = @"{ ""short"": { ""error"": @@ -1657,127 +1651,127 @@ Parameter name: arrayIndex", } }"; - JsonReader reader = new JsonTextReader(new StringReader(jsonText)); - reader.Read(); - reader.Read(); - reader.Read(); - reader.Read(); - reader.Read(); + JsonReader reader = new JsonTextReader(new StringReader(jsonText)); + reader.Read(); + reader.Read(); + reader.Read(); + reader.Read(); + reader.Read(); - JObject o = (JObject)JToken.ReadFrom(reader); - Assert.IsNotNull(o); - Assert.AreEqual(@"{ + JObject o = (JObject)JToken.ReadFrom(reader); + Assert.IsNotNull(o); + Assert.AreEqual(@"{ ""code"": 0, ""msg"": ""No action taken"" }", o.ToString(Formatting.Indented)); - } + } - [Test] - public void LoadFromNestedObjectIncomplete() - { - ExceptionAssert.Throws("Unexpected end of content while loading JObject. Path 'short.error.code', line 6, position 15.", - () => - { - string jsonText = @"{ + [Test] + public void LoadFromNestedObjectIncomplete() + { + ExceptionAssert.Throws("Unexpected end of content while loading JObject. Path 'short.error.code', line 6, position 15.", + () => + { + string jsonText = @"{ ""short"": { ""error"": { ""code"":0"; - JsonReader reader = new JsonTextReader(new StringReader(jsonText)); - reader.Read(); - reader.Read(); - reader.Read(); - reader.Read(); - reader.Read(); + JsonReader reader = new JsonTextReader(new StringReader(jsonText)); + reader.Read(); + reader.Read(); + reader.Read(); + reader.Read(); + reader.Read(); - JToken.ReadFrom(reader); - }); - } + JToken.ReadFrom(reader); + }); + } #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - [Test] - public void GetProperties() - { - JObject o = JObject.Parse("{'prop1':12,'prop2':'hi!','prop3':null,'prop4':[1,2,3]}"); + [Test] + public void GetProperties() + { + JObject o = JObject.Parse("{'prop1':12,'prop2':'hi!','prop3':null,'prop4':[1,2,3]}"); - ICustomTypeDescriptor descriptor = o; + ICustomTypeDescriptor descriptor = o; - PropertyDescriptorCollection properties = descriptor.GetProperties(); - Assert.AreEqual(4, properties.Count); + PropertyDescriptorCollection properties = descriptor.GetProperties(); + Assert.AreEqual(4, properties.Count); - PropertyDescriptor prop1 = properties[0]; - Assert.AreEqual("prop1", prop1.Name); - Assert.AreEqual(typeof(long), prop1.PropertyType); - Assert.AreEqual(typeof(JObject), prop1.ComponentType); - Assert.AreEqual(false, prop1.CanResetValue(o)); - Assert.AreEqual(false, prop1.ShouldSerializeValue(o)); + PropertyDescriptor prop1 = properties[0]; + Assert.AreEqual("prop1", prop1.Name); + Assert.AreEqual(typeof(long), prop1.PropertyType); + Assert.AreEqual(typeof(JObject), prop1.ComponentType); + Assert.AreEqual(false, prop1.CanResetValue(o)); + Assert.AreEqual(false, prop1.ShouldSerializeValue(o)); - PropertyDescriptor prop2 = properties[1]; - Assert.AreEqual("prop2", prop2.Name); - Assert.AreEqual(typeof(string), prop2.PropertyType); - Assert.AreEqual(typeof(JObject), prop2.ComponentType); - Assert.AreEqual(false, prop2.CanResetValue(o)); - Assert.AreEqual(false, prop2.ShouldSerializeValue(o)); + PropertyDescriptor prop2 = properties[1]; + Assert.AreEqual("prop2", prop2.Name); + Assert.AreEqual(typeof(string), prop2.PropertyType); + Assert.AreEqual(typeof(JObject), prop2.ComponentType); + Assert.AreEqual(false, prop2.CanResetValue(o)); + Assert.AreEqual(false, prop2.ShouldSerializeValue(o)); - PropertyDescriptor prop3 = properties[2]; - Assert.AreEqual("prop3", prop3.Name); - Assert.AreEqual(typeof(object), prop3.PropertyType); - Assert.AreEqual(typeof(JObject), prop3.ComponentType); - Assert.AreEqual(false, prop3.CanResetValue(o)); - Assert.AreEqual(false, prop3.ShouldSerializeValue(o)); + PropertyDescriptor prop3 = properties[2]; + Assert.AreEqual("prop3", prop3.Name); + Assert.AreEqual(typeof(object), prop3.PropertyType); + Assert.AreEqual(typeof(JObject), prop3.ComponentType); + Assert.AreEqual(false, prop3.CanResetValue(o)); + Assert.AreEqual(false, prop3.ShouldSerializeValue(o)); - PropertyDescriptor prop4 = properties[3]; - Assert.AreEqual("prop4", prop4.Name); - Assert.AreEqual(typeof(JArray), prop4.PropertyType); - Assert.AreEqual(typeof(JObject), prop4.ComponentType); - Assert.AreEqual(false, prop4.CanResetValue(o)); - Assert.AreEqual(false, prop4.ShouldSerializeValue(o)); - } + PropertyDescriptor prop4 = properties[3]; + Assert.AreEqual("prop4", prop4.Name); + Assert.AreEqual(typeof(JArray), prop4.PropertyType); + Assert.AreEqual(typeof(JObject), prop4.ComponentType); + Assert.AreEqual(false, prop4.CanResetValue(o)); + Assert.AreEqual(false, prop4.ShouldSerializeValue(o)); + } #endif - [Test] - public void ParseEmptyObjectWithComment() - { - JObject o = JObject.Parse("{ /* A Comment */ }"); - Assert.AreEqual(0, o.Count); - } + [Test] + public void ParseEmptyObjectWithComment() + { + JObject o = JObject.Parse("{ /* A Comment */ }"); + Assert.AreEqual(0, o.Count); + } - [Test] - public void FromObjectTimeSpan() - { - JValue v = (JValue)JToken.FromObject(TimeSpan.FromDays(1)); - Assert.AreEqual(v.Value, TimeSpan.FromDays(1)); + [Test] + public void FromObjectTimeSpan() + { + JValue v = (JValue)JToken.FromObject(TimeSpan.FromDays(1)); + Assert.AreEqual(v.Value, TimeSpan.FromDays(1)); - Assert.AreEqual("1.00:00:00", v.ToString()); - } + Assert.AreEqual("1.00:00:00", v.ToString()); + } - [Test] - public void FromObjectUri() - { - JValue v = (JValue)JToken.FromObject(new Uri("http://www.stuff.co.nz")); - Assert.AreEqual(v.Value, new Uri("http://www.stuff.co.nz")); + [Test] + public void FromObjectUri() + { + JValue v = (JValue)JToken.FromObject(new Uri("http://www.stuff.co.nz")); + Assert.AreEqual(v.Value, new Uri("http://www.stuff.co.nz")); - Assert.AreEqual("http://www.stuff.co.nz/", v.ToString()); - } + Assert.AreEqual("http://www.stuff.co.nz/", v.ToString()); + } - [Test] - public void FromObjectGuid() - { - JValue v = (JValue)JToken.FromObject(new Guid("9065ACF3-C820-467D-BE50-8D4664BEAF35")); - Assert.AreEqual(v.Value, new Guid("9065ACF3-C820-467D-BE50-8D4664BEAF35")); + [Test] + public void FromObjectGuid() + { + JValue v = (JValue)JToken.FromObject(new Guid("9065ACF3-C820-467D-BE50-8D4664BEAF35")); + Assert.AreEqual(v.Value, new Guid("9065ACF3-C820-467D-BE50-8D4664BEAF35")); - Assert.AreEqual("9065acf3-c820-467d-be50-8d4664beaf35", v.ToString()); - } + Assert.AreEqual("9065acf3-c820-467d-be50-8d4664beaf35", v.ToString()); + } - [Test] - public void ParseAdditionalContent() - { - ExceptionAssert.Throws("Additional text encountered after finished reading JSON content: ,. Path '', line 10, position 2.", - () => - { - string json = @"{ + [Test] + public void ParseAdditionalContent() + { + ExceptionAssert.Throws("Additional text encountered after finished reading JSON content: ,. Path '', line 10, position 2.", + () => + { + string json = @"{ ""Name"": ""Apple"", ""Expiry"": new Date(1230422400000), ""Price"": 3.99, @@ -1788,195 +1782,195 @@ Parameter name: arrayIndex", ] }, 987987"; - JObject o = JObject.Parse(json); - }); - } + JObject o = JObject.Parse(json); + }); + } - [Test] - public void DeepEqualsIgnoreOrder() - { - JObject o1 = new JObject( - new JProperty("null", null), - new JProperty("integer", 1), - new JProperty("string", "string!"), - new JProperty("decimal", 0.5m), - new JProperty("array", new JArray(1, 2))); + [Test] + public void DeepEqualsIgnoreOrder() + { + JObject o1 = new JObject( + new JProperty("null", null), + new JProperty("integer", 1), + new JProperty("string", "string!"), + new JProperty("decimal", 0.5m), + new JProperty("array", new JArray(1, 2))); - Assert.IsTrue(o1.DeepEquals(o1)); + Assert.IsTrue(o1.DeepEquals(o1)); - JObject o2 = new JObject( - new JProperty("null", null), - new JProperty("string", "string!"), - new JProperty("decimal", 0.5m), - new JProperty("integer", 1), - new JProperty("array", new JArray(1, 2))); + JObject o2 = new JObject( + new JProperty("null", null), + new JProperty("string", "string!"), + new JProperty("decimal", 0.5m), + new JProperty("integer", 1), + new JProperty("array", new JArray(1, 2))); - Assert.IsTrue(o1.DeepEquals(o2)); + Assert.IsTrue(o1.DeepEquals(o2)); - JObject o3 = new JObject( - new JProperty("null", null), - new JProperty("string", "string!"), - new JProperty("decimal", 0.5m), - new JProperty("integer", 2), - new JProperty("array", new JArray(1, 2))); + JObject o3 = new JObject( + new JProperty("null", null), + new JProperty("string", "string!"), + new JProperty("decimal", 0.5m), + new JProperty("integer", 2), + new JProperty("array", new JArray(1, 2))); - Assert.IsFalse(o1.DeepEquals(o3)); + Assert.IsFalse(o1.DeepEquals(o3)); - JObject o4 = new JObject( - new JProperty("null", null), - new JProperty("string", "string!"), - new JProperty("decimal", 0.5m), - new JProperty("integer", 1), - new JProperty("array", new JArray(2, 1))); + JObject o4 = new JObject( + new JProperty("null", null), + new JProperty("string", "string!"), + new JProperty("decimal", 0.5m), + new JProperty("integer", 1), + new JProperty("array", new JArray(2, 1))); - Assert.IsFalse(o1.DeepEquals(o4)); + Assert.IsFalse(o1.DeepEquals(o4)); - JObject o5 = new JObject( - new JProperty("null", null), - new JProperty("string", "string!"), - new JProperty("decimal", 0.5m), - new JProperty("integer", 1)); + JObject o5 = new JObject( + new JProperty("null", null), + new JProperty("string", "string!"), + new JProperty("decimal", 0.5m), + new JProperty("integer", 1)); - Assert.IsFalse(o1.DeepEquals(o5)); + Assert.IsFalse(o1.DeepEquals(o5)); - Assert.IsFalse(o1.DeepEquals(null)); - } + Assert.IsFalse(o1.DeepEquals(null)); + } - [Test] - public void ToListOnEmptyObject() - { - JObject o = JObject.Parse(@"{}"); - IList l1 = o.ToList(); - Assert.AreEqual(0, l1.Count); + [Test] + public void ToListOnEmptyObject() + { + JObject o = JObject.Parse(@"{}"); + IList l1 = o.ToList(); + Assert.AreEqual(0, l1.Count); - IList> l2 = o.ToList>(); - Assert.AreEqual(0, l2.Count); + IList> l2 = o.ToList>(); + Assert.AreEqual(0, l2.Count); - o = JObject.Parse(@"{'hi':null}"); - - l1 = o.ToList(); - Assert.AreEqual(1, l1.Count); + o = JObject.Parse(@"{'hi':null}"); - l2 = o.ToList>(); - Assert.AreEqual(1, l2.Count); - } + l1 = o.ToList(); + Assert.AreEqual(1, l1.Count); - [Test] - public void EmptyObjectDeepEquals() - { - Assert.IsTrue(JToken.DeepEquals(new JObject(), new JObject())); + l2 = o.ToList>(); + Assert.AreEqual(1, l2.Count); + } - JObject a = new JObject(); - JObject b = new JObject(); + [Test] + public void EmptyObjectDeepEquals() + { + Assert.IsTrue(JToken.DeepEquals(new JObject(), new JObject())); - b.Add("hi", "bye"); - b.Remove("hi"); + JObject a = new JObject(); + JObject b = new JObject(); - Assert.IsTrue(JToken.DeepEquals(a, b)); - Assert.IsTrue(JToken.DeepEquals(b, a)); - } + b.Add("hi", "bye"); + b.Remove("hi"); - [Test] - public void GetValueBlogExample() - { - JObject o = JObject.Parse(@"{ + Assert.IsTrue(JToken.DeepEquals(a, b)); + Assert.IsTrue(JToken.DeepEquals(b, a)); + } + + [Test] + public void GetValueBlogExample() + { + JObject o = JObject.Parse(@"{ 'name': 'Lower', 'NAME': 'Upper' }"); - string exactMatch = (string)o.GetValue("NAME", StringComparison.OrdinalIgnoreCase); - // Upper + string exactMatch = (string)o.GetValue("NAME", StringComparison.OrdinalIgnoreCase); + // Upper - string ignoreCase = (string)o.GetValue("Name", StringComparison.OrdinalIgnoreCase); - // Lower + string ignoreCase = (string)o.GetValue("Name", StringComparison.OrdinalIgnoreCase); + // Lower - Assert.AreEqual("Upper", exactMatch); - Assert.AreEqual("Lower", ignoreCase); - } - - [Test] - public void GetValue() - { - JObject a = new JObject(); - a["Name"] = "Name!"; - a["name"] = "name!"; - a["title"] = "Title!"; - - Assert.AreEqual(null, a.GetValue("NAME", StringComparison.Ordinal)); - Assert.AreEqual(null, a.GetValue("NAME")); - Assert.AreEqual(null, a.GetValue("TITLE")); - Assert.AreEqual("Name!", (string)a.GetValue("NAME", StringComparison.OrdinalIgnoreCase)); - Assert.AreEqual("name!", (string)a.GetValue("name", StringComparison.Ordinal)); - Assert.AreEqual(null, a.GetValue(null, StringComparison.Ordinal)); - Assert.AreEqual(null, a.GetValue(null)); - - JToken v; - Assert.IsFalse(a.TryGetValue("NAME", StringComparison.Ordinal, out v)); - Assert.AreEqual(null, v); - - Assert.IsFalse(a.TryGetValue("NAME", out v)); - Assert.IsFalse(a.TryGetValue("TITLE", out v)); - - Assert.IsTrue(a.TryGetValue("NAME", StringComparison.OrdinalIgnoreCase, out v)); - Assert.AreEqual("Name!", (string)v); - - Assert.IsTrue(a.TryGetValue("name", StringComparison.Ordinal, out v)); - Assert.AreEqual("name!", (string)v); - - Assert.IsFalse(a.TryGetValue(null, StringComparison.Ordinal, out v)); - } - - public class FooJsonConverter : JsonConverter - { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - var token = JToken.FromObject(value, new JsonSerializer - { - ContractResolver = new CamelCasePropertyNamesContractResolver() - }); - if (token.Type == JTokenType.Object) - { - var o = (JObject)token; - o.AddFirst(new JProperty("foo", "bar")); - o.WriteTo(writer); + Assert.AreEqual("Upper", exactMatch); + Assert.AreEqual("Lower", ignoreCase); } - else - token.WriteTo(writer); - } - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - throw new NotSupportedException("This custom converter only supportes serialization and not deserialization."); - } + [Test] + public void GetValue() + { + JObject a = new JObject(); + a["Name"] = "Name!"; + a["name"] = "name!"; + a["title"] = "Title!"; - public override bool CanRead - { - get { return false; } - } + Assert.AreEqual(null, a.GetValue("NAME", StringComparison.Ordinal)); + Assert.AreEqual(null, a.GetValue("NAME")); + Assert.AreEqual(null, a.GetValue("TITLE")); + Assert.AreEqual("Name!", (string)a.GetValue("NAME", StringComparison.OrdinalIgnoreCase)); + Assert.AreEqual("name!", (string)a.GetValue("name", StringComparison.Ordinal)); + Assert.AreEqual(null, a.GetValue(null, StringComparison.Ordinal)); + Assert.AreEqual(null, a.GetValue(null)); - public override bool CanConvert(Type objectType) - { - return true; - } + JToken v; + Assert.IsFalse(a.TryGetValue("NAME", StringComparison.Ordinal, out v)); + Assert.AreEqual(null, v); + + Assert.IsFalse(a.TryGetValue("NAME", out v)); + Assert.IsFalse(a.TryGetValue("TITLE", out v)); + + Assert.IsTrue(a.TryGetValue("NAME", StringComparison.OrdinalIgnoreCase, out v)); + Assert.AreEqual("Name!", (string)v); + + Assert.IsTrue(a.TryGetValue("name", StringComparison.Ordinal, out v)); + Assert.AreEqual("name!", (string)v); + + Assert.IsFalse(a.TryGetValue(null, StringComparison.Ordinal, out v)); + } + + public class FooJsonConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + var token = JToken.FromObject(value, new JsonSerializer + { + ContractResolver = new CamelCasePropertyNamesContractResolver() + }); + if (token.Type == JTokenType.Object) + { + var o = (JObject)token; + o.AddFirst(new JProperty("foo", "bar")); + o.WriteTo(writer); + } + else + token.WriteTo(writer); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + throw new NotSupportedException("This custom converter only supportes serialization and not deserialization."); + } + + public override bool CanRead + { + get { return false; } + } + + public override bool CanConvert(Type objectType) + { + return true; + } + } + + [Test] + public void FromObjectInsideConverterWithCustomSerializer() + { + var p = new Person + { + Name = "Daniel Wertheim", + }; + + var settings = new JsonSerializerSettings + { + Converters = new List { new FooJsonConverter() }, + ContractResolver = new CamelCasePropertyNamesContractResolver() + }; + + var json = JsonConvert.SerializeObject(p, settings); + + Assert.AreEqual(@"{""foo"":""bar"",""name"":""Daniel Wertheim"",""birthDate"":""0001-01-01T00:00:00"",""lastModified"":""0001-01-01T00:00:00""}", json); + } } - - [Test] - public void FromObjectInsideConverterWithCustomSerializer() - { - var p = new Person - { - Name = "Daniel Wertheim", - }; - - var settings = new JsonSerializerSettings - { - Converters = new List { new FooJsonConverter() }, - ContractResolver = new CamelCasePropertyNamesContractResolver() - }; - - var json = JsonConvert.SerializeObject(p, settings); - - Assert.AreEqual(@"{""foo"":""bar"",""name"":""Daniel Wertheim"",""birthDate"":""0001-01-01T00:00:00"",""lastModified"":""0001-01-01T00:00:00""}", json); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Linq/JPathTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JPathTests.cs index 83c7b9f4..a4cf505d 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/JPathTests.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/JPathTests.cs @@ -37,295 +37,266 @@ using Newtonsoft.Json.Linq; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json.Tests.Linq { - [TestFixture] - public class JPathTests : TestFixtureBase - { - [Test] - public void SingleProperty() + [TestFixture] + public class JPathTests : TestFixtureBase { - JPath path = new JPath("Blah"); - Assert.AreEqual(1, path.Parts.Count); - Assert.AreEqual("Blah", path.Parts[0]); - } - - [Test] - public void TwoProperties() - { - JPath path = new JPath("Blah.Two"); - Assert.AreEqual(2, path.Parts.Count); - Assert.AreEqual("Blah", path.Parts[0]); - Assert.AreEqual("Two", path.Parts[1]); - } - - [Test] - public void SinglePropertyAndIndexer() - { - JPath path = new JPath("Blah[0]"); - Assert.AreEqual(2, path.Parts.Count); - Assert.AreEqual("Blah", path.Parts[0]); - Assert.AreEqual(0, path.Parts[1]); - } - - [Test] - public void MultiplePropertiesAndIndexers() - { - JPath path = new JPath("Blah[0].Two.Three[1].Four"); - Assert.AreEqual(6, path.Parts.Count); - Assert.AreEqual("Blah", path.Parts[0]); - Assert.AreEqual(0, path.Parts[1]); - Assert.AreEqual("Two", path.Parts[2]); - Assert.AreEqual("Three", path.Parts[3]); - Assert.AreEqual(1, path.Parts[4]); - Assert.AreEqual("Four", path.Parts[5]); - } - - [Test] - public void BadCharactersInIndexer() - { - ExceptionAssert.Throws( - @"Unexpected character while parsing path indexer: [", - () => + [Test] + public void SingleProperty() { - new JPath("Blah[[0]].Two.Three[1].Four"); - }); - } + JPath path = new JPath("Blah"); + Assert.AreEqual(1, path.Parts.Count); + Assert.AreEqual("Blah", path.Parts[0]); + } - [Test] - public void UnclosedIndexer() - { - ExceptionAssert.Throws( - @"Path ended with open indexer. Expected ]", - () => + [Test] + public void TwoProperties() { - new JPath("Blah[0"); - }); - } + JPath path = new JPath("Blah.Two"); + Assert.AreEqual(2, path.Parts.Count); + Assert.AreEqual("Blah", path.Parts[0]); + Assert.AreEqual("Two", path.Parts[1]); + } - [Test] - public void AdditionalDots() - { - JPath path = new JPath(".Blah..[0]..Two.Three....[1].Four."); - Assert.AreEqual(6, path.Parts.Count); - Assert.AreEqual("Blah", path.Parts[0]); - Assert.AreEqual(0, path.Parts[1]); - Assert.AreEqual("Two", path.Parts[2]); - Assert.AreEqual("Three", path.Parts[3]); - Assert.AreEqual(1, path.Parts[4]); - Assert.AreEqual("Four", path.Parts[5]); - } - - [Test] - public void IndexerOnly() - { - JPath path = new JPath("[111119990]"); - Assert.AreEqual(1, path.Parts.Count); - Assert.AreEqual(111119990, path.Parts[0]); - } - - [Test] - public void EmptyIndexer() - { - ExceptionAssert.Throws( - "Empty path indexer.", - () => + [Test] + public void SinglePropertyAndIndexer() { - new JPath("[]"); - }); - } + JPath path = new JPath("Blah[0]"); + Assert.AreEqual(2, path.Parts.Count); + Assert.AreEqual("Blah", path.Parts[0]); + Assert.AreEqual(0, path.Parts[1]); + } - [Test] - public void IndexerCloseInProperty() - { - ExceptionAssert.Throws( - "Unexpected character while parsing path: ]", - () => + [Test] + public void MultiplePropertiesAndIndexers() { - new JPath("]"); - }); - } + JPath path = new JPath("Blah[0].Two.Three[1].Four"); + Assert.AreEqual(6, path.Parts.Count); + Assert.AreEqual("Blah", path.Parts[0]); + Assert.AreEqual(0, path.Parts[1]); + Assert.AreEqual("Two", path.Parts[2]); + Assert.AreEqual("Three", path.Parts[3]); + Assert.AreEqual(1, path.Parts[4]); + Assert.AreEqual("Four", path.Parts[5]); + } - [Test] - public void AdjacentIndexers() - { - JPath path = new JPath("[1][0][0][" + int.MaxValue + "]"); - Assert.AreEqual(4, path.Parts.Count); - Assert.AreEqual(1, path.Parts[0]); - Assert.AreEqual(0, path.Parts[1]); - Assert.AreEqual(0, path.Parts[2]); - Assert.AreEqual(int.MaxValue, path.Parts[3]); - } - - [Test] - public void MissingDotAfterIndexer() - { - ExceptionAssert.Throws( - "Unexpected character following indexer: B", - () => + [Test] + public void BadCharactersInIndexer() { - new JPath("[1]Blah"); - }); - } + ExceptionAssert.Throws( + @"Unexpected character while parsing path indexer: [", + () => { new JPath("Blah[[0]].Two.Three[1].Four"); }); + } - [Test] - public void EvaluateSingleProperty() - { - JObject o = new JObject( - new JProperty("Blah", 1)); - - JToken t = o.SelectToken("Blah"); - Assert.IsNotNull(t); - Assert.AreEqual(JTokenType.Integer, t.Type); - Assert.AreEqual(1, (int)t); - } - - [Test] - public void EvaluateMissingProperty() - { - JObject o = new JObject( - new JProperty("Blah", 1)); - - JToken t = o.SelectToken("Missing[1]"); - Assert.IsNull(t); - } - - [Test] - public void EvaluateIndexerOnObject() - { - JObject o = new JObject( - new JProperty("Blah", 1)); - - JToken t = o.SelectToken("[1]"); - Assert.IsNull(t); - } - - [Test] - public void EvaluateIndexerOnObjectWithError() - { - JObject o = new JObject( - new JProperty("Blah", 1)); - - ExceptionAssert.Throws( - @"Index 1 not valid on JObject.", - () => + [Test] + public void UnclosedIndexer() { - o.SelectToken("[1]", true); - }); - } + ExceptionAssert.Throws( + @"Path ended with open indexer. Expected ]", + () => { new JPath("Blah[0"); }); + } - [Test] - public void EvaluatePropertyOnArray() - { - JArray a = new JArray(1, 2, 3, 4, 5); - - JToken t = a.SelectToken("BlahBlah"); - Assert.IsNull(t); - } - - [Test] - public void EvaluatePropertyOnArrayWithError() - { - JArray a = new JArray(1, 2, 3, 4, 5); - - ExceptionAssert.Throws( - @"Property 'BlahBlah' not valid on JArray.", - () => + [Test] + public void AdditionalDots() { - a.SelectToken("BlahBlah", true); - }); - } + JPath path = new JPath(".Blah..[0]..Two.Three....[1].Four."); + Assert.AreEqual(6, path.Parts.Count); + Assert.AreEqual("Blah", path.Parts[0]); + Assert.AreEqual(0, path.Parts[1]); + Assert.AreEqual("Two", path.Parts[2]); + Assert.AreEqual("Three", path.Parts[3]); + Assert.AreEqual(1, path.Parts[4]); + Assert.AreEqual("Four", path.Parts[5]); + } - [Test] - public void EvaluateConstructorOutOfBoundsIndxerWithError() - { - JConstructor c = new JConstructor("Blah"); - - ExceptionAssert.Throws( - @"Index 1 outside the bounds of JConstructor.", - () => + [Test] + public void IndexerOnly() { - c.SelectToken("[1]", true); - }); - } + JPath path = new JPath("[111119990]"); + Assert.AreEqual(1, path.Parts.Count); + Assert.AreEqual(111119990, path.Parts[0]); + } - [Test] - public void EvaluateMissingPropertyWithError() - { - JObject o = new JObject( - new JProperty("Blah", 1)); - - ExceptionAssert.Throws( - "Property 'Missing' does not exist on JObject.", - () => + [Test] + public void EmptyIndexer() { - o.SelectToken("Missing", true); - }); - } + ExceptionAssert.Throws( + "Empty path indexer.", + () => { new JPath("[]"); }); + } - [Test] - public void EvaluateOutOfBoundsIndxer() - { - JArray a = new JArray(1, 2, 3, 4, 5); - - JToken t = a.SelectToken("[1000].Ha"); - Assert.IsNull(t); - } - - [Test] - public void EvaluateArrayOutOfBoundsIndxerWithError() - { - JArray a = new JArray(1, 2, 3, 4, 5); - - ExceptionAssert.Throws( - "Index 1000 outside the bounds of JArray.", - () => + [Test] + public void IndexerCloseInProperty() { - a.SelectToken("[1000].Ha", true); - }); - } + ExceptionAssert.Throws( + "Unexpected character while parsing path: ]", + () => { new JPath("]"); }); + } - [Test] - public void EvaluateArray() - { - JArray a = new JArray(1, 2, 3, 4); + [Test] + public void AdjacentIndexers() + { + JPath path = new JPath("[1][0][0][" + int.MaxValue + "]"); + Assert.AreEqual(4, path.Parts.Count); + Assert.AreEqual(1, path.Parts[0]); + Assert.AreEqual(0, path.Parts[1]); + Assert.AreEqual(0, path.Parts[2]); + Assert.AreEqual(int.MaxValue, path.Parts[3]); + } - JToken t = a.SelectToken("[1]"); - Assert.IsNotNull(t); - Assert.AreEqual(JTokenType.Integer, t.Type); - Assert.AreEqual(2, (int)t); - } + [Test] + public void MissingDotAfterIndexer() + { + ExceptionAssert.Throws( + "Unexpected character following indexer: B", + () => { new JPath("[1]Blah"); }); + } - [Test] - public void EvaluateSinglePropertyReturningArray() - { - JObject o = new JObject( - new JProperty("Blah", new [] { 1, 2, 3 })); + [Test] + public void EvaluateSingleProperty() + { + JObject o = new JObject( + new JProperty("Blah", 1)); - JToken t = o.SelectToken("Blah"); - Assert.IsNotNull(t); - Assert.AreEqual(JTokenType.Array, t.Type); + JToken t = o.SelectToken("Blah"); + Assert.IsNotNull(t); + Assert.AreEqual(JTokenType.Integer, t.Type); + Assert.AreEqual(1, (int)t); + } - t = o.SelectToken("Blah[2]"); - Assert.AreEqual(JTokenType.Integer, t.Type); - Assert.AreEqual(3, (int)t); - } + [Test] + public void EvaluateMissingProperty() + { + JObject o = new JObject( + new JProperty("Blah", 1)); - [Test] - public void EvaluateLastSingleCharacterProperty() - { - JObject o2 = JObject.Parse("{'People':[{'N':'Jeff'}]}"); - string a2 = (string)o2.SelectToken("People[0].N"); + JToken t = o.SelectToken("Missing[1]"); + Assert.IsNull(t); + } - Assert.AreEqual("Jeff", a2); - } + [Test] + public void EvaluateIndexerOnObject() + { + JObject o = new JObject( + new JProperty("Blah", 1)); - [Test] - public void PathWithConstructor() - { - JArray a = JArray.Parse(@"[ + JToken t = o.SelectToken("[1]"); + Assert.IsNull(t); + } + + [Test] + public void EvaluateIndexerOnObjectWithError() + { + JObject o = new JObject( + new JProperty("Blah", 1)); + + ExceptionAssert.Throws( + @"Index 1 not valid on JObject.", + () => { o.SelectToken("[1]", true); }); + } + + [Test] + public void EvaluatePropertyOnArray() + { + JArray a = new JArray(1, 2, 3, 4, 5); + + JToken t = a.SelectToken("BlahBlah"); + Assert.IsNull(t); + } + + [Test] + public void EvaluatePropertyOnArrayWithError() + { + JArray a = new JArray(1, 2, 3, 4, 5); + + ExceptionAssert.Throws( + @"Property 'BlahBlah' not valid on JArray.", + () => { a.SelectToken("BlahBlah", true); }); + } + + [Test] + public void EvaluateConstructorOutOfBoundsIndxerWithError() + { + JConstructor c = new JConstructor("Blah"); + + ExceptionAssert.Throws( + @"Index 1 outside the bounds of JConstructor.", + () => { c.SelectToken("[1]", true); }); + } + + [Test] + public void EvaluateMissingPropertyWithError() + { + JObject o = new JObject( + new JProperty("Blah", 1)); + + ExceptionAssert.Throws( + "Property 'Missing' does not exist on JObject.", + () => { o.SelectToken("Missing", true); }); + } + + [Test] + public void EvaluateOutOfBoundsIndxer() + { + JArray a = new JArray(1, 2, 3, 4, 5); + + JToken t = a.SelectToken("[1000].Ha"); + Assert.IsNull(t); + } + + [Test] + public void EvaluateArrayOutOfBoundsIndxerWithError() + { + JArray a = new JArray(1, 2, 3, 4, 5); + + ExceptionAssert.Throws( + "Index 1000 outside the bounds of JArray.", + () => { a.SelectToken("[1000].Ha", true); }); + } + + [Test] + public void EvaluateArray() + { + JArray a = new JArray(1, 2, 3, 4); + + JToken t = a.SelectToken("[1]"); + Assert.IsNotNull(t); + Assert.AreEqual(JTokenType.Integer, t.Type); + Assert.AreEqual(2, (int)t); + } + + [Test] + public void EvaluateSinglePropertyReturningArray() + { + JObject o = new JObject( + new JProperty("Blah", new[] { 1, 2, 3 })); + + JToken t = o.SelectToken("Blah"); + Assert.IsNotNull(t); + Assert.AreEqual(JTokenType.Array, t.Type); + + t = o.SelectToken("Blah[2]"); + Assert.AreEqual(JTokenType.Integer, t.Type); + Assert.AreEqual(3, (int)t); + } + + [Test] + public void EvaluateLastSingleCharacterProperty() + { + JObject o2 = JObject.Parse("{'People':[{'N':'Jeff'}]}"); + string a2 = (string)o2.SelectToken("People[0].N"); + + Assert.AreEqual("Jeff", a2); + } + + [Test] + public void PathWithConstructor() + { + JArray a = JArray.Parse(@"[ { ""Property1"": [ 1, @@ -346,15 +317,15 @@ namespace Newtonsoft.Json.Tests.Linq } ]"); - JValue v = (JValue)a.SelectToken("[1].Property2[1][0]"); - Assert.AreEqual(1L, v.Value); - } + JValue v = (JValue)a.SelectToken("[1].Property2[1][0]"); + Assert.AreEqual(1L, v.Value); + } - [Test] - public void Example() - { - JObject o = JObject.Parse(@"{ + [Test] + public void Example() + { + JObject o = JObject.Parse(@"{ ""Stores"": [ ""Lambton Quay"", ""Willis Street"" @@ -385,37 +356,37 @@ namespace Newtonsoft.Json.Tests.Linq ] }"); - string name = (string)o.SelectToken("Manufacturers[0].Name"); - // Acme Co + string name = (string)o.SelectToken("Manufacturers[0].Name"); + // Acme Co - decimal productPrice = (decimal)o.SelectToken("Manufacturers[0].Products[0].Price"); - // 50 + decimal productPrice = (decimal)o.SelectToken("Manufacturers[0].Products[0].Price"); + // 50 - string productName = (string)o.SelectToken("Manufacturers[1].Products[0].Name"); - // Elbow Grease + string productName = (string)o.SelectToken("Manufacturers[1].Products[0].Name"); + // Elbow Grease - Assert.AreEqual("Acme Co", name); - Assert.AreEqual(50m, productPrice); - Assert.AreEqual("Elbow Grease", productName); + Assert.AreEqual("Acme Co", name); + Assert.AreEqual(50m, productPrice); + Assert.AreEqual("Elbow Grease", productName); - IList storeNames = o.SelectToken("Stores").Select(s => (string)s).ToList(); - // Lambton Quay - // Willis Street + IList storeNames = o.SelectToken("Stores").Select(s => (string)s).ToList(); + // Lambton Quay + // Willis Street - IList firstProductNames = o["Manufacturers"].Select(m => (string)m.SelectToken("Products[1].Name")).ToList(); - // null - // Headlight Fluid + IList firstProductNames = o["Manufacturers"].Select(m => (string)m.SelectToken("Products[1].Name")).ToList(); + // null + // Headlight Fluid - decimal totalPrice = o["Manufacturers"].Sum(m => (decimal)m.SelectToken("Products[0].Price")); - // 149.95 + decimal totalPrice = o["Manufacturers"].Sum(m => (decimal)m.SelectToken("Products[0].Price")); + // 149.95 - Assert.AreEqual(2, storeNames.Count); - Assert.AreEqual("Lambton Quay", storeNames[0]); - Assert.AreEqual("Willis Street", storeNames[1]); - Assert.AreEqual(2, firstProductNames.Count); - Assert.AreEqual(null, firstProductNames[0]); - Assert.AreEqual("Headlight Fluid", firstProductNames[1]); - Assert.AreEqual(149.95m, totalPrice); + Assert.AreEqual(2, storeNames.Count); + Assert.AreEqual("Lambton Quay", storeNames[0]); + Assert.AreEqual("Willis Street", storeNames[1]); + Assert.AreEqual(2, firstProductNames.Count); + Assert.AreEqual(null, firstProductNames[0]); + Assert.AreEqual("Headlight Fluid", firstProductNames[1]); + Assert.AreEqual(149.95m, totalPrice); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Linq/JPropertyTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JPropertyTests.cs index 1d5365e7..45f876ff 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/JPropertyTests.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/JPropertyTests.cs @@ -39,147 +39,135 @@ using System.IO; namespace Newtonsoft.Json.Tests.Linq { - [TestFixture] - public class JPropertyTests : TestFixtureBase - { - [Test] - public void NullValue() + [TestFixture] + public class JPropertyTests : TestFixtureBase { - JProperty p = new JProperty("TestProperty", null); - Assert.IsNotNull(p.Value); - Assert.AreEqual(JTokenType.Null, p.Value.Type); - Assert.AreEqual(p, p.Value.Parent); + [Test] + public void NullValue() + { + JProperty p = new JProperty("TestProperty", null); + Assert.IsNotNull(p.Value); + Assert.AreEqual(JTokenType.Null, p.Value.Type); + Assert.AreEqual(p, p.Value.Parent); - p.Value = null; - Assert.IsNotNull(p.Value); - Assert.AreEqual(JTokenType.Null, p.Value.Type); - Assert.AreEqual(p, p.Value.Parent); - } + p.Value = null; + Assert.IsNotNull(p.Value); + Assert.AreEqual(JTokenType.Null, p.Value.Type); + Assert.AreEqual(p, p.Value.Parent); + } #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - [Test] - public void ListChanged() - { - JProperty p = new JProperty("TestProperty", null); - IBindingList l = p; - - ListChangedType? listChangedType = null; - int? index = null; - - l.ListChanged += (sender, args) => + [Test] + public void ListChanged() { - listChangedType = args.ListChangedType; - index = args.NewIndex; - }; + JProperty p = new JProperty("TestProperty", null); + IBindingList l = p; - p.Value = 1; + ListChangedType? listChangedType = null; + int? index = null; - Assert.AreEqual(ListChangedType.ItemChanged, listChangedType.Value); - Assert.AreEqual(0, index.Value); - } + l.ListChanged += (sender, args) => + { + listChangedType = args.ListChangedType; + index = args.NewIndex; + }; + + p.Value = 1; + + Assert.AreEqual(ListChangedType.ItemChanged, listChangedType.Value); + Assert.AreEqual(0, index.Value); + } #endif - [Test] - public void IListCount() - { - JProperty p = new JProperty("TestProperty", null); - IList l = p; - - Assert.AreEqual(1, l.Count); - } - - [Test] - public void IListClear() - { - JProperty p = new JProperty("TestProperty", null); - IList l = p; - - ExceptionAssert.Throws( - "Cannot add or remove items from Newtonsoft.Json.Linq.JProperty.", - () => + [Test] + public void IListCount() { - l.Clear(); - }); + JProperty p = new JProperty("TestProperty", null); + IList l = p; + + Assert.AreEqual(1, l.Count); + } + + [Test] + public void IListClear() + { + JProperty p = new JProperty("TestProperty", null); + IList l = p; + + ExceptionAssert.Throws( + "Cannot add or remove items from Newtonsoft.Json.Linq.JProperty.", + () => { l.Clear(); }); + } + + [Test] + public void IListAdd() + { + JProperty p = new JProperty("TestProperty", null); + IList l = p; + + ExceptionAssert.Throws( + "Newtonsoft.Json.Linq.JProperty cannot have multiple values.", + () => { l.Add(null); }); + } + + [Test] + public void IListRemove() + { + JProperty p = new JProperty("TestProperty", null); + IList l = p; + + ExceptionAssert.Throws( + "Cannot add or remove items from Newtonsoft.Json.Linq.JProperty.", + () => { l.Remove(p.Value); }); + } + + [Test] + public void Load() + { + JsonReader reader = new JsonTextReader(new StringReader("{'propertyname':['value1']}")); + reader.Read(); + + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + reader.Read(); + + JProperty property = JProperty.Load(reader); + Assert.AreEqual("propertyname", property.Name); + Assert.IsTrue(JToken.DeepEquals(JArray.Parse("['value1']"), property.Value)); + + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + + reader = new JsonTextReader(new StringReader("{'propertyname':null}")); + reader.Read(); + + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + reader.Read(); + + property = JProperty.Load(reader); + Assert.AreEqual("propertyname", property.Name); + Assert.IsTrue(JToken.DeepEquals(new JValue(null, JTokenType.Null), property.Value)); + + Assert.AreEqual(JsonToken.EndObject, reader.TokenType); + } + + [Test] + public void MultiContentConstructor() + { + JProperty p = new JProperty("error", new List { "one", "two" }); + JArray a = (JArray)p.Value; + + Assert.AreEqual(a.Count, 2); + Assert.AreEqual("one", (string)a[0]); + Assert.AreEqual("two", (string)a[1]); + } + + [Test] + public void IListGenericAdd() + { + IList t = new JProperty("error", new List { "one", "two" }); + + ExceptionAssert.Throws( + "Newtonsoft.Json.Linq.JProperty cannot have multiple values.", + () => { t.Add(1); }); + } } - - [Test] - public void IListAdd() - { - JProperty p = new JProperty("TestProperty", null); - IList l = p; - - ExceptionAssert.Throws( - "Newtonsoft.Json.Linq.JProperty cannot have multiple values.", - () => - { - l.Add(null); - }); - } - - [Test] - public void IListRemove() - { - JProperty p = new JProperty("TestProperty", null); - IList l = p; - - ExceptionAssert.Throws( - "Cannot add or remove items from Newtonsoft.Json.Linq.JProperty.", - () => - { - l.Remove(p.Value); - }); - } - - [Test] - public void Load() - { - JsonReader reader = new JsonTextReader(new StringReader("{'propertyname':['value1']}")); - reader.Read(); - - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - reader.Read(); - - JProperty property = JProperty.Load(reader); - Assert.AreEqual("propertyname", property.Name); - Assert.IsTrue(JToken.DeepEquals(JArray.Parse("['value1']"), property.Value)); - - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - - reader = new JsonTextReader(new StringReader("{'propertyname':null}")); - reader.Read(); - - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - reader.Read(); - - property = JProperty.Load(reader); - Assert.AreEqual("propertyname", property.Name); - Assert.IsTrue(JToken.DeepEquals(new JValue(null, JTokenType.Null), property.Value)); - - Assert.AreEqual(JsonToken.EndObject, reader.TokenType); - } - - [Test] - public void MultiContentConstructor() - { - JProperty p = new JProperty("error", new List {"one", "two"}); - JArray a = (JArray) p.Value; - - Assert.AreEqual(a.Count, 2); - Assert.AreEqual("one", (string) a[0]); - Assert.AreEqual("two", (string) a[1]); - } - - [Test] - public void IListGenericAdd() - { - IList t = new JProperty("error", new List {"one", "two"}); - - ExceptionAssert.Throws( - "Newtonsoft.Json.Linq.JProperty cannot have multiple values.", - () => - { - t.Add(1); - }); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Linq/JRawTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JRawTests.cs index 4a816d7b..ac050738 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/JRawTests.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/JRawTests.cs @@ -35,36 +35,36 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Linq { - [TestFixture] - public class JRawTests : TestFixtureBase - { - [Test] - public void RawEquals() + [TestFixture] + public class JRawTests : TestFixtureBase { - JRaw r1 = new JRaw("raw1"); - JRaw r2 = new JRaw("raw1"); - JRaw r3 = new JRaw("raw2"); + [Test] + public void RawEquals() + { + JRaw r1 = new JRaw("raw1"); + JRaw r2 = new JRaw("raw1"); + JRaw r3 = new JRaw("raw2"); - Assert.IsTrue(JToken.DeepEquals(r1, r2)); - Assert.IsFalse(JToken.DeepEquals(r1, r3)); + Assert.IsTrue(JToken.DeepEquals(r1, r2)); + Assert.IsFalse(JToken.DeepEquals(r1, r3)); + } + + [Test] + public void RawClone() + { + JRaw r1 = new JRaw("raw1"); + JToken r2 = r1.CloneToken(); + + CustomAssert.IsInstanceOfType(typeof(JRaw), r2); + } + + [Test] + public void RawToObject() + { + JRaw r1 = new JRaw("1"); + int i = r1.ToObject(); + + Assert.AreEqual(1, i); + } } - - [Test] - public void RawClone() - { - JRaw r1 = new JRaw("raw1"); - JToken r2 = r1.CloneToken(); - - CustomAssert.IsInstanceOfType(typeof(JRaw), r2); - } - - [Test] - public void RawToObject() - { - JRaw r1 = new JRaw("1"); - int i = r1.ToObject(); - - Assert.AreEqual(1, i); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Linq/JTokenEqualityComparerTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JTokenEqualityComparerTests.cs index f4ec6838..7235d1bd 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/JTokenEqualityComparerTests.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/JTokenEqualityComparerTests.cs @@ -35,55 +35,55 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Linq { - [TestFixture] - public class JTokenEqualityComparerTests : TestFixtureBase - { - [Test] - public void JValueDictionary() + [TestFixture] + public class JTokenEqualityComparerTests : TestFixtureBase { - Dictionary dic = new Dictionary(JToken.EqualityComparer); - JValue v11 = new JValue(1); - JValue v12 = new JValue(1); + [Test] + public void JValueDictionary() + { + Dictionary dic = new Dictionary(JToken.EqualityComparer); + JValue v11 = new JValue(1); + JValue v12 = new JValue(1); - dic[v11] = 1; - dic[v12] += 1; - Assert.AreEqual(2, dic[v11]); + dic[v11] = 1; + dic[v12] += 1; + Assert.AreEqual(2, dic[v11]); + } + + [Test] + public void JArrayDictionary() + { + Dictionary dic = new Dictionary(JToken.EqualityComparer); + JArray v11 = new JArray(); + JArray v12 = new JArray(); + + dic[v11] = 1; + dic[v12] += 1; + Assert.AreEqual(2, dic[v11]); + } + + [Test] + public void JObjectDictionary() + { + Dictionary dic = new Dictionary(JToken.EqualityComparer); + JObject v11 = new JObject() { { "Test", new JValue(1) }, { "Test1", new JValue(1) } }; + JObject v12 = new JObject() { { "Test", new JValue(1) }, { "Test1", new JValue(1) } }; + + dic[v11] = 1; + dic[v12] += 1; + Assert.AreEqual(2, dic[v11]); + } + + [Test] + public void JConstructorDictionary() + { + Dictionary dic = new Dictionary(JToken.EqualityComparer); + JConstructor v11 = new JConstructor("ConstructorValue"); + JConstructor v12 = new JConstructor("ConstructorValue"); + + dic[v11] = 1; + dic[v12] += 1; + Assert.AreEqual(2, dic[v11]); + } } - - [Test] - public void JArrayDictionary() - { - Dictionary dic = new Dictionary(JToken.EqualityComparer); - JArray v11 = new JArray(); - JArray v12 = new JArray(); - - dic[v11] = 1; - dic[v12] += 1; - Assert.AreEqual(2, dic[v11]); - } - - [Test] - public void JObjectDictionary() - { - Dictionary dic = new Dictionary(JToken.EqualityComparer); - JObject v11 = new JObject() { { "Test", new JValue(1) }, { "Test1", new JValue(1) } }; - JObject v12 = new JObject() { { "Test", new JValue(1) }, { "Test1", new JValue(1) } }; - - dic[v11] = 1; - dic[v12] += 1; - Assert.AreEqual(2, dic[v11]); - } - - [Test] - public void JConstructorDictionary() - { - Dictionary dic = new Dictionary(JToken.EqualityComparer); - JConstructor v11 = new JConstructor("ConstructorValue"); - JConstructor v12 = new JConstructor("ConstructorValue"); - - dic[v11] = 1; - dic[v12] += 1; - Assert.AreEqual(2, dic[v11]); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Linq/JTokenReaderTest.cs b/Src/Newtonsoft.Json.Tests/Linq/JTokenReaderTest.cs index 7e716f43..dcb71a58 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/JTokenReaderTest.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/JTokenReaderTest.cs @@ -41,159 +41,153 @@ using Newtonsoft.Json.Tests.TestObjects; namespace Newtonsoft.Json.Tests.Linq { - [TestFixture] - public class JTokenReaderTest : TestFixtureBase - { + [TestFixture] + public class JTokenReaderTest : TestFixtureBase + { #if !NET20 - [Test] - public void YahooFinance() - { - JObject o = - new JObject( - new JProperty("Test1", new DateTime(2000, 10, 15, 5, 5, 5, DateTimeKind.Utc)), - new JProperty("Test2", new DateTimeOffset(2000, 10, 15, 5, 5, 5, new TimeSpan(11, 11, 0))), - new JProperty("Test3", "Test3Value"), - new JProperty("Test4", null) - ); - - using (JTokenReader jsonReader = new JTokenReader(o)) - { - IJsonLineInfo lineInfo = jsonReader; - - jsonReader.Read(); - Assert.AreEqual(JsonToken.StartObject, jsonReader.TokenType); - Assert.AreEqual(false, lineInfo.HasLineInfo()); - - jsonReader.Read(); - Assert.AreEqual(JsonToken.PropertyName, jsonReader.TokenType); - Assert.AreEqual("Test1", jsonReader.Value); - Assert.AreEqual(false, lineInfo.HasLineInfo()); - - jsonReader.Read(); - Assert.AreEqual(JsonToken.Date, jsonReader.TokenType); - Assert.AreEqual(new DateTime(2000, 10, 15, 5, 5, 5, DateTimeKind.Utc), jsonReader.Value); - Assert.AreEqual(false, lineInfo.HasLineInfo()); - Assert.AreEqual(0, lineInfo.LinePosition); - Assert.AreEqual(0, lineInfo.LineNumber); - - jsonReader.Read(); - Assert.AreEqual(JsonToken.PropertyName, jsonReader.TokenType); - Assert.AreEqual("Test2", jsonReader.Value); - - jsonReader.Read(); - Assert.AreEqual(JsonToken.Date, jsonReader.TokenType); - Assert.AreEqual(new DateTimeOffset(2000, 10, 15, 5, 5, 5, new TimeSpan(11, 11, 0)), jsonReader.Value); - - jsonReader.Read(); - Assert.AreEqual(JsonToken.PropertyName, jsonReader.TokenType); - Assert.AreEqual("Test3", jsonReader.Value); - - jsonReader.Read(); - Assert.AreEqual(JsonToken.String, jsonReader.TokenType); - Assert.AreEqual("Test3Value", jsonReader.Value); - - jsonReader.Read(); - Assert.AreEqual(JsonToken.PropertyName, jsonReader.TokenType); - Assert.AreEqual("Test4", jsonReader.Value); - - jsonReader.Read(); - Assert.AreEqual(JsonToken.Null, jsonReader.TokenType); - Assert.AreEqual(null, jsonReader.Value); - - Assert.IsTrue(jsonReader.Read()); - Assert.AreEqual(JsonToken.EndObject, jsonReader.TokenType); - - Assert.IsFalse(jsonReader.Read()); - Assert.AreEqual(JsonToken.None, jsonReader.TokenType); - } - - using (JsonReader jsonReader = new JTokenReader(o.Property("Test2"))) - { - Assert.IsTrue(jsonReader.Read()); - Assert.AreEqual(JsonToken.PropertyName, jsonReader.TokenType); - Assert.AreEqual("Test2", jsonReader.Value); - - Assert.IsTrue(jsonReader.Read()); - Assert.AreEqual(JsonToken.Date, jsonReader.TokenType); - Assert.AreEqual(new DateTimeOffset(2000, 10, 15, 5, 5, 5, new TimeSpan(11, 11, 0)), jsonReader.Value); - - Assert.IsFalse(jsonReader.Read()); - Assert.AreEqual(JsonToken.None, jsonReader.TokenType); - } - } - - [Test] - public void ReadAsDateTimeOffsetBadString() - { - string json = @"{""Offset"":""blablahbla""}"; - - JObject o = JObject.Parse(json); - - JsonReader reader = o.CreateReader(); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - - ExceptionAssert.Throws( - "Could not convert string to DateTimeOffset: blablahbla. Path 'Offset', line 1, position 22.", - () => - { - reader.ReadAsDateTimeOffset(); - }); - } - - [Test] - public void ReadAsDateTimeOffsetBoolean() - { - string json = @"{""Offset"":true}"; - - JObject o = JObject.Parse(json); - - JsonReader reader = o.CreateReader(); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - - ExceptionAssert.Throws( - "Error reading date. Unexpected token: Boolean. Path 'Offset', line 1, position 14.", - () => + [Test] + public void YahooFinance() { - reader.ReadAsDateTimeOffset(); - }); - } + JObject o = + new JObject( + new JProperty("Test1", new DateTime(2000, 10, 15, 5, 5, 5, DateTimeKind.Utc)), + new JProperty("Test2", new DateTimeOffset(2000, 10, 15, 5, 5, 5, new TimeSpan(11, 11, 0))), + new JProperty("Test3", "Test3Value"), + new JProperty("Test4", null) + ); - [Test] - public void ReadAsDateTimeOffsetString() - { - string json = @"{""Offset"":""2012-01-24T03:50Z""}"; + using (JTokenReader jsonReader = new JTokenReader(o)) + { + IJsonLineInfo lineInfo = jsonReader; - JObject o = JObject.Parse(json); + jsonReader.Read(); + Assert.AreEqual(JsonToken.StartObject, jsonReader.TokenType); + Assert.AreEqual(false, lineInfo.HasLineInfo()); - JsonReader reader = o.CreateReader(); + jsonReader.Read(); + Assert.AreEqual(JsonToken.PropertyName, jsonReader.TokenType); + Assert.AreEqual("Test1", jsonReader.Value); + Assert.AreEqual(false, lineInfo.HasLineInfo()); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + jsonReader.Read(); + Assert.AreEqual(JsonToken.Date, jsonReader.TokenType); + Assert.AreEqual(new DateTime(2000, 10, 15, 5, 5, 5, DateTimeKind.Utc), jsonReader.Value); + Assert.AreEqual(false, lineInfo.HasLineInfo()); + Assert.AreEqual(0, lineInfo.LinePosition); + Assert.AreEqual(0, lineInfo.LineNumber); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + jsonReader.Read(); + Assert.AreEqual(JsonToken.PropertyName, jsonReader.TokenType); + Assert.AreEqual("Test2", jsonReader.Value); - reader.ReadAsDateTimeOffset(); - Assert.AreEqual(JsonToken.Date, reader.TokenType); - Assert.AreEqual(typeof (DateTimeOffset), reader.ValueType); - Assert.AreEqual(new DateTimeOffset(2012, 1, 24, 3, 50, 0, TimeSpan.Zero), reader.Value); - } + jsonReader.Read(); + Assert.AreEqual(JsonToken.Date, jsonReader.TokenType); + Assert.AreEqual(new DateTimeOffset(2000, 10, 15, 5, 5, 5, new TimeSpan(11, 11, 0)), jsonReader.Value); + + jsonReader.Read(); + Assert.AreEqual(JsonToken.PropertyName, jsonReader.TokenType); + Assert.AreEqual("Test3", jsonReader.Value); + + jsonReader.Read(); + Assert.AreEqual(JsonToken.String, jsonReader.TokenType); + Assert.AreEqual("Test3Value", jsonReader.Value); + + jsonReader.Read(); + Assert.AreEqual(JsonToken.PropertyName, jsonReader.TokenType); + Assert.AreEqual("Test4", jsonReader.Value); + + jsonReader.Read(); + Assert.AreEqual(JsonToken.Null, jsonReader.TokenType); + Assert.AreEqual(null, jsonReader.Value); + + Assert.IsTrue(jsonReader.Read()); + Assert.AreEqual(JsonToken.EndObject, jsonReader.TokenType); + + Assert.IsFalse(jsonReader.Read()); + Assert.AreEqual(JsonToken.None, jsonReader.TokenType); + } + + using (JsonReader jsonReader = new JTokenReader(o.Property("Test2"))) + { + Assert.IsTrue(jsonReader.Read()); + Assert.AreEqual(JsonToken.PropertyName, jsonReader.TokenType); + Assert.AreEqual("Test2", jsonReader.Value); + + Assert.IsTrue(jsonReader.Read()); + Assert.AreEqual(JsonToken.Date, jsonReader.TokenType); + Assert.AreEqual(new DateTimeOffset(2000, 10, 15, 5, 5, 5, new TimeSpan(11, 11, 0)), jsonReader.Value); + + Assert.IsFalse(jsonReader.Read()); + Assert.AreEqual(JsonToken.None, jsonReader.TokenType); + } + } + + [Test] + public void ReadAsDateTimeOffsetBadString() + { + string json = @"{""Offset"":""blablahbla""}"; + + JObject o = JObject.Parse(json); + + JsonReader reader = o.CreateReader(); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + + ExceptionAssert.Throws( + "Could not convert string to DateTimeOffset: blablahbla. Path 'Offset', line 1, position 22.", + () => { reader.ReadAsDateTimeOffset(); }); + } + + [Test] + public void ReadAsDateTimeOffsetBoolean() + { + string json = @"{""Offset"":true}"; + + JObject o = JObject.Parse(json); + + JsonReader reader = o.CreateReader(); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + + ExceptionAssert.Throws( + "Error reading date. Unexpected token: Boolean. Path 'Offset', line 1, position 14.", + () => { reader.ReadAsDateTimeOffset(); }); + } + + [Test] + public void ReadAsDateTimeOffsetString() + { + string json = @"{""Offset"":""2012-01-24T03:50Z""}"; + + JObject o = JObject.Parse(json); + + JsonReader reader = o.CreateReader(); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + + reader.ReadAsDateTimeOffset(); + Assert.AreEqual(JsonToken.Date, reader.TokenType); + Assert.AreEqual(typeof(DateTimeOffset), reader.ValueType); + Assert.AreEqual(new DateTimeOffset(2012, 1, 24, 3, 50, 0, TimeSpan.Zero), reader.Value); + } #endif - [Test] - public void ReadLineInfo() - { - string input = @"{ + [Test] + public void ReadLineInfo() + { + string input = @"{ CPU: 'Intel', Drives: [ 'DVD read/writer', @@ -201,417 +195,405 @@ namespace Newtonsoft.Json.Tests.Linq ] }"; - StringReader sr = new StringReader(input); + StringReader sr = new StringReader(input); - JObject o = JObject.Parse(input); - - using (JTokenReader jsonReader = new JTokenReader(o)) - { - IJsonLineInfo lineInfo = jsonReader; - - Assert.AreEqual(jsonReader.TokenType, JsonToken.None); - Assert.AreEqual(0, lineInfo.LineNumber); - Assert.AreEqual(0, lineInfo.LinePosition); - Assert.AreEqual(false, lineInfo.HasLineInfo()); - - jsonReader.Read(); - Assert.AreEqual(jsonReader.TokenType, JsonToken.StartObject); - Assert.AreEqual(1, lineInfo.LineNumber); - Assert.AreEqual(1, lineInfo.LinePosition); - Assert.AreEqual(true, lineInfo.HasLineInfo()); - - jsonReader.Read(); - Assert.AreEqual(jsonReader.TokenType, JsonToken.PropertyName); - Assert.AreEqual(jsonReader.Value, "CPU"); - Assert.AreEqual(2, lineInfo.LineNumber); - Assert.AreEqual(7, lineInfo.LinePosition); - Assert.AreEqual(true, lineInfo.HasLineInfo()); - - jsonReader.Read(); - Assert.AreEqual(jsonReader.TokenType, JsonToken.String); - Assert.AreEqual(jsonReader.Value, "Intel"); - Assert.AreEqual(2, lineInfo.LineNumber); - Assert.AreEqual(15, lineInfo.LinePosition); - Assert.AreEqual(true, lineInfo.HasLineInfo()); - - jsonReader.Read(); - Assert.AreEqual(jsonReader.TokenType, JsonToken.PropertyName); - Assert.AreEqual(jsonReader.Value, "Drives"); - Assert.AreEqual(3, lineInfo.LineNumber); - Assert.AreEqual(10, lineInfo.LinePosition); - Assert.AreEqual(true, lineInfo.HasLineInfo()); - - jsonReader.Read(); - Assert.AreEqual(jsonReader.TokenType, JsonToken.StartArray); - Assert.AreEqual(3, lineInfo.LineNumber); - Assert.AreEqual(12, lineInfo.LinePosition); - Assert.AreEqual(true, lineInfo.HasLineInfo()); - - jsonReader.Read(); - Assert.AreEqual(jsonReader.TokenType, JsonToken.String); - Assert.AreEqual(jsonReader.Value, "DVD read/writer"); - Assert.AreEqual(4, lineInfo.LineNumber); - Assert.AreEqual(22, lineInfo.LinePosition); - Assert.AreEqual(true, lineInfo.HasLineInfo()); - - jsonReader.Read(); - Assert.AreEqual(jsonReader.TokenType, JsonToken.String); - Assert.AreEqual(jsonReader.Value, "500 gigabyte hard drive"); - Assert.AreEqual(5, lineInfo.LineNumber); - Assert.AreEqual(30, lineInfo.LinePosition); - Assert.AreEqual(true, lineInfo.HasLineInfo()); - - jsonReader.Read(); - Assert.AreEqual(jsonReader.TokenType, JsonToken.EndArray); - Assert.AreEqual(0, lineInfo.LineNumber); - Assert.AreEqual(0, lineInfo.LinePosition); - Assert.AreEqual(false, lineInfo.HasLineInfo()); - - jsonReader.Read(); - Assert.AreEqual(jsonReader.TokenType, JsonToken.EndObject); - Assert.AreEqual(0, lineInfo.LineNumber); - Assert.AreEqual(0, lineInfo.LinePosition); - Assert.AreEqual(false, lineInfo.HasLineInfo()); - - jsonReader.Read(); - Assert.AreEqual(jsonReader.TokenType, JsonToken.None); - } - } - - [Test] - public void ReadBytes() - { - byte[] data = Encoding.UTF8.GetBytes("Hello world!"); - - JObject o = - new JObject( - new JProperty("Test1", data) - ); - - using (JTokenReader jsonReader = new JTokenReader(o)) - { - jsonReader.Read(); - Assert.AreEqual(JsonToken.StartObject, jsonReader.TokenType); - - jsonReader.Read(); - Assert.AreEqual(JsonToken.PropertyName, jsonReader.TokenType); - Assert.AreEqual("Test1", jsonReader.Value); - - byte[] readBytes = jsonReader.ReadAsBytes(); - Assert.AreEqual(data, readBytes); - - Assert.IsTrue(jsonReader.Read()); - Assert.AreEqual(JsonToken.EndObject, jsonReader.TokenType); - - Assert.IsFalse(jsonReader.Read()); - Assert.AreEqual(JsonToken.None, jsonReader.TokenType); - } - } - - [Test] - public void ReadBytesFailure() - { - ExceptionAssert.Throws( - "Error reading bytes. Unexpected token: Integer. Path 'Test1'.", - () => - { - JObject o = - new JObject( - new JProperty("Test1", 1) - ); + JObject o = JObject.Parse(input); using (JTokenReader jsonReader = new JTokenReader(o)) { - jsonReader.Read(); - Assert.AreEqual(JsonToken.StartObject, jsonReader.TokenType); + IJsonLineInfo lineInfo = jsonReader; - jsonReader.Read(); - Assert.AreEqual(JsonToken.PropertyName, jsonReader.TokenType); - Assert.AreEqual("Test1", jsonReader.Value); + Assert.AreEqual(jsonReader.TokenType, JsonToken.None); + Assert.AreEqual(0, lineInfo.LineNumber); + Assert.AreEqual(0, lineInfo.LinePosition); + Assert.AreEqual(false, lineInfo.HasLineInfo()); - jsonReader.ReadAsBytes(); + jsonReader.Read(); + Assert.AreEqual(jsonReader.TokenType, JsonToken.StartObject); + Assert.AreEqual(1, lineInfo.LineNumber); + Assert.AreEqual(1, lineInfo.LinePosition); + Assert.AreEqual(true, lineInfo.HasLineInfo()); + + jsonReader.Read(); + Assert.AreEqual(jsonReader.TokenType, JsonToken.PropertyName); + Assert.AreEqual(jsonReader.Value, "CPU"); + Assert.AreEqual(2, lineInfo.LineNumber); + Assert.AreEqual(7, lineInfo.LinePosition); + Assert.AreEqual(true, lineInfo.HasLineInfo()); + + jsonReader.Read(); + Assert.AreEqual(jsonReader.TokenType, JsonToken.String); + Assert.AreEqual(jsonReader.Value, "Intel"); + Assert.AreEqual(2, lineInfo.LineNumber); + Assert.AreEqual(15, lineInfo.LinePosition); + Assert.AreEqual(true, lineInfo.HasLineInfo()); + + jsonReader.Read(); + Assert.AreEqual(jsonReader.TokenType, JsonToken.PropertyName); + Assert.AreEqual(jsonReader.Value, "Drives"); + Assert.AreEqual(3, lineInfo.LineNumber); + Assert.AreEqual(10, lineInfo.LinePosition); + Assert.AreEqual(true, lineInfo.HasLineInfo()); + + jsonReader.Read(); + Assert.AreEqual(jsonReader.TokenType, JsonToken.StartArray); + Assert.AreEqual(3, lineInfo.LineNumber); + Assert.AreEqual(12, lineInfo.LinePosition); + Assert.AreEqual(true, lineInfo.HasLineInfo()); + + jsonReader.Read(); + Assert.AreEqual(jsonReader.TokenType, JsonToken.String); + Assert.AreEqual(jsonReader.Value, "DVD read/writer"); + Assert.AreEqual(4, lineInfo.LineNumber); + Assert.AreEqual(22, lineInfo.LinePosition); + Assert.AreEqual(true, lineInfo.HasLineInfo()); + + jsonReader.Read(); + Assert.AreEqual(jsonReader.TokenType, JsonToken.String); + Assert.AreEqual(jsonReader.Value, "500 gigabyte hard drive"); + Assert.AreEqual(5, lineInfo.LineNumber); + Assert.AreEqual(30, lineInfo.LinePosition); + Assert.AreEqual(true, lineInfo.HasLineInfo()); + + jsonReader.Read(); + Assert.AreEqual(jsonReader.TokenType, JsonToken.EndArray); + Assert.AreEqual(0, lineInfo.LineNumber); + Assert.AreEqual(0, lineInfo.LinePosition); + Assert.AreEqual(false, lineInfo.HasLineInfo()); + + jsonReader.Read(); + Assert.AreEqual(jsonReader.TokenType, JsonToken.EndObject); + Assert.AreEqual(0, lineInfo.LineNumber); + Assert.AreEqual(0, lineInfo.LinePosition); + Assert.AreEqual(false, lineInfo.HasLineInfo()); + + jsonReader.Read(); + Assert.AreEqual(jsonReader.TokenType, JsonToken.None); } - }); - } + } - public class HasBytes - { - public byte[] Bytes { get; set; } - } - - [Test] - public void ReadBytesFromString() - { - var bytes = new HasBytes { Bytes = new byte[] { 1, 2, 3, 4 } }; - var json = JsonConvert.SerializeObject(bytes); - - TextReader textReader = new StringReader(json); - JsonReader jsonReader = new JsonTextReader(textReader); - - var jToken = JToken.ReadFrom(jsonReader); - - jsonReader = new JTokenReader(jToken); - - var result2 = (HasBytes)JsonSerializer.Create(null) - .Deserialize(jsonReader, typeof(HasBytes)); - - CollectionAssert.AreEqual(new byte[] { 1, 2, 3, 4 }, result2.Bytes); - } - - [Test] - public void ReadBytesFromEmptyString() - { - var bytes = new HasBytes { Bytes = new byte[0] }; - var json = JsonConvert.SerializeObject(bytes); - - TextReader textReader = new StringReader(json); - JsonReader jsonReader = new JsonTextReader(textReader); - - var jToken = JToken.ReadFrom(jsonReader); - - jsonReader = new JTokenReader(jToken); - - var result2 = (HasBytes)JsonSerializer.Create(null) - .Deserialize(jsonReader, typeof(HasBytes)); - - CollectionAssert.AreEquivalent(new byte[0], result2.Bytes); - } - - public class ReadAsBytesTestObject - { - public byte[] Data; - } - - [Test] - public void ReadAsBytesNull() - { - JsonSerializer s = new JsonSerializer(); - - JToken nullToken = JToken.ReadFrom(new JsonTextReader(new StringReader("{ Data: null }"))); - ReadAsBytesTestObject x = s.Deserialize(new JTokenReader(nullToken)); - Assert.IsNull(x.Data); - } - - [Test] - public void DeserializeByteArrayWithTypeNameHandling() - { - TestObject test = new TestObject("Test", new byte[] { 72, 63, 62, 71, 92, 55 }); - - string json = JsonConvert.SerializeObject(test, Formatting.Indented, new JsonSerializerSettings + [Test] + public void ReadBytes() { - TypeNameHandling = TypeNameHandling.All - }); + byte[] data = Encoding.UTF8.GetBytes("Hello world!"); - JObject o = JObject.Parse(json); + JObject o = + new JObject( + new JProperty("Test1", data) + ); - JsonSerializer serializer = new JsonSerializer(); - serializer.TypeNameHandling = TypeNameHandling.All; + using (JTokenReader jsonReader = new JTokenReader(o)) + { + jsonReader.Read(); + Assert.AreEqual(JsonToken.StartObject, jsonReader.TokenType); - using (JsonReader nodeReader = o.CreateReader()) - { - // Get exception here - TestObject newObject = (TestObject)serializer.Deserialize(nodeReader); + jsonReader.Read(); + Assert.AreEqual(JsonToken.PropertyName, jsonReader.TokenType); + Assert.AreEqual("Test1", jsonReader.Value); - Assert.AreEqual("Test", newObject.Name); - CollectionAssert.AreEquivalent(new byte[] { 72, 63, 62, 71, 92, 55 }, newObject.Data); - } - } + byte[] readBytes = jsonReader.ReadAsBytes(); + Assert.AreEqual(data, readBytes); - [Test] - public void DeserializeStringInt() - { - string json = @"{ + Assert.IsTrue(jsonReader.Read()); + Assert.AreEqual(JsonToken.EndObject, jsonReader.TokenType); + + Assert.IsFalse(jsonReader.Read()); + Assert.AreEqual(JsonToken.None, jsonReader.TokenType); + } + } + + [Test] + public void ReadBytesFailure() + { + ExceptionAssert.Throws( + "Error reading bytes. Unexpected token: Integer. Path 'Test1'.", + () => + { + JObject o = + new JObject( + new JProperty("Test1", 1) + ); + + using (JTokenReader jsonReader = new JTokenReader(o)) + { + jsonReader.Read(); + Assert.AreEqual(JsonToken.StartObject, jsonReader.TokenType); + + jsonReader.Read(); + Assert.AreEqual(JsonToken.PropertyName, jsonReader.TokenType); + Assert.AreEqual("Test1", jsonReader.Value); + + jsonReader.ReadAsBytes(); + } + }); + } + + public class HasBytes + { + public byte[] Bytes { get; set; } + } + + [Test] + public void ReadBytesFromString() + { + var bytes = new HasBytes { Bytes = new byte[] { 1, 2, 3, 4 } }; + var json = JsonConvert.SerializeObject(bytes); + + TextReader textReader = new StringReader(json); + JsonReader jsonReader = new JsonTextReader(textReader); + + var jToken = JToken.ReadFrom(jsonReader); + + jsonReader = new JTokenReader(jToken); + + var result2 = (HasBytes)JsonSerializer.Create(null) + .Deserialize(jsonReader, typeof(HasBytes)); + + CollectionAssert.AreEqual(new byte[] { 1, 2, 3, 4 }, result2.Bytes); + } + + [Test] + public void ReadBytesFromEmptyString() + { + var bytes = new HasBytes { Bytes = new byte[0] }; + var json = JsonConvert.SerializeObject(bytes); + + TextReader textReader = new StringReader(json); + JsonReader jsonReader = new JsonTextReader(textReader); + + var jToken = JToken.ReadFrom(jsonReader); + + jsonReader = new JTokenReader(jToken); + + var result2 = (HasBytes)JsonSerializer.Create(null) + .Deserialize(jsonReader, typeof(HasBytes)); + + CollectionAssert.AreEquivalent(new byte[0], result2.Bytes); + } + + public class ReadAsBytesTestObject + { + public byte[] Data; + } + + [Test] + public void ReadAsBytesNull() + { + JsonSerializer s = new JsonSerializer(); + + JToken nullToken = JToken.ReadFrom(new JsonTextReader(new StringReader("{ Data: null }"))); + ReadAsBytesTestObject x = s.Deserialize(new JTokenReader(nullToken)); + Assert.IsNull(x.Data); + } + + [Test] + public void DeserializeByteArrayWithTypeNameHandling() + { + TestObject test = new TestObject("Test", new byte[] { 72, 63, 62, 71, 92, 55 }); + + string json = JsonConvert.SerializeObject(test, Formatting.Indented, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.All + }); + + JObject o = JObject.Parse(json); + + JsonSerializer serializer = new JsonSerializer(); + serializer.TypeNameHandling = TypeNameHandling.All; + + using (JsonReader nodeReader = o.CreateReader()) + { + // Get exception here + TestObject newObject = (TestObject)serializer.Deserialize(nodeReader); + + Assert.AreEqual("Test", newObject.Name); + CollectionAssert.AreEquivalent(new byte[] { 72, 63, 62, 71, 92, 55 }, newObject.Data); + } + } + + [Test] + public void DeserializeStringInt() + { + string json = @"{ ""PreProperty"": ""99"", ""PostProperty"": ""-1"" }"; - JObject o = JObject.Parse(json); + JObject o = JObject.Parse(json); - JsonSerializer serializer = new JsonSerializer(); + JsonSerializer serializer = new JsonSerializer(); - using (JsonReader nodeReader = o.CreateReader()) - { - MyClass c = serializer.Deserialize(nodeReader); + using (JsonReader nodeReader = o.CreateReader()) + { + MyClass c = serializer.Deserialize(nodeReader); - Assert.AreEqual(99, c.PreProperty); - Assert.AreEqual(-1, c.PostProperty); - } - } + Assert.AreEqual(99, c.PreProperty); + Assert.AreEqual(-1, c.PostProperty); + } + } - [Test] - public void ReadAsDecimalInt() - { - string json = @"{""Name"":1}"; - - JObject o = JObject.Parse(json); - - JsonReader reader = o.CreateReader(); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - - reader.ReadAsDecimal(); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual(typeof(decimal), reader.ValueType); - Assert.AreEqual(1m, reader.Value); - } - - [Test] - public void ReadAsInt32Int() - { - string json = @"{""Name"":1}"; - - JObject o = JObject.Parse(json); - - JsonReader reader = o.CreateReader(); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - - reader.ReadAsInt32(); - Assert.AreEqual(JsonToken.Integer, reader.TokenType); - Assert.AreEqual(typeof(int), reader.ValueType); - Assert.AreEqual(1, reader.Value); - } - - [Test] - public void ReadAsInt32BadString() - { - string json = @"{""Name"":""hi""}"; - - JObject o = JObject.Parse(json); - - JsonReader reader = o.CreateReader(); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - - ExceptionAssert.Throws( - "Could not convert string to integer: hi. Path 'Name', line 1, position 12.", - () => - { - reader.ReadAsInt32(); - }); - } - - [Test] - public void ReadAsInt32Boolean() - { - string json = @"{""Name"":true}"; - - JObject o = JObject.Parse(json); - - JsonReader reader = o.CreateReader(); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - - ExceptionAssert.Throws( - "Error reading integer. Unexpected token: Boolean. Path 'Name', line 1, position 12.", - () => - { - reader.ReadAsInt32(); - }); - } - - [Test] - public void ReadAsDecimalString() - { - string json = @"{""Name"":""1.1""}"; - - JObject o = JObject.Parse(json); - - JsonReader reader = o.CreateReader(); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - - reader.ReadAsDecimal(); - Assert.AreEqual(JsonToken.Float, reader.TokenType); - Assert.AreEqual(typeof(decimal), reader.ValueType); - Assert.AreEqual(1.1m, reader.Value); - } - - [Test] - public void ReadAsDecimalBadString() - { - string json = @"{""Name"":""blah""}"; - - JObject o = JObject.Parse(json); - - JsonReader reader = o.CreateReader(); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - - ExceptionAssert.Throws( - "Could not convert string to decimal: blah. Path 'Name', line 1, position 14.", - () => + [Test] + public void ReadAsDecimalInt() { - reader.ReadAsDecimal(); - }); - } + string json = @"{""Name"":1}"; - [Test] - public void ReadAsDecimalBoolean() - { - string json = @"{""Name"":true}"; + JObject o = JObject.Parse(json); - JObject o = JObject.Parse(json); + JsonReader reader = o.CreateReader(); - JsonReader reader = o.CreateReader(); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - - ExceptionAssert.Throws( - "Error reading decimal. Unexpected token: Boolean. Path 'Name', line 1, position 12.", - () => - { reader.ReadAsDecimal(); - }); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual(typeof(decimal), reader.ValueType); + Assert.AreEqual(1m, reader.Value); + } + + [Test] + public void ReadAsInt32Int() + { + string json = @"{""Name"":1}"; + + JObject o = JObject.Parse(json); + + JsonReader reader = o.CreateReader(); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + + reader.ReadAsInt32(); + Assert.AreEqual(JsonToken.Integer, reader.TokenType); + Assert.AreEqual(typeof(int), reader.ValueType); + Assert.AreEqual(1, reader.Value); + } + + [Test] + public void ReadAsInt32BadString() + { + string json = @"{""Name"":""hi""}"; + + JObject o = JObject.Parse(json); + + JsonReader reader = o.CreateReader(); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + + ExceptionAssert.Throws( + "Could not convert string to integer: hi. Path 'Name', line 1, position 12.", + () => { reader.ReadAsInt32(); }); + } + + [Test] + public void ReadAsInt32Boolean() + { + string json = @"{""Name"":true}"; + + JObject o = JObject.Parse(json); + + JsonReader reader = o.CreateReader(); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + + ExceptionAssert.Throws( + "Error reading integer. Unexpected token: Boolean. Path 'Name', line 1, position 12.", + () => { reader.ReadAsInt32(); }); + } + + [Test] + public void ReadAsDecimalString() + { + string json = @"{""Name"":""1.1""}"; + + JObject o = JObject.Parse(json); + + JsonReader reader = o.CreateReader(); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + + reader.ReadAsDecimal(); + Assert.AreEqual(JsonToken.Float, reader.TokenType); + Assert.AreEqual(typeof(decimal), reader.ValueType); + Assert.AreEqual(1.1m, reader.Value); + } + + [Test] + public void ReadAsDecimalBadString() + { + string json = @"{""Name"":""blah""}"; + + JObject o = JObject.Parse(json); + + JsonReader reader = o.CreateReader(); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + + ExceptionAssert.Throws( + "Could not convert string to decimal: blah. Path 'Name', line 1, position 14.", + () => { reader.ReadAsDecimal(); }); + } + + [Test] + public void ReadAsDecimalBoolean() + { + string json = @"{""Name"":true}"; + + JObject o = JObject.Parse(json); + + JsonReader reader = o.CreateReader(); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + + ExceptionAssert.Throws( + "Error reading decimal. Unexpected token: Boolean. Path 'Name', line 1, position 12.", + () => { reader.ReadAsDecimal(); }); + } + + [Test] + public void ReadAsDecimalNull() + { + string json = @"{""Name"":null}"; + + JObject o = JObject.Parse(json); + + JsonReader reader = o.CreateReader(); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.StartObject, reader.TokenType); + + Assert.IsTrue(reader.Read()); + Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); + + reader.ReadAsDecimal(); + Assert.AreEqual(JsonToken.Null, reader.TokenType); + Assert.AreEqual(null, reader.ValueType); + Assert.AreEqual(null, reader.Value); + } } - - [Test] - public void ReadAsDecimalNull() - { - string json = @"{""Name"":null}"; - - JObject o = JObject.Parse(json); - - JsonReader reader = o.CreateReader(); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.StartObject, reader.TokenType); - - Assert.IsTrue(reader.Read()); - Assert.AreEqual(JsonToken.PropertyName, reader.TokenType); - - reader.ReadAsDecimal(); - Assert.AreEqual(JsonToken.Null, reader.TokenType); - Assert.AreEqual(null, reader.ValueType); - Assert.AreEqual(null, reader.Value); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs index 270f13c5..25fa9440 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs @@ -44,1008 +44,1009 @@ using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; using Newtonsoft.Json.Utilities; + #endif namespace Newtonsoft.Json.Tests.Linq { - [TestFixture] - public class JTokenTests : TestFixtureBase - { - [Test] - public void ReadFrom() + [TestFixture] + public class JTokenTests : TestFixtureBase { - JObject o = (JObject)JToken.ReadFrom(new JsonTextReader(new StringReader("{'pie':true}"))); - Assert.AreEqual(true, (bool)o["pie"]); - - JArray a = (JArray)JToken.ReadFrom(new JsonTextReader(new StringReader("[1,2,3]"))); - Assert.AreEqual(1, (int)a[0]); - Assert.AreEqual(2, (int)a[1]); - Assert.AreEqual(3, (int)a[2]); - - JsonReader reader = new JsonTextReader(new StringReader("{'pie':true}")); - reader.Read(); - reader.Read(); - - JProperty p = (JProperty)JToken.ReadFrom(reader); - Assert.AreEqual("pie", p.Name); - Assert.AreEqual(true, (bool)p.Value); - - JConstructor c = (JConstructor)JToken.ReadFrom(new JsonTextReader(new StringReader("new Date(1)"))); - Assert.AreEqual("Date", c.Name); - Assert.IsTrue(JToken.DeepEquals(new JValue(1), c.Values().ElementAt(0))); - - JValue v; - - v = (JValue)JToken.ReadFrom(new JsonTextReader(new StringReader(@"""stringvalue"""))); - Assert.AreEqual("stringvalue", (string)v); - - v = (JValue)JToken.ReadFrom(new JsonTextReader(new StringReader(@"1"))); - Assert.AreEqual(1, (int)v); - - v = (JValue)JToken.ReadFrom(new JsonTextReader(new StringReader(@"1.1"))); - Assert.AreEqual(1.1, (double)v); - -#if !NET20 - v = (JValue)JToken.ReadFrom(new JsonTextReader(new StringReader(@"""1970-01-01T00:00:00+12:31""")) + [Test] + public void ReadFrom() { - DateParseHandling = DateParseHandling.DateTimeOffset - }); - Assert.AreEqual(typeof(DateTimeOffset), v.Value.GetType()); - Assert.AreEqual(new DateTimeOffset(DateTimeUtils.InitialJavaScriptDateTicks, new TimeSpan(12, 31, 0)), v.Value); -#endif - } + JObject o = (JObject)JToken.ReadFrom(new JsonTextReader(new StringReader("{'pie':true}"))); + Assert.AreEqual(true, (bool)o["pie"]); - [Test] - public void Load() - { - JObject o = (JObject)JToken.Load(new JsonTextReader(new StringReader("{'pie':true}"))); - Assert.AreEqual(true, (bool)o["pie"]); - } + JArray a = (JArray)JToken.ReadFrom(new JsonTextReader(new StringReader("[1,2,3]"))); + Assert.AreEqual(1, (int)a[0]); + Assert.AreEqual(2, (int)a[1]); + Assert.AreEqual(3, (int)a[2]); - [Test] - public void Parse() - { - JObject o = (JObject)JToken.Parse("{'pie':true}"); - Assert.AreEqual(true, (bool)o["pie"]); - } + JsonReader reader = new JsonTextReader(new StringReader("{'pie':true}")); + reader.Read(); + reader.Read(); - [Test] - public void Parent() - { - JArray v = new JArray(new JConstructor("TestConstructor"), new JValue(new DateTime(2000, 12, 20))); + JProperty p = (JProperty)JToken.ReadFrom(reader); + Assert.AreEqual("pie", p.Name); + Assert.AreEqual(true, (bool)p.Value); - Assert.AreEqual(null, v.Parent); + JConstructor c = (JConstructor)JToken.ReadFrom(new JsonTextReader(new StringReader("new Date(1)"))); + Assert.AreEqual("Date", c.Name); + Assert.IsTrue(JToken.DeepEquals(new JValue(1), c.Values().ElementAt(0))); - JObject o = - new JObject( - new JProperty("Test1", v), - new JProperty("Test2", "Test2Value"), - new JProperty("Test3", "Test3Value"), - new JProperty("Test4", null) - ); + JValue v; - Assert.AreEqual(o.Property("Test1"), v.Parent); + v = (JValue)JToken.ReadFrom(new JsonTextReader(new StringReader(@"""stringvalue"""))); + Assert.AreEqual("stringvalue", (string)v); - JProperty p = new JProperty("NewProperty", v); + v = (JValue)JToken.ReadFrom(new JsonTextReader(new StringReader(@"1"))); + Assert.AreEqual(1, (int)v); - // existing value should still have same parent - Assert.AreEqual(o.Property("Test1"), v.Parent); + v = (JValue)JToken.ReadFrom(new JsonTextReader(new StringReader(@"1.1"))); + Assert.AreEqual(1.1, (double)v); - // new value should be cloned - Assert.AreNotSame(p.Value, v); - - Assert.AreEqual((DateTime)((JValue)p.Value[1]).Value, (DateTime)((JValue)v[1]).Value); - - Assert.AreEqual(v, o["Test1"]); - - Assert.AreEqual(null, o.Parent); - JProperty o1 = new JProperty("O1", o); - Assert.AreEqual(o, o1.Value); - - Assert.AreNotEqual(null, o.Parent); - JProperty o2 = new JProperty("O2", o); - - Assert.AreNotSame(o1.Value, o2.Value); - Assert.AreEqual(o1.Value.Children().Count(), o2.Value.Children().Count()); - Assert.AreEqual(false, JToken.DeepEquals(o1, o2)); - Assert.AreEqual(true, JToken.DeepEquals(o1.Value, o2.Value)); - } - - [Test] - public void Next() - { - JArray a = - new JArray( - 5, - 6, - new JArray(7, 8), - new JArray(9, 10) - ); - - JToken next = a[0].Next; - Assert.AreEqual(6, (int)next); - - next = next.Next; - Assert.IsTrue(JToken.DeepEquals(new JArray(7, 8), next)); - - next = next.Next; - Assert.IsTrue(JToken.DeepEquals(new JArray(9, 10), next)); - - next = next.Next; - Assert.IsNull(next); - } - - [Test] - public void Previous() - { - JArray a = - new JArray( - 5, - 6, - new JArray(7, 8), - new JArray(9, 10) - ); - - JToken previous = a[3].Previous; - Assert.IsTrue(JToken.DeepEquals(new JArray(7, 8), previous)); - - previous = previous.Previous; - Assert.AreEqual(6, (int)previous); - - previous = previous.Previous; - Assert.AreEqual(5, (int)previous); - - previous = previous.Previous; - Assert.IsNull(previous); - } - - [Test] - public void Children() - { - JArray a = - new JArray( - 5, - new JArray(1), - new JArray(1, 2), - new JArray(1, 2, 3) - ); - - Assert.AreEqual(4, a.Count()); - Assert.AreEqual(3, a.Children().Count()); - } - - [Test] - public void BeforeAfter() - { - JArray a = - new JArray( - 5, - new JArray(1, 2, 3), - new JArray(1, 2, 3), - new JArray(1, 2, 3) - ); - - Assert.AreEqual(5, (int)a[1].Previous); - Assert.AreEqual(2, a[2].BeforeSelf().Count()); - //Assert.AreEqual(2, a[2].AfterSelf().Count()); - } - - [Test] - public void Casting() - { - Assert.AreEqual(1L, (long)(new JValue(1))); - Assert.AreEqual(2L, (long)new JArray(1, 2, 3)[1]); - - Assert.AreEqual(new DateTime(2000, 12, 20), (DateTime)new JValue(new DateTime(2000, 12, 20))); #if !NET20 - Assert.AreEqual(new DateTimeOffset(2000, 12, 20, 0, 0, 0, TimeSpan.Zero), (DateTimeOffset)new JValue(new DateTime(2000, 12, 20, 0, 0, 0, DateTimeKind.Utc))); - Assert.AreEqual(new DateTimeOffset(2000, 12, 20, 23, 50, 10, TimeSpan.Zero), (DateTimeOffset)new JValue(new DateTimeOffset(2000, 12, 20, 23, 50, 10, TimeSpan.Zero))); - Assert.AreEqual(null, (DateTimeOffset?)new JValue((DateTimeOffset?)null)); - Assert.AreEqual(null, (DateTimeOffset?)(JValue)null); + v = (JValue)JToken.ReadFrom(new JsonTextReader(new StringReader(@"""1970-01-01T00:00:00+12:31""")) + { + DateParseHandling = DateParseHandling.DateTimeOffset + }); + Assert.AreEqual(typeof(DateTimeOffset), v.Value.GetType()); + Assert.AreEqual(new DateTimeOffset(DateTimeUtils.InitialJavaScriptDateTicks, new TimeSpan(12, 31, 0)), v.Value); #endif - Assert.AreEqual(true, (bool)new JValue(true)); - Assert.AreEqual(true, (bool?)new JValue(true)); - Assert.AreEqual(null, (bool?)((JValue)null)); - Assert.AreEqual(null, (bool?)new JValue((object)null)); - Assert.AreEqual(10, (long)new JValue(10)); - Assert.AreEqual(null, (long?)new JValue((long?)null)); - Assert.AreEqual(null, (long?)(JValue)null); - Assert.AreEqual(null, (int?)new JValue((int?)null)); - Assert.AreEqual(null, (int?)(JValue)null); - Assert.AreEqual(null, (DateTime?)new JValue((DateTime?)null)); - Assert.AreEqual(null, (DateTime?)(JValue)null); - Assert.AreEqual(null, (short?)new JValue((short?)null)); - Assert.AreEqual(null, (short?)(JValue)null); - Assert.AreEqual(null, (float?)new JValue((float?)null)); - Assert.AreEqual(null, (float?)(JValue)null); - Assert.AreEqual(null, (double?)new JValue((double?)null)); - Assert.AreEqual(null, (double?)(JValue)null); - Assert.AreEqual(null, (decimal?)new JValue((decimal?)null)); - Assert.AreEqual(null, (decimal?)(JValue)null); - Assert.AreEqual(null, (uint?)new JValue((uint?)null)); - Assert.AreEqual(null, (uint?)(JValue)null); - Assert.AreEqual(null, (sbyte?)new JValue((sbyte?)null)); - Assert.AreEqual(null, (sbyte?)(JValue)null); - Assert.AreEqual(null, (byte?)new JValue((byte?)null)); - Assert.AreEqual(null, (byte?)(JValue)null); - Assert.AreEqual(null, (ulong?)new JValue((ulong?)null)); - Assert.AreEqual(null, (ulong?)(JValue)null); - Assert.AreEqual(null, (uint?)new JValue((uint?)null)); - Assert.AreEqual(null, (uint?)(JValue)null); - Assert.AreEqual(11.1f, (float)new JValue(11.1)); - Assert.AreEqual(float.MinValue, (float)new JValue(float.MinValue)); - Assert.AreEqual(1.1, (double)new JValue(1.1)); - Assert.AreEqual(uint.MaxValue, (uint)new JValue(uint.MaxValue)); - Assert.AreEqual(ulong.MaxValue, (ulong)new JValue(ulong.MaxValue)); - Assert.AreEqual(ulong.MaxValue, (ulong)new JProperty("Test", new JValue(ulong.MaxValue))); - Assert.AreEqual(null, (string)new JValue((string)null)); - Assert.AreEqual(5m, (decimal)(new JValue(5L))); - Assert.AreEqual(5m, (decimal?)(new JValue(5L))); - Assert.AreEqual(5f, (float)(new JValue(5L))); - Assert.AreEqual(5f, (float)(new JValue(5m))); - Assert.AreEqual(5f, (float?)(new JValue(5m))); - Assert.AreEqual(5, (byte)(new JValue(5))); + } - Assert.AreEqual(null, (sbyte?)new JValue((object)null)); + [Test] + public void Load() + { + JObject o = (JObject)JToken.Load(new JsonTextReader(new StringReader("{'pie':true}"))); + Assert.AreEqual(true, (bool)o["pie"]); + } - Assert.AreEqual("1", (string)(new JValue(1))); - Assert.AreEqual("1", (string)(new JValue(1.0))); - Assert.AreEqual("1.0", (string)(new JValue(1.0m))); - Assert.AreEqual("True", (string)(new JValue(true))); - Assert.AreEqual(null, (string)(new JValue((object)null))); - Assert.AreEqual(null, (string)(JValue)null); - Assert.AreEqual("12/12/2000 12:12:12", (string)(new JValue(new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc)))); + [Test] + public void Parse() + { + JObject o = (JObject)JToken.Parse("{'pie':true}"); + Assert.AreEqual(true, (bool)o["pie"]); + } + + [Test] + public void Parent() + { + JArray v = new JArray(new JConstructor("TestConstructor"), new JValue(new DateTime(2000, 12, 20))); + + Assert.AreEqual(null, v.Parent); + + JObject o = + new JObject( + new JProperty("Test1", v), + new JProperty("Test2", "Test2Value"), + new JProperty("Test3", "Test3Value"), + new JProperty("Test4", null) + ); + + Assert.AreEqual(o.Property("Test1"), v.Parent); + + JProperty p = new JProperty("NewProperty", v); + + // existing value should still have same parent + Assert.AreEqual(o.Property("Test1"), v.Parent); + + // new value should be cloned + Assert.AreNotSame(p.Value, v); + + Assert.AreEqual((DateTime)((JValue)p.Value[1]).Value, (DateTime)((JValue)v[1]).Value); + + Assert.AreEqual(v, o["Test1"]); + + Assert.AreEqual(null, o.Parent); + JProperty o1 = new JProperty("O1", o); + Assert.AreEqual(o, o1.Value); + + Assert.AreNotEqual(null, o.Parent); + JProperty o2 = new JProperty("O2", o); + + Assert.AreNotSame(o1.Value, o2.Value); + Assert.AreEqual(o1.Value.Children().Count(), o2.Value.Children().Count()); + Assert.AreEqual(false, JToken.DeepEquals(o1, o2)); + Assert.AreEqual(true, JToken.DeepEquals(o1.Value, o2.Value)); + } + + [Test] + public void Next() + { + JArray a = + new JArray( + 5, + 6, + new JArray(7, 8), + new JArray(9, 10) + ); + + JToken next = a[0].Next; + Assert.AreEqual(6, (int)next); + + next = next.Next; + Assert.IsTrue(JToken.DeepEquals(new JArray(7, 8), next)); + + next = next.Next; + Assert.IsTrue(JToken.DeepEquals(new JArray(9, 10), next)); + + next = next.Next; + Assert.IsNull(next); + } + + [Test] + public void Previous() + { + JArray a = + new JArray( + 5, + 6, + new JArray(7, 8), + new JArray(9, 10) + ); + + JToken previous = a[3].Previous; + Assert.IsTrue(JToken.DeepEquals(new JArray(7, 8), previous)); + + previous = previous.Previous; + Assert.AreEqual(6, (int)previous); + + previous = previous.Previous; + Assert.AreEqual(5, (int)previous); + + previous = previous.Previous; + Assert.IsNull(previous); + } + + [Test] + public void Children() + { + JArray a = + new JArray( + 5, + new JArray(1), + new JArray(1, 2), + new JArray(1, 2, 3) + ); + + Assert.AreEqual(4, a.Count()); + Assert.AreEqual(3, a.Children().Count()); + } + + [Test] + public void BeforeAfter() + { + JArray a = + new JArray( + 5, + new JArray(1, 2, 3), + new JArray(1, 2, 3), + new JArray(1, 2, 3) + ); + + Assert.AreEqual(5, (int)a[1].Previous); + Assert.AreEqual(2, a[2].BeforeSelf().Count()); + //Assert.AreEqual(2, a[2].AfterSelf().Count()); + } + + [Test] + public void Casting() + { + Assert.AreEqual(1L, (long)(new JValue(1))); + Assert.AreEqual(2L, (long)new JArray(1, 2, 3)[1]); + + Assert.AreEqual(new DateTime(2000, 12, 20), (DateTime)new JValue(new DateTime(2000, 12, 20))); #if !NET20 - Assert.AreEqual("12/12/2000 12:12:12 +00:00", (string)(new JValue(new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.Zero)))); + Assert.AreEqual(new DateTimeOffset(2000, 12, 20, 0, 0, 0, TimeSpan.Zero), (DateTimeOffset)new JValue(new DateTime(2000, 12, 20, 0, 0, 0, DateTimeKind.Utc))); + Assert.AreEqual(new DateTimeOffset(2000, 12, 20, 23, 50, 10, TimeSpan.Zero), (DateTimeOffset)new JValue(new DateTimeOffset(2000, 12, 20, 23, 50, 10, TimeSpan.Zero))); + Assert.AreEqual(null, (DateTimeOffset?)new JValue((DateTimeOffset?)null)); + Assert.AreEqual(null, (DateTimeOffset?)(JValue)null); #endif - Assert.AreEqual(true, (bool)(new JValue(1))); - Assert.AreEqual(true, (bool)(new JValue(1.0))); - Assert.AreEqual(true, (bool)(new JValue("true"))); - Assert.AreEqual(true, (bool)(new JValue(true))); - Assert.AreEqual(1, (int)(new JValue(1))); - Assert.AreEqual(1, (int)(new JValue(1.0))); - Assert.AreEqual(1, (int)(new JValue("1"))); - Assert.AreEqual(1, (int)(new JValue(true))); - Assert.AreEqual(1m, (decimal)(new JValue(1))); - Assert.AreEqual(1m, (decimal)(new JValue(1.0))); - Assert.AreEqual(1m, (decimal)(new JValue("1"))); - Assert.AreEqual(1m, (decimal)(new JValue(true))); - Assert.AreEqual(TimeSpan.FromMinutes(1), (TimeSpan)(new JValue(TimeSpan.FromMinutes(1)))); - Assert.AreEqual("00:01:00", (string)(new JValue(TimeSpan.FromMinutes(1)))); - Assert.AreEqual(TimeSpan.FromMinutes(1), (TimeSpan)(new JValue("00:01:00"))); - Assert.AreEqual("46efe013-b56a-4e83-99e4-4dce7678a5bc", (string)(new JValue(new Guid("46EFE013-B56A-4E83-99E4-4DCE7678A5BC")))); - Assert.AreEqual("http://www.google.com/", (string)(new JValue(new Uri("http://www.google.com")))); - Assert.AreEqual(new Guid("46EFE013-B56A-4E83-99E4-4DCE7678A5BC"), (Guid)(new JValue("46EFE013-B56A-4E83-99E4-4DCE7678A5BC"))); - Assert.AreEqual(new Guid("46EFE013-B56A-4E83-99E4-4DCE7678A5BC"), (Guid)(new JValue(new Guid("46EFE013-B56A-4E83-99E4-4DCE7678A5BC")))); - Assert.AreEqual(new Uri("http://www.google.com"), (Uri)(new JValue("http://www.google.com"))); - Assert.AreEqual(new Uri("http://www.google.com"), (Uri)(new JValue(new Uri("http://www.google.com")))); - Assert.AreEqual(null, (Uri)(new JValue((object)null))); - Assert.AreEqual(Convert.ToBase64String(Encoding.UTF8.GetBytes("hi")), (string)(new JValue(Encoding.UTF8.GetBytes("hi")))); - CollectionAssert.AreEquivalent((byte[])Encoding.UTF8.GetBytes("hi"), (byte[])(new JValue(Convert.ToBase64String(Encoding.UTF8.GetBytes("hi"))))); - Assert.AreEqual(new Guid("46EFE013-B56A-4E83-99E4-4DCE7678A5BC"), (Guid)(new JValue(new Guid("46EFE013-B56A-4E83-99E4-4DCE7678A5BC").ToByteArray()))); - Assert.AreEqual(new Guid("46EFE013-B56A-4E83-99E4-4DCE7678A5BC"), (Guid?)(new JValue(new Guid("46EFE013-B56A-4E83-99E4-4DCE7678A5BC").ToByteArray()))); - Assert.AreEqual((sbyte?)1, (sbyte?)(new JValue((short?)1))); + Assert.AreEqual(true, (bool)new JValue(true)); + Assert.AreEqual(true, (bool?)new JValue(true)); + Assert.AreEqual(null, (bool?)((JValue)null)); + Assert.AreEqual(null, (bool?)new JValue((object)null)); + Assert.AreEqual(10, (long)new JValue(10)); + Assert.AreEqual(null, (long?)new JValue((long?)null)); + Assert.AreEqual(null, (long?)(JValue)null); + Assert.AreEqual(null, (int?)new JValue((int?)null)); + Assert.AreEqual(null, (int?)(JValue)null); + Assert.AreEqual(null, (DateTime?)new JValue((DateTime?)null)); + Assert.AreEqual(null, (DateTime?)(JValue)null); + Assert.AreEqual(null, (short?)new JValue((short?)null)); + Assert.AreEqual(null, (short?)(JValue)null); + Assert.AreEqual(null, (float?)new JValue((float?)null)); + Assert.AreEqual(null, (float?)(JValue)null); + Assert.AreEqual(null, (double?)new JValue((double?)null)); + Assert.AreEqual(null, (double?)(JValue)null); + Assert.AreEqual(null, (decimal?)new JValue((decimal?)null)); + Assert.AreEqual(null, (decimal?)(JValue)null); + Assert.AreEqual(null, (uint?)new JValue((uint?)null)); + Assert.AreEqual(null, (uint?)(JValue)null); + Assert.AreEqual(null, (sbyte?)new JValue((sbyte?)null)); + Assert.AreEqual(null, (sbyte?)(JValue)null); + Assert.AreEqual(null, (byte?)new JValue((byte?)null)); + Assert.AreEqual(null, (byte?)(JValue)null); + Assert.AreEqual(null, (ulong?)new JValue((ulong?)null)); + Assert.AreEqual(null, (ulong?)(JValue)null); + Assert.AreEqual(null, (uint?)new JValue((uint?)null)); + Assert.AreEqual(null, (uint?)(JValue)null); + Assert.AreEqual(11.1f, (float)new JValue(11.1)); + Assert.AreEqual(float.MinValue, (float)new JValue(float.MinValue)); + Assert.AreEqual(1.1, (double)new JValue(1.1)); + Assert.AreEqual(uint.MaxValue, (uint)new JValue(uint.MaxValue)); + Assert.AreEqual(ulong.MaxValue, (ulong)new JValue(ulong.MaxValue)); + Assert.AreEqual(ulong.MaxValue, (ulong)new JProperty("Test", new JValue(ulong.MaxValue))); + Assert.AreEqual(null, (string)new JValue((string)null)); + Assert.AreEqual(5m, (decimal)(new JValue(5L))); + Assert.AreEqual(5m, (decimal?)(new JValue(5L))); + Assert.AreEqual(5f, (float)(new JValue(5L))); + Assert.AreEqual(5f, (float)(new JValue(5m))); + Assert.AreEqual(5f, (float?)(new JValue(5m))); + Assert.AreEqual(5, (byte)(new JValue(5))); - Assert.AreEqual(null, (Uri)(JValue)null); - Assert.AreEqual(null, (int?)(JValue)null); - Assert.AreEqual(null, (uint?)(JValue)null); - Assert.AreEqual(null, (Guid?)(JValue)null); - Assert.AreEqual(null, (TimeSpan?)(JValue)null); - Assert.AreEqual(null, (byte[])(JValue)null); - Assert.AreEqual(null, (bool?)(JValue)null); - Assert.AreEqual(null, (char?)(JValue)null); - Assert.AreEqual(null, (DateTime?)(JValue)null); + Assert.AreEqual(null, (sbyte?)new JValue((object)null)); + + Assert.AreEqual("1", (string)(new JValue(1))); + Assert.AreEqual("1", (string)(new JValue(1.0))); + Assert.AreEqual("1.0", (string)(new JValue(1.0m))); + Assert.AreEqual("True", (string)(new JValue(true))); + Assert.AreEqual(null, (string)(new JValue((object)null))); + Assert.AreEqual(null, (string)(JValue)null); + Assert.AreEqual("12/12/2000 12:12:12", (string)(new JValue(new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc)))); #if !NET20 - Assert.AreEqual(null, (DateTimeOffset?)(JValue)null); + Assert.AreEqual("12/12/2000 12:12:12 +00:00", (string)(new JValue(new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.Zero)))); #endif - Assert.AreEqual(null, (short?)(JValue)null); - Assert.AreEqual(null, (ushort?)(JValue)null); - Assert.AreEqual(null, (byte?)(JValue)null); - Assert.AreEqual(null, (byte?)(JValue)null); - Assert.AreEqual(null, (sbyte?)(JValue)null); - Assert.AreEqual(null, (sbyte?)(JValue)null); - Assert.AreEqual(null, (long?)(JValue)null); - Assert.AreEqual(null, (ulong?)(JValue)null); - Assert.AreEqual(null, (double?)(JValue)null); - Assert.AreEqual(null, (float?)(JValue)null); + Assert.AreEqual(true, (bool)(new JValue(1))); + Assert.AreEqual(true, (bool)(new JValue(1.0))); + Assert.AreEqual(true, (bool)(new JValue("true"))); + Assert.AreEqual(true, (bool)(new JValue(true))); + Assert.AreEqual(1, (int)(new JValue(1))); + Assert.AreEqual(1, (int)(new JValue(1.0))); + Assert.AreEqual(1, (int)(new JValue("1"))); + Assert.AreEqual(1, (int)(new JValue(true))); + Assert.AreEqual(1m, (decimal)(new JValue(1))); + Assert.AreEqual(1m, (decimal)(new JValue(1.0))); + Assert.AreEqual(1m, (decimal)(new JValue("1"))); + Assert.AreEqual(1m, (decimal)(new JValue(true))); + Assert.AreEqual(TimeSpan.FromMinutes(1), (TimeSpan)(new JValue(TimeSpan.FromMinutes(1)))); + Assert.AreEqual("00:01:00", (string)(new JValue(TimeSpan.FromMinutes(1)))); + Assert.AreEqual(TimeSpan.FromMinutes(1), (TimeSpan)(new JValue("00:01:00"))); + Assert.AreEqual("46efe013-b56a-4e83-99e4-4dce7678a5bc", (string)(new JValue(new Guid("46EFE013-B56A-4E83-99E4-4DCE7678A5BC")))); + Assert.AreEqual("http://www.google.com/", (string)(new JValue(new Uri("http://www.google.com")))); + Assert.AreEqual(new Guid("46EFE013-B56A-4E83-99E4-4DCE7678A5BC"), (Guid)(new JValue("46EFE013-B56A-4E83-99E4-4DCE7678A5BC"))); + Assert.AreEqual(new Guid("46EFE013-B56A-4E83-99E4-4DCE7678A5BC"), (Guid)(new JValue(new Guid("46EFE013-B56A-4E83-99E4-4DCE7678A5BC")))); + Assert.AreEqual(new Uri("http://www.google.com"), (Uri)(new JValue("http://www.google.com"))); + Assert.AreEqual(new Uri("http://www.google.com"), (Uri)(new JValue(new Uri("http://www.google.com")))); + Assert.AreEqual(null, (Uri)(new JValue((object)null))); + Assert.AreEqual(Convert.ToBase64String(Encoding.UTF8.GetBytes("hi")), (string)(new JValue(Encoding.UTF8.GetBytes("hi")))); + CollectionAssert.AreEquivalent((byte[])Encoding.UTF8.GetBytes("hi"), (byte[])(new JValue(Convert.ToBase64String(Encoding.UTF8.GetBytes("hi"))))); + Assert.AreEqual(new Guid("46EFE013-B56A-4E83-99E4-4DCE7678A5BC"), (Guid)(new JValue(new Guid("46EFE013-B56A-4E83-99E4-4DCE7678A5BC").ToByteArray()))); + Assert.AreEqual(new Guid("46EFE013-B56A-4E83-99E4-4DCE7678A5BC"), (Guid?)(new JValue(new Guid("46EFE013-B56A-4E83-99E4-4DCE7678A5BC").ToByteArray()))); + Assert.AreEqual((sbyte?)1, (sbyte?)(new JValue((short?)1))); - byte[] data = new byte[0]; - Assert.AreEqual(data, (byte[])(new JValue(data))); + Assert.AreEqual(null, (Uri)(JValue)null); + Assert.AreEqual(null, (int?)(JValue)null); + Assert.AreEqual(null, (uint?)(JValue)null); + Assert.AreEqual(null, (Guid?)(JValue)null); + Assert.AreEqual(null, (TimeSpan?)(JValue)null); + Assert.AreEqual(null, (byte[])(JValue)null); + Assert.AreEqual(null, (bool?)(JValue)null); + Assert.AreEqual(null, (char?)(JValue)null); + Assert.AreEqual(null, (DateTime?)(JValue)null); +#if !NET20 + Assert.AreEqual(null, (DateTimeOffset?)(JValue)null); +#endif + Assert.AreEqual(null, (short?)(JValue)null); + Assert.AreEqual(null, (ushort?)(JValue)null); + Assert.AreEqual(null, (byte?)(JValue)null); + Assert.AreEqual(null, (byte?)(JValue)null); + Assert.AreEqual(null, (sbyte?)(JValue)null); + Assert.AreEqual(null, (sbyte?)(JValue)null); + Assert.AreEqual(null, (long?)(JValue)null); + Assert.AreEqual(null, (ulong?)(JValue)null); + Assert.AreEqual(null, (double?)(JValue)null); + Assert.AreEqual(null, (float?)(JValue)null); - Assert.AreEqual(5, (int)(new JValue(StringComparison.OrdinalIgnoreCase))); + byte[] data = new byte[0]; + Assert.AreEqual(data, (byte[])(new JValue(data))); + + Assert.AreEqual(5, (int)(new JValue(StringComparison.OrdinalIgnoreCase))); #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE || PORTABLE40) - string bigIntegerText = "1234567899999999999999999999999999999999999999999999999999999999999990"; + string bigIntegerText = "1234567899999999999999999999999999999999999999999999999999999999999990"; - Assert.AreEqual(BigInteger.Parse(bigIntegerText), (new JValue(BigInteger.Parse(bigIntegerText))).Value); + Assert.AreEqual(BigInteger.Parse(bigIntegerText), (new JValue(BigInteger.Parse(bigIntegerText))).Value); - Assert.AreEqual(BigInteger.Parse(bigIntegerText), (new JValue(bigIntegerText)).ToObject()); - Assert.AreEqual(new BigInteger(long.MaxValue), (new JValue(long.MaxValue)).ToObject()); - Assert.AreEqual(new BigInteger(4.5d), (new JValue((4.5d))).ToObject()); - Assert.AreEqual(new BigInteger(4.5f), (new JValue((4.5f))).ToObject()); - Assert.AreEqual(new BigInteger(byte.MaxValue), (new JValue(byte.MaxValue)).ToObject()); - Assert.AreEqual(new BigInteger(123), (new JValue(123)).ToObject()); - Assert.AreEqual(new BigInteger(123), (new JValue(123)).ToObject()); - Assert.AreEqual(null, (new JValue((object)null)).ToObject()); + Assert.AreEqual(BigInteger.Parse(bigIntegerText), (new JValue(bigIntegerText)).ToObject()); + Assert.AreEqual(new BigInteger(long.MaxValue), (new JValue(long.MaxValue)).ToObject()); + Assert.AreEqual(new BigInteger(4.5d), (new JValue((4.5d))).ToObject()); + Assert.AreEqual(new BigInteger(4.5f), (new JValue((4.5f))).ToObject()); + Assert.AreEqual(new BigInteger(byte.MaxValue), (new JValue(byte.MaxValue)).ToObject()); + Assert.AreEqual(new BigInteger(123), (new JValue(123)).ToObject()); + Assert.AreEqual(new BigInteger(123), (new JValue(123)).ToObject()); + Assert.AreEqual(null, (new JValue((object)null)).ToObject()); - byte[] intData = BigInteger.Parse(bigIntegerText).ToByteArray(); - Assert.AreEqual(BigInteger.Parse(bigIntegerText), (new JValue(intData)).ToObject()); + byte[] intData = BigInteger.Parse(bigIntegerText).ToByteArray(); + Assert.AreEqual(BigInteger.Parse(bigIntegerText), (new JValue(intData)).ToObject()); - Assert.AreEqual(4.0d, (double)(new JValue(new BigInteger(4.5d)))); - Assert.AreEqual(true, (bool)(new JValue(new BigInteger(1)))); - Assert.AreEqual(long.MaxValue, (long)(new JValue(new BigInteger(long.MaxValue)))); - Assert.AreEqual(long.MaxValue, (long)(new JValue(new BigInteger(new byte[] { 255, 255, 255, 255, 255, 255, 255, 127 })))); - Assert.AreEqual("9223372036854775807", (string)(new JValue(new BigInteger(long.MaxValue)))); + Assert.AreEqual(4.0d, (double)(new JValue(new BigInteger(4.5d)))); + Assert.AreEqual(true, (bool)(new JValue(new BigInteger(1)))); + Assert.AreEqual(long.MaxValue, (long)(new JValue(new BigInteger(long.MaxValue)))); + Assert.AreEqual(long.MaxValue, (long)(new JValue(new BigInteger(new byte[] { 255, 255, 255, 255, 255, 255, 255, 127 })))); + Assert.AreEqual("9223372036854775807", (string)(new JValue(new BigInteger(long.MaxValue)))); - intData = (byte[]) (new JValue(new BigInteger(long.MaxValue))); - CollectionAssert.AreEqual(new byte[] { 255, 255, 255, 255, 255, 255, 255, 127 }, intData); + intData = (byte[])(new JValue(new BigInteger(long.MaxValue))); + CollectionAssert.AreEqual(new byte[] { 255, 255, 255, 255, 255, 255, 255, 127 }, intData); #endif - } + } - [Test] - public void FailedCasting() - { - ExceptionAssert.Throws("Can not convert Boolean to DateTime.", () => { var i = (DateTime)new JValue(true); }); - ExceptionAssert.Throws("Can not convert Integer to DateTime.", () => { var i = (DateTime)new JValue(1); }); - ExceptionAssert.Throws("Can not convert Float to DateTime.", () => { var i = (DateTime)new JValue(1.1); }); - ExceptionAssert.Throws("Can not convert Float to DateTime.", () => { var i = (DateTime)new JValue(1.1m); }); - ExceptionAssert.Throws("Can not convert TimeSpan to DateTime.", () => { var i = (DateTime)new JValue(TimeSpan.Zero); }); - ExceptionAssert.Throws("Can not convert Uri to DateTime.", () => { var i = (DateTime)new JValue(new Uri("http://www.google.com")); }); - ExceptionAssert.Throws("Can not convert Null to DateTime.", () => { var i = (DateTime)new JValue((object)null); }); - ExceptionAssert.Throws("Can not convert Guid to DateTime.", () => { var i = (DateTime)new JValue(Guid.NewGuid()); }); + [Test] + public void FailedCasting() + { + ExceptionAssert.Throws("Can not convert Boolean to DateTime.", () => { var i = (DateTime)new JValue(true); }); + ExceptionAssert.Throws("Can not convert Integer to DateTime.", () => { var i = (DateTime)new JValue(1); }); + ExceptionAssert.Throws("Can not convert Float to DateTime.", () => { var i = (DateTime)new JValue(1.1); }); + ExceptionAssert.Throws("Can not convert Float to DateTime.", () => { var i = (DateTime)new JValue(1.1m); }); + ExceptionAssert.Throws("Can not convert TimeSpan to DateTime.", () => { var i = (DateTime)new JValue(TimeSpan.Zero); }); + ExceptionAssert.Throws("Can not convert Uri to DateTime.", () => { var i = (DateTime)new JValue(new Uri("http://www.google.com")); }); + ExceptionAssert.Throws("Can not convert Null to DateTime.", () => { var i = (DateTime)new JValue((object)null); }); + ExceptionAssert.Throws("Can not convert Guid to DateTime.", () => { var i = (DateTime)new JValue(Guid.NewGuid()); }); - ExceptionAssert.Throws("Can not convert Boolean to Uri.", () => { var i = (Uri)new JValue(true); }); - ExceptionAssert.Throws("Can not convert Integer to Uri.", () => { var i = (Uri)new JValue(1); }); - ExceptionAssert.Throws("Can not convert Float to Uri.", () => { var i = (Uri)new JValue(1.1); }); - ExceptionAssert.Throws("Can not convert Float to Uri.", () => { var i = (Uri)new JValue(1.1m); }); - ExceptionAssert.Throws("Can not convert TimeSpan to Uri.", () => { var i = (Uri)new JValue(TimeSpan.Zero); }); - ExceptionAssert.Throws("Can not convert Guid to Uri.", () => { var i = (Uri)new JValue(Guid.NewGuid()); }); - ExceptionAssert.Throws("Can not convert Date to Uri.", () => { var i = (Uri)new JValue(DateTime.Now); }); + ExceptionAssert.Throws("Can not convert Boolean to Uri.", () => { var i = (Uri)new JValue(true); }); + ExceptionAssert.Throws("Can not convert Integer to Uri.", () => { var i = (Uri)new JValue(1); }); + ExceptionAssert.Throws("Can not convert Float to Uri.", () => { var i = (Uri)new JValue(1.1); }); + ExceptionAssert.Throws("Can not convert Float to Uri.", () => { var i = (Uri)new JValue(1.1m); }); + ExceptionAssert.Throws("Can not convert TimeSpan to Uri.", () => { var i = (Uri)new JValue(TimeSpan.Zero); }); + ExceptionAssert.Throws("Can not convert Guid to Uri.", () => { var i = (Uri)new JValue(Guid.NewGuid()); }); + ExceptionAssert.Throws("Can not convert Date to Uri.", () => { var i = (Uri)new JValue(DateTime.Now); }); #if !NET20 - ExceptionAssert.Throws("Can not convert Date to Uri.", () => { var i = (Uri)new JValue(DateTimeOffset.Now); }); + ExceptionAssert.Throws("Can not convert Date to Uri.", () => { var i = (Uri)new JValue(DateTimeOffset.Now); }); #endif - ExceptionAssert.Throws("Can not convert Boolean to TimeSpan.", () => { var i = (TimeSpan)new JValue(true); }); - ExceptionAssert.Throws("Can not convert Integer to TimeSpan.", () => { var i = (TimeSpan)new JValue(1); }); - ExceptionAssert.Throws("Can not convert Float to TimeSpan.", () => { var i = (TimeSpan)new JValue(1.1); }); - ExceptionAssert.Throws("Can not convert Float to TimeSpan.", () => { var i = (TimeSpan)new JValue(1.1m); }); - ExceptionAssert.Throws("Can not convert Null to TimeSpan.", () => { var i = (TimeSpan)new JValue((object)null); }); - ExceptionAssert.Throws("Can not convert Guid to TimeSpan.", () => { var i = (TimeSpan)new JValue(Guid.NewGuid()); }); - ExceptionAssert.Throws("Can not convert Date to TimeSpan.", () => { var i = (TimeSpan)new JValue(DateTime.Now); }); + ExceptionAssert.Throws("Can not convert Boolean to TimeSpan.", () => { var i = (TimeSpan)new JValue(true); }); + ExceptionAssert.Throws("Can not convert Integer to TimeSpan.", () => { var i = (TimeSpan)new JValue(1); }); + ExceptionAssert.Throws("Can not convert Float to TimeSpan.", () => { var i = (TimeSpan)new JValue(1.1); }); + ExceptionAssert.Throws("Can not convert Float to TimeSpan.", () => { var i = (TimeSpan)new JValue(1.1m); }); + ExceptionAssert.Throws("Can not convert Null to TimeSpan.", () => { var i = (TimeSpan)new JValue((object)null); }); + ExceptionAssert.Throws("Can not convert Guid to TimeSpan.", () => { var i = (TimeSpan)new JValue(Guid.NewGuid()); }); + ExceptionAssert.Throws("Can not convert Date to TimeSpan.", () => { var i = (TimeSpan)new JValue(DateTime.Now); }); #if !NET20 - ExceptionAssert.Throws("Can not convert Date to TimeSpan.", () => { var i = (TimeSpan)new JValue(DateTimeOffset.Now); }); + ExceptionAssert.Throws("Can not convert Date to TimeSpan.", () => { var i = (TimeSpan)new JValue(DateTimeOffset.Now); }); #endif - ExceptionAssert.Throws("Can not convert Uri to TimeSpan.", () => { var i = (TimeSpan)new JValue(new Uri("http://www.google.com")); }); + ExceptionAssert.Throws("Can not convert Uri to TimeSpan.", () => { var i = (TimeSpan)new JValue(new Uri("http://www.google.com")); }); - ExceptionAssert.Throws("Can not convert Boolean to Guid.", () => { var i = (Guid)new JValue(true); }); - ExceptionAssert.Throws("Can not convert Integer to Guid.", () => { var i = (Guid)new JValue(1); }); - ExceptionAssert.Throws("Can not convert Float to Guid.", () => { var i = (Guid)new JValue(1.1); }); - ExceptionAssert.Throws("Can not convert Float to Guid.", () => { var i = (Guid)new JValue(1.1m); }); - ExceptionAssert.Throws("Can not convert Null to Guid.", () => { var i = (Guid)new JValue((object)null); }); - ExceptionAssert.Throws("Can not convert Date to Guid.", () => { var i = (Guid)new JValue(DateTime.Now); }); + ExceptionAssert.Throws("Can not convert Boolean to Guid.", () => { var i = (Guid)new JValue(true); }); + ExceptionAssert.Throws("Can not convert Integer to Guid.", () => { var i = (Guid)new JValue(1); }); + ExceptionAssert.Throws("Can not convert Float to Guid.", () => { var i = (Guid)new JValue(1.1); }); + ExceptionAssert.Throws("Can not convert Float to Guid.", () => { var i = (Guid)new JValue(1.1m); }); + ExceptionAssert.Throws("Can not convert Null to Guid.", () => { var i = (Guid)new JValue((object)null); }); + ExceptionAssert.Throws("Can not convert Date to Guid.", () => { var i = (Guid)new JValue(DateTime.Now); }); #if !NET20 - ExceptionAssert.Throws("Can not convert Date to Guid.", () => { var i = (Guid)new JValue(DateTimeOffset.Now); }); + ExceptionAssert.Throws("Can not convert Date to Guid.", () => { var i = (Guid)new JValue(DateTimeOffset.Now); }); #endif - ExceptionAssert.Throws("Can not convert TimeSpan to Guid.", () => { var i = (Guid)new JValue(TimeSpan.FromMinutes(1)); }); - ExceptionAssert.Throws("Can not convert Uri to Guid.", () => { var i = (Guid)new JValue(new Uri("http://www.google.com")); }); + ExceptionAssert.Throws("Can not convert TimeSpan to Guid.", () => { var i = (Guid)new JValue(TimeSpan.FromMinutes(1)); }); + ExceptionAssert.Throws("Can not convert Uri to Guid.", () => { var i = (Guid)new JValue(new Uri("http://www.google.com")); }); #if !NET20 - ExceptionAssert.Throws("Can not convert Boolean to DateTimeOffset.", () => { var i = (DateTimeOffset)new JValue(true); }); + ExceptionAssert.Throws("Can not convert Boolean to DateTimeOffset.", () => { var i = (DateTimeOffset)new JValue(true); }); #endif - ExceptionAssert.Throws("Can not convert Boolean to Uri.", () => { var i = (Uri)new JValue(true); }); + ExceptionAssert.Throws("Can not convert Boolean to Uri.", () => { var i = (Uri)new JValue(true); }); #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE || PORTABLE40) - ExceptionAssert.Throws("Can not convert Uri to BigInteger.", () => { var i = (new JValue(new Uri("http://www.google.com"))).ToObject(); }); - ExceptionAssert.Throws("Can not convert Null to BigInteger.", () => { var i = (new JValue((object)null)).ToObject(); }); - ExceptionAssert.Throws("Can not convert Guid to BigInteger.", () => { var i = (new JValue(Guid.NewGuid())).ToObject(); }); - ExceptionAssert.Throws("Can not convert Guid to BigInteger.", () => { var i = (new JValue(Guid.NewGuid())).ToObject(); }); + ExceptionAssert.Throws("Can not convert Uri to BigInteger.", () => { var i = (new JValue(new Uri("http://www.google.com"))).ToObject(); }); + ExceptionAssert.Throws("Can not convert Null to BigInteger.", () => { var i = (new JValue((object)null)).ToObject(); }); + ExceptionAssert.Throws("Can not convert Guid to BigInteger.", () => { var i = (new JValue(Guid.NewGuid())).ToObject(); }); + ExceptionAssert.Throws("Can not convert Guid to BigInteger.", () => { var i = (new JValue(Guid.NewGuid())).ToObject(); }); #endif - ExceptionAssert.Throws("Can not convert Date to SByte.", () => { var i = (sbyte?)new JValue(DateTime.Now); }); - ExceptionAssert.Throws("Can not convert Date to SByte.", () => { var i = (sbyte)new JValue(DateTime.Now); }); - } + ExceptionAssert.Throws("Can not convert Date to SByte.", () => { var i = (sbyte?)new JValue(DateTime.Now); }); + ExceptionAssert.Throws("Can not convert Date to SByte.", () => { var i = (sbyte)new JValue(DateTime.Now); }); + } - [Test] - public void ToObject() - { + [Test] + public void ToObject() + { #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE) - Assert.AreEqual((BigInteger)1, (new JValue(1).ToObject(typeof(BigInteger)))); - Assert.AreEqual((BigInteger)1, (new JValue(1).ToObject(typeof(BigInteger?)))); - Assert.AreEqual((BigInteger?)null, (new JValue((object)null).ToObject(typeof(BigInteger?)))); + Assert.AreEqual((BigInteger)1, (new JValue(1).ToObject(typeof(BigInteger)))); + Assert.AreEqual((BigInteger)1, (new JValue(1).ToObject(typeof(BigInteger?)))); + Assert.AreEqual((BigInteger?)null, (new JValue((object)null).ToObject(typeof(BigInteger?)))); #endif - Assert.AreEqual((ushort)1, (new JValue(1).ToObject(typeof(ushort)))); - Assert.AreEqual((ushort)1, (new JValue(1).ToObject(typeof(ushort?)))); - Assert.AreEqual((uint)1L, (new JValue(1).ToObject(typeof(uint)))); - Assert.AreEqual((uint)1L, (new JValue(1).ToObject(typeof(uint?)))); - Assert.AreEqual((ulong)1L, (new JValue(1).ToObject(typeof(ulong)))); - Assert.AreEqual((ulong)1L, (new JValue(1).ToObject(typeof(ulong?)))); - Assert.AreEqual((sbyte)1L, (new JValue(1).ToObject(typeof(sbyte)))); - Assert.AreEqual((sbyte)1L, (new JValue(1).ToObject(typeof(sbyte?)))); - Assert.AreEqual((byte)1L, (new JValue(1).ToObject(typeof(byte)))); - Assert.AreEqual((byte)1L, (new JValue(1).ToObject(typeof(byte?)))); - Assert.AreEqual((short)1L, (new JValue(1).ToObject(typeof(short)))); - Assert.AreEqual((short)1L, (new JValue(1).ToObject(typeof(short?)))); - Assert.AreEqual(1, (new JValue(1).ToObject(typeof(int)))); - Assert.AreEqual(1, (new JValue(1).ToObject(typeof(int?)))); - Assert.AreEqual(1L, (new JValue(1).ToObject(typeof(long)))); - Assert.AreEqual(1L, (new JValue(1).ToObject(typeof(long?)))); - Assert.AreEqual((float)1, (new JValue(1.0).ToObject(typeof(float)))); - Assert.AreEqual((float)1, (new JValue(1.0).ToObject(typeof(float?)))); - Assert.AreEqual((double)1, (new JValue(1.0).ToObject(typeof(double)))); - Assert.AreEqual((double)1, (new JValue(1.0).ToObject(typeof(double?)))); - Assert.AreEqual(1m, (new JValue(1).ToObject(typeof(decimal)))); - Assert.AreEqual(1m, (new JValue(1).ToObject(typeof(decimal?)))); - Assert.AreEqual(true, (new JValue(true).ToObject(typeof(bool)))); - Assert.AreEqual(true, (new JValue(true).ToObject(typeof(bool?)))); - Assert.AreEqual('b', (new JValue('b').ToObject(typeof(char)))); - Assert.AreEqual('b', (new JValue('b').ToObject(typeof(char?)))); - Assert.AreEqual(TimeSpan.MaxValue, (new JValue(TimeSpan.MaxValue).ToObject(typeof(TimeSpan)))); - Assert.AreEqual(TimeSpan.MaxValue, (new JValue(TimeSpan.MaxValue).ToObject(typeof(TimeSpan?)))); - Assert.AreEqual(DateTime.MaxValue, (new JValue(DateTime.MaxValue).ToObject(typeof(DateTime)))); - Assert.AreEqual(DateTime.MaxValue, (new JValue(DateTime.MaxValue).ToObject(typeof(DateTime?)))); + Assert.AreEqual((ushort)1, (new JValue(1).ToObject(typeof(ushort)))); + Assert.AreEqual((ushort)1, (new JValue(1).ToObject(typeof(ushort?)))); + Assert.AreEqual((uint)1L, (new JValue(1).ToObject(typeof(uint)))); + Assert.AreEqual((uint)1L, (new JValue(1).ToObject(typeof(uint?)))); + Assert.AreEqual((ulong)1L, (new JValue(1).ToObject(typeof(ulong)))); + Assert.AreEqual((ulong)1L, (new JValue(1).ToObject(typeof(ulong?)))); + Assert.AreEqual((sbyte)1L, (new JValue(1).ToObject(typeof(sbyte)))); + Assert.AreEqual((sbyte)1L, (new JValue(1).ToObject(typeof(sbyte?)))); + Assert.AreEqual((byte)1L, (new JValue(1).ToObject(typeof(byte)))); + Assert.AreEqual((byte)1L, (new JValue(1).ToObject(typeof(byte?)))); + Assert.AreEqual((short)1L, (new JValue(1).ToObject(typeof(short)))); + Assert.AreEqual((short)1L, (new JValue(1).ToObject(typeof(short?)))); + Assert.AreEqual(1, (new JValue(1).ToObject(typeof(int)))); + Assert.AreEqual(1, (new JValue(1).ToObject(typeof(int?)))); + Assert.AreEqual(1L, (new JValue(1).ToObject(typeof(long)))); + Assert.AreEqual(1L, (new JValue(1).ToObject(typeof(long?)))); + Assert.AreEqual((float)1, (new JValue(1.0).ToObject(typeof(float)))); + Assert.AreEqual((float)1, (new JValue(1.0).ToObject(typeof(float?)))); + Assert.AreEqual((double)1, (new JValue(1.0).ToObject(typeof(double)))); + Assert.AreEqual((double)1, (new JValue(1.0).ToObject(typeof(double?)))); + Assert.AreEqual(1m, (new JValue(1).ToObject(typeof(decimal)))); + Assert.AreEqual(1m, (new JValue(1).ToObject(typeof(decimal?)))); + Assert.AreEqual(true, (new JValue(true).ToObject(typeof(bool)))); + Assert.AreEqual(true, (new JValue(true).ToObject(typeof(bool?)))); + Assert.AreEqual('b', (new JValue('b').ToObject(typeof(char)))); + Assert.AreEqual('b', (new JValue('b').ToObject(typeof(char?)))); + Assert.AreEqual(TimeSpan.MaxValue, (new JValue(TimeSpan.MaxValue).ToObject(typeof(TimeSpan)))); + Assert.AreEqual(TimeSpan.MaxValue, (new JValue(TimeSpan.MaxValue).ToObject(typeof(TimeSpan?)))); + Assert.AreEqual(DateTime.MaxValue, (new JValue(DateTime.MaxValue).ToObject(typeof(DateTime)))); + Assert.AreEqual(DateTime.MaxValue, (new JValue(DateTime.MaxValue).ToObject(typeof(DateTime?)))); #if !NET20 - Assert.AreEqual(DateTimeOffset.MaxValue, (new JValue(DateTimeOffset.MaxValue).ToObject(typeof(DateTimeOffset)))); - Assert.AreEqual(DateTimeOffset.MaxValue, (new JValue(DateTimeOffset.MaxValue).ToObject(typeof(DateTimeOffset?)))); + Assert.AreEqual(DateTimeOffset.MaxValue, (new JValue(DateTimeOffset.MaxValue).ToObject(typeof(DateTimeOffset)))); + Assert.AreEqual(DateTimeOffset.MaxValue, (new JValue(DateTimeOffset.MaxValue).ToObject(typeof(DateTimeOffset?)))); #endif - Assert.AreEqual("b", (new JValue("b").ToObject(typeof(string)))); - Assert.AreEqual(new Guid("A34B2080-B5F0-488E-834D-45D44ECB9E5C"), (new JValue(new Guid("A34B2080-B5F0-488E-834D-45D44ECB9E5C")).ToObject(typeof(Guid)))); - Assert.AreEqual(new Guid("A34B2080-B5F0-488E-834D-45D44ECB9E5C"), (new JValue(new Guid("A34B2080-B5F0-488E-834D-45D44ECB9E5C")).ToObject(typeof(Guid?)))); - Assert.AreEqual(new Uri("http://www.google.com/"), (new JValue(new Uri("http://www.google.com/")).ToObject(typeof(Uri)))); - } + Assert.AreEqual("b", (new JValue("b").ToObject(typeof(string)))); + Assert.AreEqual(new Guid("A34B2080-B5F0-488E-834D-45D44ECB9E5C"), (new JValue(new Guid("A34B2080-B5F0-488E-834D-45D44ECB9E5C")).ToObject(typeof(Guid)))); + Assert.AreEqual(new Guid("A34B2080-B5F0-488E-834D-45D44ECB9E5C"), (new JValue(new Guid("A34B2080-B5F0-488E-834D-45D44ECB9E5C")).ToObject(typeof(Guid?)))); + Assert.AreEqual(new Uri("http://www.google.com/"), (new JValue(new Uri("http://www.google.com/")).ToObject(typeof(Uri)))); + } - [Test] - public void ImplicitCastingTo() - { - Assert.IsTrue(JToken.DeepEquals(new JValue(new DateTime(2000, 12, 20)), (JValue)new DateTime(2000, 12, 20))); + [Test] + public void ImplicitCastingTo() + { + Assert.IsTrue(JToken.DeepEquals(new JValue(new DateTime(2000, 12, 20)), (JValue)new DateTime(2000, 12, 20))); #if !NET20 - Assert.IsTrue(JToken.DeepEquals(new JValue(new DateTimeOffset(2000, 12, 20, 23, 50, 10, TimeSpan.Zero)), (JValue)new DateTimeOffset(2000, 12, 20, 23, 50, 10, TimeSpan.Zero))); - Assert.IsTrue(JToken.DeepEquals(new JValue((DateTimeOffset?)null), (JValue)(DateTimeOffset?)null)); + Assert.IsTrue(JToken.DeepEquals(new JValue(new DateTimeOffset(2000, 12, 20, 23, 50, 10, TimeSpan.Zero)), (JValue)new DateTimeOffset(2000, 12, 20, 23, 50, 10, TimeSpan.Zero))); + Assert.IsTrue(JToken.DeepEquals(new JValue((DateTimeOffset?)null), (JValue)(DateTimeOffset?)null)); #endif #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE || PORTABLE40) - // had to remove implicit casting to avoid user reference to System.Numerics.dll - Assert.IsTrue(JToken.DeepEquals(new JValue(new BigInteger(1)), new JValue(new BigInteger(1)))); - Assert.IsTrue(JToken.DeepEquals(new JValue((BigInteger?)null), new JValue((BigInteger?)null))); + // had to remove implicit casting to avoid user reference to System.Numerics.dll + Assert.IsTrue(JToken.DeepEquals(new JValue(new BigInteger(1)), new JValue(new BigInteger(1)))); + Assert.IsTrue(JToken.DeepEquals(new JValue((BigInteger?)null), new JValue((BigInteger?)null))); #endif - Assert.IsTrue(JToken.DeepEquals(new JValue(true), (JValue)true)); - Assert.IsTrue(JToken.DeepEquals(new JValue(true), (JValue)true)); - Assert.IsTrue(JToken.DeepEquals(new JValue(true), (JValue)(bool?)true)); - Assert.IsTrue(JToken.DeepEquals(new JValue((bool?)null), (JValue)(bool?)null)); - Assert.IsTrue(JToken.DeepEquals(new JValue(10), (JValue)10)); - Assert.IsTrue(JToken.DeepEquals(new JValue((long?)null), (JValue)(long?)null)); - Assert.IsTrue(JToken.DeepEquals(new JValue((DateTime?)null), (JValue)(DateTime?)null)); - Assert.IsTrue(JToken.DeepEquals(new JValue(long.MaxValue), (JValue)long.MaxValue)); - Assert.IsTrue(JToken.DeepEquals(new JValue((int?)null), (JValue)(int?)null)); - Assert.IsTrue(JToken.DeepEquals(new JValue((short?)null), (JValue)(short?)null)); - Assert.IsTrue(JToken.DeepEquals(new JValue((double?)null), (JValue)(double?)null)); - Assert.IsTrue(JToken.DeepEquals(new JValue((uint?)null), (JValue)(uint?)null)); - Assert.IsTrue(JToken.DeepEquals(new JValue((decimal?)null), (JValue)(decimal?)null)); - Assert.IsTrue(JToken.DeepEquals(new JValue((ulong?)null), (JValue)(ulong?)null)); - Assert.IsTrue(JToken.DeepEquals(new JValue((sbyte?)null), (JValue)(sbyte?)null)); - Assert.IsTrue(JToken.DeepEquals(new JValue((sbyte)1), (JValue)(sbyte)1)); - Assert.IsTrue(JToken.DeepEquals(new JValue((byte?)null), (JValue)(byte?)null)); - Assert.IsTrue(JToken.DeepEquals(new JValue((byte)1), (JValue)(byte)1)); - Assert.IsTrue(JToken.DeepEquals(new JValue((ushort?)null), (JValue)(ushort?)null)); - Assert.IsTrue(JToken.DeepEquals(new JValue(short.MaxValue), (JValue)short.MaxValue)); - Assert.IsTrue(JToken.DeepEquals(new JValue(ushort.MaxValue), (JValue)ushort.MaxValue)); - Assert.IsTrue(JToken.DeepEquals(new JValue(11.1f), (JValue)11.1f)); - Assert.IsTrue(JToken.DeepEquals(new JValue(float.MinValue), (JValue)float.MinValue)); - Assert.IsTrue(JToken.DeepEquals(new JValue(double.MinValue), (JValue)double.MinValue)); - Assert.IsTrue(JToken.DeepEquals(new JValue(uint.MaxValue), (JValue)uint.MaxValue)); - Assert.IsTrue(JToken.DeepEquals(new JValue(ulong.MaxValue), (JValue)ulong.MaxValue)); - Assert.IsTrue(JToken.DeepEquals(new JValue(ulong.MinValue), (JValue)ulong.MinValue)); - Assert.IsTrue(JToken.DeepEquals(new JValue((string)null), (JValue)(string)null)); - Assert.IsTrue(JToken.DeepEquals(new JValue((DateTime?)null), (JValue)(DateTime?)null)); - Assert.IsTrue(JToken.DeepEquals(new JValue(decimal.MaxValue), (JValue)decimal.MaxValue)); - Assert.IsTrue(JToken.DeepEquals(new JValue(decimal.MaxValue), (JValue)(decimal?)decimal.MaxValue)); - Assert.IsTrue(JToken.DeepEquals(new JValue(decimal.MinValue), (JValue)decimal.MinValue)); - Assert.IsTrue(JToken.DeepEquals(new JValue(float.MaxValue), (JValue)(float?)float.MaxValue)); - Assert.IsTrue(JToken.DeepEquals(new JValue(double.MaxValue), (JValue)(double?)double.MaxValue)); - Assert.IsTrue(JToken.DeepEquals(new JValue((object)null), (JValue)(double?)null)); + Assert.IsTrue(JToken.DeepEquals(new JValue(true), (JValue)true)); + Assert.IsTrue(JToken.DeepEquals(new JValue(true), (JValue)true)); + Assert.IsTrue(JToken.DeepEquals(new JValue(true), (JValue)(bool?)true)); + Assert.IsTrue(JToken.DeepEquals(new JValue((bool?)null), (JValue)(bool?)null)); + Assert.IsTrue(JToken.DeepEquals(new JValue(10), (JValue)10)); + Assert.IsTrue(JToken.DeepEquals(new JValue((long?)null), (JValue)(long?)null)); + Assert.IsTrue(JToken.DeepEquals(new JValue((DateTime?)null), (JValue)(DateTime?)null)); + Assert.IsTrue(JToken.DeepEquals(new JValue(long.MaxValue), (JValue)long.MaxValue)); + Assert.IsTrue(JToken.DeepEquals(new JValue((int?)null), (JValue)(int?)null)); + Assert.IsTrue(JToken.DeepEquals(new JValue((short?)null), (JValue)(short?)null)); + Assert.IsTrue(JToken.DeepEquals(new JValue((double?)null), (JValue)(double?)null)); + Assert.IsTrue(JToken.DeepEquals(new JValue((uint?)null), (JValue)(uint?)null)); + Assert.IsTrue(JToken.DeepEquals(new JValue((decimal?)null), (JValue)(decimal?)null)); + Assert.IsTrue(JToken.DeepEquals(new JValue((ulong?)null), (JValue)(ulong?)null)); + Assert.IsTrue(JToken.DeepEquals(new JValue((sbyte?)null), (JValue)(sbyte?)null)); + Assert.IsTrue(JToken.DeepEquals(new JValue((sbyte)1), (JValue)(sbyte)1)); + Assert.IsTrue(JToken.DeepEquals(new JValue((byte?)null), (JValue)(byte?)null)); + Assert.IsTrue(JToken.DeepEquals(new JValue((byte)1), (JValue)(byte)1)); + Assert.IsTrue(JToken.DeepEquals(new JValue((ushort?)null), (JValue)(ushort?)null)); + Assert.IsTrue(JToken.DeepEquals(new JValue(short.MaxValue), (JValue)short.MaxValue)); + Assert.IsTrue(JToken.DeepEquals(new JValue(ushort.MaxValue), (JValue)ushort.MaxValue)); + Assert.IsTrue(JToken.DeepEquals(new JValue(11.1f), (JValue)11.1f)); + Assert.IsTrue(JToken.DeepEquals(new JValue(float.MinValue), (JValue)float.MinValue)); + Assert.IsTrue(JToken.DeepEquals(new JValue(double.MinValue), (JValue)double.MinValue)); + Assert.IsTrue(JToken.DeepEquals(new JValue(uint.MaxValue), (JValue)uint.MaxValue)); + Assert.IsTrue(JToken.DeepEquals(new JValue(ulong.MaxValue), (JValue)ulong.MaxValue)); + Assert.IsTrue(JToken.DeepEquals(new JValue(ulong.MinValue), (JValue)ulong.MinValue)); + Assert.IsTrue(JToken.DeepEquals(new JValue((string)null), (JValue)(string)null)); + Assert.IsTrue(JToken.DeepEquals(new JValue((DateTime?)null), (JValue)(DateTime?)null)); + Assert.IsTrue(JToken.DeepEquals(new JValue(decimal.MaxValue), (JValue)decimal.MaxValue)); + Assert.IsTrue(JToken.DeepEquals(new JValue(decimal.MaxValue), (JValue)(decimal?)decimal.MaxValue)); + Assert.IsTrue(JToken.DeepEquals(new JValue(decimal.MinValue), (JValue)decimal.MinValue)); + Assert.IsTrue(JToken.DeepEquals(new JValue(float.MaxValue), (JValue)(float?)float.MaxValue)); + Assert.IsTrue(JToken.DeepEquals(new JValue(double.MaxValue), (JValue)(double?)double.MaxValue)); + Assert.IsTrue(JToken.DeepEquals(new JValue((object)null), (JValue)(double?)null)); - Assert.IsFalse(JToken.DeepEquals(new JValue(true), (JValue)(bool?)null)); - Assert.IsFalse(JToken.DeepEquals(new JValue((object)null), (JValue)(object)null)); + Assert.IsFalse(JToken.DeepEquals(new JValue(true), (JValue)(bool?)null)); + Assert.IsFalse(JToken.DeepEquals(new JValue((object)null), (JValue)(object)null)); - byte[] emptyData = new byte[0]; - Assert.IsTrue(JToken.DeepEquals(new JValue(emptyData), (JValue)emptyData)); - Assert.IsFalse(JToken.DeepEquals(new JValue(emptyData), (JValue)new byte[1])); - Assert.IsTrue(JToken.DeepEquals(new JValue(Encoding.UTF8.GetBytes("Hi")), (JValue)Encoding.UTF8.GetBytes("Hi"))); + byte[] emptyData = new byte[0]; + Assert.IsTrue(JToken.DeepEquals(new JValue(emptyData), (JValue)emptyData)); + Assert.IsFalse(JToken.DeepEquals(new JValue(emptyData), (JValue)new byte[1])); + Assert.IsTrue(JToken.DeepEquals(new JValue(Encoding.UTF8.GetBytes("Hi")), (JValue)Encoding.UTF8.GetBytes("Hi"))); - Assert.IsTrue(JToken.DeepEquals(new JValue(TimeSpan.FromMinutes(1)), (JValue)TimeSpan.FromMinutes(1))); - Assert.IsTrue(JToken.DeepEquals(new JValue((object)null), (JValue)(TimeSpan?)null)); - Assert.IsTrue(JToken.DeepEquals(new JValue(TimeSpan.FromMinutes(1)), (JValue)(TimeSpan?)TimeSpan.FromMinutes(1))); - Assert.IsTrue(JToken.DeepEquals(new JValue(new Guid("46EFE013-B56A-4E83-99E4-4DCE7678A5BC")), (JValue)new Guid("46EFE013-B56A-4E83-99E4-4DCE7678A5BC"))); - Assert.IsTrue(JToken.DeepEquals(new JValue(new Uri("http://www.google.com")), (JValue)new Uri("http://www.google.com"))); - Assert.IsTrue(JToken.DeepEquals(new JValue((object)null), (JValue)(Uri)null)); - Assert.IsTrue(JToken.DeepEquals(new JValue((object)null), (JValue)(Guid?)null)); - } + Assert.IsTrue(JToken.DeepEquals(new JValue(TimeSpan.FromMinutes(1)), (JValue)TimeSpan.FromMinutes(1))); + Assert.IsTrue(JToken.DeepEquals(new JValue((object)null), (JValue)(TimeSpan?)null)); + Assert.IsTrue(JToken.DeepEquals(new JValue(TimeSpan.FromMinutes(1)), (JValue)(TimeSpan?)TimeSpan.FromMinutes(1))); + Assert.IsTrue(JToken.DeepEquals(new JValue(new Guid("46EFE013-B56A-4E83-99E4-4DCE7678A5BC")), (JValue)new Guid("46EFE013-B56A-4E83-99E4-4DCE7678A5BC"))); + Assert.IsTrue(JToken.DeepEquals(new JValue(new Uri("http://www.google.com")), (JValue)new Uri("http://www.google.com"))); + Assert.IsTrue(JToken.DeepEquals(new JValue((object)null), (JValue)(Uri)null)); + Assert.IsTrue(JToken.DeepEquals(new JValue((object)null), (JValue)(Guid?)null)); + } - [Test] - public void Root() - { - JArray a = - new JArray( - 5, - 6, - new JArray(7, 8), - new JArray(9, 10) - ); - - Assert.AreEqual(a, a.Root); - Assert.AreEqual(a, a[0].Root); - Assert.AreEqual(a, ((JArray)a[2])[0].Root); - } - - [Test] - public void Remove() - { - JToken t; - JArray a = - new JArray( - 5, - 6, - new JArray(7, 8), - new JArray(9, 10) - ); - - a[0].Remove(); - - Assert.AreEqual(6, (int)a[0]); - - a[1].Remove(); - - Assert.AreEqual(6, (int)a[0]); - Assert.IsTrue(JToken.DeepEquals(new JArray(9, 10), a[1])); - Assert.AreEqual(2, a.Count()); - - t = a[1]; - t.Remove(); - Assert.AreEqual(6, (int)a[0]); - Assert.IsNull(t.Next); - Assert.IsNull(t.Previous); - Assert.IsNull(t.Parent); - - t = a[0]; - t.Remove(); - Assert.AreEqual(0, a.Count()); - - Assert.IsNull(t.Next); - Assert.IsNull(t.Previous); - Assert.IsNull(t.Parent); - } - - [Test] - public void AfterSelf() - { - JArray a = - new JArray( - 5, - new JArray(1), - new JArray(1, 2), - new JArray(1, 2, 3) - ); - - JToken t = a[1]; - List afterTokens = t.AfterSelf().ToList(); - - Assert.AreEqual(2, afterTokens.Count); - Assert.IsTrue(JToken.DeepEquals(new JArray(1, 2), afterTokens[0])); - Assert.IsTrue(JToken.DeepEquals(new JArray(1, 2, 3), afterTokens[1])); - } - - [Test] - public void BeforeSelf() - { - JArray a = - new JArray( - 5, - new JArray(1), - new JArray(1, 2), - new JArray(1, 2, 3) - ); - - JToken t = a[2]; - List beforeTokens = t.BeforeSelf().ToList(); - - Assert.AreEqual(2, beforeTokens.Count); - Assert.IsTrue(JToken.DeepEquals(new JValue(5), beforeTokens[0])); - Assert.IsTrue(JToken.DeepEquals(new JArray(1), beforeTokens[1])); - } - - [Test] - public void HasValues() - { - JArray a = - new JArray( - 5, - new JArray(1), - new JArray(1, 2), - new JArray(1, 2, 3) - ); - - Assert.IsTrue(a.HasValues); - } - - [Test] - public void Ancestors() - { - JArray a = - new JArray( - 5, - new JArray(1), - new JArray(1, 2), - new JArray(1, 2, 3) - ); - - JToken t = a[1][0]; - List ancestors = t.Ancestors().ToList(); - Assert.AreEqual(2, ancestors.Count()); - Assert.AreEqual(a[1], ancestors[0]); - Assert.AreEqual(a, ancestors[1]); - } - - [Test] - public void Descendants() - { - JArray a = - new JArray( - 5, - new JArray(1), - new JArray(1, 2), - new JArray(1, 2, 3) - ); - - List descendants = a.Descendants().ToList(); - Assert.AreEqual(10, descendants.Count()); - Assert.AreEqual(5, (int)descendants[0]); - Assert.IsTrue(JToken.DeepEquals(new JArray(1, 2, 3), descendants[descendants.Count - 4])); - Assert.AreEqual(1, (int)descendants[descendants.Count - 3]); - Assert.AreEqual(2, (int)descendants[descendants.Count - 2]); - Assert.AreEqual(3, (int)descendants[descendants.Count - 1]); - } - - [Test] - public void CreateWriter() - { - JArray a = - new JArray( - 5, - new JArray(1), - new JArray(1, 2), - new JArray(1, 2, 3) - ); - - JsonWriter writer = a.CreateWriter(); - Assert.IsNotNull(writer); - Assert.AreEqual(4, a.Count()); - - writer.WriteValue("String"); - Assert.AreEqual(5, a.Count()); - Assert.AreEqual("String", (string)a[4]); - - writer.WriteStartObject(); - writer.WritePropertyName("Property"); - writer.WriteValue("PropertyValue"); - writer.WriteEnd(); - - Assert.AreEqual(6, a.Count()); - Assert.IsTrue(JToken.DeepEquals(new JObject(new JProperty("Property", "PropertyValue")), a[5])); - } - - [Test] - public void AddFirst() - { - JArray a = - new JArray( - 5, - new JArray(1), - new JArray(1, 2), - new JArray(1, 2, 3) - ); - - a.AddFirst("First"); - - Assert.AreEqual("First", (string)a[0]); - Assert.AreEqual(a, a[0].Parent); - Assert.AreEqual(a[1], a[0].Next); - Assert.AreEqual(5, a.Count()); - - a.AddFirst("NewFirst"); - Assert.AreEqual("NewFirst", (string)a[0]); - Assert.AreEqual(a, a[0].Parent); - Assert.AreEqual(a[1], a[0].Next); - Assert.AreEqual(6, a.Count()); - - Assert.AreEqual(a[0], a[0].Next.Previous); - } - - [Test] - public void RemoveAll() - { - JArray a = - new JArray( - 5, - new JArray(1), - new JArray(1, 2), - new JArray(1, 2, 3) - ); - - JToken first = a.First; - Assert.AreEqual(5, (int)first); - - a.RemoveAll(); - Assert.AreEqual(0, a.Count()); - - Assert.IsNull(first.Parent); - Assert.IsNull(first.Next); - } - - [Test] - public void AddPropertyToArray() - { - ExceptionAssert.Throws("Can not add Newtonsoft.Json.Linq.JProperty to Newtonsoft.Json.Linq.JArray.", - () => - { - JArray a = new JArray(); - a.Add(new JProperty("PropertyName")); - }); - } - - [Test] - public void AddValueToObject() - { - ExceptionAssert.Throws( - "Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject.", - () => + [Test] + public void Root() { - JObject o = new JObject(); - o.Add(5); - }); - } + JArray a = + new JArray( + 5, + 6, + new JArray(7, 8), + new JArray(9, 10) + ); - [Test] - public void Replace() - { - JArray a = - new JArray( - 5, - new JArray(1), - new JArray(1, 2), - new JArray(1, 2, 3) - ); + Assert.AreEqual(a, a.Root); + Assert.AreEqual(a, a[0].Root); + Assert.AreEqual(a, ((JArray)a[2])[0].Root); + } - a[0].Replace(new JValue(int.MaxValue)); - Assert.AreEqual(int.MaxValue, (int)a[0]); - Assert.AreEqual(4, a.Count()); + [Test] + public void Remove() + { + JToken t; + JArray a = + new JArray( + 5, + 6, + new JArray(7, 8), + new JArray(9, 10) + ); - a[1][0].Replace(new JValue("Test")); - Assert.AreEqual("Test", (string)a[1][0]); + a[0].Remove(); - a[2].Replace(new JValue(int.MaxValue)); - Assert.AreEqual(int.MaxValue, (int)a[2]); - Assert.AreEqual(4, a.Count()); + Assert.AreEqual(6, (int)a[0]); - Assert.IsTrue(JToken.DeepEquals(new JArray(int.MaxValue, new JArray("Test"), int.MaxValue, new JArray(1, 2, 3)), a)); - } + a[1].Remove(); - [Test] - public void ToStringWithConverters() - { - JArray a = - new JArray( - new JValue(new DateTime(2009, 2, 15, 0, 0, 0, DateTimeKind.Utc)) - ); + Assert.AreEqual(6, (int)a[0]); + Assert.IsTrue(JToken.DeepEquals(new JArray(9, 10), a[1])); + Assert.AreEqual(2, a.Count()); - string json = a.ToString(Formatting.Indented, new IsoDateTimeConverter()); + t = a[1]; + t.Remove(); + Assert.AreEqual(6, (int)a[0]); + Assert.IsNull(t.Next); + Assert.IsNull(t.Previous); + Assert.IsNull(t.Parent); - Assert.AreEqual(@"[ + t = a[0]; + t.Remove(); + Assert.AreEqual(0, a.Count()); + + Assert.IsNull(t.Next); + Assert.IsNull(t.Previous); + Assert.IsNull(t.Parent); + } + + [Test] + public void AfterSelf() + { + JArray a = + new JArray( + 5, + new JArray(1), + new JArray(1, 2), + new JArray(1, 2, 3) + ); + + JToken t = a[1]; + List afterTokens = t.AfterSelf().ToList(); + + Assert.AreEqual(2, afterTokens.Count); + Assert.IsTrue(JToken.DeepEquals(new JArray(1, 2), afterTokens[0])); + Assert.IsTrue(JToken.DeepEquals(new JArray(1, 2, 3), afterTokens[1])); + } + + [Test] + public void BeforeSelf() + { + JArray a = + new JArray( + 5, + new JArray(1), + new JArray(1, 2), + new JArray(1, 2, 3) + ); + + JToken t = a[2]; + List beforeTokens = t.BeforeSelf().ToList(); + + Assert.AreEqual(2, beforeTokens.Count); + Assert.IsTrue(JToken.DeepEquals(new JValue(5), beforeTokens[0])); + Assert.IsTrue(JToken.DeepEquals(new JArray(1), beforeTokens[1])); + } + + [Test] + public void HasValues() + { + JArray a = + new JArray( + 5, + new JArray(1), + new JArray(1, 2), + new JArray(1, 2, 3) + ); + + Assert.IsTrue(a.HasValues); + } + + [Test] + public void Ancestors() + { + JArray a = + new JArray( + 5, + new JArray(1), + new JArray(1, 2), + new JArray(1, 2, 3) + ); + + JToken t = a[1][0]; + List ancestors = t.Ancestors().ToList(); + Assert.AreEqual(2, ancestors.Count()); + Assert.AreEqual(a[1], ancestors[0]); + Assert.AreEqual(a, ancestors[1]); + } + + [Test] + public void Descendants() + { + JArray a = + new JArray( + 5, + new JArray(1), + new JArray(1, 2), + new JArray(1, 2, 3) + ); + + List descendants = a.Descendants().ToList(); + Assert.AreEqual(10, descendants.Count()); + Assert.AreEqual(5, (int)descendants[0]); + Assert.IsTrue(JToken.DeepEquals(new JArray(1, 2, 3), descendants[descendants.Count - 4])); + Assert.AreEqual(1, (int)descendants[descendants.Count - 3]); + Assert.AreEqual(2, (int)descendants[descendants.Count - 2]); + Assert.AreEqual(3, (int)descendants[descendants.Count - 1]); + } + + [Test] + public void CreateWriter() + { + JArray a = + new JArray( + 5, + new JArray(1), + new JArray(1, 2), + new JArray(1, 2, 3) + ); + + JsonWriter writer = a.CreateWriter(); + Assert.IsNotNull(writer); + Assert.AreEqual(4, a.Count()); + + writer.WriteValue("String"); + Assert.AreEqual(5, a.Count()); + Assert.AreEqual("String", (string)a[4]); + + writer.WriteStartObject(); + writer.WritePropertyName("Property"); + writer.WriteValue("PropertyValue"); + writer.WriteEnd(); + + Assert.AreEqual(6, a.Count()); + Assert.IsTrue(JToken.DeepEquals(new JObject(new JProperty("Property", "PropertyValue")), a[5])); + } + + [Test] + public void AddFirst() + { + JArray a = + new JArray( + 5, + new JArray(1), + new JArray(1, 2), + new JArray(1, 2, 3) + ); + + a.AddFirst("First"); + + Assert.AreEqual("First", (string)a[0]); + Assert.AreEqual(a, a[0].Parent); + Assert.AreEqual(a[1], a[0].Next); + Assert.AreEqual(5, a.Count()); + + a.AddFirst("NewFirst"); + Assert.AreEqual("NewFirst", (string)a[0]); + Assert.AreEqual(a, a[0].Parent); + Assert.AreEqual(a[1], a[0].Next); + Assert.AreEqual(6, a.Count()); + + Assert.AreEqual(a[0], a[0].Next.Previous); + } + + [Test] + public void RemoveAll() + { + JArray a = + new JArray( + 5, + new JArray(1), + new JArray(1, 2), + new JArray(1, 2, 3) + ); + + JToken first = a.First; + Assert.AreEqual(5, (int)first); + + a.RemoveAll(); + Assert.AreEqual(0, a.Count()); + + Assert.IsNull(first.Parent); + Assert.IsNull(first.Next); + } + + [Test] + public void AddPropertyToArray() + { + ExceptionAssert.Throws("Can not add Newtonsoft.Json.Linq.JProperty to Newtonsoft.Json.Linq.JArray.", + () => + { + JArray a = new JArray(); + a.Add(new JProperty("PropertyName")); + }); + } + + [Test] + public void AddValueToObject() + { + ExceptionAssert.Throws( + "Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject.", + () => + { + JObject o = new JObject(); + o.Add(5); + }); + } + + [Test] + public void Replace() + { + JArray a = + new JArray( + 5, + new JArray(1), + new JArray(1, 2), + new JArray(1, 2, 3) + ); + + a[0].Replace(new JValue(int.MaxValue)); + Assert.AreEqual(int.MaxValue, (int)a[0]); + Assert.AreEqual(4, a.Count()); + + a[1][0].Replace(new JValue("Test")); + Assert.AreEqual("Test", (string)a[1][0]); + + a[2].Replace(new JValue(int.MaxValue)); + Assert.AreEqual(int.MaxValue, (int)a[2]); + Assert.AreEqual(4, a.Count()); + + Assert.IsTrue(JToken.DeepEquals(new JArray(int.MaxValue, new JArray("Test"), int.MaxValue, new JArray(1, 2, 3)), a)); + } + + [Test] + public void ToStringWithConverters() + { + JArray a = + new JArray( + new JValue(new DateTime(2009, 2, 15, 0, 0, 0, DateTimeKind.Utc)) + ); + + string json = a.ToString(Formatting.Indented, new IsoDateTimeConverter()); + + Assert.AreEqual(@"[ ""2009-02-15T00:00:00Z"" ]", json); - json = JsonConvert.SerializeObject(a, new IsoDateTimeConverter()); + json = JsonConvert.SerializeObject(a, new IsoDateTimeConverter()); - Assert.AreEqual(@"[""2009-02-15T00:00:00Z""]", json); - } + Assert.AreEqual(@"[""2009-02-15T00:00:00Z""]", json); + } - [Test] - public void ToStringWithNoIndenting() - { - JArray a = - new JArray( - new JValue(new DateTime(2009, 2, 15, 0, 0, 0, DateTimeKind.Utc)) - ); + [Test] + public void ToStringWithNoIndenting() + { + JArray a = + new JArray( + new JValue(new DateTime(2009, 2, 15, 0, 0, 0, DateTimeKind.Utc)) + ); - string json = a.ToString(Formatting.None, new IsoDateTimeConverter()); + string json = a.ToString(Formatting.None, new IsoDateTimeConverter()); - Assert.AreEqual(@"[""2009-02-15T00:00:00Z""]", json); - } + Assert.AreEqual(@"[""2009-02-15T00:00:00Z""]", json); + } - [Test] - public void AddAfterSelf() - { - JArray a = - new JArray( - 5, - new JArray(1), - new JArray(1, 2), - new JArray(1, 2, 3) - ); + [Test] + public void AddAfterSelf() + { + JArray a = + new JArray( + 5, + new JArray(1), + new JArray(1, 2), + new JArray(1, 2, 3) + ); - a[1].AddAfterSelf("pie"); + a[1].AddAfterSelf("pie"); - Assert.AreEqual(5, (int)a[0]); - Assert.AreEqual(1, a[1].Count()); - Assert.AreEqual("pie", (string)a[2]); - Assert.AreEqual(5, a.Count()); + Assert.AreEqual(5, (int)a[0]); + Assert.AreEqual(1, a[1].Count()); + Assert.AreEqual("pie", (string)a[2]); + Assert.AreEqual(5, a.Count()); - a[4].AddAfterSelf("lastpie"); + a[4].AddAfterSelf("lastpie"); - Assert.AreEqual("lastpie", (string)a[5]); - Assert.AreEqual("lastpie", (string)a.Last); - } + Assert.AreEqual("lastpie", (string)a[5]); + Assert.AreEqual("lastpie", (string)a.Last); + } - [Test] - public void AddBeforeSelf() - { - JArray a = - new JArray( - 5, - new JArray(1), - new JArray(1, 2), - new JArray(1, 2, 3) - ); + [Test] + public void AddBeforeSelf() + { + JArray a = + new JArray( + 5, + new JArray(1), + new JArray(1, 2), + new JArray(1, 2, 3) + ); - a[1].AddBeforeSelf("pie"); + a[1].AddBeforeSelf("pie"); - Assert.AreEqual(5, (int)a[0]); - Assert.AreEqual("pie", (string)a[1]); - Assert.AreEqual(a, a[1].Parent); - Assert.AreEqual(a[2], a[1].Next); - Assert.AreEqual(5, a.Count()); + Assert.AreEqual(5, (int)a[0]); + Assert.AreEqual("pie", (string)a[1]); + Assert.AreEqual(a, a[1].Parent); + Assert.AreEqual(a[2], a[1].Next); + Assert.AreEqual(5, a.Count()); - a[0].AddBeforeSelf("firstpie"); + a[0].AddBeforeSelf("firstpie"); - Assert.AreEqual("firstpie", (string)a[0]); - Assert.AreEqual(5, (int)a[1]); - Assert.AreEqual("pie", (string)a[2]); - Assert.AreEqual(a, a[0].Parent); - Assert.AreEqual(a[1], a[0].Next); - Assert.AreEqual(6, a.Count()); + Assert.AreEqual("firstpie", (string)a[0]); + Assert.AreEqual(5, (int)a[1]); + Assert.AreEqual("pie", (string)a[2]); + Assert.AreEqual(a, a[0].Parent); + Assert.AreEqual(a[1], a[0].Next); + Assert.AreEqual(6, a.Count()); - a.Last.AddBeforeSelf("secondlastpie"); + a.Last.AddBeforeSelf("secondlastpie"); - Assert.AreEqual("secondlastpie", (string)a[5]); - Assert.AreEqual(7, a.Count()); - } + Assert.AreEqual("secondlastpie", (string)a[5]); + Assert.AreEqual(7, a.Count()); + } - [Test] - public void DeepClone() - { - JArray a = - new JArray( - 5, - new JArray(1), - new JArray(1, 2), - new JArray(1, 2, 3), - new JObject( - new JProperty("First", new JValue(Encoding.UTF8.GetBytes("Hi"))), - new JProperty("Second", 1), - new JProperty("Third", null), - new JProperty("Fourth", new JConstructor("Date", 12345)), - new JProperty("Fifth", double.PositiveInfinity), - new JProperty("Sixth", double.NaN) - ) - ); + [Test] + public void DeepClone() + { + JArray a = + new JArray( + 5, + new JArray(1), + new JArray(1, 2), + new JArray(1, 2, 3), + new JObject( + new JProperty("First", new JValue(Encoding.UTF8.GetBytes("Hi"))), + new JProperty("Second", 1), + new JProperty("Third", null), + new JProperty("Fourth", new JConstructor("Date", 12345)), + new JProperty("Fifth", double.PositiveInfinity), + new JProperty("Sixth", double.NaN) + ) + ); - JArray a2 = (JArray)a.DeepClone(); + JArray a2 = (JArray)a.DeepClone(); - Console.WriteLine(a2.ToString(Formatting.Indented)); + Console.WriteLine(a2.ToString(Formatting.Indented)); - Assert.IsTrue(a.DeepEquals(a2)); - } + Assert.IsTrue(a.DeepEquals(a2)); + } #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - [Test] - public void Clone() - { - JArray a = - new JArray( - 5, - new JArray(1), - new JArray(1, 2), - new JArray(1, 2, 3), - new JObject( - new JProperty("First", new JValue(Encoding.UTF8.GetBytes("Hi"))), - new JProperty("Second", 1), - new JProperty("Third", null), - new JProperty("Fourth", new JConstructor("Date", 12345)), - new JProperty("Fifth", double.PositiveInfinity), - new JProperty("Sixth", double.NaN) - ) - ); + [Test] + public void Clone() + { + JArray a = + new JArray( + 5, + new JArray(1), + new JArray(1, 2), + new JArray(1, 2, 3), + new JObject( + new JProperty("First", new JValue(Encoding.UTF8.GetBytes("Hi"))), + new JProperty("Second", 1), + new JProperty("Third", null), + new JProperty("Fourth", new JConstructor("Date", 12345)), + new JProperty("Fifth", double.PositiveInfinity), + new JProperty("Sixth", double.NaN) + ) + ); - ICloneable c = a; + ICloneable c = a; - JArray a2 = (JArray) c.Clone(); + JArray a2 = (JArray)c.Clone(); - Assert.IsTrue(a.DeepEquals(a2)); - } + Assert.IsTrue(a.DeepEquals(a2)); + } #endif - [Test] - public void DoubleDeepEquals() - { - JArray a = - new JArray( - double.NaN, - double.PositiveInfinity, - double.NegativeInfinity - ); - - JArray a2 = (JArray)a.DeepClone(); - - Assert.IsTrue(a.DeepEquals(a2)); - - double d = 1 + 0.1 + 0.1 + 0.1; - - JValue v1 = new JValue(d); - JValue v2 = new JValue(1.3); - - Assert.IsTrue(v1.DeepEquals(v2)); - } - - [Test] - public void ParseAdditionalContent() - { - ExceptionAssert.Throws("Additional text encountered after finished reading JSON content: ,. Path '', line 5, position 2.", - () => + [Test] + public void DoubleDeepEquals() { - string json = @"[ + JArray a = + new JArray( + double.NaN, + double.PositiveInfinity, + double.NegativeInfinity + ); + + JArray a2 = (JArray)a.DeepClone(); + + Assert.IsTrue(a.DeepEquals(a2)); + + double d = 1 + 0.1 + 0.1 + 0.1; + + JValue v1 = new JValue(d); + JValue v2 = new JValue(1.3); + + Assert.IsTrue(v1.DeepEquals(v2)); + } + + [Test] + public void ParseAdditionalContent() + { + ExceptionAssert.Throws("Additional text encountered after finished reading JSON content: ,. Path '', line 5, position 2.", + () => + { + string json = @"[ ""Small"", ""Medium"", ""Large"" ],"; - JToken.Parse(json); - }); + JToken.Parse(json); + }); + } + + [Test] + public void Path() + { + JObject o = + new JObject( + new JProperty("Test1", new JArray(1, 2, 3)), + new JProperty("Test2", "Test2Value"), + new JProperty("Test3", new JObject(new JProperty("Test1", new JArray(1, new JObject(new JProperty("Test1", 1)), 3)))), + new JProperty("Test4", new JConstructor("Date", new JArray(1, 2, 3))) + ); + + JToken t = o.SelectToken("Test1[0]"); + Assert.AreEqual("Test1[0]", t.Path); + + t = o.SelectToken("Test2"); + Assert.AreEqual("Test2", t.Path); + + t = o.SelectToken(""); + Assert.AreEqual("", t.Path); + + t = o.SelectToken("Test4[0][0]"); + Assert.AreEqual("Test4[0][0]", t.Path); + + t = o.SelectToken("Test4[0]"); + Assert.AreEqual("Test4[0]", t.Path); + + t = t.DeepClone(); + Assert.AreEqual("", t.Path); + + t = o.SelectToken("Test3.Test1[1].Test1"); + Assert.AreEqual("Test3.Test1[1].Test1", t.Path); + + JArray a = new JArray(1); + Assert.AreEqual("", a.Path); + + Assert.AreEqual("[0]", a[0].Path); + } } - - [Test] - public void Path() - { - JObject o = - new JObject( - new JProperty("Test1", new JArray(1, 2, 3)), - new JProperty("Test2", "Test2Value"), - new JProperty("Test3", new JObject(new JProperty("Test1", new JArray(1, new JObject(new JProperty("Test1", 1)), 3)))), - new JProperty("Test4", new JConstructor("Date", new JArray(1, 2, 3))) - ); - - JToken t = o.SelectToken("Test1[0]"); - Assert.AreEqual("Test1[0]", t.Path); - - t = o.SelectToken("Test2"); - Assert.AreEqual("Test2", t.Path); - - t = o.SelectToken(""); - Assert.AreEqual("", t.Path); - - t = o.SelectToken("Test4[0][0]"); - Assert.AreEqual("Test4[0][0]", t.Path); - - t = o.SelectToken("Test4[0]"); - Assert.AreEqual("Test4[0]", t.Path); - - t = t.DeepClone(); - Assert.AreEqual("", t.Path); - - t = o.SelectToken("Test3.Test1[1].Test1"); - Assert.AreEqual("Test3.Test1[1].Test1", t.Path); - - JArray a = new JArray(1); - Assert.AreEqual("", a.Path); - - Assert.AreEqual("[0]", a[0].Path); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Linq/JTokenWriterTest.cs b/Src/Newtonsoft.Json.Tests/Linq/JTokenWriterTest.cs index f5494e8b..96246127 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/JTokenWriterTest.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/JTokenWriterTest.cs @@ -43,181 +43,182 @@ using Newtonsoft.Json.Linq; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json.Tests.Linq { - [TestFixture] - public class JTokenWriterTest : TestFixtureBase - { - [Test] - public void ValueFormatting() + [TestFixture] + public class JTokenWriterTest : TestFixtureBase { - byte[] data = Encoding.UTF8.GetBytes("Hello world."); + [Test] + public void ValueFormatting() + { + byte[] data = Encoding.UTF8.GetBytes("Hello world."); - JToken root; - using (JTokenWriter jsonWriter = new JTokenWriter()) - { - jsonWriter.WriteStartArray(); - jsonWriter.WriteValue('@'); - jsonWriter.WriteValue("\r\n\t\f\b?{\\r\\n\"\'"); - jsonWriter.WriteValue(true); - jsonWriter.WriteValue(10); - jsonWriter.WriteValue(10.99); - jsonWriter.WriteValue(0.99); - jsonWriter.WriteValue(0.000000000000000001d); - jsonWriter.WriteValue(0.000000000000000001m); - jsonWriter.WriteValue((string)null); - jsonWriter.WriteValue("This is a string."); - jsonWriter.WriteNull(); - jsonWriter.WriteUndefined(); - jsonWriter.WriteValue(data); - jsonWriter.WriteEndArray(); + JToken root; + using (JTokenWriter jsonWriter = new JTokenWriter()) + { + jsonWriter.WriteStartArray(); + jsonWriter.WriteValue('@'); + jsonWriter.WriteValue("\r\n\t\f\b?{\\r\\n\"\'"); + jsonWriter.WriteValue(true); + jsonWriter.WriteValue(10); + jsonWriter.WriteValue(10.99); + jsonWriter.WriteValue(0.99); + jsonWriter.WriteValue(0.000000000000000001d); + jsonWriter.WriteValue(0.000000000000000001m); + jsonWriter.WriteValue((string)null); + jsonWriter.WriteValue("This is a string."); + jsonWriter.WriteNull(); + jsonWriter.WriteUndefined(); + jsonWriter.WriteValue(data); + jsonWriter.WriteEndArray(); - root = jsonWriter.Token; - } + root = jsonWriter.Token; + } - CustomAssert.IsInstanceOfType(typeof(JArray), root); - Assert.AreEqual(13, root.Children().Count()); - Assert.AreEqual("@", (string)root[0]); - Assert.AreEqual("\r\n\t\f\b?{\\r\\n\"\'", (string)root[1]); - Assert.AreEqual(true, (bool)root[2]); - Assert.AreEqual(10, (int)root[3]); - Assert.AreEqual(10.99, (double)root[4]); - Assert.AreEqual(0.99, (double)root[5]); - Assert.AreEqual(0.000000000000000001d, (double)root[6]); - Assert.AreEqual(0.000000000000000001m, (decimal)root[7]); - Assert.AreEqual(string.Empty, (string)root[8]); - Assert.AreEqual("This is a string.", (string)root[9]); - Assert.AreEqual(null, ((JValue)root[10]).Value); - Assert.AreEqual(null, ((JValue)root[11]).Value); - Assert.AreEqual(data, (byte[])root[12]); - } + CustomAssert.IsInstanceOfType(typeof(JArray), root); + Assert.AreEqual(13, root.Children().Count()); + Assert.AreEqual("@", (string)root[0]); + Assert.AreEqual("\r\n\t\f\b?{\\r\\n\"\'", (string)root[1]); + Assert.AreEqual(true, (bool)root[2]); + Assert.AreEqual(10, (int)root[3]); + Assert.AreEqual(10.99, (double)root[4]); + Assert.AreEqual(0.99, (double)root[5]); + Assert.AreEqual(0.000000000000000001d, (double)root[6]); + Assert.AreEqual(0.000000000000000001m, (decimal)root[7]); + Assert.AreEqual(string.Empty, (string)root[8]); + Assert.AreEqual("This is a string.", (string)root[9]); + Assert.AreEqual(null, ((JValue)root[10]).Value); + Assert.AreEqual(null, ((JValue)root[11]).Value); + Assert.AreEqual(data, (byte[])root[12]); + } - [Test] - public void State() - { - using (JsonWriter jsonWriter = new JTokenWriter()) - { - Assert.AreEqual(WriteState.Start, jsonWriter.WriteState); + [Test] + public void State() + { + using (JsonWriter jsonWriter = new JTokenWriter()) + { + Assert.AreEqual(WriteState.Start, jsonWriter.WriteState); - jsonWriter.WriteStartObject(); - Assert.AreEqual(WriteState.Object, jsonWriter.WriteState); + jsonWriter.WriteStartObject(); + Assert.AreEqual(WriteState.Object, jsonWriter.WriteState); - jsonWriter.WritePropertyName("CPU"); - Assert.AreEqual(WriteState.Property, jsonWriter.WriteState); + jsonWriter.WritePropertyName("CPU"); + Assert.AreEqual(WriteState.Property, jsonWriter.WriteState); - jsonWriter.WriteValue("Intel"); - Assert.AreEqual(WriteState.Object, jsonWriter.WriteState); + jsonWriter.WriteValue("Intel"); + Assert.AreEqual(WriteState.Object, jsonWriter.WriteState); - jsonWriter.WritePropertyName("Drives"); - Assert.AreEqual(WriteState.Property, jsonWriter.WriteState); + jsonWriter.WritePropertyName("Drives"); + Assert.AreEqual(WriteState.Property, jsonWriter.WriteState); - jsonWriter.WriteStartArray(); - Assert.AreEqual(WriteState.Array, jsonWriter.WriteState); + jsonWriter.WriteStartArray(); + Assert.AreEqual(WriteState.Array, jsonWriter.WriteState); - jsonWriter.WriteValue("DVD read/writer"); - Assert.AreEqual(WriteState.Array, jsonWriter.WriteState); + jsonWriter.WriteValue("DVD read/writer"); + Assert.AreEqual(WriteState.Array, jsonWriter.WriteState); #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE || PORTABLE40) - jsonWriter.WriteValue(new BigInteger(123)); - Assert.AreEqual(WriteState.Array, jsonWriter.WriteState); + jsonWriter.WriteValue(new BigInteger(123)); + Assert.AreEqual(WriteState.Array, jsonWriter.WriteState); #endif - jsonWriter.WriteValue(new byte[0]); - Assert.AreEqual(WriteState.Array, jsonWriter.WriteState); + jsonWriter.WriteValue(new byte[0]); + Assert.AreEqual(WriteState.Array, jsonWriter.WriteState); - jsonWriter.WriteEnd(); - Assert.AreEqual(WriteState.Object, jsonWriter.WriteState); + jsonWriter.WriteEnd(); + Assert.AreEqual(WriteState.Object, jsonWriter.WriteState); - jsonWriter.WriteEndObject(); - Assert.AreEqual(WriteState.Start, jsonWriter.WriteState); - } - } + jsonWriter.WriteEndObject(); + Assert.AreEqual(WriteState.Start, jsonWriter.WriteState); + } + } - [Test] - public void WriteComment() - { - JTokenWriter writer = new JTokenWriter(); + [Test] + public void WriteComment() + { + JTokenWriter writer = new JTokenWriter(); - writer.WriteStartArray(); - writer.WriteComment("fail"); - writer.WriteEndArray(); + writer.WriteStartArray(); + writer.WriteComment("fail"); + writer.WriteEndArray(); - Assert.AreEqual(@"[ + Assert.AreEqual(@"[ /*fail*/]", writer.Token.ToString()); - } + } #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE || PORTABLE40) - [Test] - public void WriteBigInteger() - { - JTokenWriter writer = new JTokenWriter(); + [Test] + public void WriteBigInteger() + { + JTokenWriter writer = new JTokenWriter(); - writer.WriteStartArray(); - writer.WriteValue(new BigInteger(123)); - writer.WriteEndArray(); + writer.WriteStartArray(); + writer.WriteValue(new BigInteger(123)); + writer.WriteEndArray(); - JValue i = (JValue) writer.Token[0]; + JValue i = (JValue)writer.Token[0]; - Assert.AreEqual(new BigInteger(123), i.Value); - Assert.AreEqual(JTokenType.Integer, i.Type); + Assert.AreEqual(new BigInteger(123), i.Value); + Assert.AreEqual(JTokenType.Integer, i.Type); - Assert.AreEqual(@"[ + Assert.AreEqual(@"[ 123 ]", writer.Token.ToString()); - } + } #endif - [Test] - public void WriteRaw() - { - JTokenWriter writer = new JTokenWriter(); + [Test] + public void WriteRaw() + { + JTokenWriter writer = new JTokenWriter(); - writer.WriteStartArray(); - writer.WriteRaw("fail"); - writer.WriteRaw("fail"); - writer.WriteEndArray(); + writer.WriteStartArray(); + writer.WriteRaw("fail"); + writer.WriteRaw("fail"); + writer.WriteEndArray(); - // this is a bug. write raw shouldn't be autocompleting like this - // hard to fix without introducing Raw and RawValue token types - // meh - Assert.AreEqual(@"[ + // this is a bug. write raw shouldn't be autocompleting like this + // hard to fix without introducing Raw and RawValue token types + // meh + Assert.AreEqual(@"[ fail, fail ]", writer.Token.ToString()); - } + } - [Test] - public void WriteRawValue() - { - JTokenWriter writer = new JTokenWriter(); + [Test] + public void WriteRawValue() + { + JTokenWriter writer = new JTokenWriter(); - writer.WriteStartArray(); - writer.WriteRawValue("fail"); - writer.WriteRawValue("fail"); - writer.WriteEndArray(); + writer.WriteStartArray(); + writer.WriteRawValue("fail"); + writer.WriteRawValue("fail"); + writer.WriteEndArray(); - Assert.AreEqual(@"[ + Assert.AreEqual(@"[ fail, fail ]", writer.Token.ToString()); + } + + [Test] + public void DateTimeZoneHandling() + { + JTokenWriter writer = new JTokenWriter + { + DateTimeZoneHandling = Json.DateTimeZoneHandling.Utc + }; + + writer.WriteValue(new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Unspecified)); + + JValue value = (JValue)writer.Token; + DateTime dt = (DateTime)value.Value; + + Assert.AreEqual(new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc), dt); + } } - - [Test] - public void DateTimeZoneHandling() - { - JTokenWriter writer = new JTokenWriter - { - DateTimeZoneHandling = Json.DateTimeZoneHandling.Utc - }; - - writer.WriteValue(new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Unspecified)); - - JValue value = (JValue) writer.Token; - DateTime dt = (DateTime)value.Value; - - Assert.AreEqual(new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc), dt); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs index e99e4223..5f90e430 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs @@ -48,639 +48,639 @@ using Newtonsoft.Json.Tests.Serialization; namespace Newtonsoft.Json.Tests.Linq { - [TestFixture] - public class JValueTests : TestFixtureBase - { - [Test] - public void FloatParseHandling() + [TestFixture] + public class JValueTests : TestFixtureBase { - JValue v = (JValue) JToken.ReadFrom( - new JsonTextReader(new StringReader("9.9")) - { - FloatParseHandling = Json.FloatParseHandling.Decimal - }); + [Test] + public void FloatParseHandling() + { + JValue v = (JValue)JToken.ReadFrom( + new JsonTextReader(new StringReader("9.9")) + { + FloatParseHandling = Json.FloatParseHandling.Decimal + }); - Assert.AreEqual(9.9m, v.Value); - Assert.AreEqual(typeof(decimal), v.Value.GetType()); - } + Assert.AreEqual(9.9m, v.Value); + Assert.AreEqual(typeof(decimal), v.Value.GetType()); + } - [Test] - public void ToObjectWithDefaultSettings() - { - try - { - JsonConvert.DefaultSettings = () => - { - return new JsonSerializerSettings - { - Converters = { new MetroStringConverter() } - }; - }; + [Test] + public void ToObjectWithDefaultSettings() + { + try + { + JsonConvert.DefaultSettings = () => + { + return new JsonSerializerSettings + { + Converters = { new MetroStringConverter() } + }; + }; - JValue v = new JValue(":::STRING:::"); - string s = v.ToObject(); + JValue v = new JValue(":::STRING:::"); + string s = v.ToObject(); - Assert.AreEqual("string", s); - } - finally - { - JsonConvert.DefaultSettings = null; - } - } + Assert.AreEqual("string", s); + } + finally + { + JsonConvert.DefaultSettings = null; + } + } - [Test] - public void ChangeValue() - { - JValue v = new JValue(true); - Assert.AreEqual(true, v.Value); - Assert.AreEqual(JTokenType.Boolean, v.Type); + [Test] + public void ChangeValue() + { + JValue v = new JValue(true); + Assert.AreEqual(true, v.Value); + Assert.AreEqual(JTokenType.Boolean, v.Type); - v.Value = "Pie"; - Assert.AreEqual("Pie", v.Value); - Assert.AreEqual(JTokenType.String, v.Type); + v.Value = "Pie"; + Assert.AreEqual("Pie", v.Value); + Assert.AreEqual(JTokenType.String, v.Type); - v.Value = null; - Assert.AreEqual(null, v.Value); - Assert.AreEqual(JTokenType.Null, v.Type); + v.Value = null; + Assert.AreEqual(null, v.Value); + Assert.AreEqual(JTokenType.Null, v.Type); - v.Value = (int?) null; - Assert.AreEqual(null, v.Value); - Assert.AreEqual(JTokenType.Null, v.Type); + v.Value = (int?)null; + Assert.AreEqual(null, v.Value); + Assert.AreEqual(JTokenType.Null, v.Type); - v.Value = "Pie"; - Assert.AreEqual("Pie", v.Value); - Assert.AreEqual(JTokenType.String, v.Type); + v.Value = "Pie"; + Assert.AreEqual("Pie", v.Value); + Assert.AreEqual(JTokenType.String, v.Type); #if !(NETFX_CORE || PORTABLE || PORTABLE40) - v.Value = DBNull.Value; - Assert.AreEqual(DBNull.Value, v.Value); - Assert.AreEqual(JTokenType.Null, v.Type); + v.Value = DBNull.Value; + Assert.AreEqual(DBNull.Value, v.Value); + Assert.AreEqual(JTokenType.Null, v.Type); #endif - byte[] data = new byte[0]; - v.Value = data; + byte[] data = new byte[0]; + v.Value = data; - Assert.AreEqual(data, v.Value); - Assert.AreEqual(JTokenType.Bytes, v.Type); + Assert.AreEqual(data, v.Value); + Assert.AreEqual(JTokenType.Bytes, v.Type); - v.Value = StringComparison.OrdinalIgnoreCase; - Assert.AreEqual(StringComparison.OrdinalIgnoreCase, v.Value); - Assert.AreEqual(JTokenType.Integer, v.Type); + v.Value = StringComparison.OrdinalIgnoreCase; + Assert.AreEqual(StringComparison.OrdinalIgnoreCase, v.Value); + Assert.AreEqual(JTokenType.Integer, v.Type); - v.Value = new Uri("http://json.codeplex.com/"); - Assert.AreEqual(new Uri("http://json.codeplex.com/"), v.Value); - Assert.AreEqual(JTokenType.Uri, v.Type); + v.Value = new Uri("http://json.codeplex.com/"); + Assert.AreEqual(new Uri("http://json.codeplex.com/"), v.Value); + Assert.AreEqual(JTokenType.Uri, v.Type); - v.Value = TimeSpan.FromDays(1); - Assert.AreEqual(TimeSpan.FromDays(1), v.Value); - Assert.AreEqual(JTokenType.TimeSpan, v.Type); + v.Value = TimeSpan.FromDays(1); + Assert.AreEqual(TimeSpan.FromDays(1), v.Value); + Assert.AreEqual(JTokenType.TimeSpan, v.Type); - Guid g = Guid.NewGuid(); - v.Value = g; - Assert.AreEqual(g, v.Value); - Assert.AreEqual(JTokenType.Guid, v.Type); + Guid g = Guid.NewGuid(); + v.Value = g; + Assert.AreEqual(g, v.Value); + Assert.AreEqual(JTokenType.Guid, v.Type); #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE || PORTABLE40) - BigInteger i = BigInteger.Parse("123456789999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999990"); - v.Value = i; - Assert.AreEqual(i, v.Value); - Assert.AreEqual(JTokenType.Integer, v.Type); + BigInteger i = BigInteger.Parse("123456789999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999990"); + v.Value = i; + Assert.AreEqual(i, v.Value); + Assert.AreEqual(JTokenType.Integer, v.Type); #endif - } + } - [Test] - public void CreateComment() - { - JValue commentValue = JValue.CreateComment(null); - Assert.AreEqual(null, commentValue.Value); - Assert.AreEqual(JTokenType.Comment, commentValue.Type); + [Test] + public void CreateComment() + { + JValue commentValue = JValue.CreateComment(null); + Assert.AreEqual(null, commentValue.Value); + Assert.AreEqual(JTokenType.Comment, commentValue.Type); - commentValue.Value = "Comment"; - Assert.AreEqual("Comment", commentValue.Value); - Assert.AreEqual(JTokenType.Comment, commentValue.Type); - } + commentValue.Value = "Comment"; + Assert.AreEqual("Comment", commentValue.Value); + Assert.AreEqual(JTokenType.Comment, commentValue.Type); + } - [Test] - public void CreateString() - { - JValue stringValue = JValue.CreateString(null); - Assert.AreEqual(null, stringValue.Value); - Assert.AreEqual(JTokenType.String, stringValue.Type); - } + [Test] + public void CreateString() + { + JValue stringValue = JValue.CreateString(null); + Assert.AreEqual(null, stringValue.Value); + Assert.AreEqual(JTokenType.String, stringValue.Type); + } - [Test] - public void JValueToString() - { - JValue v; + [Test] + public void JValueToString() + { + JValue v; - v = new JValue(true); - Assert.AreEqual("True", v.ToString()); + v = new JValue(true); + Assert.AreEqual("True", v.ToString()); - v = new JValue(Encoding.UTF8.GetBytes("Blah")); - Assert.AreEqual("System.Byte[]", v.ToString(null, CultureInfo.InvariantCulture)); + v = new JValue(Encoding.UTF8.GetBytes("Blah")); + Assert.AreEqual("System.Byte[]", v.ToString(null, CultureInfo.InvariantCulture)); - v = new JValue("I am a string!"); - Assert.AreEqual("I am a string!", v.ToString()); + v = new JValue("I am a string!"); + Assert.AreEqual("I am a string!", v.ToString()); - v = new JValue(null, JTokenType.Null); - Assert.AreEqual("", v.ToString()); + v = new JValue(null, JTokenType.Null); + Assert.AreEqual("", v.ToString()); - v = new JValue(null, JTokenType.Null); - Assert.AreEqual("", v.ToString(null, CultureInfo.InvariantCulture)); + v = new JValue(null, JTokenType.Null); + Assert.AreEqual("", v.ToString(null, CultureInfo.InvariantCulture)); - v = new JValue(new DateTime(2000, 12, 12, 20, 59, 59, DateTimeKind.Utc), JTokenType.Date); - Assert.AreEqual("12/12/2000 20:59:59", v.ToString(null, CultureInfo.InvariantCulture)); + v = new JValue(new DateTime(2000, 12, 12, 20, 59, 59, DateTimeKind.Utc), JTokenType.Date); + Assert.AreEqual("12/12/2000 20:59:59", v.ToString(null, CultureInfo.InvariantCulture)); - v = new JValue(new Uri("http://json.codeplex.com/")); - Assert.AreEqual("http://json.codeplex.com/", v.ToString(null, CultureInfo.InvariantCulture)); + v = new JValue(new Uri("http://json.codeplex.com/")); + Assert.AreEqual("http://json.codeplex.com/", v.ToString(null, CultureInfo.InvariantCulture)); - v = new JValue(TimeSpan.FromDays(1)); - Assert.AreEqual("1.00:00:00", v.ToString(null, CultureInfo.InvariantCulture)); + v = new JValue(TimeSpan.FromDays(1)); + Assert.AreEqual("1.00:00:00", v.ToString(null, CultureInfo.InvariantCulture)); - v = new JValue(new Guid("B282ADE7-C520-496C-A448-4084F6803DE5")); - Assert.AreEqual("b282ade7-c520-496c-a448-4084f6803de5", v.ToString(null, CultureInfo.InvariantCulture)); + v = new JValue(new Guid("B282ADE7-C520-496C-A448-4084F6803DE5")); + Assert.AreEqual("b282ade7-c520-496c-a448-4084f6803de5", v.ToString(null, CultureInfo.InvariantCulture)); #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE || PORTABLE40) - v = new JValue(BigInteger.Parse("123456789999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999990")); - Assert.AreEqual("123456789999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999990", v.ToString(null, CultureInfo.InvariantCulture)); + v = new JValue(BigInteger.Parse("123456789999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999990")); + Assert.AreEqual("123456789999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999990", v.ToString(null, CultureInfo.InvariantCulture)); #endif - } + } #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE || PORTABLE40) - [Test] - public void JValueParse() - { - JValue v = (JValue)JToken.Parse("123456789999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999990"); - - Assert.AreEqual(JTokenType.Integer, v.Type); - Assert.AreEqual(BigInteger.Parse("123456789999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999990"), v.Value); - } + [Test] + public void JValueParse() + { + JValue v = (JValue)JToken.Parse("123456789999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999990"); + + Assert.AreEqual(JTokenType.Integer, v.Type); + Assert.AreEqual(BigInteger.Parse("123456789999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999990"), v.Value); + } #endif - [Test] - public void Last() - { - ExceptionAssert.Throws("Cannot access child value on Newtonsoft.Json.Linq.JValue.", - () => - { + [Test] + public void Last() + { + ExceptionAssert.Throws("Cannot access child value on Newtonsoft.Json.Linq.JValue.", + () => + { + JValue v = new JValue(true); + JToken last = v.Last; + }); + } + + [Test] + public void Children() + { JValue v = new JValue(true); - JToken last = v.Last; - }); - } + var c = v.Children(); + Assert.AreEqual(JEnumerable.Empty, c); + } - [Test] - public void Children() - { - JValue v = new JValue(true); - var c = v.Children(); - Assert.AreEqual(JEnumerable.Empty, c); - } + [Test] + public void First() + { + ExceptionAssert.Throws("Cannot access child value on Newtonsoft.Json.Linq.JValue.", + () => + { + JValue v = new JValue(true); + JToken first = v.First; + }); + } - [Test] - public void First() - { - ExceptionAssert.Throws("Cannot access child value on Newtonsoft.Json.Linq.JValue.", - () => - { + [Test] + public void Item() + { + ExceptionAssert.Throws("Cannot access child value on Newtonsoft.Json.Linq.JValue.", + () => + { + JValue v = new JValue(true); + JToken first = v[0]; + }); + } + + [Test] + public void Values() + { + ExceptionAssert.Throws("Cannot access child value on Newtonsoft.Json.Linq.JValue.", + () => + { + JValue v = new JValue(true); + v.Values(); + }); + } + + [Test] + public void RemoveParentNull() + { + ExceptionAssert.Throws("The parent is missing.", + () => + { + JValue v = new JValue(true); + v.Remove(); + }); + } + + [Test] + public void Root() + { JValue v = new JValue(true); - JToken first = v.First; - }); - } + Assert.AreEqual(v, v.Root); + } - [Test] - public void Item() - { - ExceptionAssert.Throws("Cannot access child value on Newtonsoft.Json.Linq.JValue.", - () => - { + [Test] + public void Previous() + { JValue v = new JValue(true); - JToken first = v[0]; - }); - } + Assert.IsNull(v.Previous); + } - [Test] - public void Values() - { - ExceptionAssert.Throws("Cannot access child value on Newtonsoft.Json.Linq.JValue.", - () => - { + [Test] + public void Next() + { JValue v = new JValue(true); - v.Values(); - }); - } + Assert.IsNull(v.Next); + } - [Test] - public void RemoveParentNull() - { - ExceptionAssert.Throws("The parent is missing.", - () => - { - JValue v = new JValue(true); - v.Remove(); - }); - } + [Test] + public void DeepEquals() + { + Assert.IsTrue(JToken.DeepEquals(new JValue(5L), new JValue(5))); + Assert.IsFalse(JToken.DeepEquals(new JValue(5M), new JValue(5))); + Assert.IsTrue(JToken.DeepEquals(new JValue((ulong)long.MaxValue), new JValue(long.MaxValue))); + } - [Test] - public void Root() - { - JValue v = new JValue(true); - Assert.AreEqual(v, v.Root); - } + [Test] + public void HasValues() + { + Assert.IsFalse((new JValue(5L)).HasValues); + } - [Test] - public void Previous() - { - JValue v = new JValue(true); - Assert.IsNull(v.Previous); - } + [Test] + public void SetValue() + { + ExceptionAssert.Throws("Cannot set child value on Newtonsoft.Json.Linq.JValue.", + () => + { + JToken t = new JValue(5L); + t[0] = new JValue(3); + }); + } - [Test] - public void Next() - { - JValue v = new JValue(true); - Assert.IsNull(v.Next); - } + [Test] + public void CastNullValueToNonNullable() + { + ExceptionAssert.Throws("Can not convert Null to Int32.", + () => + { + JValue v = new JValue((object)null); + int i = (int)v; + }); + } - [Test] - public void DeepEquals() - { - Assert.IsTrue(JToken.DeepEquals(new JValue(5L), new JValue(5))); - Assert.IsFalse(JToken.DeepEquals(new JValue(5M), new JValue(5))); - Assert.IsTrue(JToken.DeepEquals(new JValue((ulong) long.MaxValue), new JValue(long.MaxValue))); - } + [Test] + public void ConvertValueToCompatibleType() + { + IComparable c = (new JValue(1).Value()); + Assert.AreEqual(1L, c); + } - [Test] - public void HasValues() - { - Assert.IsFalse((new JValue(5L)).HasValues); - } + [Test] + public void ConvertValueToFormattableType() + { + IFormattable f = (new JValue(1).Value()); + Assert.AreEqual(1L, f); - [Test] - public void SetValue() - { - ExceptionAssert.Throws("Cannot set child value on Newtonsoft.Json.Linq.JValue.", - () => - { - JToken t = new JValue(5L); - t[0] = new JValue(3); - }); - } + Assert.AreEqual("01", f.ToString("00", CultureInfo.InvariantCulture)); + } - [Test] - public void CastNullValueToNonNullable() - { - ExceptionAssert.Throws("Can not convert Null to Int32.", - () => - { - JValue v = new JValue((object) null); - int i = (int) v; - }); - } + [Test] + public void Ordering() + { + JObject o = new JObject( + new JProperty("Integer", new JValue(1)), + new JProperty("Float", new JValue(1.2d)), + new JProperty("Decimal", new JValue(1.1m)) + ); - [Test] - public void ConvertValueToCompatibleType() - { - IComparable c = (new JValue(1).Value()); - Assert.AreEqual(1L, c); - } + IList orderedValues = o.Values().Cast().OrderBy(v => v).Select(v => v.Value).ToList(); - [Test] - public void ConvertValueToFormattableType() - { - IFormattable f = (new JValue(1).Value()); - Assert.AreEqual(1L, f); + Assert.AreEqual(1L, orderedValues[0]); + Assert.AreEqual(1.1m, orderedValues[1]); + Assert.AreEqual(1.2d, orderedValues[2]); + } - Assert.AreEqual("01", f.ToString("00", CultureInfo.InvariantCulture)); - } + [Test] + public void WriteSingle() + { + float f = 5.2f; + JValue value = new JValue(f); - [Test] - public void Ordering() - { - JObject o = new JObject( - new JProperty("Integer", new JValue(1)), - new JProperty("Float", new JValue(1.2d)), - new JProperty("Decimal", new JValue(1.1m)) - ); + string json = value.ToString(Formatting.None); - IList orderedValues = o.Values().Cast().OrderBy(v => v).Select(v => v.Value).ToList(); + Assert.AreEqual("5.2", json); + } - Assert.AreEqual(1L, orderedValues[0]); - Assert.AreEqual(1.1m, orderedValues[1]); - Assert.AreEqual(1.2d, orderedValues[2]); - } + public class Rate + { + public decimal Compoundings { get; set; } + } - [Test] - public void WriteSingle() - { - float f = 5.2f; - JValue value = new JValue(f); + private readonly Rate rate = new Rate { Compoundings = 12.166666666666666666666666667m }; - string json = value.ToString(Formatting.None); - - Assert.AreEqual("5.2", json); - } - - public class Rate - { - public decimal Compoundings { get; set; } - } - - private readonly Rate rate = new Rate {Compoundings = 12.166666666666666666666666667m}; - - [Test] - public void WriteFullDecimalPrecision() - { - var jTokenWriter = new JTokenWriter(); - new JsonSerializer().Serialize(jTokenWriter, rate); - string json = jTokenWriter.Token.ToString(); - Assert.AreEqual(@"{ + [Test] + public void WriteFullDecimalPrecision() + { + var jTokenWriter = new JTokenWriter(); + new JsonSerializer().Serialize(jTokenWriter, rate); + string json = jTokenWriter.Token.ToString(); + Assert.AreEqual(@"{ ""Compoundings"": 12.166666666666666666666666667 }", json); - } + } - [Test] - public void RoundTripDecimal() - { - var jTokenWriter = new JTokenWriter(); - new JsonSerializer().Serialize(jTokenWriter, rate); - var rate2 = new JsonSerializer().Deserialize(new JTokenReader(jTokenWriter.Token)); + [Test] + public void RoundTripDecimal() + { + var jTokenWriter = new JTokenWriter(); + new JsonSerializer().Serialize(jTokenWriter, rate); + var rate2 = new JsonSerializer().Deserialize(new JTokenReader(jTokenWriter.Token)); - Assert.AreEqual(rate.Compoundings, rate2.Compoundings); - } + Assert.AreEqual(rate.Compoundings, rate2.Compoundings); + } #if !NET20 - public class ObjectWithDateTimeOffset - { - public DateTimeOffset DateTimeOffset { get; set; } - } + public class ObjectWithDateTimeOffset + { + public DateTimeOffset DateTimeOffset { get; set; } + } - [Test] - public void SetDateTimeOffsetProperty() - { - var dateTimeOffset = new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(3)); - var json = JsonConvert.SerializeObject( - new ObjectWithDateTimeOffset - { - DateTimeOffset = dateTimeOffset - }); + [Test] + public void SetDateTimeOffsetProperty() + { + var dateTimeOffset = new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(3)); + var json = JsonConvert.SerializeObject( + new ObjectWithDateTimeOffset + { + DateTimeOffset = dateTimeOffset + }); - var o = JObject.Parse(json); - o.Property("DateTimeOffset").Value = dateTimeOffset; - } + var o = JObject.Parse(json); + o.Property("DateTimeOffset").Value = dateTimeOffset; + } - public void ParseAndConvertDateTimeOffset() - { - var json = @"{ d: ""\/Date(0+0100)\/"" }"; + public void ParseAndConvertDateTimeOffset() + { + var json = @"{ d: ""\/Date(0+0100)\/"" }"; - using (var stringReader = new StringReader(json)) - using (var jsonReader = new JsonTextReader(stringReader)) - { - jsonReader.DateParseHandling = DateParseHandling.DateTimeOffset; + using (var stringReader = new StringReader(json)) + using (var jsonReader = new JsonTextReader(stringReader)) + { + jsonReader.DateParseHandling = DateParseHandling.DateTimeOffset; - var obj = JObject.Load(jsonReader); - var d = (JValue)obj["d"]; + var obj = JObject.Load(jsonReader); + var d = (JValue)obj["d"]; - CustomAssert.IsInstanceOfType(typeof(DateTimeOffset), d.Value); - TimeSpan offset = ((DateTimeOffset)d.Value).Offset; - Assert.AreEqual(TimeSpan.FromHours(1), offset); + CustomAssert.IsInstanceOfType(typeof(DateTimeOffset), d.Value); + TimeSpan offset = ((DateTimeOffset)d.Value).Offset; + Assert.AreEqual(TimeSpan.FromHours(1), offset); - DateTimeOffset dateTimeOffset = (DateTimeOffset) d; - Assert.AreEqual(TimeSpan.FromHours(1), dateTimeOffset.Offset); - } - } + DateTimeOffset dateTimeOffset = (DateTimeOffset)d; + Assert.AreEqual(TimeSpan.FromHours(1), dateTimeOffset.Offset); + } + } - public void ReadDatesAsDateTimeOffsetViaJsonConvert() - { - var content = @"{""startDateTime"":""2012-07-19T14:30:00+09:30""}"; + public void ReadDatesAsDateTimeOffsetViaJsonConvert() + { + var content = @"{""startDateTime"":""2012-07-19T14:30:00+09:30""}"; - var jsonSerializerSettings = new JsonSerializerSettings() { DateFormatHandling = DateFormatHandling.IsoDateFormat, DateParseHandling = DateParseHandling.DateTimeOffset, DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind }; - JObject obj = (JObject)JsonConvert.DeserializeObject(content, jsonSerializerSettings); + var jsonSerializerSettings = new JsonSerializerSettings() { DateFormatHandling = DateFormatHandling.IsoDateFormat, DateParseHandling = DateParseHandling.DateTimeOffset, DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind }; + JObject obj = (JObject)JsonConvert.DeserializeObject(content, jsonSerializerSettings); - object startDateTime = obj["startDateTime"]; + object startDateTime = obj["startDateTime"]; - CustomAssert.IsInstanceOfType(typeof(DateTimeOffset), startDateTime); - } + CustomAssert.IsInstanceOfType(typeof(DateTimeOffset), startDateTime); + } #endif #if !(NETFX_CORE || PORTABLE) - [Test] - public void ConvertsToBoolean() - { - Assert.AreEqual(true, Convert.ToBoolean(new JValue(true))); - } + [Test] + public void ConvertsToBoolean() + { + Assert.AreEqual(true, Convert.ToBoolean(new JValue(true))); + } - [Test] - public void ConvertsToBoolean_String() - { - Assert.AreEqual(true, Convert.ToBoolean(new JValue("true"))); - } + [Test] + public void ConvertsToBoolean_String() + { + Assert.AreEqual(true, Convert.ToBoolean(new JValue("true"))); + } - [Test] - public void ConvertsToInt32() - { - Assert.AreEqual(Int32.MaxValue, Convert.ToInt32(new JValue(Int32.MaxValue))); - } + [Test] + public void ConvertsToInt32() + { + Assert.AreEqual(Int32.MaxValue, Convert.ToInt32(new JValue(Int32.MaxValue))); + } #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE || PORTABLE40) - [Test] - public void ConvertsToInt32_BigInteger() - { - Assert.AreEqual(123, Convert.ToInt32(new JValue(BigInteger.Parse("123")))); - } + [Test] + public void ConvertsToInt32_BigInteger() + { + Assert.AreEqual(123, Convert.ToInt32(new JValue(BigInteger.Parse("123")))); + } #endif - [Test] - public void ConvertsToChar() - { - Assert.AreEqual('c', Convert.ToChar(new JValue('c'))); - } + [Test] + public void ConvertsToChar() + { + Assert.AreEqual('c', Convert.ToChar(new JValue('c'))); + } - [Test] - public void ConvertsToSByte() - { - Assert.AreEqual(SByte.MaxValue, Convert.ToSByte(new JValue(SByte.MaxValue))); - } + [Test] + public void ConvertsToSByte() + { + Assert.AreEqual(SByte.MaxValue, Convert.ToSByte(new JValue(SByte.MaxValue))); + } - [Test] - public void ConvertsToByte() - { - Assert.AreEqual(Byte.MaxValue, Convert.ToByte(new JValue(Byte.MaxValue))); - } + [Test] + public void ConvertsToByte() + { + Assert.AreEqual(Byte.MaxValue, Convert.ToByte(new JValue(Byte.MaxValue))); + } - [Test] - public void ConvertsToInt16() - { - Assert.AreEqual(Int16.MaxValue, Convert.ToInt16(new JValue(Int16.MaxValue))); - } + [Test] + public void ConvertsToInt16() + { + Assert.AreEqual(Int16.MaxValue, Convert.ToInt16(new JValue(Int16.MaxValue))); + } - [Test] - public void ConvertsToUInt16() - { - Assert.AreEqual(UInt16.MaxValue, Convert.ToUInt16(new JValue(UInt16.MaxValue))); - } + [Test] + public void ConvertsToUInt16() + { + Assert.AreEqual(UInt16.MaxValue, Convert.ToUInt16(new JValue(UInt16.MaxValue))); + } - [Test] - public void ConvertsToUInt32() - { - Assert.AreEqual(UInt32.MaxValue, Convert.ToUInt32(new JValue(UInt32.MaxValue))); - } + [Test] + public void ConvertsToUInt32() + { + Assert.AreEqual(UInt32.MaxValue, Convert.ToUInt32(new JValue(UInt32.MaxValue))); + } - [Test] - public void ConvertsToInt64() - { - Assert.AreEqual(Int64.MaxValue, Convert.ToInt64(new JValue(Int64.MaxValue))); - } + [Test] + public void ConvertsToInt64() + { + Assert.AreEqual(Int64.MaxValue, Convert.ToInt64(new JValue(Int64.MaxValue))); + } - [Test] - public void ConvertsToUInt64() - { - Assert.AreEqual(UInt64.MaxValue, Convert.ToUInt64(new JValue(UInt64.MaxValue))); - } + [Test] + public void ConvertsToUInt64() + { + Assert.AreEqual(UInt64.MaxValue, Convert.ToUInt64(new JValue(UInt64.MaxValue))); + } - [Test] - public void ConvertsToSingle() - { - Assert.AreEqual(Single.MaxValue, Convert.ToSingle(new JValue(Single.MaxValue))); - } + [Test] + public void ConvertsToSingle() + { + Assert.AreEqual(Single.MaxValue, Convert.ToSingle(new JValue(Single.MaxValue))); + } - [Test] - public void ConvertsToDouble() - { - Assert.AreEqual(Double.MaxValue, Convert.ToDouble(new JValue(Double.MaxValue))); - } + [Test] + public void ConvertsToDouble() + { + Assert.AreEqual(Double.MaxValue, Convert.ToDouble(new JValue(Double.MaxValue))); + } - [Test] - public void ConvertsToDecimal() - { - Assert.AreEqual(Decimal.MaxValue, Convert.ToDecimal(new JValue(Decimal.MaxValue))); - } + [Test] + public void ConvertsToDecimal() + { + Assert.AreEqual(Decimal.MaxValue, Convert.ToDecimal(new JValue(Decimal.MaxValue))); + } - [Test] - public void ConvertsToDecimal_Int64() - { - Assert.AreEqual(123, Convert.ToDecimal(new JValue(123))); - } + [Test] + public void ConvertsToDecimal_Int64() + { + Assert.AreEqual(123, Convert.ToDecimal(new JValue(123))); + } - [Test] - public void ConvertsToString_Decimal() - { - Assert.AreEqual("79228162514264337593543950335", Convert.ToString(new JValue(Decimal.MaxValue))); - } + [Test] + public void ConvertsToString_Decimal() + { + Assert.AreEqual("79228162514264337593543950335", Convert.ToString(new JValue(Decimal.MaxValue))); + } - [Test] - public void ConvertsToString_Uri() - { - Assert.AreEqual("http://www.google.com/", Convert.ToString(new JValue(new Uri("http://www.google.com")))); - } + [Test] + public void ConvertsToString_Uri() + { + Assert.AreEqual("http://www.google.com/", Convert.ToString(new JValue(new Uri("http://www.google.com")))); + } - [Test] - public void ConvertsToString_Null() - { - Assert.AreEqual(string.Empty, Convert.ToString(new JValue((object)null))); - } + [Test] + public void ConvertsToString_Null() + { + Assert.AreEqual(string.Empty, Convert.ToString(new JValue((object)null))); + } - [Test] - public void ConvertsToString_Guid() - { - Guid g = new Guid("0B5D4F85-E94C-4143-94C8-35F2AAEBB100"); + [Test] + public void ConvertsToString_Guid() + { + Guid g = new Guid("0B5D4F85-E94C-4143-94C8-35F2AAEBB100"); - Assert.AreEqual("0b5d4f85-e94c-4143-94c8-35f2aaebb100", Convert.ToString(new JValue(g))); - } + Assert.AreEqual("0b5d4f85-e94c-4143-94c8-35f2aaebb100", Convert.ToString(new JValue(g))); + } - [Test] - public void ConvertsToType() - { - Assert.AreEqual(Int32.MaxValue, Convert.ChangeType(new JValue(Int32.MaxValue), typeof(Int32), CultureInfo.InvariantCulture)); - } + [Test] + public void ConvertsToType() + { + Assert.AreEqual(Int32.MaxValue, Convert.ChangeType(new JValue(Int32.MaxValue), typeof(Int32), CultureInfo.InvariantCulture)); + } - [Test] - public void ConvertsToDateTime() - { - Assert.AreEqual(new DateTime(2013, 02, 01, 01, 02, 03, 04), Convert.ToDateTime(new JValue(new DateTime(2013, 02, 01, 01, 02, 03, 04)))); - } + [Test] + public void ConvertsToDateTime() + { + Assert.AreEqual(new DateTime(2013, 02, 01, 01, 02, 03, 04), Convert.ToDateTime(new JValue(new DateTime(2013, 02, 01, 01, 02, 03, 04)))); + } #if !NET20 - [Test] - public void ConvertsToDateTime_DateTimeOffset() - { - var offset = new DateTimeOffset(2013, 02, 01, 01, 02, 03, 04, TimeSpan.Zero); + [Test] + public void ConvertsToDateTime_DateTimeOffset() + { + var offset = new DateTimeOffset(2013, 02, 01, 01, 02, 03, 04, TimeSpan.Zero); - Assert.AreEqual(new DateTime(2013, 02, 01, 01, 02, 03, 04), Convert.ToDateTime(new JValue(offset))); - } + Assert.AreEqual(new DateTime(2013, 02, 01, 01, 02, 03, 04), Convert.ToDateTime(new JValue(offset))); + } #endif - [Test] - public void GetTypeCode() - { - IConvertible v = new JValue(new Guid("0B5D4F85-E94C-4143-94C8-35F2AAEBB100")); - Assert.AreEqual(TypeCode.Object, v.GetTypeCode()); + [Test] + public void GetTypeCode() + { + IConvertible v = new JValue(new Guid("0B5D4F85-E94C-4143-94C8-35F2AAEBB100")); + Assert.AreEqual(TypeCode.Object, v.GetTypeCode()); - v = new JValue(new Uri("http://www.google.com")); - Assert.AreEqual(TypeCode.Object, v.GetTypeCode()); + v = new JValue(new Uri("http://www.google.com")); + Assert.AreEqual(TypeCode.Object, v.GetTypeCode()); #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE || PORTABLE40) - v = new JValue(new BigInteger(3)); - Assert.AreEqual(TypeCode.Object, v.GetTypeCode()); + v = new JValue(new BigInteger(3)); + Assert.AreEqual(TypeCode.Object, v.GetTypeCode()); #endif - } + } - [Test] - public void ToType() - { - IConvertible v = new JValue(9.0m); + [Test] + public void ToType() + { + IConvertible v = new JValue(9.0m); - int i = (int)v.ToType(typeof (int), CultureInfo.InvariantCulture); - Assert.AreEqual(9, i); + int i = (int)v.ToType(typeof(int), CultureInfo.InvariantCulture); + Assert.AreEqual(9, i); #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE) - BigInteger bi = (BigInteger)v.ToType(typeof(BigInteger), CultureInfo.InvariantCulture); - Assert.AreEqual(new BigInteger(9), bi); + BigInteger bi = (BigInteger)v.ToType(typeof(BigInteger), CultureInfo.InvariantCulture); + Assert.AreEqual(new BigInteger(9), bi); #endif - } + } #endif - [Test] - public void ToStringFormat() - { - JValue v = new JValue(new DateTime(2013, 02, 01, 01, 02, 03, 04)); + [Test] + public void ToStringFormat() + { + JValue v = new JValue(new DateTime(2013, 02, 01, 01, 02, 03, 04)); - Assert.AreEqual("2013", v.ToString("yyyy")); - } + Assert.AreEqual("2013", v.ToString("yyyy")); + } #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE || PORTABLE40) - [Test] - public void ToStringNewTypes() - { - JArray a = new JArray( - new JValue(new DateTimeOffset(2013, 02, 01, 01, 02, 03, 04, TimeSpan.FromHours(1))), - new JValue(new BigInteger(5)), - new JValue(1.1f) - ); + [Test] + public void ToStringNewTypes() + { + JArray a = new JArray( + new JValue(new DateTimeOffset(2013, 02, 01, 01, 02, 03, 04, TimeSpan.FromHours(1))), + new JValue(new BigInteger(5)), + new JValue(1.1f) + ); - Assert.AreEqual(@"[ + Assert.AreEqual(@"[ ""2013-02-01T01:02:03.004+01:00"", 5, 1.1 ]", a.ToString()); - } + } #endif #if !NET20 - [Test] - public void ParseIsoTimeZones() - { - DateTimeOffset expectedDate = new DateTimeOffset(2013, 08, 14, 4, 38, 31, TimeSpan.FromHours(12).Add(TimeSpan.FromMinutes(30))); - JsonTextReader reader = new JsonTextReader(new StringReader("'2013-08-14T04:38:31.000+1230'")); - reader.DateParseHandling = DateParseHandling.DateTimeOffset; - JValue date = (JValue)JToken.ReadFrom(reader); - Assert.AreEqual(expectedDate, date.Value); + [Test] + public void ParseIsoTimeZones() + { + DateTimeOffset expectedDate = new DateTimeOffset(2013, 08, 14, 4, 38, 31, TimeSpan.FromHours(12).Add(TimeSpan.FromMinutes(30))); + JsonTextReader reader = new JsonTextReader(new StringReader("'2013-08-14T04:38:31.000+1230'")); + reader.DateParseHandling = DateParseHandling.DateTimeOffset; + JValue date = (JValue)JToken.ReadFrom(reader); + Assert.AreEqual(expectedDate, date.Value); - DateTimeOffset expectedDate2 = new DateTimeOffset(2013, 08, 14, 4, 38, 31, TimeSpan.FromHours(12)); - JsonTextReader reader2 = new JsonTextReader(new StringReader("'2013-08-14T04:38:31.000+12'")); - reader2.DateParseHandling = DateParseHandling.DateTimeOffset; - JValue date2 = (JValue)JToken.ReadFrom(reader2); - Assert.AreEqual(expectedDate2, date2.Value); - } + DateTimeOffset expectedDate2 = new DateTimeOffset(2013, 08, 14, 4, 38, 31, TimeSpan.FromHours(12)); + JsonTextReader reader2 = new JsonTextReader(new StringReader("'2013-08-14T04:38:31.000+12'")); + reader2.DateParseHandling = DateParseHandling.DateTimeOffset; + JValue date2 = (JValue)JToken.ReadFrom(reader2); + Assert.AreEqual(expectedDate2, date2.Value); + } #endif - } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Linq/LinqToJsonTest.cs b/Src/Newtonsoft.Json.Tests/Linq/LinqToJsonTest.cs index 71b7bed4..2402de04 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/LinqToJsonTest.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/LinqToJsonTest.cs @@ -46,68 +46,68 @@ using System.IO; namespace Newtonsoft.Json.Tests.Linq { - [TestFixture] - public class LinqToJsonTest : TestFixtureBase - { - [Test] - public void ForEach() + [TestFixture] + public class LinqToJsonTest : TestFixtureBase { - JArray items = new JArray(new JObject(new JProperty("name", "value!"))); + [Test] + public void ForEach() + { + JArray items = new JArray(new JObject(new JProperty("name", "value!"))); - foreach (JObject friend in items) - { - Console.WriteLine(friend); - } - } + foreach (JObject friend in items) + { + Console.WriteLine(friend); + } + } - [Test] - public void DoubleValue() - { - JArray j = JArray.Parse("[-1E+4,100.0e-2]"); + [Test] + public void DoubleValue() + { + JArray j = JArray.Parse("[-1E+4,100.0e-2]"); - double value = (double)j[0]; - Assert.AreEqual(-10000d, value); + double value = (double)j[0]; + Assert.AreEqual(-10000d, value); - value = (double)j[1]; - Assert.AreEqual(1d, value); - } + value = (double)j[1]; + Assert.AreEqual(1d, value); + } - [Test] - public void Manual() - { - JArray array = new JArray(); - JValue text = new JValue("Manual text"); - JValue date = new JValue(new DateTime(2000, 5, 23)); + [Test] + public void Manual() + { + JArray array = new JArray(); + JValue text = new JValue("Manual text"); + JValue date = new JValue(new DateTime(2000, 5, 23)); - array.Add(text); - array.Add(date); + array.Add(text); + array.Add(date); - string json = array.ToString(); - // [ - // "Manual text", - // "\/Date(958996800000+1200)\/" - // ] - } + string json = array.ToString(); + // [ + // "Manual text", + // "\/Date(958996800000+1200)\/" + // ] + } - [Test] - public void LinqToJsonDeserialize() - { - JObject o = new JObject( - new JProperty("Name", "John Smith"), - new JProperty("BirthDate", new DateTime(1983, 3, 20)) - ); + [Test] + public void LinqToJsonDeserialize() + { + JObject o = new JObject( + new JProperty("Name", "John Smith"), + new JProperty("BirthDate", new DateTime(1983, 3, 20)) + ); - JsonSerializer serializer = new JsonSerializer(); - Person p = (Person)serializer.Deserialize(new JTokenReader(o), typeof(Person)); + JsonSerializer serializer = new JsonSerializer(); + Person p = (Person)serializer.Deserialize(new JTokenReader(o), typeof(Person)); - // John Smith - Console.WriteLine(p.Name); - } + // John Smith + Console.WriteLine(p.Name); + } - [Test] - public void ObjectParse() - { - string json = @"{ + [Test] + public void ObjectParse() + { + string json = @"{ CPU: 'Intel', Drives: [ 'DVD read/writer', @@ -115,45 +115,45 @@ namespace Newtonsoft.Json.Tests.Linq ] }"; - JObject o = JObject.Parse(json); - IList properties = o.Properties().ToList(); + JObject o = JObject.Parse(json); + IList properties = o.Properties().ToList(); - Assert.AreEqual("CPU", properties[0].Name); - Assert.AreEqual("Intel", (string)properties[0].Value); - Assert.AreEqual("Drives", properties[1].Name); + Assert.AreEqual("CPU", properties[0].Name); + Assert.AreEqual("Intel", (string)properties[0].Value); + Assert.AreEqual("Drives", properties[1].Name); - JArray list = (JArray)properties[1].Value; - Assert.AreEqual(2, list.Children().Count()); - Assert.AreEqual("DVD read/writer", (string)list.Children().ElementAt(0)); - Assert.AreEqual("500 gigabyte hard drive", (string)list.Children().ElementAt(1)); + JArray list = (JArray)properties[1].Value; + Assert.AreEqual(2, list.Children().Count()); + Assert.AreEqual("DVD read/writer", (string)list.Children().ElementAt(0)); + Assert.AreEqual("500 gigabyte hard drive", (string)list.Children().ElementAt(1)); - List parameterValues = - (from p in o.Properties() - where p.Value is JValue - select ((JValue)p.Value).Value).ToList(); + List parameterValues = + (from p in o.Properties() + where p.Value is JValue + select ((JValue)p.Value).Value).ToList(); - Assert.AreEqual(1, parameterValues.Count); - Assert.AreEqual("Intel", parameterValues[0]); - } + Assert.AreEqual(1, parameterValues.Count); + Assert.AreEqual("Intel", parameterValues[0]); + } - [Test] - public void CreateLongArray() - { - string json = @"[0,1,2,3,4,5,6,7,8,9]"; + [Test] + public void CreateLongArray() + { + string json = @"[0,1,2,3,4,5,6,7,8,9]"; - JArray a = JArray.Parse(json); - List list = a.Values().ToList(); + JArray a = JArray.Parse(json); + List list = a.Values().ToList(); - List expected = new List() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + List expected = new List() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - CollectionAssert.AreEqual(expected, list); - } + CollectionAssert.AreEqual(expected, list); + } - [Test] - public void GoogleSearchAPI() - { - #region GoogleJson - string json = @"{ + [Test] + public void GoogleSearchAPI() + { + #region GoogleJson + string json = @"{ results: [ { @@ -231,34 +231,34 @@ keyword such as type of business."" ] } "; - #endregion + #endregion - JObject o = JObject.Parse(json); + JObject o = JObject.Parse(json); - List resultObjects = o["results"].Children().ToList(); + List resultObjects = o["results"].Children().ToList(); - Assert.AreEqual(32, resultObjects.Properties().Count()); + Assert.AreEqual(32, resultObjects.Properties().Count()); - Assert.AreEqual(32, resultObjects.Cast().Values().Count()); + Assert.AreEqual(32, resultObjects.Cast().Values().Count()); - Assert.AreEqual(4, resultObjects.Cast().Values("GsearchResultClass").Count()); + Assert.AreEqual(4, resultObjects.Cast().Values("GsearchResultClass").Count()); - Assert.AreEqual(5, o.PropertyValues().Cast().Children().Count()); + Assert.AreEqual(5, o.PropertyValues().Cast().Children().Count()); - List resultUrls = o["results"].Children().Values("url").ToList(); + List resultUrls = o["results"].Children().Values("url").ToList(); - List expectedUrls = new List() { "http://www.google.com/", "http://news.google.com/", "http://groups.google.com/", "http://maps.google.com/" }; + List expectedUrls = new List() { "http://www.google.com/", "http://news.google.com/", "http://groups.google.com/", "http://maps.google.com/" }; - CollectionAssert.AreEqual(expectedUrls, resultUrls); + CollectionAssert.AreEqual(expectedUrls, resultUrls); - List descendants = o.Descendants().ToList(); - Assert.AreEqual(89, descendants.Count); - } + List descendants = o.Descendants().ToList(); + Assert.AreEqual(89, descendants.Count); + } - [Test] - public void JTokenToString() - { - string json = @"{ + [Test] + public void JTokenToString() + { + string json = @"{ CPU: 'Intel', Drives: [ 'DVD read/writer', @@ -266,9 +266,9 @@ keyword such as type of business."" ] }"; - JObject o = JObject.Parse(json); + JObject o = JObject.Parse(json); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""CPU"": ""Intel"", ""Drives"": [ ""DVD read/writer"", @@ -276,93 +276,93 @@ keyword such as type of business."" ] }", o.ToString()); - JArray list = o.Value("Drives"); + JArray list = o.Value("Drives"); - Assert.AreEqual(@"[ + Assert.AreEqual(@"[ ""DVD read/writer"", ""500 gigabyte hard drive"" ]", list.ToString()); - JProperty cpuProperty = o.Property("CPU"); - Assert.AreEqual(@"""CPU"": ""Intel""", cpuProperty.ToString()); + JProperty cpuProperty = o.Property("CPU"); + Assert.AreEqual(@"""CPU"": ""Intel""", cpuProperty.ToString()); - JProperty drivesProperty = o.Property("Drives"); - Assert.AreEqual(@"""Drives"": [ + JProperty drivesProperty = o.Property("Drives"); + Assert.AreEqual(@"""Drives"": [ ""DVD read/writer"", ""500 gigabyte hard drive"" ]", drivesProperty.ToString()); - } + } - [Test] - public void JTokenToStringTypes() - { - string json = @"{""Color"":2,""Establised"":new Date(1264118400000),""Width"":1.1,""Employees"":999,""RoomsPerFloor"":[1,2,3,4,5,6,7,8,9],""Open"":false,""Symbol"":""@"",""Mottos"":[""Hello World"",""öäüÖÄÜ\\'{new Date(12345);}[222]_µ@²³~"",null,"" ""],""Cost"":100980.1,""Escape"":""\r\n\t\f\b?{\\r\\n\""'"",""product"":[{""Name"":""Rocket"",""ExpiryDate"":new Date(949532490000),""Price"":0},{""Name"":""Alien"",""ExpiryDate"":new Date(-62135596800000),""Price"":0}]}"; + [Test] + public void JTokenToStringTypes() + { + string json = @"{""Color"":2,""Establised"":new Date(1264118400000),""Width"":1.1,""Employees"":999,""RoomsPerFloor"":[1,2,3,4,5,6,7,8,9],""Open"":false,""Symbol"":""@"",""Mottos"":[""Hello World"",""öäüÖÄÜ\\'{new Date(12345);}[222]_µ@²³~"",null,"" ""],""Cost"":100980.1,""Escape"":""\r\n\t\f\b?{\\r\\n\""'"",""product"":[{""Name"":""Rocket"",""ExpiryDate"":new Date(949532490000),""Price"":0},{""Name"":""Alien"",""ExpiryDate"":new Date(-62135596800000),""Price"":0}]}"; - JObject o = JObject.Parse(json); + JObject o = JObject.Parse(json); - Assert.AreEqual(@"""Establised"": new Date( + Assert.AreEqual(@"""Establised"": new Date( 1264118400000 )", o.Property("Establised").ToString()); - Assert.AreEqual(@"new Date( + Assert.AreEqual(@"new Date( 1264118400000 )", o.Property("Establised").Value.ToString()); - Assert.AreEqual(@"""Width"": 1.1", o.Property("Width").ToString()); - Assert.AreEqual(@"1.1", ((JValue)o.Property("Width").Value).ToString(CultureInfo.InvariantCulture)); - Assert.AreEqual(@"""Open"": false", o.Property("Open").ToString()); - Assert.AreEqual(@"False", o.Property("Open").Value.ToString()); + Assert.AreEqual(@"""Width"": 1.1", o.Property("Width").ToString()); + Assert.AreEqual(@"1.1", ((JValue)o.Property("Width").Value).ToString(CultureInfo.InvariantCulture)); + Assert.AreEqual(@"""Open"": false", o.Property("Open").ToString()); + Assert.AreEqual(@"False", o.Property("Open").Value.ToString()); - json = @"[null,undefined]"; + json = @"[null,undefined]"; - JArray a = JArray.Parse(json); - Assert.AreEqual(@"[ + JArray a = JArray.Parse(json); + Assert.AreEqual(@"[ null, undefined ]", a.ToString()); - Assert.AreEqual(@"", a.Children().ElementAt(0).ToString()); - Assert.AreEqual(@"", a.Children().ElementAt(1).ToString()); - } + Assert.AreEqual(@"", a.Children().ElementAt(0).ToString()); + Assert.AreEqual(@"", a.Children().ElementAt(1).ToString()); + } - [Test] - public void CreateJTokenTree() - { - JObject o = - new JObject( - new JProperty("Test1", "Test1Value"), - new JProperty("Test2", "Test2Value"), - new JProperty("Test3", "Test3Value"), - new JProperty("Test4", null) - ); + [Test] + public void CreateJTokenTree() + { + JObject o = + new JObject( + new JProperty("Test1", "Test1Value"), + new JProperty("Test2", "Test2Value"), + new JProperty("Test3", "Test3Value"), + new JProperty("Test4", null) + ); - Assert.AreEqual(4, o.Properties().Count()); + Assert.AreEqual(4, o.Properties().Count()); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Test1"": ""Test1Value"", ""Test2"": ""Test2Value"", ""Test3"": ""Test3Value"", ""Test4"": null }", o.ToString()); - JArray a = - new JArray( - o, - new DateTime(2000, 10, 10, 0, 0, 0, DateTimeKind.Utc), - 55, - new JArray( - "1", - 2, - 3.0, - new DateTime(4, 5, 6, 7, 8, 9, DateTimeKind.Utc) - ), - new JConstructor( - "ConstructorName", - "param1", - 2, - 3.0 - ) - ); + JArray a = + new JArray( + o, + new DateTime(2000, 10, 10, 0, 0, 0, DateTimeKind.Utc), + 55, + new JArray( + "1", + 2, + 3.0, + new DateTime(4, 5, 6, 7, 8, 9, DateTimeKind.Utc) + ), + new JConstructor( + "ConstructorName", + "param1", + 2, + 3.0 + ) + ); - Assert.AreEqual(5, a.Count()); - Assert.AreEqual(@"[ + Assert.AreEqual(5, a.Count()); + Assert.AreEqual(@"[ { ""Test1"": ""Test1Value"", ""Test2"": ""Test2Value"", @@ -383,124 +383,125 @@ keyword such as type of business."" 3.0 ) ]", a.ToString()); - } - - private class Post - { - public string Title { get; set; } - public string Description { get; set; } - public string Link { get; set; } - public IList Categories { get; set; } - } - - private List GetPosts() - { - return new List() - { - new Post() - { - Title = "LINQ to JSON beta", - Description = "Annoucing LINQ to JSON", - Link = "http://james.newtonking.com/projects/json-net.aspx", - Categories = new List() { "Json.NET", "LINQ" } - }, - new Post() - { - Title = "Json.NET 1.3 + New license + Now on CodePlex", - Description = "Annoucing the release of Json.NET 1.3, the MIT license and being available on CodePlex", - Link = "http://james.newtonking.com/projects/json-net.aspx", - Categories = new List() { "Json.NET", "CodePlex" } } - }; - } - [Test] - public void CreateJTokenTreeNested() - { - List posts = GetPosts(); + private class Post + { + public string Title { get; set; } + public string Description { get; set; } + public string Link { get; set; } + public IList Categories { get; set; } + } - JObject rss = - new JObject( - new JProperty("channel", - new JObject( - new JProperty("title", "James Newton-King"), - new JProperty("link", "http://james.newtonking.com"), - new JProperty("description", "James Newton-King's blog."), - new JProperty("item", - new JArray( - from p in posts - orderby p.Title - select new JObject( - new JProperty("title", p.Title), - new JProperty("description", p.Description), - new JProperty("link", p.Link), - new JProperty("category", - new JArray( - from c in p.Categories - select new JValue(c))))))))); + private List GetPosts() + { + return new List() + { + new Post() + { + Title = "LINQ to JSON beta", + Description = "Annoucing LINQ to JSON", + Link = "http://james.newtonking.com/projects/json-net.aspx", + Categories = new List() { "Json.NET", "LINQ" } + }, + new Post() + { + Title = "Json.NET 1.3 + New license + Now on CodePlex", + Description = "Annoucing the release of Json.NET 1.3, the MIT license and being available on CodePlex", + Link = "http://james.newtonking.com/projects/json-net.aspx", + Categories = new List() { "Json.NET", "CodePlex" } + } + }; + } - Console.WriteLine(rss.ToString()); + [Test] + public void CreateJTokenTreeNested() + { + List posts = GetPosts(); - //{ - // "channel": { - // "title": "James Newton-King", - // "link": "http://james.newtonking.com", - // "description": "James Newton-King's blog.", - // "item": [ - // { - // "title": "Json.NET 1.3 + New license + Now on CodePlex", - // "description": "Annoucing the release of Json.NET 1.3, the MIT license and being available on CodePlex", - // "link": "http://james.newtonking.com/projects/json-net.aspx", - // "category": [ - // "Json.NET", - // "CodePlex" - // ] - // }, - // { - // "title": "LINQ to JSON beta", - // "description": "Annoucing LINQ to JSON", - // "link": "http://james.newtonking.com/projects/json-net.aspx", - // "category": [ - // "Json.NET", - // "LINQ" - // ] - // } - // ] - // } - //} + JObject rss = + new JObject( + new JProperty("channel", + new JObject( + new JProperty("title", "James Newton-King"), + new JProperty("link", "http://james.newtonking.com"), + new JProperty("description", "James Newton-King's blog."), + new JProperty("item", + new JArray( + from p in posts + orderby p.Title + select new JObject( + new JProperty("title", p.Title), + new JProperty("description", p.Description), + new JProperty("link", p.Link), + new JProperty("category", + new JArray( + from c in p.Categories + select new JValue(c))))))))); - var postTitles = - from p in rss["channel"]["item"] - select p.Value("title"); + Console.WriteLine(rss.ToString()); - foreach (var item in postTitles) - { - Console.WriteLine(item); - } + //{ + // "channel": { + // "title": "James Newton-King", + // "link": "http://james.newtonking.com", + // "description": "James Newton-King's blog.", + // "item": [ + // { + // "title": "Json.NET 1.3 + New license + Now on CodePlex", + // "description": "Annoucing the release of Json.NET 1.3, the MIT license and being available on CodePlex", + // "link": "http://james.newtonking.com/projects/json-net.aspx", + // "category": [ + // "Json.NET", + // "CodePlex" + // ] + // }, + // { + // "title": "LINQ to JSON beta", + // "description": "Annoucing LINQ to JSON", + // "link": "http://james.newtonking.com/projects/json-net.aspx", + // "category": [ + // "Json.NET", + // "LINQ" + // ] + // } + // ] + // } + //} - //LINQ to JSON beta - //Json.NET 1.3 + New license + Now on CodePlex + var postTitles = + from p in rss["channel"]["item"] + select p.Value("title"); - var categories = - from c in rss["channel"]["item"].Children()["category"].Values() - group c by c into g - orderby g.Count() descending - select new { Category = g.Key, Count = g.Count() }; + foreach (var item in postTitles) + { + Console.WriteLine(item); + } - foreach (var c in categories) - { - Console.WriteLine(c.Category + " - Count: " + c.Count); - } + //LINQ to JSON beta + //Json.NET 1.3 + New license + Now on CodePlex - //Json.NET - Count: 2 - //LINQ - Count: 1 - //CodePlex - Count: 1 - } + var categories = + from c in rss["channel"]["item"].Children()["category"].Values() + group c by c + into g + orderby g.Count() descending + select new { Category = g.Key, Count = g.Count() }; - [Test] - public void BasicQuerying() - { - string json = @"{ + foreach (var c in categories) + { + Console.WriteLine(c.Category + " - Count: " + c.Count); + } + + //Json.NET - Count: 2 + //LINQ - Count: 1 + //CodePlex - Count: 1 + } + + [Test] + public void BasicQuerying() + { + string json = @"{ ""channel"": { ""title"": ""James Newton-King"", ""link"": ""http://james.newtonking.com"", @@ -528,76 +529,76 @@ keyword such as type of business."" } }"; - JObject o = JObject.Parse(json); + JObject o = JObject.Parse(json); - Assert.AreEqual(null, o["purple"]); - Assert.AreEqual(null, o.Value("purple")); + Assert.AreEqual(null, o["purple"]); + Assert.AreEqual(null, o.Value("purple")); - CustomAssert.IsInstanceOfType(typeof(JArray), o["channel"]["item"]); + CustomAssert.IsInstanceOfType(typeof(JArray), o["channel"]["item"]); - Assert.AreEqual(2, o["channel"]["item"].Children()["title"].Count()); - Assert.AreEqual(0, o["channel"]["item"].Children()["monkey"].Count()); + Assert.AreEqual(2, o["channel"]["item"].Children()["title"].Count()); + Assert.AreEqual(0, o["channel"]["item"].Children()["monkey"].Count()); - Assert.AreEqual("Json.NET 1.3 + New license + Now on CodePlex", (string)o["channel"]["item"][0]["title"]); + Assert.AreEqual("Json.NET 1.3 + New license + Now on CodePlex", (string)o["channel"]["item"][0]["title"]); - CollectionAssert.AreEqual(new string[] { "Json.NET 1.3 + New license + Now on CodePlex", "LINQ to JSON beta" }, o["channel"]["item"].Children().Values("title").ToArray()); - } + CollectionAssert.AreEqual(new string[] { "Json.NET 1.3 + New license + Now on CodePlex", "LINQ to JSON beta" }, o["channel"]["item"].Children().Values("title").ToArray()); + } - [Test] - public void JObjectIntIndex() - { - ExceptionAssert.Throws("Accessed JObject values with invalid key value: 0. Object property name expected.", - () => - { - JObject o = new JObject(); - Assert.AreEqual(null, o[0]); - }); - } + [Test] + public void JObjectIntIndex() + { + ExceptionAssert.Throws("Accessed JObject values with invalid key value: 0. Object property name expected.", + () => + { + JObject o = new JObject(); + Assert.AreEqual(null, o[0]); + }); + } - [Test] - public void JArrayStringIndex() - { - ExceptionAssert.Throws(@"Accessed JArray values with invalid key value: ""purple"". Array position index expected.", - () => - { - JArray a = new JArray(); - Assert.AreEqual(null, a["purple"]); - }); - } + [Test] + public void JArrayStringIndex() + { + ExceptionAssert.Throws(@"Accessed JArray values with invalid key value: ""purple"". Array position index expected.", + () => + { + JArray a = new JArray(); + Assert.AreEqual(null, a["purple"]); + }); + } - [Test] - public void JConstructorStringIndex() - { - ExceptionAssert.Throws(@"Accessed JConstructor values with invalid key value: ""purple"". Argument position index expected.", - () => - { - JConstructor c = new JConstructor("ConstructorValue"); - Assert.AreEqual(null, c["purple"]); - }); - } + [Test] + public void JConstructorStringIndex() + { + ExceptionAssert.Throws(@"Accessed JConstructor values with invalid key value: ""purple"". Argument position index expected.", + () => + { + JConstructor c = new JConstructor("ConstructorValue"); + Assert.AreEqual(null, c["purple"]); + }); + } #if !NET20 - [Test] - public void ToStringJsonConverter() - { - JObject o = - new JObject( - new JProperty("Test1", new DateTime(2000, 10, 15, 5, 5, 5, DateTimeKind.Utc)), - new JProperty("Test2", new DateTimeOffset(2000, 10, 15, 5, 5, 5, new TimeSpan(11, 11, 0))), - new JProperty("Test3", "Test3Value"), - new JProperty("Test4", null) - ); + [Test] + public void ToStringJsonConverter() + { + JObject o = + new JObject( + new JProperty("Test1", new DateTime(2000, 10, 15, 5, 5, 5, DateTimeKind.Utc)), + new JProperty("Test2", new DateTimeOffset(2000, 10, 15, 5, 5, 5, new TimeSpan(11, 11, 0))), + new JProperty("Test3", "Test3Value"), + new JProperty("Test4", null) + ); - JsonSerializer serializer = new JsonSerializer(); - serializer.Converters.Add(new JavaScriptDateTimeConverter()); - StringWriter sw = new StringWriter(); - JsonWriter writer = new JsonTextWriter(sw); - writer.Formatting = Formatting.Indented; - serializer.Serialize(writer, o); + JsonSerializer serializer = new JsonSerializer(); + serializer.Converters.Add(new JavaScriptDateTimeConverter()); + StringWriter sw = new StringWriter(); + JsonWriter writer = new JsonTextWriter(sw); + writer.Formatting = Formatting.Indented; + serializer.Serialize(writer, o); - string json = sw.ToString(); + string json = sw.ToString(); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Test1"": new Date( 971586305000 ), @@ -607,160 +608,162 @@ keyword such as type of business."" ""Test3"": ""Test3Value"", ""Test4"": null }", json); - } + } - [Test] - public void DateTimeOffset() - { - List testDates = new List { - new DateTimeOffset(new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Utc)), - new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero), - new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(13)), - new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(-3.5)), - }; + [Test] + public void DateTimeOffset() + { + List testDates = new List + { + new DateTimeOffset(new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Utc)), + new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero), + new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(13)), + new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(-3.5)), + }; - JsonSerializer jsonSerializer = new JsonSerializer(); + JsonSerializer jsonSerializer = new JsonSerializer(); - JTokenWriter jsonWriter; - using (jsonWriter = new JTokenWriter()) - { - jsonSerializer.Serialize(jsonWriter, testDates); - } + JTokenWriter jsonWriter; + using (jsonWriter = new JTokenWriter()) + { + jsonSerializer.Serialize(jsonWriter, testDates); + } - Assert.AreEqual(4, jsonWriter.Token.Children().Count()); - } + Assert.AreEqual(4, jsonWriter.Token.Children().Count()); + } #endif - [Test] - public void FromObject() - { - List posts = GetPosts(); - - JObject o = JObject.FromObject(new - { - channel = new + [Test] + public void FromObject() { - title = "James Newton-King", - link = "http://james.newtonking.com", - description = "James Newton-King's blog.", - item = - from p in posts - orderby p.Title - select new - { - title = p.Title, - description = p.Description, - link = p.Link, - category = p.Categories - } + List posts = GetPosts(); + + JObject o = JObject.FromObject(new + { + channel = new + { + title = "James Newton-King", + link = "http://james.newtonking.com", + description = "James Newton-King's blog.", + item = + from p in posts + orderby p.Title + select new + { + title = p.Title, + description = p.Description, + link = p.Link, + category = p.Categories + } + } + }); + + Console.WriteLine(o.ToString()); + CustomAssert.IsInstanceOfType(typeof(JObject), o); + CustomAssert.IsInstanceOfType(typeof(JObject), o["channel"]); + Assert.AreEqual("James Newton-King", (string)o["channel"]["title"]); + Assert.AreEqual(2, o["channel"]["item"].Children().Count()); + + JArray a = JArray.FromObject(new List() { 0, 1, 2, 3, 4 }); + CustomAssert.IsInstanceOfType(typeof(JArray), a); + Assert.AreEqual(5, a.Count()); } - }); - Console.WriteLine(o.ToString()); - CustomAssert.IsInstanceOfType(typeof(JObject), o); - CustomAssert.IsInstanceOfType(typeof(JObject), o["channel"]); - Assert.AreEqual("James Newton-King", (string)o["channel"]["title"]); - Assert.AreEqual(2, o["channel"]["item"].Children().Count()); - - JArray a = JArray.FromObject(new List() { 0, 1, 2, 3, 4 }); - CustomAssert.IsInstanceOfType(typeof(JArray), a); - Assert.AreEqual(5, a.Count()); - } - - [Test] - public void FromAnonDictionary() - { - List posts = GetPosts(); - - JObject o = JObject.FromObject(new - { - channel = new Dictionary + [Test] + public void FromAnonDictionary() { - { "title", "James Newton-King" }, - { "link", "http://james.newtonking.com" }, - { "description", "James Newton-King's blog." }, - { "item", - (from p in posts - orderby p.Title - select new - { - title = p.Title, - description = p.Description, - link = p.Link, - category = p.Categories - }) - } + List posts = GetPosts(); + + JObject o = JObject.FromObject(new + { + channel = new Dictionary + { + { "title", "James Newton-King" }, + { "link", "http://james.newtonking.com" }, + { "description", "James Newton-King's blog." }, + { + "item", + (from p in posts + orderby p.Title + select new + { + title = p.Title, + description = p.Description, + link = p.Link, + category = p.Categories + }) + } + } + }); + + Console.WriteLine(o.ToString()); + CustomAssert.IsInstanceOfType(typeof(JObject), o); + CustomAssert.IsInstanceOfType(typeof(JObject), o["channel"]); + Assert.AreEqual("James Newton-King", (string)o["channel"]["title"]); + Assert.AreEqual(2, o["channel"]["item"].Children().Count()); + + JArray a = JArray.FromObject(new List() { 0, 1, 2, 3, 4 }); + CustomAssert.IsInstanceOfType(typeof(JArray), a); + Assert.AreEqual(5, a.Count()); } - }); - Console.WriteLine(o.ToString()); - CustomAssert.IsInstanceOfType(typeof(JObject), o); - CustomAssert.IsInstanceOfType(typeof(JObject), o["channel"]); - Assert.AreEqual("James Newton-King", (string)o["channel"]["title"]); - Assert.AreEqual(2, o["channel"]["item"].Children().Count()); + [Test] + public void AsJEnumerable() + { + JObject o = null; + IJEnumerable enumerable = null; - JArray a = JArray.FromObject(new List() { 0, 1, 2, 3, 4 }); - CustomAssert.IsInstanceOfType(typeof(JArray), a); - Assert.AreEqual(5, a.Count()); - } + enumerable = o.AsJEnumerable(); + Assert.IsNull(enumerable); - [Test] - public void AsJEnumerable() - { - JObject o = null; - IJEnumerable enumerable = null; + o = + new JObject( + new JProperty("Test1", new DateTime(2000, 10, 15, 5, 5, 5, DateTimeKind.Utc)), + new JProperty("Test2", "Test2Value"), + new JProperty("Test3", null) + ); - enumerable = o.AsJEnumerable(); - Assert.IsNull(enumerable); - - o = - new JObject( - new JProperty("Test1", new DateTime(2000, 10, 15, 5, 5, 5, DateTimeKind.Utc)), - new JProperty("Test2", "Test2Value"), - new JProperty("Test3", null) - ); + enumerable = o.AsJEnumerable(); + Assert.IsNotNull(enumerable); + Assert.AreEqual(o, enumerable); - enumerable = o.AsJEnumerable(); - Assert.IsNotNull(enumerable); - Assert.AreEqual(o, enumerable); + DateTime d = enumerable["Test1"].Value(); - DateTime d = enumerable["Test1"].Value(); - - Assert.AreEqual(new DateTime(2000, 10, 15, 5, 5, 5, DateTimeKind.Utc), d); - } + Assert.AreEqual(new DateTime(2000, 10, 15, 5, 5, 5, DateTimeKind.Utc), d); + } #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40) - [Test] - public void CovariantIJEnumerable() - { - IEnumerable o = new[] + [Test] + public void CovariantIJEnumerable() { - JObject.FromObject(new {First = 1, Second = 2}), - JObject.FromObject(new {First = 1, Second = 2}) - }; + IEnumerable o = new[] + { + JObject.FromObject(new { First = 1, Second = 2 }), + JObject.FromObject(new { First = 1, Second = 2 }) + }; - IJEnumerable values = o.Properties(); - Assert.AreEqual(4, values.Count()); - } + IJEnumerable values = o.Properties(); + Assert.AreEqual(4, values.Count()); + } #endif #if !NET20 - [Test] - public void LinqCast() - { - JToken olist = JArray.Parse("[12,55]"); + [Test] + public void LinqCast() + { + JToken olist = JArray.Parse("[12,55]"); - List list1 = olist.AsEnumerable().Values().ToList(); + List list1 = olist.AsEnumerable().Values().ToList(); - Assert.AreEqual(12, list1[0]); - Assert.AreEqual(55, list1[1]); - } + Assert.AreEqual(12, list1[0]); + Assert.AreEqual(55, list1[1]); + } #endif - [Test] - public void ChildrenExtension() - { - string json = @"[ + [Test] + public void ChildrenExtension() + { + string json = @"[ { ""title"": ""James Newton-King"", ""link"": ""http://james.newtonking.com"", @@ -813,26 +816,26 @@ keyword such as type of business."" } ]"; - JArray o = JArray.Parse(json); + JArray o = JArray.Parse(json); - Assert.AreEqual(4, o.Children()["item"].Children()["title"].Count()); - CollectionAssert.AreEqual(new string[] + Assert.AreEqual(4, o.Children()["item"].Children()["title"].Count()); + CollectionAssert.AreEqual(new string[] + { + "Json.NET 1.3 + New license + Now on CodePlex", + "LINQ to JSON beta", + "Json.NET 1.3 + New license + Now on CodePlex", + "LINQ to JSON beta" + }, + o.Children()["item"].Children()["title"].Values().ToArray()); + } + + [Test] + public void UriGuidTimeSpanTestClassEmptyTest() { - "Json.NET 1.3 + New license + Now on CodePlex", - "LINQ to JSON beta", - "Json.NET 1.3 + New license + Now on CodePlex", - "LINQ to JSON beta" - }, - o.Children()["item"].Children()["title"].Values().ToArray()); - } + UriGuidTimeSpanTestClass c1 = new UriGuidTimeSpanTestClass(); + JObject o = JObject.FromObject(c1); - [Test] - public void UriGuidTimeSpanTestClassEmptyTest() - { - UriGuidTimeSpanTestClass c1 = new UriGuidTimeSpanTestClass(); - JObject o = JObject.FromObject(c1); - - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Guid"": ""00000000-0000-0000-0000-000000000000"", ""NullableGuid"": null, ""TimeSpan"": ""00:00:00"", @@ -840,28 +843,28 @@ keyword such as type of business."" ""Uri"": null }", o.ToString()); - UriGuidTimeSpanTestClass c2 = o.ToObject(); - Assert.AreEqual(c1.Guid, c2.Guid); - Assert.AreEqual(c1.NullableGuid, c2.NullableGuid); - Assert.AreEqual(c1.TimeSpan, c2.TimeSpan); - Assert.AreEqual(c1.NullableTimeSpan, c2.NullableTimeSpan); - Assert.AreEqual(c1.Uri, c2.Uri); - } + UriGuidTimeSpanTestClass c2 = o.ToObject(); + Assert.AreEqual(c1.Guid, c2.Guid); + Assert.AreEqual(c1.NullableGuid, c2.NullableGuid); + Assert.AreEqual(c1.TimeSpan, c2.TimeSpan); + Assert.AreEqual(c1.NullableTimeSpan, c2.NullableTimeSpan); + Assert.AreEqual(c1.Uri, c2.Uri); + } - [Test] - public void UriGuidTimeSpanTestClassValuesTest() - { - UriGuidTimeSpanTestClass c1 = new UriGuidTimeSpanTestClass - { - Guid = new Guid("1924129C-F7E0-40F3-9607-9939C531395A"), - NullableGuid = new Guid("9E9F3ADF-E017-4F72-91E0-617EBE85967D"), - TimeSpan = TimeSpan.FromDays(1), - NullableTimeSpan = TimeSpan.FromHours(1), - Uri = new Uri("http://testuri.com") - }; - JObject o = JObject.FromObject(c1); + [Test] + public void UriGuidTimeSpanTestClassValuesTest() + { + UriGuidTimeSpanTestClass c1 = new UriGuidTimeSpanTestClass + { + Guid = new Guid("1924129C-F7E0-40F3-9607-9939C531395A"), + NullableGuid = new Guid("9E9F3ADF-E017-4F72-91E0-617EBE85967D"), + TimeSpan = TimeSpan.FromDays(1), + NullableTimeSpan = TimeSpan.FromHours(1), + Uri = new Uri("http://testuri.com") + }; + JObject o = JObject.FromObject(c1); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Guid"": ""1924129c-f7e0-40f3-9607-9939c531395a"", ""NullableGuid"": ""9e9f3adf-e017-4f72-91e0-617ebe85967d"", ""TimeSpan"": ""1.00:00:00"", @@ -869,43 +872,43 @@ keyword such as type of business."" ""Uri"": ""http://testuri.com/"" }", o.ToString()); - UriGuidTimeSpanTestClass c2 = o.ToObject(); - Assert.AreEqual(c1.Guid, c2.Guid); - Assert.AreEqual(c1.NullableGuid, c2.NullableGuid); - Assert.AreEqual(c1.TimeSpan, c2.TimeSpan); - Assert.AreEqual(c1.NullableTimeSpan, c2.NullableTimeSpan); - Assert.AreEqual(c1.Uri, c2.Uri); - } + UriGuidTimeSpanTestClass c2 = o.ToObject(); + Assert.AreEqual(c1.Guid, c2.Guid); + Assert.AreEqual(c1.NullableGuid, c2.NullableGuid); + Assert.AreEqual(c1.TimeSpan, c2.TimeSpan); + Assert.AreEqual(c1.NullableTimeSpan, c2.NullableTimeSpan); + Assert.AreEqual(c1.Uri, c2.Uri); + } - [Test] - public void ParseWithPrecendingComments() - { - string json = @"/* blah */ {'hi':'hi!'}"; - JObject o = JObject.Parse(json); - Assert.AreEqual("hi!", (string)o["hi"]); + [Test] + public void ParseWithPrecendingComments() + { + string json = @"/* blah */ {'hi':'hi!'}"; + JObject o = JObject.Parse(json); + Assert.AreEqual("hi!", (string)o["hi"]); - json = @"/* blah */ ['hi!']"; - JArray a = JArray.Parse(json); - Assert.AreEqual("hi!", (string)a[0]); - } + json = @"/* blah */ ['hi!']"; + JArray a = JArray.Parse(json); + Assert.AreEqual("hi!", (string)a[0]); + } #if !(NET35 || NET20 || WINDOWS_PHONE) - [Test] - public void ExceptionFromOverloadWithJValue() - { - dynamic name = new JValue("Matthew Doig"); + [Test] + public void ExceptionFromOverloadWithJValue() + { + dynamic name = new JValue("Matthew Doig"); - IDictionary users = new Dictionary(); + IDictionary users = new Dictionary(); - // unfortunatly there doesn't appear to be a way around this - ExceptionAssert.Throws("The best overloaded method match for 'System.Collections.Generic.IDictionary.Add(string, string)' has some invalid arguments", - () => - { - users.Add("name2", name); + // unfortunatly there doesn't appear to be a way around this + ExceptionAssert.Throws("The best overloaded method match for 'System.Collections.Generic.IDictionary.Add(string, string)' has some invalid arguments", + () => + { + users.Add("name2", name); - Assert.AreEqual(users["name2"], "Matthew Doig"); - }); - } + Assert.AreEqual(users["name2"], "Matthew Doig"); + }); + } #endif - } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/LinqToSql/Department.cs b/Src/Newtonsoft.Json.Tests/LinqToSql/Department.cs index 582e9a6b..1dc6c5af 100644 --- a/Src/Newtonsoft.Json.Tests/LinqToSql/Department.cs +++ b/Src/Newtonsoft.Json.Tests/LinqToSql/Department.cs @@ -32,12 +32,12 @@ using System.Text; namespace Newtonsoft.Json.Tests.LinqToSql { - [MetadataType(typeof(DepartmentMetadata))] - public partial class Department - { - [JsonConverter(typeof(DepartmentConverter))] - public class DepartmentMetadata + [MetadataType(typeof(DepartmentMetadata))] + public partial class Department { + [JsonConverter(typeof(DepartmentConverter))] + public class DepartmentMetadata + { + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/LinqToSql/DepartmentConverter.cs b/Src/Newtonsoft.Json.Tests/LinqToSql/DepartmentConverter.cs index f710f46e..afaa3d79 100644 --- a/Src/Newtonsoft.Json.Tests/LinqToSql/DepartmentConverter.cs +++ b/Src/Newtonsoft.Json.Tests/LinqToSql/DepartmentConverter.cs @@ -31,33 +31,33 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.LinqToSql { - public class DepartmentConverter : JsonConverter - { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + public class DepartmentConverter : JsonConverter { - Department department = (Department)value; + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + Department department = (Department)value; - JObject o = new JObject(); - o["DepartmentId"] = new JValue(department.DepartmentId.ToString()); - o["Name"] = new JValue(new string(department.Name.Reverse().ToArray())); + JObject o = new JObject(); + o["DepartmentId"] = new JValue(department.DepartmentId.ToString()); + o["Name"] = new JValue(new string(department.Name.Reverse().ToArray())); - o.WriteTo(writer); + o.WriteTo(writer); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + JObject o = JObject.Load(reader); + + Department department = new Department(); + department.DepartmentId = new Guid((string)o["DepartmentId"]); + department.Name = new string(((string)o["Name"]).Reverse().ToArray()); + + return department; + } + + public override bool CanConvert(Type objectType) + { + return (objectType == typeof(Department)); + } } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - JObject o = JObject.Load(reader); - - Department department = new Department(); - department.DepartmentId = new Guid((string)o["DepartmentId"]); - department.Name = new string(((string) o["Name"]).Reverse().ToArray()); - - return department; - } - - public override bool CanConvert(Type objectType) - { - return (objectType == typeof (Department)); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/LinqToSql/GuidByteArrayConverter.cs b/Src/Newtonsoft.Json.Tests/LinqToSql/GuidByteArrayConverter.cs index db619cbb..b6e324dc 100644 --- a/Src/Newtonsoft.Json.Tests/LinqToSql/GuidByteArrayConverter.cs +++ b/Src/Newtonsoft.Json.Tests/LinqToSql/GuidByteArrayConverter.cs @@ -30,24 +30,24 @@ using System.Text; namespace Newtonsoft.Json.Tests.LinqToSql { - public class GuidByteArrayConverter : JsonConverter - { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + public class GuidByteArrayConverter : JsonConverter { - Guid guid = (Guid) value; - writer.WriteValue(Convert.ToBase64String(guid.ToByteArray())); - } + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + Guid guid = (Guid)value; + writer.WriteValue(Convert.ToBase64String(guid.ToByteArray())); + } - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - string encodedData = (string) reader.Value; - byte[] data = Convert.FromBase64String(encodedData); - return new Guid(data); - } + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + string encodedData = (string)reader.Value; + byte[] data = Convert.FromBase64String(encodedData); + return new Guid(data); + } - public override bool CanConvert(Type objectType) - { - return (objectType == typeof (Guid)); + public override bool CanConvert(Type objectType) + { + return (objectType == typeof(Guid)); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClassesSerializationTests.cs b/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClassesSerializationTests.cs index 8fd3e5c1..b98c6811 100644 --- a/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClassesSerializationTests.cs +++ b/Src/Newtonsoft.Json.Tests/LinqToSql/LinqToSqlClassesSerializationTests.cs @@ -37,34 +37,34 @@ using System.Data.Linq.Mapping; namespace Newtonsoft.Json.Tests.LinqToSql { - public class LinqToSqlClassesSerializationTests : TestFixtureBase - { - [Test] - public void Serialize() + public class LinqToSqlClassesSerializationTests : TestFixtureBase { - Role role = new Role(); - role.Name = "Role1"; - role.RoleId = new Guid("67EA92B7-4BD3-4718-BD75-3C7EDF800B34"); + [Test] + public void Serialize() + { + Role role = new Role(); + role.Name = "Role1"; + role.RoleId = new Guid("67EA92B7-4BD3-4718-BD75-3C7EDF800B34"); - Person person = new Person(); - person.FirstName = "FirstName!"; - person.LastName = "LastName!"; - person.PersonId = new Guid("7AA027AA-C995-4986-908D-999D8063599F"); - person.PersonRoles.Add(new PersonRole - { - PersonRoleId = new Guid("B012DD41-71DF-4839-B8D5-D1333FB886BC"), - Role = role - }); + Person person = new Person(); + person.FirstName = "FirstName!"; + person.LastName = "LastName!"; + person.PersonId = new Guid("7AA027AA-C995-4986-908D-999D8063599F"); + person.PersonRoles.Add(new PersonRole + { + PersonRoleId = new Guid("B012DD41-71DF-4839-B8D5-D1333FB886BC"), + Role = role + }); - person.Department = new Department - { - DepartmentId = new Guid("08F68BF9-929B-4434-BC47-C9489D22112B"), - Name = "Name!" - }; + person.Department = new Department + { + DepartmentId = new Guid("08F68BF9-929B-4434-BC47-C9489D22112B"), + Name = "Name!" + }; - string json = JsonConvert.SerializeObject(person, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); + string json = JsonConvert.SerializeObject(person, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""first_name"": ""FirstName!"", ""LastName"": ""LastName!"", ""PersonId"": ""7aa027aa-c995-4986-908d-999d8063599f"", @@ -85,12 +85,12 @@ namespace Newtonsoft.Json.Tests.LinqToSql ""Name"": ""!emaN"" } }", json); - } + } - [Test] - public void Deserialize() - { - string json = @"{ + [Test] + public void Deserialize() + { + string json = @"{ ""first_name"": ""FirstName!"", ""LastName"": ""LastName!"", ""PersonId"": ""7aa027aa-c995-4986-908d-999d8063599f"", @@ -111,25 +111,25 @@ namespace Newtonsoft.Json.Tests.LinqToSql } }"; - Person person = JsonConvert.DeserializeObject(json); - Assert.IsNotNull(person); + Person person = JsonConvert.DeserializeObject(json); + Assert.IsNotNull(person); - Assert.AreEqual(new Guid("7AA027AA-C995-4986-908D-999D8063599F"), person.PersonId); - Assert.AreEqual("FirstName!", person.FirstName); - Assert.AreEqual("LastName!", person.LastName); - Assert.AreEqual(1, person.PersonRoles.Count); - Assert.AreEqual(person.PersonId, person.PersonRoles[0].PersonId); - Assert.AreEqual(new Guid("67EA92B7-4BD3-4718-BD75-3C7EDF800B34"), person.PersonRoles[0].RoleId); - Assert.IsNotNull(person.PersonRoles[0].Role); - Assert.AreEqual(1, person.PersonRoles[0].Role.PersonRoles.Count); + Assert.AreEqual(new Guid("7AA027AA-C995-4986-908D-999D8063599F"), person.PersonId); + Assert.AreEqual("FirstName!", person.FirstName); + Assert.AreEqual("LastName!", person.LastName); + Assert.AreEqual(1, person.PersonRoles.Count); + Assert.AreEqual(person.PersonId, person.PersonRoles[0].PersonId); + Assert.AreEqual(new Guid("67EA92B7-4BD3-4718-BD75-3C7EDF800B34"), person.PersonRoles[0].RoleId); + Assert.IsNotNull(person.PersonRoles[0].Role); + Assert.AreEqual(1, person.PersonRoles[0].Role.PersonRoles.Count); - Assert.AreEqual("Name!", person.Department.Name); + Assert.AreEqual("Name!", person.Department.Name); - TableAttribute tableAttribute = JsonTypeReflector.GetAttribute(typeof(Person)); - Assert.AreEqual("", tableAttribute.Name); + TableAttribute tableAttribute = JsonTypeReflector.GetAttribute(typeof(Person)); + Assert.AreEqual("", tableAttribute.Name); - ColumnAttribute columnAttribute = JsonTypeReflector.GetAttribute(typeof(Person).GetProperty("FirstName")); - Assert.AreEqual("_FirstName", columnAttribute.Storage); + ColumnAttribute columnAttribute = JsonTypeReflector.GetAttribute(typeof(Person).GetProperty("FirstName")); + Assert.AreEqual("_FirstName", columnAttribute.Storage); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/LinqToSql/Person.cs b/Src/Newtonsoft.Json.Tests/LinqToSql/Person.cs index 7c27d030..b797a13d 100644 --- a/Src/Newtonsoft.Json.Tests/LinqToSql/Person.cs +++ b/Src/Newtonsoft.Json.Tests/LinqToSql/Person.cs @@ -31,13 +31,13 @@ using System.Text; namespace Newtonsoft.Json.Tests.LinqToSql { - [MetadataType(typeof(PersonMetadata))] - public partial class Person - { - public class PersonMetadata + [MetadataType(typeof(PersonMetadata))] + public partial class Person { - [JsonProperty("first_name")] - public string FirstName { get; set; } + public class PersonMetadata + { + [JsonProperty("first_name")] + public string FirstName { get; set; } + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/LinqToSql/Role.cs b/Src/Newtonsoft.Json.Tests/LinqToSql/Role.cs index fb8a1e35..039722bf 100644 --- a/Src/Newtonsoft.Json.Tests/LinqToSql/Role.cs +++ b/Src/Newtonsoft.Json.Tests/LinqToSql/Role.cs @@ -32,15 +32,16 @@ using System.Text; namespace Newtonsoft.Json.Tests.LinqToSql { - [MetadataType(typeof(RoleMetadata))] - public partial class Role - { - public class RoleMetadata + [MetadataType(typeof(RoleMetadata))] + public partial class Role { - [JsonConverter(typeof(GuidByteArrayConverter))] - public Guid RoleId { get; set; } - [JsonIgnore] - public EntitySet PersonRoles { get; set; } + public class RoleMetadata + { + [JsonConverter(typeof(GuidByteArrayConverter))] + public Guid RoleId { get; set; } + + [JsonIgnore] + public EntitySet PersonRoles { get; set; } + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/PerformanceTests.cs b/Src/Newtonsoft.Json.Tests/PerformanceTests.cs index 7f235129..af267a3e 100644 --- a/Src/Newtonsoft.Json.Tests/PerformanceTests.cs +++ b/Src/Newtonsoft.Json.Tests/PerformanceTests.cs @@ -45,185 +45,183 @@ using Newtonsoft.Json.Converters; namespace Newtonsoft.Json.Tests { - [Serializable] - [DataContract] - public class Image - { - [DataMember] - public string FileName { get; set; } - - [DataMember] - public string Author { get; set; } - - [DataMember] - public string Caption { get; set; } - - [DataMember] - public byte[] Data { get; set; } - } - - [TestFixture] - public class PerformanceTests : TestFixtureBase - { - private const int Iterations = 100; - //private const int Iterations = 5000; - -#region Data - - private const string BsonHex = - @"A9-01-00-00-04-73-74-72-69-6E-67-73-00-2B-00-00-00-0A-30-00-02-31-00-19-00-00-00-4D-61-72-6B-75-73-20-65-67-67-65-72-20-5D-3E-3C-5B-2C-20-28-32-6E-64-29-00-0A-32-00-00-03-64-69-63-74-69-6F-6E-61-72-79-00-37-00-00-00-10-56-61-6C-20-26-20-61-73-64-31-00-01-00-00-00-10-56-61-6C-32-20-26-20-61-73-64-31-00-03-00-00-00-10-56-61-6C-33-20-26-20-61-73-64-31-00-04-00-00-00-00-02-4E-61-6D-65-00-05-00-00-00-52-69-63-6B-00-09-4E-6F-77-00-EF-BD-69-EC-25-01-00-00-01-42-69-67-4E-75-6D-62-65-72-00-E7-7B-CC-26-96-C7-1F-42-03-41-64-64-72-65-73-73-31-00-47-00-00-00-02-53-74-72-65-65-74-00-0B-00-00-00-66-66-66-20-53-74-72-65-65-74-00-02-50-68-6F-6E-65-00-0F-00-00-00-28-35-30-33-29-20-38-31-34-2D-36-33-33-35-00-09-45-6E-74-65-72-65-64-00-6F-FF-31-53-26-01-00-00-00-04-41-64-64-72-65-73-73-65-73-00-A2-00-00-00-03-30-00-4B-00-00-00-02-53-74-72-65-65-74-00-0F-00-00-00-1F-61-72-72-61-79-3C-61-64-64-72-65-73-73-00-02-50-68-6F-6E-65-00-0F-00-00-00-28-35-30-33-29-20-38-31-34-2D-36-33-33-35-00-09-45-6E-74-65-72-65-64-00-6F-73-0C-E7-25-01-00-00-00-03-31-00-4C-00-00-00-02-53-74-72-65-65-74-00-10-00-00-00-61-72-72-61-79-20-32-20-61-64-64-72-65-73-73-00-02-50-68-6F-6E-65-00-0F-00-00-00-28-35-30-33-29-20-38-31-34-2D-36-33-33-35-00-09-45-6E-74-65-72-65-64-00-6F-17-E6-E1-25-01-00-00-00-00-00"; - - private const string BinaryFormatterHex = - @"00-01-00-00-00-FF-FF-FF-FF-01-00-00-00-00-00-00-00-0C-02-00-00-00-4C-4E-65-77-74-6F-6E-73-6F-66-74-2E-4A-73-6F-6E-2E-54-65-73-74-73-2C-20-56-65-72-73-69-6F-6E-3D-33-2E-35-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-6E-75-6C-6C-05-01-00-00-00-1F-4E-65-77-74-6F-6E-73-6F-66-74-2E-4A-73-6F-6E-2E-54-65-73-74-73-2E-54-65-73-74-43-6C-61-73-73-07-00-00-00-05-5F-4E-61-6D-65-04-5F-4E-6F-77-0A-5F-42-69-67-4E-75-6D-62-65-72-09-5F-41-64-64-72-65-73-73-31-0A-5F-41-64-64-72-65-73-73-65-73-07-73-74-72-69-6E-67-73-0A-64-69-63-74-69-6F-6E-61-72-79-01-00-00-04-03-03-03-0D-05-1D-4E-65-77-74-6F-6E-73-6F-66-74-2E-4A-73-6F-6E-2E-54-65-73-74-73-2E-41-64-64-72-65-73-73-02-00-00-00-90-01-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-4C-69-73-74-60-31-5B-5B-4E-65-77-74-6F-6E-73-6F-66-74-2E-4A-73-6F-6E-2E-54-65-73-74-73-2E-41-64-64-72-65-73-73-2C-20-4E-65-77-74-6F-6E-73-6F-66-74-2E-4A-73-6F-6E-2E-54-65-73-74-73-2C-20-56-65-72-73-69-6F-6E-3D-33-2E-35-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-6E-75-6C-6C-5D-5D-7F-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-4C-69-73-74-60-31-5B-5B-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-5D-E1-01-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-44-69-63-74-69-6F-6E-61-72-79-60-32-5B-5B-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-2C-5B-53-79-73-74-65-6D-2E-49-6E-74-33-32-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-5D-02-00-00-00-06-03-00-00-00-04-52-69-63-6B-B6-25-3A-D1-C5-59-CC-88-0F-33-34-31-32-33-31-32-33-31-32-33-2E-31-32-31-09-04-00-00-00-09-05-00-00-00-09-06-00-00-00-09-07-00-00-00-05-04-00-00-00-1D-4E-65-77-74-6F-6E-73-6F-66-74-2E-4A-73-6F-6E-2E-54-65-73-74-73-2E-41-64-64-72-65-73-73-03-00-00-00-07-5F-73-74-72-65-65-74-06-5F-50-68-6F-6E-65-08-5F-45-6E-74-65-72-65-64-01-01-00-0D-02-00-00-00-06-08-00-00-00-0A-66-66-66-20-53-74-72-65-65-74-06-09-00-00-00-0E-28-35-30-33-29-20-38-31-34-2D-36-33-33-35-B6-BD-B8-BF-74-69-CC-88-04-05-00-00-00-90-01-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-4C-69-73-74-60-31-5B-5B-4E-65-77-74-6F-6E-73-6F-66-74-2E-4A-73-6F-6E-2E-54-65-73-74-73-2E-41-64-64-72-65-73-73-2C-20-4E-65-77-74-6F-6E-73-6F-66-74-2E-4A-73-6F-6E-2E-54-65-73-74-73-2C-20-56-65-72-73-69-6F-6E-3D-33-2E-35-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-6E-75-6C-6C-5D-5D-03-00-00-00-06-5F-69-74-65-6D-73-05-5F-73-69-7A-65-08-5F-76-65-72-73-69-6F-6E-04-00-00-1F-4E-65-77-74-6F-6E-73-6F-66-74-2E-4A-73-6F-6E-2E-54-65-73-74-73-2E-41-64-64-72-65-73-73-5B-5D-02-00-00-00-08-08-09-0A-00-00-00-02-00-00-00-02-00-00-00-04-06-00-00-00-7F-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-4C-69-73-74-60-31-5B-5B-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-5D-03-00-00-00-06-5F-69-74-65-6D-73-05-5F-73-69-7A-65-08-5F-76-65-72-73-69-6F-6E-06-00-00-08-08-09-0B-00-00-00-03-00-00-00-03-00-00-00-04-07-00-00-00-E1-01-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-44-69-63-74-69-6F-6E-61-72-79-60-32-5B-5B-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-2C-5B-53-79-73-74-65-6D-2E-49-6E-74-33-32-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-5D-04-00-00-00-07-56-65-72-73-69-6F-6E-08-43-6F-6D-70-61-72-65-72-08-48-61-73-68-53-69-7A-65-0D-4B-65-79-56-61-6C-75-65-50-61-69-72-73-00-03-00-03-08-92-01-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-47-65-6E-65-72-69-63-45-71-75-61-6C-69-74-79-43-6F-6D-70-61-72-65-72-60-31-5B-5B-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-5D-08-E5-01-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-4B-65-79-56-61-6C-75-65-50-61-69-72-60-32-5B-5B-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-2C-5B-53-79-73-74-65-6D-2E-49-6E-74-33-32-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-5D-5B-5D-03-00-00-00-09-0C-00-00-00-03-00-00-00-09-0D-00-00-00-07-0A-00-00-00-00-01-00-00-00-04-00-00-00-04-1D-4E-65-77-74-6F-6E-73-6F-66-74-2E-4A-73-6F-6E-2E-54-65-73-74-73-2E-41-64-64-72-65-73-73-02-00-00-00-09-0E-00-00-00-09-0F-00-00-00-0D-02-11-0B-00-00-00-04-00-00-00-0A-06-10-00-00-00-18-4D-61-72-6B-75-73-20-65-67-67-65-72-20-5D-3E-3C-5B-2C-20-28-32-6E-64-29-0D-02-04-0C-00-00-00-92-01-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-47-65-6E-65-72-69-63-45-71-75-61-6C-69-74-79-43-6F-6D-70-61-72-65-72-60-31-5B-5B-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-5D-00-00-00-00-07-0D-00-00-00-00-01-00-00-00-03-00-00-00-03-E3-01-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-4B-65-79-56-61-6C-75-65-50-61-69-72-60-32-5B-5B-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-2C-5B-53-79-73-74-65-6D-2E-49-6E-74-33-32-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-5D-04-EF-FF-FF-FF-E3-01-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-4B-65-79-56-61-6C-75-65-50-61-69-72-60-32-5B-5B-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-2C-5B-53-79-73-74-65-6D-2E-49-6E-74-33-32-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-5D-02-00-00-00-03-6B-65-79-05-76-61-6C-75-65-01-00-08-06-12-00-00-00-0A-56-61-6C-20-26-20-61-73-64-31-01-00-00-00-01-ED-FF-FF-FF-EF-FF-FF-FF-06-14-00-00-00-0B-56-61-6C-32-20-26-20-61-73-64-31-03-00-00-00-01-EB-FF-FF-FF-EF-FF-FF-FF-06-16-00-00-00-0B-56-61-6C-33-20-26-20-61-73-64-31-04-00-00-00-01-0E-00-00-00-04-00-00-00-06-17-00-00-00-0E-1F-61-72-72-61-79-3C-61-64-64-72-65-73-73-09-09-00-00-00-B6-FD-0B-45-F4-58-CC-88-01-0F-00-00-00-04-00-00-00-06-19-00-00-00-0F-61-72-72-61-79-20-32-20-61-64-64-72-65-73-73-09-09-00-00-00-B6-3D-A2-1A-2B-58-CC-88-0B"; - - private const string XmlText = - @"2010-01-21T11:12:16.0809174+13:00(503) 814-6335fff Street
2009-12-31T11:12:16.0809174+13:00(503) 814-6335array<address
2009-12-30T11:12:16.0809174+13:00(503) 814-6335array 2 address
34123123123.121Rick2010-01-01T12:12:16.0809174+13:00Val & asd11Val2 & asd13Val3 & asd14Markus egger ]><[, (2nd)
"; - - private const string JsonText = - @"{""strings"":[null,""Markus egger ]><[, (2nd)"",null],""dictionary"":{""Val & asd1"":1,""Val2 & asd1"":3,""Val3 & asd1"":4},""Name"":""Rick"",""Now"":""\/Date(1262301136080+1300)\/"",""BigNumber"":34123123123.121,""Address1"":{""Street"":""fff Street"",""Phone"":""(503) 814-6335"",""Entered"":""\/Date(1264025536080+1300)\/""},""Addresses"":[{""Street"":""\u001farray<[, (2nd)"",null],""dictionary"":{""Val & asd1"":1,""Val2 & asd1"":3,""Val3 & asd1"":4},""Name"":""Rick"",""Now"":""2012-02-25T19:55:50.6095676+13:00"",""BigNumber"":34123123123.121,""Address1"":{""Street"":""fff Street"",""Phone"":""(503) 814-6335"",""Entered"":""2012-02-24T18:55:50.6095676+13:00""},""Addresses"":[{""Street"":""\u001farray(SimpleJsonText); - } + private const string BinaryFormatterHex = + @"00-01-00-00-00-FF-FF-FF-FF-01-00-00-00-00-00-00-00-0C-02-00-00-00-4C-4E-65-77-74-6F-6E-73-6F-66-74-2E-4A-73-6F-6E-2E-54-65-73-74-73-2C-20-56-65-72-73-69-6F-6E-3D-33-2E-35-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-6E-75-6C-6C-05-01-00-00-00-1F-4E-65-77-74-6F-6E-73-6F-66-74-2E-4A-73-6F-6E-2E-54-65-73-74-73-2E-54-65-73-74-43-6C-61-73-73-07-00-00-00-05-5F-4E-61-6D-65-04-5F-4E-6F-77-0A-5F-42-69-67-4E-75-6D-62-65-72-09-5F-41-64-64-72-65-73-73-31-0A-5F-41-64-64-72-65-73-73-65-73-07-73-74-72-69-6E-67-73-0A-64-69-63-74-69-6F-6E-61-72-79-01-00-00-04-03-03-03-0D-05-1D-4E-65-77-74-6F-6E-73-6F-66-74-2E-4A-73-6F-6E-2E-54-65-73-74-73-2E-41-64-64-72-65-73-73-02-00-00-00-90-01-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-4C-69-73-74-60-31-5B-5B-4E-65-77-74-6F-6E-73-6F-66-74-2E-4A-73-6F-6E-2E-54-65-73-74-73-2E-41-64-64-72-65-73-73-2C-20-4E-65-77-74-6F-6E-73-6F-66-74-2E-4A-73-6F-6E-2E-54-65-73-74-73-2C-20-56-65-72-73-69-6F-6E-3D-33-2E-35-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-6E-75-6C-6C-5D-5D-7F-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-4C-69-73-74-60-31-5B-5B-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-5D-E1-01-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-44-69-63-74-69-6F-6E-61-72-79-60-32-5B-5B-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-2C-5B-53-79-73-74-65-6D-2E-49-6E-74-33-32-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-5D-02-00-00-00-06-03-00-00-00-04-52-69-63-6B-B6-25-3A-D1-C5-59-CC-88-0F-33-34-31-32-33-31-32-33-31-32-33-2E-31-32-31-09-04-00-00-00-09-05-00-00-00-09-06-00-00-00-09-07-00-00-00-05-04-00-00-00-1D-4E-65-77-74-6F-6E-73-6F-66-74-2E-4A-73-6F-6E-2E-54-65-73-74-73-2E-41-64-64-72-65-73-73-03-00-00-00-07-5F-73-74-72-65-65-74-06-5F-50-68-6F-6E-65-08-5F-45-6E-74-65-72-65-64-01-01-00-0D-02-00-00-00-06-08-00-00-00-0A-66-66-66-20-53-74-72-65-65-74-06-09-00-00-00-0E-28-35-30-33-29-20-38-31-34-2D-36-33-33-35-B6-BD-B8-BF-74-69-CC-88-04-05-00-00-00-90-01-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-4C-69-73-74-60-31-5B-5B-4E-65-77-74-6F-6E-73-6F-66-74-2E-4A-73-6F-6E-2E-54-65-73-74-73-2E-41-64-64-72-65-73-73-2C-20-4E-65-77-74-6F-6E-73-6F-66-74-2E-4A-73-6F-6E-2E-54-65-73-74-73-2C-20-56-65-72-73-69-6F-6E-3D-33-2E-35-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-6E-75-6C-6C-5D-5D-03-00-00-00-06-5F-69-74-65-6D-73-05-5F-73-69-7A-65-08-5F-76-65-72-73-69-6F-6E-04-00-00-1F-4E-65-77-74-6F-6E-73-6F-66-74-2E-4A-73-6F-6E-2E-54-65-73-74-73-2E-41-64-64-72-65-73-73-5B-5D-02-00-00-00-08-08-09-0A-00-00-00-02-00-00-00-02-00-00-00-04-06-00-00-00-7F-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-4C-69-73-74-60-31-5B-5B-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-5D-03-00-00-00-06-5F-69-74-65-6D-73-05-5F-73-69-7A-65-08-5F-76-65-72-73-69-6F-6E-06-00-00-08-08-09-0B-00-00-00-03-00-00-00-03-00-00-00-04-07-00-00-00-E1-01-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-44-69-63-74-69-6F-6E-61-72-79-60-32-5B-5B-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-2C-5B-53-79-73-74-65-6D-2E-49-6E-74-33-32-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-5D-04-00-00-00-07-56-65-72-73-69-6F-6E-08-43-6F-6D-70-61-72-65-72-08-48-61-73-68-53-69-7A-65-0D-4B-65-79-56-61-6C-75-65-50-61-69-72-73-00-03-00-03-08-92-01-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-47-65-6E-65-72-69-63-45-71-75-61-6C-69-74-79-43-6F-6D-70-61-72-65-72-60-31-5B-5B-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-5D-08-E5-01-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-4B-65-79-56-61-6C-75-65-50-61-69-72-60-32-5B-5B-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-2C-5B-53-79-73-74-65-6D-2E-49-6E-74-33-32-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-5D-5B-5D-03-00-00-00-09-0C-00-00-00-03-00-00-00-09-0D-00-00-00-07-0A-00-00-00-00-01-00-00-00-04-00-00-00-04-1D-4E-65-77-74-6F-6E-73-6F-66-74-2E-4A-73-6F-6E-2E-54-65-73-74-73-2E-41-64-64-72-65-73-73-02-00-00-00-09-0E-00-00-00-09-0F-00-00-00-0D-02-11-0B-00-00-00-04-00-00-00-0A-06-10-00-00-00-18-4D-61-72-6B-75-73-20-65-67-67-65-72-20-5D-3E-3C-5B-2C-20-28-32-6E-64-29-0D-02-04-0C-00-00-00-92-01-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-47-65-6E-65-72-69-63-45-71-75-61-6C-69-74-79-43-6F-6D-70-61-72-65-72-60-31-5B-5B-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-5D-00-00-00-00-07-0D-00-00-00-00-01-00-00-00-03-00-00-00-03-E3-01-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-4B-65-79-56-61-6C-75-65-50-61-69-72-60-32-5B-5B-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-2C-5B-53-79-73-74-65-6D-2E-49-6E-74-33-32-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-5D-04-EF-FF-FF-FF-E3-01-53-79-73-74-65-6D-2E-43-6F-6C-6C-65-63-74-69-6F-6E-73-2E-47-65-6E-65-72-69-63-2E-4B-65-79-56-61-6C-75-65-50-61-69-72-60-32-5B-5B-53-79-73-74-65-6D-2E-53-74-72-69-6E-67-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-2C-5B-53-79-73-74-65-6D-2E-49-6E-74-33-32-2C-20-6D-73-63-6F-72-6C-69-62-2C-20-56-65-72-73-69-6F-6E-3D-32-2E-30-2E-30-2E-30-2C-20-43-75-6C-74-75-72-65-3D-6E-65-75-74-72-61-6C-2C-20-50-75-62-6C-69-63-4B-65-79-54-6F-6B-65-6E-3D-62-37-37-61-35-63-35-36-31-39-33-34-65-30-38-39-5D-5D-02-00-00-00-03-6B-65-79-05-76-61-6C-75-65-01-00-08-06-12-00-00-00-0A-56-61-6C-20-26-20-61-73-64-31-01-00-00-00-01-ED-FF-FF-FF-EF-FF-FF-FF-06-14-00-00-00-0B-56-61-6C-32-20-26-20-61-73-64-31-03-00-00-00-01-EB-FF-FF-FF-EF-FF-FF-FF-06-16-00-00-00-0B-56-61-6C-33-20-26-20-61-73-64-31-04-00-00-00-01-0E-00-00-00-04-00-00-00-06-17-00-00-00-0E-1F-61-72-72-61-79-3C-61-64-64-72-65-73-73-09-09-00-00-00-B6-FD-0B-45-F4-58-CC-88-01-0F-00-00-00-04-00-00-00-06-19-00-00-00-0F-61-72-72-61-79-20-32-20-61-64-64-72-65-73-73-09-09-00-00-00-B6-3D-A2-1A-2B-58-CC-88-0B"; - [Test] - public void Serialize() - { - TestClass test = CreateSerializationObject(); + private const string XmlText = + @"2010-01-21T11:12:16.0809174+13:00(503) 814-6335fff Street
2009-12-31T11:12:16.0809174+13:00(503) 814-6335array<address
2009-12-30T11:12:16.0809174+13:00(503) 814-6335array 2 address
34123123123.121Rick2010-01-01T12:12:16.0809174+13:00Val & asd11Val2 & asd13Val3 & asd14Markus egger ]><[, (2nd)
"; - SerializeTests(test); - } + private const string JsonText = + @"{""strings"":[null,""Markus egger ]><[, (2nd)"",null],""dictionary"":{""Val & asd1"":1,""Val2 & asd1"":3,""Val3 & asd1"":4},""Name"":""Rick"",""Now"":""\/Date(1262301136080+1300)\/"",""BigNumber"":34123123123.121,""Address1"":{""Street"":""fff Street"",""Phone"":""(503) 814-6335"",""Entered"":""\/Date(1264025536080+1300)\/""},""Addresses"":[{""Street"":""\u001farray<[, (2nd)"",null],""dictionary"":{""Val & asd1"":1,""Val2 & asd1"":3,""Val3 & asd1"":4},""Name"":""Rick"",""Now"":""2012-02-25T19:55:50.6095676+13:00"",""BigNumber"":34123123123.121,""Address1"":{""Street"":""fff Street"",""Phone"":""(503) 814-6335"",""Entered"":""2012-02-24T18:55:50.6095676+13:00""},""Addresses"":[{""Street"":""\u001farray(SerializeMethod.DataContractSerializer, XmlText); - BenchmarkDeserializeMethod(SerializeMethod.BinaryFormatter, HexToBytes(BinaryFormatterHex)); - DeserializeTests(JsonText); - BenchmarkDeserializeMethod(SerializeMethod.JsonNetWithIsoConverter, JsonIsoText); - BenchmarkDeserializeMethod(SerializeMethod.JsonNetBinary, HexToBytes(BsonHex)); - } + private const string SimpleJsonText = + @"{""Id"":2311,""Name"":""Simple-1"",""Address"":""Planet Earth"",""Scores"":[82,96,49,40,38,38,78,96,2,39]}"; - public void DeserializeTests(string json) - { - BenchmarkDeserializeMethod(SerializeMethod.JavaScriptSerializer, json); - BenchmarkDeserializeMethod(SerializeMethod.DataContractJsonSerializer, json); - BenchmarkDeserializeMethod(SerializeMethod.JsonNet, json); - BenchmarkDeserializeMethod(SerializeMethod.JsonNetManual, json); - } - - [Test] - public void SerializeSizeNormal() - { - SerializeSize(CreateSerializationObject()); - } - - [Test] - public void SerializeSizeData() - { - Image image = new Image(); - image.Data = System.IO.File.ReadAllBytes(@"bunny_pancake.jpg"); - image.FileName = "bunny_pancake.jpg"; - image.Author = "Hironori Akutagawa"; - image.Caption = "I have no idea what you are talking about so here's a bunny with a pancake on its head"; - - SerializeSize(image); - } - - private T TimeOperation(Func operation, string name) - { - // warm up - operation(); - - Stopwatch timed = new Stopwatch(); - timed.Start(); - - T result = operation(); - - Console.WriteLine(name); - Console.WriteLine("{0} ms", timed.ElapsedMilliseconds); - - timed.Stop(); - - return result; - } - - [Test] - public void BuildJObject() - { - JObject o = new JObject(); - for (int i = 0; i < 50; i++) - { - o[i.ToString()] = i; - } - string jsonText = o.ToString(); - - // this is extremely slow with 5000 interations - int interations = 1000; - - TimeOperation(() => + public enum SerializeMethod { - JObject oo = null; - for (int i = 0; i < interations; i++) - { - oo = JObject.Parse(jsonText); - } + JsonNet, + JsonNetWithIsoConverter, + JsonNetBinary, + JsonNetLinq, + JsonNetManual, + BinaryFormatter, + JavaScriptSerializer, + DataContractSerializer, + DataContractJsonSerializer + } + #endregion - return oo; - }, "JObject"); - } + [Test] + public void SerializeSimpleObject() + { + SimpleObject value = CreateSimpleObject(); - [Test] - public void BuildJObjectComparedToXml() - { - const long totalIterations = 100000; + SerializeTests(value); + } - const String xml = - @" + [Test] + public void DeserializeSimpleObject() + { + DeserializeTests(SimpleJsonText); + } + + [Test] + public void Serialize() + { + TestClass test = CreateSerializationObject(); + + SerializeTests(test); + } + + private void SerializeTests(object value) + { + BenchmarkSerializeMethod(SerializeMethod.DataContractSerializer, value); + BenchmarkSerializeMethod(SerializeMethod.BinaryFormatter, value); + BenchmarkSerializeMethod(SerializeMethod.JavaScriptSerializer, value); + BenchmarkSerializeMethod(SerializeMethod.DataContractJsonSerializer, value); + BenchmarkSerializeMethod(SerializeMethod.JsonNet, value); + BenchmarkSerializeMethod(SerializeMethod.JsonNetLinq, value); + BenchmarkSerializeMethod(SerializeMethod.JsonNetManual, value); + BenchmarkSerializeMethod(SerializeMethod.JsonNetWithIsoConverter, value); + BenchmarkSerializeMethod(SerializeMethod.JsonNetBinary, value); + } + + [Test] + public void Deserialize() + { + BenchmarkDeserializeMethod(SerializeMethod.DataContractSerializer, XmlText); + BenchmarkDeserializeMethod(SerializeMethod.BinaryFormatter, HexToBytes(BinaryFormatterHex)); + DeserializeTests(JsonText); + BenchmarkDeserializeMethod(SerializeMethod.JsonNetWithIsoConverter, JsonIsoText); + BenchmarkDeserializeMethod(SerializeMethod.JsonNetBinary, HexToBytes(BsonHex)); + } + + public void DeserializeTests(string json) + { + BenchmarkDeserializeMethod(SerializeMethod.JavaScriptSerializer, json); + BenchmarkDeserializeMethod(SerializeMethod.DataContractJsonSerializer, json); + BenchmarkDeserializeMethod(SerializeMethod.JsonNet, json); + BenchmarkDeserializeMethod(SerializeMethod.JsonNetManual, json); + } + + [Test] + public void SerializeSizeNormal() + { + SerializeSize(CreateSerializationObject()); + } + + [Test] + public void SerializeSizeData() + { + Image image = new Image(); + image.Data = System.IO.File.ReadAllBytes(@"bunny_pancake.jpg"); + image.FileName = "bunny_pancake.jpg"; + image.Author = "Hironori Akutagawa"; + image.Caption = "I have no idea what you are talking about so here's a bunny with a pancake on its head"; + + SerializeSize(image); + } + + private T TimeOperation(Func operation, string name) + { + // warm up + operation(); + + Stopwatch timed = new Stopwatch(); + timed.Start(); + + T result = operation(); + + Console.WriteLine(name); + Console.WriteLine("{0} ms", timed.ElapsedMilliseconds); + + timed.Stop(); + + return result; + } + + [Test] + public void BuildJObject() + { + JObject o = new JObject(); + for (int i = 0; i < 50; i++) + { + o[i.ToString()] = i; + } + string jsonText = o.ToString(); + + // this is extremely slow with 5000 interations + int interations = 1000; + + TimeOperation(() => + { + JObject oo = null; + for (int i = 0; i < interations; i++) + { + oo = JObject.Parse(jsonText); + } + + return oo; + }, "JObject"); + } + + [Test] + public void BuildJObjectComparedToXml() + { + const long totalIterations = 100000; + + const String xml = + @" 1 2 @@ -232,8 +230,8 @@ namespace Newtonsoft.Json.Tests 5 "; - const String json = - @"{ + const String json = + @"{ ""Property1"":""1"", ""Property2"":""2"", ""Property3"":""3"", @@ -242,60 +240,60 @@ namespace Newtonsoft.Json.Tests }"; - var watch = new Stopwatch(); - watch.Start(); - for (long iteration = 0; iteration < totalIterations; ++iteration) - { - var obj = JObject.Parse(json); - obj["Property1"].Value(); - obj["Property2"].Value(); - obj["Property3"].Value(); - obj["Property4"].Value(); - obj["Property5"].Value(); - } - watch.Stop(); - var performance1 = (totalIterations/watch.ElapsedMilliseconds)*1000; - Console.WriteLine("JSON: " + watch.Elapsed.TotalSeconds); + var watch = new Stopwatch(); + watch.Start(); + for (long iteration = 0; iteration < totalIterations; ++iteration) + { + var obj = JObject.Parse(json); + obj["Property1"].Value(); + obj["Property2"].Value(); + obj["Property3"].Value(); + obj["Property4"].Value(); + obj["Property5"].Value(); + } + watch.Stop(); + var performance1 = (totalIterations / watch.ElapsedMilliseconds) * 1000; + Console.WriteLine("JSON: " + watch.Elapsed.TotalSeconds); - watch.Reset(); - watch.Start(); - for (long iteration = 0; iteration < totalIterations; ++iteration) - { - var doc = XDocument.Parse(xml); - var alarmProperties = doc.Descendants("property"); - foreach (var property in alarmProperties) - { - var attr = property.Attribute("name"); - var name = attr.Value; - switch (name) - { - case "Property1": - Int32.Parse(property.Value); - break; - case "Property2": - Int32.Parse(property.Value); - break; - case "Property3": - Int32.Parse(property.Value); - break; - case "Property4": - Int32.Parse(property.Value); - break; - case "Property5": - Int32.Parse(property.Value); - break; - } + watch.Reset(); + watch.Start(); + for (long iteration = 0; iteration < totalIterations; ++iteration) + { + var doc = XDocument.Parse(xml); + var alarmProperties = doc.Descendants("property"); + foreach (var property in alarmProperties) + { + var attr = property.Attribute("name"); + var name = attr.Value; + switch (name) + { + case "Property1": + Int32.Parse(property.Value); + break; + case "Property2": + Int32.Parse(property.Value); + break; + case "Property3": + Int32.Parse(property.Value); + break; + case "Property4": + Int32.Parse(property.Value); + break; + case "Property5": + Int32.Parse(property.Value); + break; + } + } + } + watch.Stop(); + var performance2 = (totalIterations / watch.ElapsedMilliseconds) * 1000; + Console.WriteLine("XML: " + watch.Elapsed.TotalSeconds); } - } - watch.Stop(); - var performance2 = (totalIterations/watch.ElapsedMilliseconds)*1000; - Console.WriteLine("XML: " + watch.Elapsed.TotalSeconds); - } - [Test] - public void SerializeString() - { - string text = @"The general form of an HTML element is therefore: content. + [Test] + public void SerializeString() + { + string text = @"The general form of an HTML element is therefore: content. Some HTML elements are defined as empty elements and take the form . Empty elements may enclose no content, for instance, the BR tag or the inline IMG tag. The name of an HTML element is the name used in the tags. @@ -317,841 +315,834 @@ Note that the end tag's name is preceded by a slash character, ""/"", and that i If attributes are not mentioned, default values are used in each case. "; - int interations = 1000; + int interations = 1000; - TimeOperation(() => - { - for (int i = 0; i < interations; i++) - { - using (StringWriter w = StringUtils.CreateStringWriter(StringUtils.GetLength(text) ?? 16)) - { - char[] buffer = null; - JavaScriptUtils.WriteEscapedJavaScriptString(w, text, '"', true, JavaScriptUtils.DoubleQuoteCharEscapeFlags, StringEscapeHandling.Default, ref buffer); - } + TimeOperation(() => + { + for (int i = 0; i < interations; i++) + { + using (StringWriter w = StringUtils.CreateStringWriter(StringUtils.GetLength(text) ?? 16)) + { + char[] buffer = null; + JavaScriptUtils.WriteEscapedJavaScriptString(w, text, '"', true, JavaScriptUtils.DoubleQuoteCharEscapeFlags, StringEscapeHandling.Default, ref buffer); + } + } + + return ""; + }, "New"); } - return ""; - }, "New"); - } - - [Test] - public void JTokenToObject() - { - JValue s = new JValue("String!"); - - int interations = 1000000; - - TimeOperation(() => - { - for (int i = 0; i < interations; i++) + [Test] + public void JTokenToObject() { - s.ToObject(typeof (string)); + JValue s = new JValue("String!"); + + int interations = 1000000; + + TimeOperation(() => + { + for (int i = 0; i < interations; i++) + { + s.ToObject(typeof(string)); + } + + return ""; + }, "New"); + + TimeOperation(() => + { + for (int i = 0; i < interations; i++) + { + s.ToObject(typeof(string), new JsonSerializer()); + } + + return ""; + }, "Old"); + + TimeOperation(() => + { + for (int i = 0; i < interations; i++) + { + s.Value(); + } + + return ""; + }, "Value"); } - return ""; - }, "New"); - - TimeOperation(() => - { - for (int i = 0; i < interations; i++) + private void SerializeSize(object value) { - s.ToObject(typeof(string), new JsonSerializer()); + // this is extremely slow with 5000 interations + int interations = 100; + + byte[] jsonBytes = TimeOperation(() => + { + string json = null; + for (int i = 0; i < interations; i++) + { + json = JsonConvert.SerializeObject(value, Formatting.None); + } + + return Encoding.UTF8.GetBytes(json); + }, "Json.NET"); + + byte[] bsonBytes = TimeOperation(() => + { + MemoryStream ms = null; + for (int i = 0; i < interations; i++) + { + ms = new MemoryStream(); + JsonSerializer serializer = new JsonSerializer(); + BsonWriter writer = new BsonWriter(ms); + + serializer.Serialize(writer, value); + writer.Flush(); + } + + return ms.ToArray(); + }, "Json.NET BSON"); + + byte[] xmlBytes = TimeOperation(() => + { + MemoryStream ms = null; + for (int i = 0; i < interations; i++) + { + ms = new MemoryStream(); + DataContractSerializer dataContractSerializer = new DataContractSerializer(value.GetType()); + dataContractSerializer.WriteObject(ms, value); + } + + return ms.ToArray(); + }, "DataContractSerializer"); + + byte[] wcfJsonBytes = TimeOperation(() => + { + MemoryStream ms = null; + for (int i = 0; i < interations; i++) + { + ms = new MemoryStream(); + DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(value.GetType()); + dataContractJsonSerializer.WriteObject(ms, value); + } + + return ms.ToArray(); + }, "DataContractJsonSerializer"); + + byte[] binaryFormatterBytes = TimeOperation(() => + { + MemoryStream ms = null; + for (int i = 0; i < interations; i++) + { + ms = new MemoryStream(); + BinaryFormatter formatter = new BinaryFormatter(); + formatter.Serialize(ms, value); + } + + return ms.ToArray(); + }, "BinaryFormatter"); + + Console.WriteLine("Json.NET size: {0} bytes", jsonBytes.Length); + Console.WriteLine("BSON size: {0} bytes", bsonBytes.Length); + Console.WriteLine("WCF JSON size: {0} bytes", wcfJsonBytes.Length); + Console.WriteLine("WCF XML size: {0} bytes", xmlBytes.Length); + Console.WriteLine("BinaryFormatter size: {0} bytes", binaryFormatterBytes.Length); } - return ""; - }, "Old"); + #region Serialize + private static readonly byte[] Buffer = new byte[4096]; - TimeOperation(() => - { - for (int i = 0; i < interations; i++) + public void BenchmarkSerializeMethod(SerializeMethod method, object value) { - s.Value(); + Serialize(method, value); + + Stopwatch timed = new Stopwatch(); + timed.Start(); + + string json = null; + for (int x = 0; x < Iterations; x++) + { + json = Serialize(method, value); + } + + timed.Stop(); + + Console.WriteLine("Serialize method: {0}", method); + Console.WriteLine("{0} ms", timed.ElapsedMilliseconds); + Console.WriteLine(json); + Console.WriteLine(); } - return ""; - }, "Value"); - } - - private void SerializeSize(object value) - { - // this is extremely slow with 5000 interations - int interations = 100; - - byte[] jsonBytes = TimeOperation(() => + private TestClass CreateSerializationObject() { - string json = null; - for (int i = 0; i < interations; i++) - { - json = JsonConvert.SerializeObject(value, Formatting.None); - } + TestClass test = new TestClass(); - return Encoding.UTF8.GetBytes(json); - }, "Json.NET"); + test.dictionary = new Dictionary { { "Val & asd1", 1 }, { "Val2 & asd1", 3 }, { "Val3 & asd1", 4 } }; - byte[] bsonBytes = TimeOperation(() => + + test.Address1.Street = "fff Street"; + test.Address1.Entered = DateTime.Now.AddDays(20); + + test.BigNumber = 34123123123.121M; + test.Now = DateTime.Now.AddHours(1); + test.strings = new List() { null, "Markus egger ]><[, (2nd)", null }; + + Address address = new Address(); + address.Entered = DateTime.Now.AddDays(-1); + address.Street = "\u001farray\u003caddress"; + + test.Addresses.Add(address); + + address = new Address(); + address.Entered = DateTime.Now.AddDays(-2); + address.Street = "array 2 address"; + test.Addresses.Add(address); + return test; + } + + private static SimpleObject CreateSimpleObject() { - MemoryStream ms = null; - for (int i = 0; i < interations; i++) - { - ms = new MemoryStream(); - JsonSerializer serializer = new JsonSerializer(); - BsonWriter writer = new BsonWriter(ms); + return new SimpleObject + { + Name = "Simple-1", + Id = 2311, + Address = "Planet Earth", + Scores = new[] { 82, 96, 49, 40, 38, 38, 78, 96, 2, 39 } + }; + } - serializer.Serialize(writer, value); - writer.Flush(); - } - - return ms.ToArray(); - }, "Json.NET BSON"); - - byte[] xmlBytes = TimeOperation(() => + public string SerializeWebExtensions(object value) { - MemoryStream ms = null; - for (int i = 0; i < interations; i++) - { - ms = new MemoryStream(); - DataContractSerializer dataContractSerializer = new DataContractSerializer(value.GetType()); + JavaScriptSerializer ser = new JavaScriptSerializer(); + + return ser.Serialize(value); + } + + public string SerializeDataContractJson(object value) + { + DataContractJsonSerializer dataContractSerializer + = new DataContractJsonSerializer(value.GetType()); + + MemoryStream ms = new MemoryStream(); dataContractSerializer.WriteObject(ms, value); - } - return ms.ToArray(); - }, "DataContractSerializer"); + ms.Seek(0, SeekOrigin.Begin); - byte[] wcfJsonBytes = TimeOperation(() => + using (StreamReader sr = new StreamReader(ms)) + { + return sr.ReadToEnd(); + } + } + + public string SerializeDataContract(object value) { - MemoryStream ms = null; - for (int i = 0; i < interations; i++) - { - ms = new MemoryStream(); - DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(value.GetType()); - dataContractJsonSerializer.WriteObject(ms, value); - } + DataContractSerializer dataContractSerializer + = new DataContractSerializer(value.GetType()); - return ms.ToArray(); - }, "DataContractJsonSerializer"); + MemoryStream ms = new MemoryStream(); + dataContractSerializer.WriteObject(ms, value); - byte[] binaryFormatterBytes = TimeOperation(() => + ms.Seek(0, SeekOrigin.Begin); + + using (StreamReader sr = new StreamReader(ms)) + { + return sr.ReadToEnd(); + } + } + + private string Serialize(SerializeMethod method, object value) { - MemoryStream ms = null; - for (int i = 0; i < interations; i++) - { - ms = new MemoryStream(); + string json; + + switch (method) + { + case SerializeMethod.JsonNet: + json = JsonConvert.SerializeObject(value); + break; + case SerializeMethod.JsonNetWithIsoConverter: + json = JsonConvert.SerializeObject(value, new IsoDateTimeConverter()); + break; + case SerializeMethod.JsonNetLinq: + { + TestClass c = value as TestClass; + if (c != null) + { + JObject o = new JObject( + new JProperty("strings", new JArray( + c.strings + )), + new JProperty("dictionary", new JObject(c.dictionary.Select(d => new JProperty(d.Key, d.Value)))), + new JProperty("Name", c.Name), + new JProperty("Now", c.Now), + new JProperty("BigNumber", c.BigNumber), + new JProperty("Address1", new JObject( + new JProperty("Street", c.Address1.Street), + new JProperty("Phone", c.Address1.Phone), + new JProperty("Entered", c.Address1.Entered))), + new JProperty("Addresses", new JArray(c.Addresses.Select(a => + new JObject( + new JProperty("Street", a.Street), + new JProperty("Phone", a.Phone), + new JProperty("Entered", a.Entered))))) + ); + + json = o.ToString(Formatting.None); + } + else + { + json = string.Empty; + } + break; + } + case SerializeMethod.JsonNetManual: + { + TestClass c = value as TestClass; + if (c != null) + { + StringWriter sw = new StringWriter(); + JsonTextWriter writer = new JsonTextWriter(sw); + writer.WriteStartObject(); + writer.WritePropertyName("strings"); + writer.WriteStartArray(); + foreach (string s in c.strings) + { + writer.WriteValue(s); + } + writer.WriteEndArray(); + writer.WritePropertyName("dictionary"); + writer.WriteStartObject(); + foreach (KeyValuePair keyValuePair in c.dictionary) + { + writer.WritePropertyName(keyValuePair.Key); + writer.WriteValue(keyValuePair.Value); + } + writer.WriteEndObject(); + writer.WritePropertyName("Name"); + writer.WriteValue(c.Name); + writer.WritePropertyName("Now"); + writer.WriteValue(c.Now); + writer.WritePropertyName("BigNumber"); + writer.WriteValue(c.BigNumber); + writer.WritePropertyName("Address1"); + writer.WriteStartObject(); + writer.WritePropertyName("Street"); + writer.WriteValue(c.BigNumber); + writer.WritePropertyName("Street"); + writer.WriteValue(c.BigNumber); + writer.WritePropertyName("Street"); + writer.WriteValue(c.BigNumber); + writer.WriteEndObject(); + writer.WritePropertyName("Addresses"); + writer.WriteStartArray(); + foreach (Address address in c.Addresses) + { + writer.WriteStartObject(); + writer.WritePropertyName("Street"); + writer.WriteValue(address.Street); + writer.WritePropertyName("Phone"); + writer.WriteValue(address.Phone); + writer.WritePropertyName("Entered"); + writer.WriteValue(address.Entered); + writer.WriteEndObject(); + } + writer.WriteEndArray(); + writer.WriteEndObject(); + + writer.Flush(); + json = sw.ToString(); + } + else + { + json = string.Empty; + } + break; + } + case SerializeMethod.JsonNetBinary: + { + MemoryStream ms = new MemoryStream(Buffer); + JsonSerializer serializer = new JsonSerializer(); + BsonWriter writer = new BsonWriter(ms); + serializer.Serialize(writer, value); + + //json = BitConverter.ToString(ms.ToArray(), 0, (int)ms.Position); + json = "Bytes = " + ms.Position; + break; + } + case SerializeMethod.JavaScriptSerializer: + json = SerializeWebExtensions(value); + break; + case SerializeMethod.DataContractJsonSerializer: + json = SerializeDataContractJson(value); + break; + case SerializeMethod.DataContractSerializer: + json = SerializeDataContract(value); + break; + case SerializeMethod.BinaryFormatter: + json = SerializeBinaryFormatter(value); + break; + default: + throw new ArgumentOutOfRangeException("method"); + } + + return json; + } + + private string SerializeBinaryFormatter(object value) + { + string json; + MemoryStream ms = new MemoryStream(Buffer); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(ms, value); - } - return ms.ToArray(); - }, "BinaryFormatter"); - - Console.WriteLine("Json.NET size: {0} bytes", jsonBytes.Length); - Console.WriteLine("BSON size: {0} bytes", bsonBytes.Length); - Console.WriteLine("WCF JSON size: {0} bytes", wcfJsonBytes.Length); - Console.WriteLine("WCF XML size: {0} bytes", xmlBytes.Length); - Console.WriteLine("BinaryFormatter size: {0} bytes", binaryFormatterBytes.Length); - } - -#region Serialize - - private static readonly byte[] Buffer = new byte[4096]; - - public void BenchmarkSerializeMethod(SerializeMethod method, object value) - { - Serialize(method, value); - - Stopwatch timed = new Stopwatch(); - timed.Start(); - - string json = null; - for (int x = 0; x < Iterations; x++) - { - json = Serialize(method, value); - } - - timed.Stop(); - - Console.WriteLine("Serialize method: {0}", method); - Console.WriteLine("{0} ms", timed.ElapsedMilliseconds); - Console.WriteLine(json); - Console.WriteLine(); - } - - private TestClass CreateSerializationObject() - { - TestClass test = new TestClass(); - - test.dictionary = new Dictionary {{"Val & asd1", 1}, {"Val2 & asd1", 3}, {"Val3 & asd1", 4}}; - - - test.Address1.Street = "fff Street"; - test.Address1.Entered = DateTime.Now.AddDays(20); - - test.BigNumber = 34123123123.121M; - test.Now = DateTime.Now.AddHours(1); - test.strings = new List() {null, "Markus egger ]><[, (2nd)", null}; - - Address address = new Address(); - address.Entered = DateTime.Now.AddDays(-1); - address.Street = "\u001farray\u003caddress"; - - test.Addresses.Add(address); - - address = new Address(); - address.Entered = DateTime.Now.AddDays(-2); - address.Street = "array 2 address"; - test.Addresses.Add(address); - return test; - } - - private static SimpleObject CreateSimpleObject() - { - return new SimpleObject - { - Name = "Simple-1", - Id = 2311, - Address = "Planet Earth", - Scores = new [] { 82, 96, 49, 40, 38, 38, 78, 96, 2, 39 } - }; - } - - public string SerializeWebExtensions(object value) - { - JavaScriptSerializer ser = new JavaScriptSerializer(); - - return ser.Serialize(value); - } - - public string SerializeDataContractJson(object value) - { - DataContractJsonSerializer dataContractSerializer - = new DataContractJsonSerializer(value.GetType()); - - MemoryStream ms = new MemoryStream(); - dataContractSerializer.WriteObject(ms, value); - - ms.Seek(0, SeekOrigin.Begin); - - using (StreamReader sr = new StreamReader(ms)) - { - return sr.ReadToEnd(); - } - } - - public string SerializeDataContract(object value) - { - DataContractSerializer dataContractSerializer - = new DataContractSerializer(value.GetType()); - - MemoryStream ms = new MemoryStream(); - dataContractSerializer.WriteObject(ms, value); - - ms.Seek(0, SeekOrigin.Begin); - - using (StreamReader sr = new StreamReader(ms)) - { - return sr.ReadToEnd(); - } - } - - private string Serialize(SerializeMethod method, object value) - { - string json; - - switch (method) - { - case SerializeMethod.JsonNet: - json = JsonConvert.SerializeObject(value); - break; - case SerializeMethod.JsonNetWithIsoConverter: - json = JsonConvert.SerializeObject(value, new IsoDateTimeConverter()); - break; - case SerializeMethod.JsonNetLinq: - { - TestClass c = value as TestClass; - if (c != null) - { - JObject o = new JObject( - new JProperty("strings", new JArray( - c.strings - )), - new JProperty("dictionary", new JObject(c.dictionary.Select(d => new JProperty(d.Key, d.Value)))), - new JProperty("Name", c.Name), - new JProperty("Now", c.Now), - new JProperty("BigNumber", c.BigNumber), - new JProperty("Address1", new JObject( - new JProperty("Street", c.Address1.Street), - new JProperty("Phone", c.Address1.Phone), - new JProperty("Entered", c.Address1.Entered))), - new JProperty("Addresses", new JArray(c.Addresses.Select(a => - new JObject( - new JProperty("Street", a.Street), - new JProperty("Phone", a.Phone), - new JProperty("Entered", a.Entered))))) - ); - - json = o.ToString(Formatting.None); - } - else - { - json = string.Empty; - } - break; - } - case SerializeMethod.JsonNetManual: - { - TestClass c = value as TestClass; - if (c != null) - { - StringWriter sw = new StringWriter(); - JsonTextWriter writer = new JsonTextWriter(sw); - writer.WriteStartObject(); - writer.WritePropertyName("strings"); - writer.WriteStartArray(); - foreach (string s in c.strings) - { - writer.WriteValue(s); - } - writer.WriteEndArray(); - writer.WritePropertyName("dictionary"); - writer.WriteStartObject(); - foreach (KeyValuePair keyValuePair in c.dictionary) - { - writer.WritePropertyName(keyValuePair.Key); - writer.WriteValue(keyValuePair.Value); - } - writer.WriteEndObject(); - writer.WritePropertyName("Name"); - writer.WriteValue(c.Name); - writer.WritePropertyName("Now"); - writer.WriteValue(c.Now); - writer.WritePropertyName("BigNumber"); - writer.WriteValue(c.BigNumber); - writer.WritePropertyName("Address1"); - writer.WriteStartObject(); - writer.WritePropertyName("Street"); - writer.WriteValue(c.BigNumber); - writer.WritePropertyName("Street"); - writer.WriteValue(c.BigNumber); - writer.WritePropertyName("Street"); - writer.WriteValue(c.BigNumber); - writer.WriteEndObject(); - writer.WritePropertyName("Addresses"); - writer.WriteStartArray(); - foreach (Address address in c.Addresses) - { - writer.WriteStartObject(); - writer.WritePropertyName("Street"); - writer.WriteValue(address.Street); - writer.WritePropertyName("Phone"); - writer.WriteValue(address.Phone); - writer.WritePropertyName("Entered"); - writer.WriteValue(address.Entered); - writer.WriteEndObject(); - } - writer.WriteEndArray(); - writer.WriteEndObject(); - - writer.Flush(); - json = sw.ToString(); - } - else - { - json = string.Empty; - } - break; - } - case SerializeMethod.JsonNetBinary: - { - MemoryStream ms = new MemoryStream(Buffer); - JsonSerializer serializer = new JsonSerializer(); - BsonWriter writer = new BsonWriter(ms); - serializer.Serialize(writer, value); - - //json = BitConverter.ToString(ms.ToArray(), 0, (int)ms.Position); json = "Bytes = " + ms.Position; - break; - } - case SerializeMethod.JavaScriptSerializer: - json = SerializeWebExtensions(value); - break; - case SerializeMethod.DataContractJsonSerializer: - json = SerializeDataContractJson(value); - break; - case SerializeMethod.DataContractSerializer: - json = SerializeDataContract(value); - break; - case SerializeMethod.BinaryFormatter: - json = SerializeBinaryFormatter(value); - break; - default: - throw new ArgumentOutOfRangeException("method"); - } - - return json; - } - - private string SerializeBinaryFormatter(object value) - { - string json; - MemoryStream ms = new MemoryStream(Buffer); - BinaryFormatter formatter = new BinaryFormatter(); - formatter.Serialize(ms, value); - - json = "Bytes = " + ms.Position; - //json = BitConverter.ToString(ms.ToArray(), 0, (int)ms.Position); - return json; - } - - #endregion - -#region Deserialize - - public void BenchmarkDeserializeMethod(SerializeMethod method, object json) - { - Deserialize(method, json); - - Stopwatch timed = new Stopwatch(); - timed.Start(); - - T value = default(T); - for (int x = 0; x < Iterations; x++) - { - value = Deserialize(method, json); - } - - timed.Stop(); - - Console.WriteLine("Deserialize method: {0}", method); - Console.WriteLine("{0} ms", timed.ElapsedMilliseconds); - Console.WriteLine(value); - Console.WriteLine(); - } - - public T DeserializeJsonNet(string json, bool isoDateTimeConverter) - { - Type type = typeof (T); - - JsonSerializer serializer = new JsonSerializer(); - //serializer.ObjectCreationHandling = Newtonsoft.Json.ObjectCreationHandling.Replace; - //serializer.MissingMemberHandling = Newtonsoft.Json.MissingMemberHandling.Ignore; - //serializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; - if (isoDateTimeConverter) - serializer.Converters.Add(new IsoDateTimeConverter()); - - var value = (T) serializer.Deserialize(new StringReader(json), type); - return value; - } - - public TestClass DeserializeJsonNetManual(string json) - { - TestClass c = new TestClass(); - - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - reader.Read(); - while (reader.Read()) - { - if (reader.TokenType == JsonToken.PropertyName) - { - string propertyName = (string) reader.Value; - switch (propertyName) - { - case "strings": - reader.Read(); - while (reader.Read() && reader.TokenType != JsonToken.EndArray) - { - c.strings.Add((string) reader.Value); - } - break; - case "dictionary": - reader.Read(); - while (reader.Read() && reader.TokenType != JsonToken.EndObject) - { - string key = (string) reader.Value; - c.dictionary.Add(key, reader.ReadAsInt32().GetValueOrDefault()); - } - break; - case "Name": - c.Name = reader.ReadAsString(); - break; - case "Now": - c.Now = reader.ReadAsDateTime().GetValueOrDefault(); - break; - case "BigNumber": - c.BigNumber = reader.ReadAsDecimal().GetValueOrDefault(); - break; - case "Address1": - reader.Read(); - c.Address1 = CreateAddress(reader); - break; - case "Addresses": - reader.Read(); - while (reader.Read() && reader.TokenType != JsonToken.EndArray) - { - var address = CreateAddress(reader); - c.Addresses.Add(address); - } - break; - } + //json = BitConverter.ToString(ms.ToArray(), 0, (int)ms.Position); + return json; } - else + #endregion + + #region Deserialize + public void BenchmarkDeserializeMethod(SerializeMethod method, object json) { - break; + Deserialize(method, json); + + Stopwatch timed = new Stopwatch(); + timed.Start(); + + T value = default(T); + for (int x = 0; x < Iterations; x++) + { + value = Deserialize(method, json); + } + + timed.Stop(); + + Console.WriteLine("Deserialize method: {0}", method); + Console.WriteLine("{0} ms", timed.ElapsedMilliseconds); + Console.WriteLine(value); + Console.WriteLine(); } - } - return c; - } - - private static Address CreateAddress(JsonTextReader reader) - { - Address a = new Address(); - while (reader.Read()) - { - if (reader.TokenType == JsonToken.PropertyName) + public T DeserializeJsonNet(string json, bool isoDateTimeConverter) { - switch ((string) reader.Value) - { - case "Street": - a.Street = reader.ReadAsString(); - break; - case "Phone": - a.Phone = reader.ReadAsString(); - break; - case "Entered": - a.Entered = reader.ReadAsDateTime().GetValueOrDefault(); - break; - } + Type type = typeof(T); + + JsonSerializer serializer = new JsonSerializer(); + //serializer.ObjectCreationHandling = Newtonsoft.Json.ObjectCreationHandling.Replace; + //serializer.MissingMemberHandling = Newtonsoft.Json.MissingMemberHandling.Ignore; + //serializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; + if (isoDateTimeConverter) + serializer.Converters.Add(new IsoDateTimeConverter()); + + var value = (T)serializer.Deserialize(new StringReader(json), type); + return value; } - else + + public TestClass DeserializeJsonNetManual(string json) { - break; + TestClass c = new TestClass(); + + JsonTextReader reader = new JsonTextReader(new StringReader(json)); + reader.Read(); + while (reader.Read()) + { + if (reader.TokenType == JsonToken.PropertyName) + { + string propertyName = (string)reader.Value; + switch (propertyName) + { + case "strings": + reader.Read(); + while (reader.Read() && reader.TokenType != JsonToken.EndArray) + { + c.strings.Add((string)reader.Value); + } + break; + case "dictionary": + reader.Read(); + while (reader.Read() && reader.TokenType != JsonToken.EndObject) + { + string key = (string)reader.Value; + c.dictionary.Add(key, reader.ReadAsInt32().GetValueOrDefault()); + } + break; + case "Name": + c.Name = reader.ReadAsString(); + break; + case "Now": + c.Now = reader.ReadAsDateTime().GetValueOrDefault(); + break; + case "BigNumber": + c.BigNumber = reader.ReadAsDecimal().GetValueOrDefault(); + break; + case "Address1": + reader.Read(); + c.Address1 = CreateAddress(reader); + break; + case "Addresses": + reader.Read(); + while (reader.Read() && reader.TokenType != JsonToken.EndArray) + { + var address = CreateAddress(reader); + c.Addresses.Add(address); + } + break; + } + } + else + { + break; + } + } + + return c; } - } - return a; - } - public T DeserializeJsonNetBinary(byte[] bson) - { - Type type = typeof (T); + private static Address CreateAddress(JsonTextReader reader) + { + Address a = new Address(); + while (reader.Read()) + { + if (reader.TokenType == JsonToken.PropertyName) + { + switch ((string)reader.Value) + { + case "Street": + a.Street = reader.ReadAsString(); + break; + case "Phone": + a.Phone = reader.ReadAsString(); + break; + case "Entered": + a.Entered = reader.ReadAsDateTime().GetValueOrDefault(); + break; + } + } + else + { + break; + } + } + return a; + } - JsonSerializer serializer = new JsonSerializer(); - serializer.ObjectCreationHandling = Newtonsoft.Json.ObjectCreationHandling.Replace; - serializer.MissingMemberHandling = Newtonsoft.Json.MissingMemberHandling.Ignore; - serializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; + public T DeserializeJsonNetBinary(byte[] bson) + { + Type type = typeof(T); - return (T) serializer.Deserialize(new BsonReader(new MemoryStream(bson)), type); - } + JsonSerializer serializer = new JsonSerializer(); + serializer.ObjectCreationHandling = Newtonsoft.Json.ObjectCreationHandling.Replace; + serializer.MissingMemberHandling = Newtonsoft.Json.MissingMemberHandling.Ignore; + serializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; - public T DeserializeWebExtensions(string json) - { - JavaScriptSerializer ser = new JavaScriptSerializer(); + return (T)serializer.Deserialize(new BsonReader(new MemoryStream(bson)), type); + } - return ser.Deserialize(json); - } + public T DeserializeWebExtensions(string json) + { + JavaScriptSerializer ser = new JavaScriptSerializer(); - public T DeserializeDataContractJson(string json) - { - DataContractJsonSerializer dataContractSerializer - = new DataContractJsonSerializer(typeof (T)); + return ser.Deserialize(json); + } - MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json)); + public T DeserializeDataContractJson(string json) + { + DataContractJsonSerializer dataContractSerializer + = new DataContractJsonSerializer(typeof(T)); - return (T) dataContractSerializer.ReadObject(ms); - } + MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json)); - private T Deserialize(SerializeMethod method, object json) - { - switch (method) - { - case SerializeMethod.JsonNet: - return DeserializeJsonNet((string)json, false); - case SerializeMethod.JsonNetWithIsoConverter: - return DeserializeJsonNet((string)json, true); - case SerializeMethod.JsonNetManual: - if (typeof(T) == typeof(TestClass)) - return (T)(object)DeserializeJsonNetManual((string)json); + return (T)dataContractSerializer.ReadObject(ms); + } - return default(T); - case SerializeMethod.JsonNetBinary: - return DeserializeJsonNetBinary((byte[]) json); - case SerializeMethod.BinaryFormatter: - return DeserializeBinaryFormatter((byte[]) json); - case SerializeMethod.JavaScriptSerializer: - return DeserializeWebExtensions((string) json); - case SerializeMethod.DataContractSerializer: - return DeserializeDataContract((string) json); - case SerializeMethod.DataContractJsonSerializer: - return DeserializeDataContractJson((string) json); - default: - throw new ArgumentOutOfRangeException("method"); - } - } + private T Deserialize(SerializeMethod method, object json) + { + switch (method) + { + case SerializeMethod.JsonNet: + return DeserializeJsonNet((string)json, false); + case SerializeMethod.JsonNetWithIsoConverter: + return DeserializeJsonNet((string)json, true); + case SerializeMethod.JsonNetManual: + if (typeof(T) == typeof(TestClass)) + return (T)(object)DeserializeJsonNetManual((string)json); - private T DeserializeDataContract(string xml) - { - MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(xml)); + return default(T); + case SerializeMethod.JsonNetBinary: + return DeserializeJsonNetBinary((byte[])json); + case SerializeMethod.BinaryFormatter: + return DeserializeBinaryFormatter((byte[])json); + case SerializeMethod.JavaScriptSerializer: + return DeserializeWebExtensions((string)json); + case SerializeMethod.DataContractSerializer: + return DeserializeDataContract((string)json); + case SerializeMethod.DataContractJsonSerializer: + return DeserializeDataContractJson((string)json); + default: + throw new ArgumentOutOfRangeException("method"); + } + } - DataContractSerializer serializer = new DataContractSerializer(typeof (T)); - return (T) serializer.ReadObject(ms); - } + private T DeserializeDataContract(string xml) + { + MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(xml)); - private T DeserializeBinaryFormatter(byte[] bytes) - { - BinaryFormatter formatter = new BinaryFormatter(); - return (T) formatter.Deserialize(new MemoryStream(bytes)); - } + DataContractSerializer serializer = new DataContractSerializer(typeof(T)); + return (T)serializer.ReadObject(ms); + } - #endregion + private T DeserializeBinaryFormatter(byte[] bytes) + { + BinaryFormatter formatter = new BinaryFormatter(); + return (T)formatter.Deserialize(new MemoryStream(bytes)); + } + #endregion + [Test] + public void SerializeLargeObject() + { + LargeRecursiveTestClass rootValue = null; + LargeRecursiveTestClass parentValue = null; + for (int i = 0; i < 20; i++) + { + LargeRecursiveTestClass currentValue = new LargeRecursiveTestClass() + { + Integer = int.MaxValue, + Text = "The quick red fox jumped over the lazy dog." + }; + if (rootValue == null) + rootValue = currentValue; + if (parentValue != null) + parentValue.Child = currentValue; - [Test] - public void SerializeLargeObject() - { - LargeRecursiveTestClass rootValue = null; - LargeRecursiveTestClass parentValue = null; - for (int i = 0; i < 20; i++) - { - LargeRecursiveTestClass currentValue = new LargeRecursiveTestClass() - { - Integer = int.MaxValue, - Text = "The quick red fox jumped over the lazy dog." - }; + parentValue = currentValue; + } - if (rootValue == null) - rootValue = currentValue; - if (parentValue != null) - parentValue.Child = currentValue; + BenchmarkSerializeMethod(SerializeMethod.JsonNetBinary, rootValue); + } - parentValue = currentValue; - } + [Test] + public void SerializeUnicodeChars() + { + string s = (new string('\0', 30)); - BenchmarkSerializeMethod(SerializeMethod.JsonNetBinary, rootValue); - } + BenchmarkSerializeMethod(SerializeMethod.JsonNet, s); + } - [Test] - public void SerializeUnicodeChars() - { - string s = (new string('\0', 30)); - - BenchmarkSerializeMethod(SerializeMethod.JsonNet, s); - } - - [Test] - public void ParseJObject() - { - Stopwatch timer = new Stopwatch(); - timer.Start(); - for (int i = 0; i < 100000; i++) - { - JObject o = JObject.Parse(@"{ + [Test] + public void ParseJObject() + { + Stopwatch timer = new Stopwatch(); + timer.Start(); + for (int i = 0; i < 100000; i++) + { + JObject o = JObject.Parse(@"{ ""CPU"": ""Intel"", ""Drives"": [ ""DVD read/writer"", ""500 gigabyte hard drive"" ] }"); - } - timer.Stop(); + } + timer.Stop(); - string linq = timer.Elapsed.TotalSeconds.ToString(); - Console.WriteLine(linq); - } + string linq = timer.Elapsed.TotalSeconds.ToString(); + Console.WriteLine(linq); + } - [Test] - public void JObjectToString() - { - JObject test = JObject.Parse(JsonText); + [Test] + public void JObjectToString() + { + JObject test = JObject.Parse(JsonText); + + TimeOperation(() => + { + for (int i = 0; i < Iterations; i++) + { + test["dummy"] = new JValue(i); + test.ToString(Formatting.None); + } + return null; + }, "JObject.ToString"); + } - TimeOperation(() => + [Test] + public void JObjectToString2() { - for (int i = 0; i < Iterations; i++) - { - test["dummy"] = new JValue(i); - test.ToString(Formatting.None); - } - return null; - }, "JObject.ToString"); - } - - [Test] - public void JObjectToString2() - { - JObject test = JObject.Parse(JsonText); - MemoryStream ms = new MemoryStream(); - - TimeOperation(() => + JObject test = JObject.Parse(JsonText); + MemoryStream ms = new MemoryStream(); + + TimeOperation(() => + { + for (int i = 0; i < Iterations; i++) + { + test["dummy"] = new JValue(i); + ms.Seek(0, SeekOrigin.Begin); + JsonTextWriter jsonTextWriter = new JsonTextWriter(new StreamWriter(ms)); + test.WriteTo(jsonTextWriter); + jsonTextWriter.Flush(); + ms.ToArray(); + + //Encoding.UTF8.GetBytes(test.ToString(Formatting.None)); + } + return null; + }, "JObject.ToString"); + } + + [Test] + public void NestedJToken() { - for (int i = 0; i < Iterations; i++) - { - test["dummy"] = new JValue(i); - ms.Seek(0, SeekOrigin.Begin); - JsonTextWriter jsonTextWriter = new JsonTextWriter(new StreamWriter(ms)); - test.WriteTo(jsonTextWriter); - jsonTextWriter.Flush(); - ms.ToArray(); - - //Encoding.UTF8.GetBytes(test.ToString(Formatting.None)); - } - return null; - }, "JObject.ToString"); - } - - [Test] - public void NestedJToken() - { - Stopwatch sw; - for (int i = 10000; i <= 100000; i += 10000) - { - sw = new Stopwatch(); - sw.Start(); - JArray ija = new JArray(); - JToken ijt = ija; - for (int j = 0; j < i; j++) + Stopwatch sw; + for (int i = 10000; i <= 100000; i += 10000) + { + sw = new Stopwatch(); + sw.Start(); + JArray ija = new JArray(); + JToken ijt = ija; + for (int j = 0; j < i; j++) + { + JArray temp = new JArray(); + ija.Add(temp); + ija = temp; + } + ija.Add(1); + sw.Stop(); + Console.WriteLine("Created a JToken of depth {0} (using OM) in {1} millis", i, sw.ElapsedMilliseconds); + } + } + + [Test] + public void DeserializeNestedJToken() { - JArray temp = new JArray(); - ija.Add(temp); - ija = temp; + string json = (new string('[', 100000)) + "1" + ((new string(']', 100000))); + + Stopwatch sw; + sw = new Stopwatch(); + sw.Start(); + + var a = (JArray)JsonConvert.DeserializeObject(json); + + sw.Stop(); + + Assert.AreEqual(1, a.Count); + + Console.WriteLine("Deserialize big ass nested array in {0} millis", sw.ElapsedMilliseconds); } - ija.Add(1); - sw.Stop(); - Console.WriteLine("Created a JToken of depth {0} (using OM) in {1} millis", i, sw.ElapsedMilliseconds); - } } - [Test] - public void DeserializeNestedJToken() + public class LargeRecursiveTestClass { - string json = (new string('[', 100000)) + "1" + ((new string(']', 100000))); - - Stopwatch sw; - sw = new Stopwatch(); - sw.Start(); - - var a = (JArray)JsonConvert.DeserializeObject(json); - - sw.Stop(); - - Assert.AreEqual(1, a.Count); - - Console.WriteLine("Deserialize big ass nested array in {0} millis", sw.ElapsedMilliseconds); + public LargeRecursiveTestClass Child { get; set; } + public string Text { get; set; } + public int Integer { get; set; } } - } - public class LargeRecursiveTestClass - { - public LargeRecursiveTestClass Child { get; set; } - public string Text { get; set; } - public int Integer { get; set; } - } - -#region Classes - - [Serializable] - [DataContract] - public class TestClass - { - [DataMember] - public string Name + #region Classes + [Serializable] + [DataContract] + public class TestClass { - get { return _Name; } - set { _Name = value; } + [DataMember] + public string Name + { + get { return _Name; } + set { _Name = value; } + } + + private string _Name = "Rick"; + + [DataMember] + public DateTime Now + { + get { return _Now; } + set { _Now = value; } + } + + private DateTime _Now = DateTime.Now; + + [DataMember] + public decimal BigNumber + { + get { return _BigNumber; } + set { _BigNumber = value; } + } + + private decimal _BigNumber = 1212121.22M; + + [DataMember] + public Address Address1 + { + get { return _Address1; } + set { _Address1 = value; } + } + + private Address _Address1 = new Address(); + + + [DataMember] + public List
Addresses + { + get { return _Addresses; } + set { _Addresses = value; } + } + + private List
_Addresses = new List
(); + + [DataMember] + public List strings = new List(); + + [DataMember] + public Dictionary dictionary = new Dictionary(); } - private string _Name = "Rick"; - - [DataMember] - public DateTime Now + [Serializable] + [DataContract] + public class Address { - get { return _Now; } - set { _Now = value; } + [DataMember] + public string Street + { + get { return _street; } + set { _street = value; } + } + + private string _street = "32 Kaiea"; + + [DataMember] + public string Phone + { + get { return _Phone; } + set { _Phone = value; } + } + + private string _Phone = "(503) 814-6335"; + + [DataMember] + public DateTime Entered + { + get { return _Entered; } + set { _Entered = value; } + } + + private DateTime _Entered = DateTime.Parse("01/01/2007", CultureInfo.CurrentCulture.DateTimeFormat); } - private DateTime _Now = DateTime.Now; - - [DataMember] - public decimal BigNumber + [DataContract] + [Serializable] + public class SimpleObject { - get { return _BigNumber; } - set { _BigNumber = value; } + [DataMember] + public int Id { get; set; } + + [DataMember] + public string Name { get; set; } + + [DataMember] + public string Address { get; set; } + + [DataMember] + public int[] Scores { get; set; } } - - private decimal _BigNumber = 1212121.22M; - - [DataMember] - public Address Address1 - { - get { return _Address1; } - set { _Address1 = value; } - } - - private Address _Address1 = new Address(); - - - - [DataMember] - public List
Addresses - { - get { return _Addresses; } - set { _Addresses = value; } - } - - private List
_Addresses = new List
(); - - [DataMember] public List strings = new List(); - - [DataMember] public Dictionary dictionary = new Dictionary(); - } - - [Serializable] - [DataContract] - public class Address - { - [DataMember] - public string Street - { - get { return _street; } - set { _street = value; } - } - - private string _street = "32 Kaiea"; - - [DataMember] - public string Phone - { - get { return _Phone; } - set { _Phone = value; } - } - - private string _Phone = "(503) 814-6335"; - - [DataMember] - public DateTime Entered - { - get { return _Entered; } - set { _Entered = value; } - } - - private DateTime _Entered = DateTime.Parse("01/01/2007", CultureInfo.CurrentCulture.DateTimeFormat); - } - - [DataContract] - [Serializable] - public class SimpleObject - { - [DataMember] - public int Id { get; set; } - - [DataMember] - public string Name { get; set; } - - [DataMember] - public string Address { get; set; } - - [DataMember] - public int[] Scores { get; set; } - } - - #endregion + #endregion } #endif \ 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 d015dad3..5a1eb3c4 100644 --- a/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs +++ b/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs @@ -46,6 +46,7 @@ using System.Security; #elif NET40 [assembly: AssemblyTitle("Json.NET Tests .NET 4.0")] #else + [assembly: AssemblyTitle("Json.NET Tests")] #endif @@ -60,9 +61,11 @@ using System.Security; // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. + [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM + [assembly: Guid("0be3d72b-d2ef-409c-985c-d3ede89a25f1")] // Version information for an assembly consists of the following four values: @@ -74,5 +77,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.8.16617")] +[assembly: AssemblyFileVersion("5.0.8.16620")] \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Schema/ExtensionsTests.cs b/Src/Newtonsoft.Json.Tests/Schema/ExtensionsTests.cs index 6ecc7d58..5888f6ab 100644 --- a/Src/Newtonsoft.Json.Tests/Schema/ExtensionsTests.cs +++ b/Src/Newtonsoft.Json.Tests/Schema/ExtensionsTests.cs @@ -38,100 +38,101 @@ using System.IO; using Newtonsoft.Json.Tests.TestObjects; #if !(SILVERLIGHT || NETFX_CORE) using System.Data; + #endif namespace Newtonsoft.Json.Tests.Schema { - [TestFixture] - public class ExtensionsTests : TestFixtureBase - { - [Test] - public void IsValid() + [TestFixture] + public class ExtensionsTests : TestFixtureBase { - JsonSchema schema = JsonSchema.Parse("{'type':'integer'}"); - JToken stringToken = JToken.FromObject("pie"); - JToken integerToken = JToken.FromObject(1); + [Test] + public void IsValid() + { + JsonSchema schema = JsonSchema.Parse("{'type':'integer'}"); + JToken stringToken = JToken.FromObject("pie"); + JToken integerToken = JToken.FromObject(1); - IList errorMessages; - Assert.AreEqual(true, integerToken.IsValid(schema)); - Assert.AreEqual(true, integerToken.IsValid(schema, out errorMessages)); - Assert.AreEqual(0, errorMessages.Count); + IList errorMessages; + Assert.AreEqual(true, integerToken.IsValid(schema)); + Assert.AreEqual(true, integerToken.IsValid(schema, out errorMessages)); + Assert.AreEqual(0, errorMessages.Count); - Assert.AreEqual(false, stringToken.IsValid(schema)); - Assert.AreEqual(false, stringToken.IsValid(schema, out errorMessages)); - Assert.AreEqual(1, errorMessages.Count); - Assert.AreEqual("Invalid type. Expected Integer but got String.", errorMessages[0]); - } + Assert.AreEqual(false, stringToken.IsValid(schema)); + Assert.AreEqual(false, stringToken.IsValid(schema, out errorMessages)); + Assert.AreEqual(1, errorMessages.Count); + Assert.AreEqual("Invalid type. Expected Integer but got String.", errorMessages[0]); + } - [Test] - public void ValidateWithEventHandler() - { - JsonSchema schema = JsonSchema.Parse("{'pattern':'lol'}"); - JToken stringToken = JToken.FromObject("pie lol"); + [Test] + public void ValidateWithEventHandler() + { + JsonSchema schema = JsonSchema.Parse("{'pattern':'lol'}"); + JToken stringToken = JToken.FromObject("pie lol"); - List errors = new List(); - stringToken.Validate(schema, (sender, args) => errors.Add(args.Message)); - Assert.AreEqual(0, errors.Count); + List errors = new List(); + stringToken.Validate(schema, (sender, args) => errors.Add(args.Message)); + Assert.AreEqual(0, errors.Count); - stringToken = JToken.FromObject("pie"); + stringToken = JToken.FromObject("pie"); - stringToken.Validate(schema, (sender, args) => errors.Add(args.Message)); - Assert.AreEqual(1, errors.Count); + stringToken.Validate(schema, (sender, args) => errors.Add(args.Message)); + Assert.AreEqual(1, errors.Count); - Assert.AreEqual("String 'pie' does not match regex pattern 'lol'.", errors[0]); - } + Assert.AreEqual("String 'pie' does not match regex pattern 'lol'.", errors[0]); + } - [Test] - public void ValidateWithOutEventHandlerFailure() - { - ExceptionAssert.Throws(@"String 'pie' does not match regex pattern 'lol'.", - () => - { - JsonSchema schema = JsonSchema.Parse("{'pattern':'lol'}"); - JToken stringToken = JToken.FromObject("pie"); - stringToken.Validate(schema); - }); - } + [Test] + public void ValidateWithOutEventHandlerFailure() + { + ExceptionAssert.Throws(@"String 'pie' does not match regex pattern 'lol'.", + () => + { + JsonSchema schema = JsonSchema.Parse("{'pattern':'lol'}"); + JToken stringToken = JToken.FromObject("pie"); + stringToken.Validate(schema); + }); + } - [Test] - public void ValidateWithOutEventHandlerSuccess() - { - JsonSchema schema = JsonSchema.Parse("{'pattern':'lol'}"); - JToken stringToken = JToken.FromObject("pie lol"); - stringToken.Validate(schema); - } + [Test] + public void ValidateWithOutEventHandlerSuccess() + { + JsonSchema schema = JsonSchema.Parse("{'pattern':'lol'}"); + JToken stringToken = JToken.FromObject("pie lol"); + stringToken.Validate(schema); + } - [Test] - public void ValidateFailureWithOutLineInfoBecauseOfEndToken() - { - JsonSchema schema = JsonSchema.Parse("{'properties':{'lol':{'required':true}}}"); - JObject o = JObject.Parse("{}"); + [Test] + public void ValidateFailureWithOutLineInfoBecauseOfEndToken() + { + JsonSchema schema = JsonSchema.Parse("{'properties':{'lol':{'required':true}}}"); + JObject o = JObject.Parse("{}"); - List errors = new List(); - o.Validate(schema, (sender, args) => errors.Add(args.Message)); + List errors = new List(); + o.Validate(schema, (sender, args) => errors.Add(args.Message)); - Assert.AreEqual("Required properties are missing from object: lol.", errors[0]); - Assert.AreEqual(1, errors.Count); - } + Assert.AreEqual("Required properties are missing from object: lol.", errors[0]); + Assert.AreEqual(1, errors.Count); + } - [Test] - public void ValidateFailureWithLineInfo() - { - JsonSchema schema = JsonSchema.Parse("{'properties':{'lol':{'type':'string'}}}"); - JObject o = JObject.Parse("{'lol':1}"); + [Test] + public void ValidateFailureWithLineInfo() + { + JsonSchema schema = JsonSchema.Parse("{'properties':{'lol':{'type':'string'}}}"); + JObject o = JObject.Parse("{'lol':1}"); - List errors = new List(); - o.Validate(schema, (sender, args) => errors.Add(args.Path + " - " + args.Message)); + List errors = new List(); + o.Validate(schema, (sender, args) => errors.Add(args.Path + " - " + args.Message)); - Assert.AreEqual("lol - Invalid type. Expected String but got Integer. Line 1, position 8.", errors[0]); - Assert.AreEqual("1", o.SelectToken("lol").ToString()); - Assert.AreEqual(1, errors.Count); - } + Assert.AreEqual("lol - Invalid type. Expected String but got Integer. Line 1, position 8.", errors[0]); + Assert.AreEqual("1", o.SelectToken("lol").ToString()); + Assert.AreEqual(1, errors.Count); + } - [Test] - public void Blog() - { - string schemaJson = @" + [Test] + public void Blog() + { + string schemaJson = @" { ""description"": ""A person schema"", ""type"": ""object"", @@ -146,80 +147,77 @@ namespace Newtonsoft.Json.Tests.Schema } "; - //JsonSchema schema; + //JsonSchema schema; - //using (JsonTextReader reader = new JsonTextReader(new StringReader(schemaJson))) - //{ - // JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - // schema = builder.Parse(reader); - //} + //using (JsonTextReader reader = new JsonTextReader(new StringReader(schemaJson))) + //{ + // JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + // schema = builder.Parse(reader); + //} - JsonSchema schema = JsonSchema.Parse(schemaJson); + JsonSchema schema = JsonSchema.Parse(schemaJson); - JObject person = JObject.Parse(@"{ + JObject person = JObject.Parse(@"{ ""name"": ""James"", ""hobbies"": ["".NET"", ""Blogging"", ""Reading"", ""Xbox"", ""LOLCATS""] }"); - bool valid = person.IsValid(schema); - // true - } + bool valid = person.IsValid(schema); + // true + } - private void GenerateSchemaAndSerializeFromType(T value) - { - JsonSchemaGenerator generator = new JsonSchemaGenerator(); - generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseAssemblyQualifiedName; - JsonSchema typeSchema = generator.Generate(typeof (T)); - string schema = typeSchema.ToString(); + private void GenerateSchemaAndSerializeFromType(T value) + { + JsonSchemaGenerator generator = new JsonSchemaGenerator(); + generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseAssemblyQualifiedName; + JsonSchema typeSchema = generator.Generate(typeof(T)); + string schema = typeSchema.ToString(); - string json = JsonConvert.SerializeObject(value, Formatting.Indented); - JToken token = JToken.ReadFrom(new JsonTextReader(new StringReader(json))); + string json = JsonConvert.SerializeObject(value, Formatting.Indented); + JToken token = JToken.ReadFrom(new JsonTextReader(new StringReader(json))); - List errors = new List(); + List errors = new List(); - token.Validate(typeSchema, (sender, args) => - { - errors.Add(args.Message); - }); + token.Validate(typeSchema, (sender, args) => { errors.Add(args.Message); }); - if (errors.Count > 0) - Assert.Fail("Schema generated for type '{0}' is not valid." + Environment.NewLine + string.Join(Environment.NewLine, errors.ToArray()), typeof(T)); - } + if (errors.Count > 0) + Assert.Fail("Schema generated for type '{0}' is not valid." + Environment.NewLine + string.Join(Environment.NewLine, errors.ToArray()), typeof(T)); + } - [Test] - public void GenerateSchemaAndSerializeFromTypeTests() - { - GenerateSchemaAndSerializeFromType(new List { "1", "Two", "III" }); - GenerateSchemaAndSerializeFromType(new List { 1 }); - GenerateSchemaAndSerializeFromType(new Version("1.2.3.4")); - GenerateSchemaAndSerializeFromType(new Store()); - GenerateSchemaAndSerializeFromType(new Person()); - GenerateSchemaAndSerializeFromType(new PersonRaw()); - GenerateSchemaAndSerializeFromType(new CircularReferenceClass() { Name = "I'm required" }); - GenerateSchemaAndSerializeFromType(new CircularReferenceWithIdClass()); - GenerateSchemaAndSerializeFromType(new ClassWithArray()); - GenerateSchemaAndSerializeFromType(new ClassWithGuid()); + [Test] + public void GenerateSchemaAndSerializeFromTypeTests() + { + GenerateSchemaAndSerializeFromType(new List { "1", "Two", "III" }); + GenerateSchemaAndSerializeFromType(new List { 1 }); + GenerateSchemaAndSerializeFromType(new Version("1.2.3.4")); + GenerateSchemaAndSerializeFromType(new Store()); + GenerateSchemaAndSerializeFromType(new Person()); + GenerateSchemaAndSerializeFromType(new PersonRaw()); + GenerateSchemaAndSerializeFromType(new CircularReferenceClass() { Name = "I'm required" }); + GenerateSchemaAndSerializeFromType(new CircularReferenceWithIdClass()); + GenerateSchemaAndSerializeFromType(new ClassWithArray()); + GenerateSchemaAndSerializeFromType(new ClassWithGuid()); #if !NET20 - GenerateSchemaAndSerializeFromType(new NullableDateTimeTestClass()); + GenerateSchemaAndSerializeFromType(new NullableDateTimeTestClass()); #endif #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - GenerateSchemaAndSerializeFromType(new DataSet()); + GenerateSchemaAndSerializeFromType(new DataSet()); #endif - GenerateSchemaAndSerializeFromType(new object()); - GenerateSchemaAndSerializeFromType(1); - GenerateSchemaAndSerializeFromType("Hi"); - GenerateSchemaAndSerializeFromType(new DateTime(2000, 12, 29, 23, 59, 0, DateTimeKind.Utc)); - GenerateSchemaAndSerializeFromType(TimeSpan.FromTicks(1000000)); + GenerateSchemaAndSerializeFromType(new object()); + GenerateSchemaAndSerializeFromType(1); + GenerateSchemaAndSerializeFromType("Hi"); + GenerateSchemaAndSerializeFromType(new DateTime(2000, 12, 29, 23, 59, 0, DateTimeKind.Utc)); + GenerateSchemaAndSerializeFromType(TimeSpan.FromTicks(1000000)); #if !(NETFX_CORE || PORTABLE || PORTABLE40) - GenerateSchemaAndSerializeFromType(DBNull.Value); + GenerateSchemaAndSerializeFromType(DBNull.Value); #endif - GenerateSchemaAndSerializeFromType(new JsonPropertyWithHandlingValues()); - } + GenerateSchemaAndSerializeFromType(new JsonPropertyWithHandlingValues()); + } - [Test] - public void UndefinedPropertyOnNoPropertySchema() - { - JsonSchema schema = JsonSchema.Parse(@"{ + [Test] + public void UndefinedPropertyOnNoPropertySchema() + { + JsonSchema schema = JsonSchema.Parse(@"{ ""description"": ""test"", ""type"": ""object"", ""additionalProperties"": false, @@ -227,229 +225,229 @@ namespace Newtonsoft.Json.Tests.Schema } }"); - JObject o = JObject.Parse("{'g':1}"); + JObject o = JObject.Parse("{'g':1}"); - List errors = new List(); - o.Validate(schema, (sender, args) => errors.Add(args.Message)); + List errors = new List(); + o.Validate(schema, (sender, args) => errors.Add(args.Message)); - Assert.AreEqual(1, errors.Count); - Assert.AreEqual("Property 'g' has not been defined and the schema does not allow additional properties. Line 1, position 5.", errors[0]); - } + Assert.AreEqual(1, errors.Count); + Assert.AreEqual("Property 'g' has not been defined and the schema does not allow additional properties. Line 1, position 5.", errors[0]); + } - [Test] - public void ExclusiveMaximum_Int() - { - ExceptionAssert.Throws("Integer 10 equals maximum value of 10 and exclusive maximum is true.", - () => - { - JsonSchema schema = new JsonSchema(); - schema.Maximum = 10; - schema.ExclusiveMaximum = true; - - JValue v = new JValue(10); - v.Validate(schema); - }); - } - - [Test] - public void ExclusiveMaximum_Float() - { - ExceptionAssert.Throws("Float 10.1 equals maximum value of 10.1 and exclusive maximum is true.", - () => - { - JsonSchema schema = new JsonSchema(); - schema.Maximum = 10.1; - schema.ExclusiveMaximum = true; - - JValue v = new JValue(10.1); - v.Validate(schema); - }); - } - - [Test] - public void ExclusiveMinimum_Int() - { - ExceptionAssert.Throws("Integer 10 equals minimum value of 10 and exclusive minimum is true.", - () => - { - JsonSchema schema = new JsonSchema(); - schema.Minimum = 10; - schema.ExclusiveMinimum = true; - - JValue v = new JValue(10); - v.Validate(schema); - }); - } - - [Test] - public void ExclusiveMinimum_Float() - { - ExceptionAssert.Throws("Float 10.1 equals minimum value of 10.1 and exclusive minimum is true.", - () => - { - JsonSchema schema = new JsonSchema(); - schema.Minimum = 10.1; - schema.ExclusiveMinimum = true; - - JValue v = new JValue(10.1); - v.Validate(schema); - }); - } - - [Test] - public void DivisibleBy_Int() - { - ExceptionAssert.Throws("Integer 10 is not evenly divisible by 3.", - () => - { - JsonSchema schema = new JsonSchema(); - schema.DivisibleBy = 3; - - JValue v = new JValue(10); - v.Validate(schema); - }); - } - - [Test] - public void UniqueItems_SimpleUnique() - { - JsonSchema schema = new JsonSchema(); - schema.UniqueItems = true; - - JArray a = new JArray(1, 2, 3); - Assert.IsTrue(a.IsValid(schema)); - } - - [Test] - public void UniqueItems_SimpleDuplicate() - { - JsonSchema schema = new JsonSchema(); - schema.UniqueItems = true; - - JArray a = new JArray(1, 2, 3, 2, 2); - IList errorMessages; - Assert.IsFalse(a.IsValid(schema, out errorMessages)); - Assert.AreEqual(2, errorMessages.Count); - Assert.AreEqual("Non-unique array item at index 3.", errorMessages[0]); - Assert.AreEqual("Non-unique array item at index 4.", errorMessages[1]); - } - - [Test] - public void UniqueItems_ComplexDuplicate() - { - JsonSchema schema = new JsonSchema(); - schema.UniqueItems = true; - - JArray a = new JArray(1, new JObject(new JProperty("value", "value!")), 3, 2, new JObject(new JProperty("value", "value!")), 4, 2, new JObject(new JProperty("value", "value!"))); - IList errorMessages; - Assert.IsFalse(a.IsValid(schema, out errorMessages)); - Assert.AreEqual(3, errorMessages.Count); - Assert.AreEqual("Non-unique array item at index 4.", errorMessages[0]); - Assert.AreEqual("Non-unique array item at index 6.", errorMessages[1]); - Assert.AreEqual("Non-unique array item at index 7.", errorMessages[2]); - } - - [Test] - public void UniqueItems_NestedDuplicate() - { - JsonSchema schema = new JsonSchema(); - schema.UniqueItems = true; - schema.Items = new List + [Test] + public void ExclusiveMaximum_Int() { - new JsonSchema - { - UniqueItems = true - } - }; - schema.PositionalItemsValidation = false; - - JArray a = new JArray( - new JArray(1, 2), - new JArray(1, 1), - new JArray(3, 4), - new JArray(1, 2), - new JArray(1, 1) - ); - IList errorMessages; - Assert.IsFalse(a.IsValid(schema, out errorMessages)); - Assert.AreEqual(4, errorMessages.Count); - Assert.AreEqual("Non-unique array item at index 1.", errorMessages[0]); - Assert.AreEqual("Non-unique array item at index 3.", errorMessages[1]); - Assert.AreEqual("Non-unique array item at index 1.", errorMessages[2]); - Assert.AreEqual("Non-unique array item at index 4.", errorMessages[3]); - } - - [Test] - public void Enum_Properties() - { - JsonSchema schema = new JsonSchema(); - schema.Properties = new Dictionary - { - { - "bar", - new JsonSchema - { - Enum = new List + ExceptionAssert.Throws("Integer 10 equals maximum value of 10 and exclusive maximum is true.", + () => { - new JValue(1), - new JValue(2) - } - } - } - }; + JsonSchema schema = new JsonSchema(); + schema.Maximum = 10; + schema.ExclusiveMaximum = true; - JObject o = new JObject( - new JProperty("bar", 1) - ); - IList errorMessages; - Assert.IsTrue(o.IsValid(schema, out errorMessages)); - Assert.AreEqual(0, errorMessages.Count); + JValue v = new JValue(10); + v.Validate(schema); + }); + } - o = new JObject( - new JProperty("bar", 3) - ); - Assert.IsFalse(o.IsValid(schema, out errorMessages)); - Assert.AreEqual(1, errorMessages.Count); - } - - [Test] - public void UniqueItems_Property() - { - JsonSchema schema = new JsonSchema(); - schema.Properties = new Dictionary + [Test] + public void ExclusiveMaximum_Float() { - { - "bar", - new JsonSchema + ExceptionAssert.Throws("Float 10.1 equals maximum value of 10.1 and exclusive maximum is true.", + () => + { + JsonSchema schema = new JsonSchema(); + schema.Maximum = 10.1; + schema.ExclusiveMaximum = true; + + JValue v = new JValue(10.1); + v.Validate(schema); + }); + } + + [Test] + public void ExclusiveMinimum_Int() + { + ExceptionAssert.Throws("Integer 10 equals minimum value of 10 and exclusive minimum is true.", + () => + { + JsonSchema schema = new JsonSchema(); + schema.Minimum = 10; + schema.ExclusiveMinimum = true; + + JValue v = new JValue(10); + v.Validate(schema); + }); + } + + [Test] + public void ExclusiveMinimum_Float() + { + ExceptionAssert.Throws("Float 10.1 equals minimum value of 10.1 and exclusive minimum is true.", + () => + { + JsonSchema schema = new JsonSchema(); + schema.Minimum = 10.1; + schema.ExclusiveMinimum = true; + + JValue v = new JValue(10.1); + v.Validate(schema); + }); + } + + [Test] + public void DivisibleBy_Int() + { + ExceptionAssert.Throws("Integer 10 is not evenly divisible by 3.", + () => + { + JsonSchema schema = new JsonSchema(); + schema.DivisibleBy = 3; + + JValue v = new JValue(10); + v.Validate(schema); + }); + } + + [Test] + public void UniqueItems_SimpleUnique() + { + JsonSchema schema = new JsonSchema(); + schema.UniqueItems = true; + + JArray a = new JArray(1, 2, 3); + Assert.IsTrue(a.IsValid(schema)); + } + + [Test] + public void UniqueItems_SimpleDuplicate() + { + JsonSchema schema = new JsonSchema(); + schema.UniqueItems = true; + + JArray a = new JArray(1, 2, 3, 2, 2); + IList errorMessages; + Assert.IsFalse(a.IsValid(schema, out errorMessages)); + Assert.AreEqual(2, errorMessages.Count); + Assert.AreEqual("Non-unique array item at index 3.", errorMessages[0]); + Assert.AreEqual("Non-unique array item at index 4.", errorMessages[1]); + } + + [Test] + public void UniqueItems_ComplexDuplicate() + { + JsonSchema schema = new JsonSchema(); + schema.UniqueItems = true; + + JArray a = new JArray(1, new JObject(new JProperty("value", "value!")), 3, 2, new JObject(new JProperty("value", "value!")), 4, 2, new JObject(new JProperty("value", "value!"))); + IList errorMessages; + Assert.IsFalse(a.IsValid(schema, out errorMessages)); + Assert.AreEqual(3, errorMessages.Count); + Assert.AreEqual("Non-unique array item at index 4.", errorMessages[0]); + Assert.AreEqual("Non-unique array item at index 6.", errorMessages[1]); + Assert.AreEqual("Non-unique array item at index 7.", errorMessages[2]); + } + + [Test] + public void UniqueItems_NestedDuplicate() + { + JsonSchema schema = new JsonSchema(); + schema.UniqueItems = true; + schema.Items = new List { - UniqueItems = true - } - } - }; + new JsonSchema + { + UniqueItems = true + } + }; + schema.PositionalItemsValidation = false; - JObject o = new JObject( - new JProperty("bar", new JArray(1, 2, 3, 3)) - ); - IList errorMessages; - Assert.IsFalse(o.IsValid(schema, out errorMessages)); - Assert.AreEqual(1, errorMessages.Count); - } + JArray a = new JArray( + new JArray(1, 2), + new JArray(1, 1), + new JArray(3, 4), + new JArray(1, 2), + new JArray(1, 1) + ); + IList errorMessages; + Assert.IsFalse(a.IsValid(schema, out errorMessages)); + Assert.AreEqual(4, errorMessages.Count); + Assert.AreEqual("Non-unique array item at index 1.", errorMessages[0]); + Assert.AreEqual("Non-unique array item at index 3.", errorMessages[1]); + Assert.AreEqual("Non-unique array item at index 1.", errorMessages[2]); + Assert.AreEqual("Non-unique array item at index 4.", errorMessages[3]); + } - [Test] - public void Items_Positional() - { - JsonSchema schema = new JsonSchema(); - schema.Items = new List + [Test] + public void Enum_Properties() { - new JsonSchema { Type = JsonSchemaType.Object }, - new JsonSchema { Type = JsonSchemaType.Integer } - }; - schema.PositionalItemsValidation = true; + JsonSchema schema = new JsonSchema(); + schema.Properties = new Dictionary + { + { + "bar", + new JsonSchema + { + Enum = new List + { + new JValue(1), + new JValue(2) + } + } + } + }; - JArray a = new JArray(new JObject(), 1); - IList errorMessages; - Assert.IsTrue(a.IsValid(schema, out errorMessages)); - Assert.AreEqual(0, errorMessages.Count); + JObject o = new JObject( + new JProperty("bar", 1) + ); + IList errorMessages; + Assert.IsTrue(o.IsValid(schema, out errorMessages)); + Assert.AreEqual(0, errorMessages.Count); + + o = new JObject( + new JProperty("bar", 3) + ); + Assert.IsFalse(o.IsValid(schema, out errorMessages)); + Assert.AreEqual(1, errorMessages.Count); + } + + [Test] + public void UniqueItems_Property() + { + JsonSchema schema = new JsonSchema(); + schema.Properties = new Dictionary + { + { + "bar", + new JsonSchema + { + UniqueItems = true + } + } + }; + + JObject o = new JObject( + new JProperty("bar", new JArray(1, 2, 3, 3)) + ); + IList errorMessages; + Assert.IsFalse(o.IsValid(schema, out errorMessages)); + Assert.AreEqual(1, errorMessages.Count); + } + + [Test] + public void Items_Positional() + { + JsonSchema schema = new JsonSchema(); + schema.Items = new List + { + new JsonSchema { Type = JsonSchemaType.Object }, + new JsonSchema { Type = JsonSchemaType.Integer } + }; + schema.PositionalItemsValidation = true; + + JArray a = new JArray(new JObject(), 1); + IList errorMessages; + Assert.IsTrue(a.IsValid(schema, out errorMessages)); + Assert.AreEqual(0, errorMessages.Count); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaBuilderTests.cs b/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaBuilderTests.cs index 8af22869..dc111350 100644 --- a/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaBuilderTests.cs +++ b/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaBuilderTests.cs @@ -37,13 +37,13 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Schema { - [TestFixture] - public class JsonSchemaBuilderTests : TestFixtureBase - { - [Test] - public void Simple() + [TestFixture] + public class JsonSchemaBuilderTests : TestFixtureBase { - string json = @" + [Test] + public void Simple() + { + string json = @" { ""description"": ""A person"", ""type"": ""object"", @@ -58,206 +58,206 @@ namespace Newtonsoft.Json.Tests.Schema } "; - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); - Assert.AreEqual("A person", schema.Description); - Assert.AreEqual(JsonSchemaType.Object, schema.Type); + Assert.AreEqual("A person", schema.Description); + Assert.AreEqual(JsonSchemaType.Object, schema.Type); - Assert.AreEqual(2, schema.Properties.Count); + Assert.AreEqual(2, schema.Properties.Count); - Assert.AreEqual(JsonSchemaType.String, schema.Properties["name"].Type); - Assert.AreEqual(JsonSchemaType.Array, schema.Properties["hobbies"].Type); - Assert.AreEqual(JsonSchemaType.String, schema.Properties["hobbies"].Items[0].Type); - } + Assert.AreEqual(JsonSchemaType.String, schema.Properties["name"].Type); + Assert.AreEqual(JsonSchemaType.Array, schema.Properties["hobbies"].Type); + Assert.AreEqual(JsonSchemaType.String, schema.Properties["hobbies"].Items[0].Type); + } - [Test] - public void MultipleTypes() - { - string json = @"{ + [Test] + public void MultipleTypes() + { + string json = @"{ ""description"":""Age"", ""type"":[""string"", ""integer""] }"; - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); - Assert.AreEqual("Age", schema.Description); - Assert.AreEqual(JsonSchemaType.String | JsonSchemaType.Integer, schema.Type); - } + Assert.AreEqual("Age", schema.Description); + Assert.AreEqual(JsonSchemaType.String | JsonSchemaType.Integer, schema.Type); + } - [Test] - public void MultipleItems() - { - string json = @"{ + [Test] + public void MultipleItems() + { + string json = @"{ ""description"":""MultipleItems"", ""type"":""array"", ""items"": [{""type"":""string""},{""type"":""array""}] }"; - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); - Assert.AreEqual("MultipleItems", schema.Description); - Assert.AreEqual(JsonSchemaType.String, schema.Items[0].Type); - Assert.AreEqual(JsonSchemaType.Array, schema.Items[1].Type); - } + Assert.AreEqual("MultipleItems", schema.Description); + Assert.AreEqual(JsonSchemaType.String, schema.Items[0].Type); + Assert.AreEqual(JsonSchemaType.Array, schema.Items[1].Type); + } - [Test] - public void AdditionalProperties() - { - string json = @"{ + [Test] + public void AdditionalProperties() + { + string json = @"{ ""description"":""AdditionalProperties"", ""type"":[""string"", ""integer""], ""additionalProperties"":{""type"":[""object"", ""boolean""]} }"; - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); - Assert.AreEqual("AdditionalProperties", schema.Description); - Assert.AreEqual(JsonSchemaType.Object | JsonSchemaType.Boolean, schema.AdditionalProperties.Type); - } + Assert.AreEqual("AdditionalProperties", schema.Description); + Assert.AreEqual(JsonSchemaType.Object | JsonSchemaType.Boolean, schema.AdditionalProperties.Type); + } - [Test] - public void Required() - { - string json = @"{ + [Test] + public void Required() + { + string json = @"{ ""description"":""Required"", ""required"":true }"; - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); - Assert.AreEqual("Required", schema.Description); - Assert.AreEqual(true, schema.Required); - } + Assert.AreEqual("Required", schema.Description); + Assert.AreEqual(true, schema.Required); + } - [Test] - public void ExclusiveMinimum_ExclusiveMaximum() - { - string json = @"{ + [Test] + public void ExclusiveMinimum_ExclusiveMaximum() + { + string json = @"{ ""exclusiveMinimum"":true, ""exclusiveMaximum"":true }"; - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); - Assert.AreEqual(true, schema.ExclusiveMinimum); - Assert.AreEqual(true, schema.ExclusiveMaximum); - } + Assert.AreEqual(true, schema.ExclusiveMinimum); + Assert.AreEqual(true, schema.ExclusiveMaximum); + } - [Test] - public void ReadOnly() - { - string json = @"{ + [Test] + public void ReadOnly() + { + string json = @"{ ""description"":""ReadOnly"", ""readonly"":true }"; - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); - Assert.AreEqual("ReadOnly", schema.Description); - Assert.AreEqual(true, schema.ReadOnly); - } + Assert.AreEqual("ReadOnly", schema.Description); + Assert.AreEqual(true, schema.ReadOnly); + } - [Test] - public void Hidden() - { - string json = @"{ + [Test] + public void Hidden() + { + string json = @"{ ""description"":""Hidden"", ""hidden"":true }"; - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); - Assert.AreEqual("Hidden", schema.Description); - Assert.AreEqual(true, schema.Hidden); - } + Assert.AreEqual("Hidden", schema.Description); + Assert.AreEqual(true, schema.Hidden); + } - [Test] - public void Id() - { - string json = @"{ + [Test] + public void Id() + { + string json = @"{ ""description"":""Id"", ""id"":""testid"" }"; - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); - Assert.AreEqual("Id", schema.Description); - Assert.AreEqual("testid", schema.Id); - } + Assert.AreEqual("Id", schema.Description); + Assert.AreEqual("testid", schema.Id); + } - [Test] - public void Title() - { - string json = @"{ + [Test] + public void Title() + { + string json = @"{ ""description"":""Title"", ""title"":""testtitle"" }"; - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); - Assert.AreEqual("Title", schema.Description); - Assert.AreEqual("testtitle", schema.Title); - } + Assert.AreEqual("Title", schema.Description); + Assert.AreEqual("testtitle", schema.Title); + } - [Test] - public void Pattern() - { - string json = @"{ + [Test] + public void Pattern() + { + string json = @"{ ""description"":""Pattern"", ""pattern"":""testpattern"" }"; - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); - Assert.AreEqual("Pattern", schema.Description); - Assert.AreEqual("testpattern", schema.Pattern); - } + Assert.AreEqual("Pattern", schema.Description); + Assert.AreEqual("testpattern", schema.Pattern); + } - [Test] - public void Format() - { - string json = @"{ + [Test] + public void Format() + { + string json = @"{ ""description"":""Format"", ""format"":""testformat"" }"; - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); - Assert.AreEqual("Format", schema.Description); - Assert.AreEqual("testformat", schema.Format); - } + Assert.AreEqual("Format", schema.Description); + Assert.AreEqual("testformat", schema.Format); + } - [Test] - public void Requires() - { - string json = @"{ + [Test] + public void Requires() + { + string json = @"{ ""description"":""Requires"", ""requires"":""PurpleMonkeyDishwasher"" }"; - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); - Assert.AreEqual("Requires", schema.Description); - Assert.AreEqual("PurpleMonkeyDishwasher", schema.Requires); - } + Assert.AreEqual("Requires", schema.Description); + Assert.AreEqual("PurpleMonkeyDishwasher", schema.Requires); + } - [Test] - public void MinimumMaximum() - { - string json = @"{ + [Test] + public void MinimumMaximum() + { + string json = @"{ ""description"":""MinimumMaximum"", ""minimum"":1.1, ""maximum"":1.2, @@ -268,204 +268,204 @@ namespace Newtonsoft.Json.Tests.Schema ""divisibleBy"":3, }"; - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); - Assert.AreEqual("MinimumMaximum", schema.Description); - Assert.AreEqual(1.1, schema.Minimum); - Assert.AreEqual(1.2, schema.Maximum); - Assert.AreEqual(1, schema.MinimumItems); - Assert.AreEqual(2, schema.MaximumItems); - Assert.AreEqual(5, schema.MinimumLength); - Assert.AreEqual(50, schema.MaximumLength); - Assert.AreEqual(3, schema.DivisibleBy); - } + Assert.AreEqual("MinimumMaximum", schema.Description); + Assert.AreEqual(1.1, schema.Minimum); + Assert.AreEqual(1.2, schema.Maximum); + Assert.AreEqual(1, schema.MinimumItems); + Assert.AreEqual(2, schema.MaximumItems); + Assert.AreEqual(5, schema.MinimumLength); + Assert.AreEqual(50, schema.MaximumLength); + Assert.AreEqual(3, schema.DivisibleBy); + } - [Test] - public void DisallowSingleType() - { - string json = @"{ + [Test] + public void DisallowSingleType() + { + string json = @"{ ""description"":""DisallowSingleType"", ""disallow"":""string"" }"; - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); - Assert.AreEqual("DisallowSingleType", schema.Description); - Assert.AreEqual(JsonSchemaType.String, schema.Disallow); - } + Assert.AreEqual("DisallowSingleType", schema.Description); + Assert.AreEqual(JsonSchemaType.String, schema.Disallow); + } - [Test] - public void DisallowMultipleTypes() - { - string json = @"{ + [Test] + public void DisallowMultipleTypes() + { + string json = @"{ ""description"":""DisallowMultipleTypes"", ""disallow"":[""string"",""number""] }"; - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); - Assert.AreEqual("DisallowMultipleTypes", schema.Description); - Assert.AreEqual(JsonSchemaType.String | JsonSchemaType.Float, schema.Disallow); - } + Assert.AreEqual("DisallowMultipleTypes", schema.Description); + Assert.AreEqual(JsonSchemaType.String | JsonSchemaType.Float, schema.Disallow); + } - [Test] - public void DefaultPrimitiveType() - { - string json = @"{ + [Test] + public void DefaultPrimitiveType() + { + string json = @"{ ""description"":""DefaultPrimitiveType"", ""default"":1.1 }"; - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); - Assert.AreEqual("DefaultPrimitiveType", schema.Description); - Assert.AreEqual(1.1, (double) schema.Default); - } + Assert.AreEqual("DefaultPrimitiveType", schema.Description); + Assert.AreEqual(1.1, (double)schema.Default); + } - [Test] - public void DefaultComplexType() - { - string json = @"{ + [Test] + public void DefaultComplexType() + { + string json = @"{ ""description"":""DefaultComplexType"", ""default"":{""pie"":true} }"; - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); - Assert.AreEqual("DefaultComplexType", schema.Description); - Assert.IsTrue(JToken.DeepEquals(JObject.Parse(@"{""pie"":true}"), schema.Default)); - } + Assert.AreEqual("DefaultComplexType", schema.Description); + Assert.IsTrue(JToken.DeepEquals(JObject.Parse(@"{""pie"":true}"), schema.Default)); + } - [Test] - public void Enum() - { - string json = @"{ + [Test] + public void Enum() + { + string json = @"{ ""description"":""Type"", ""type"":[""string"",""array""], ""enum"":[""string"",""object"",""array"",""boolean"",""number"",""integer"",""null"",""any""] }"; - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); - Assert.AreEqual("Type", schema.Description); - Assert.AreEqual(JsonSchemaType.String | JsonSchemaType.Array, schema.Type); + Assert.AreEqual("Type", schema.Description); + Assert.AreEqual(JsonSchemaType.String | JsonSchemaType.Array, schema.Type); - Assert.AreEqual(8, schema.Enum.Count); - Assert.AreEqual("string", (string) schema.Enum[0]); - Assert.AreEqual("any", (string) schema.Enum[schema.Enum.Count - 1]); - } + Assert.AreEqual(8, schema.Enum.Count); + Assert.AreEqual("string", (string)schema.Enum[0]); + Assert.AreEqual("any", (string)schema.Enum[schema.Enum.Count - 1]); + } - [Test] - public void CircularReference() - { - string json = @"{ + [Test] + public void CircularReference() + { + string json = @"{ ""id"":""CircularReferenceArray"", ""description"":""CircularReference"", ""type"":[""array""], ""items"":{""$ref"":""CircularReferenceArray""} }"; - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); - Assert.AreEqual("CircularReference", schema.Description); - Assert.AreEqual("CircularReferenceArray", schema.Id); - Assert.AreEqual(JsonSchemaType.Array, schema.Type); + Assert.AreEqual("CircularReference", schema.Description); + Assert.AreEqual("CircularReferenceArray", schema.Id); + Assert.AreEqual(JsonSchemaType.Array, schema.Type); - Assert.AreEqual(schema, schema.Items[0]); - } + Assert.AreEqual(schema, schema.Items[0]); + } - [Test] - public void UnresolvedReference() - { - ExceptionAssert.Throws(@"Could not resolve schema reference 'MyUnresolvedReference'.", - () => - { - string json = @"{ + [Test] + public void UnresolvedReference() + { + ExceptionAssert.Throws(@"Could not resolve schema reference 'MyUnresolvedReference'.", + () => + { + string json = @"{ ""id"":""CircularReferenceArray"", ""description"":""CircularReference"", ""type"":[""array""], ""items"":{""$ref"":""MyUnresolvedReference""} }"; - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); - }); - } + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); + }); + } - [Test] - public void PatternProperties() - { - string json = @"{ + [Test] + public void PatternProperties() + { + string json = @"{ ""patternProperties"": { ""[abc]"": { ""id"":""Blah"" } } }"; - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); - Assert.IsNotNull(schema.PatternProperties); - Assert.AreEqual(1, schema.PatternProperties.Count); - Assert.AreEqual("Blah", schema.PatternProperties["[abc]"].Id); - } + Assert.IsNotNull(schema.PatternProperties); + Assert.AreEqual(1, schema.PatternProperties.Count); + Assert.AreEqual("Blah", schema.PatternProperties["[abc]"].Id); + } - [Test] - public void AdditionalItems() - { - string json = @"{ + [Test] + public void AdditionalItems() + { + string json = @"{ ""items"": [], ""additionalItems"": {""type"": ""integer""} }"; - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); - Assert.IsNotNull(schema.AdditionalItems); - Assert.AreEqual(JsonSchemaType.Integer, schema.AdditionalItems.Type); - Assert.AreEqual(true, schema.AllowAdditionalItems); - } + Assert.IsNotNull(schema.AdditionalItems); + Assert.AreEqual(JsonSchemaType.Integer, schema.AdditionalItems.Type); + Assert.AreEqual(true, schema.AllowAdditionalItems); + } - [Test] - public void DisallowAdditionalItems() - { - string json = @"{ + [Test] + public void DisallowAdditionalItems() + { + string json = @"{ ""items"": [], ""additionalItems"": false }"; - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); - Assert.IsNull(schema.AdditionalItems); - Assert.AreEqual(false, schema.AllowAdditionalItems); - } + Assert.IsNull(schema.AdditionalItems); + Assert.AreEqual(false, schema.AllowAdditionalItems); + } - [Test] - public void AllowAdditionalItems() - { - string json = @"{ + [Test] + public void AllowAdditionalItems() + { + string json = @"{ ""items"": {}, ""additionalItems"": false }"; - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); - Assert.IsNull(schema.AdditionalItems); - Assert.AreEqual(false, schema.AllowAdditionalItems); - } + Assert.IsNull(schema.AdditionalItems); + Assert.AreEqual(false, schema.AllowAdditionalItems); + } - [Test] - public void Location() - { - string json = @"{ + [Test] + public void Location() + { + string json = @"{ ""properties"":{ ""foo"":{ ""type"":""array"", @@ -485,50 +485,50 @@ namespace Newtonsoft.Json.Tests.Schema } }"; - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); - Assert.AreEqual("#", schema.Location); - Assert.AreEqual("#/properties/foo", schema.Properties["foo"].Location); - Assert.AreEqual("#/properties/foo/items/1/properties/foo", schema.Properties["foo"].Items[1].Properties["foo"].Location); - } + Assert.AreEqual("#", schema.Location); + Assert.AreEqual("#/properties/foo", schema.Properties["foo"].Location); + Assert.AreEqual("#/properties/foo/items/1/properties/foo", schema.Properties["foo"].Items[1].Properties["foo"].Location); + } - [Test] - public void Reference_BackwardsLocation() - { - string json = @"{ + [Test] + public void Reference_BackwardsLocation() + { + string json = @"{ ""properties"": { ""foo"": {""type"": ""integer""}, ""bar"": {""$ref"": ""#/properties/foo""} } }"; - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); - Assert.AreEqual(schema.Properties["foo"], schema.Properties["bar"]); - } + Assert.AreEqual(schema.Properties["foo"], schema.Properties["bar"]); + } - [Test] - public void Reference_ForwardsLocation() - { - string json = @"{ + [Test] + public void Reference_ForwardsLocation() + { + string json = @"{ ""properties"": { ""bar"": {""$ref"": ""#/properties/foo""}, ""foo"": {""type"": ""integer""} } }"; - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); - Assert.AreEqual(schema.Properties["foo"], schema.Properties["bar"]); - } + Assert.AreEqual(schema.Properties["foo"], schema.Properties["bar"]); + } - [Test] - public void Reference_NonStandardLocation() - { - string json = @"{ + [Test] + public void Reference_NonStandardLocation() + { + string json = @"{ ""properties"": { ""bar"": {""$ref"": ""#/common/foo""}, ""foo"": {""$ref"": ""#/common/foo""} @@ -538,16 +538,16 @@ namespace Newtonsoft.Json.Tests.Schema } }"; - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); - Assert.AreEqual(schema.Properties["foo"], schema.Properties["bar"]); - } + Assert.AreEqual(schema.Properties["foo"], schema.Properties["bar"]); + } - [Test] - public void EscapedReferences() - { - string json = @"{ + [Test] + public void EscapedReferences() + { + string json = @"{ ""tilda~field"": {""type"": ""integer""}, ""slash/field"": {""type"": ""object""}, ""percent%field"": {""type"": ""array""}, @@ -558,18 +558,18 @@ namespace Newtonsoft.Json.Tests.Schema } }"; - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); - Assert.AreEqual(JsonSchemaType.Integer, schema.Properties["tilda"].Type); - Assert.AreEqual(JsonSchemaType.Object, schema.Properties["slash"].Type); - Assert.AreEqual(JsonSchemaType.Array, schema.Properties["percent"].Type); - } + Assert.AreEqual(JsonSchemaType.Integer, schema.Properties["tilda"].Type); + Assert.AreEqual(JsonSchemaType.Object, schema.Properties["slash"].Type); + Assert.AreEqual(JsonSchemaType.Array, schema.Properties["percent"].Type); + } - [Test] - public void References_Array() - { - string json = @"{ + [Test] + public void References_Array() + { + string json = @"{ ""array"": [{""type"": ""integer""},{""prop"":{""type"": ""object""}}], ""properties"": { ""array"": {""$ref"": ""#/array/0""}, @@ -577,19 +577,19 @@ namespace Newtonsoft.Json.Tests.Schema } }"; - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + JsonSchema schema = builder.Read(new JsonTextReader(new StringReader(json))); - Assert.AreEqual(JsonSchemaType.Integer, schema.Properties["array"].Type); - Assert.AreEqual(JsonSchemaType.Object, schema.Properties["arrayprop"].Type); - } + Assert.AreEqual(JsonSchemaType.Integer, schema.Properties["array"].Type); + Assert.AreEqual(JsonSchemaType.Object, schema.Properties["arrayprop"].Type); + } - [Test] - public void References_IndexTooBig() - { - // JsonException : Could not resolve schema reference '#/array/10'. + [Test] + public void References_IndexTooBig() + { + // JsonException : Could not resolve schema reference '#/array/10'. - string json = @"{ + string json = @"{ ""array"": [{""type"": ""integer""},{""prop"":{""type"": ""object""}}], ""properties"": { ""array"": {""$ref"": ""#/array/0""}, @@ -597,19 +597,19 @@ namespace Newtonsoft.Json.Tests.Schema } }"; - ExceptionAssert.Throws( - "Could not resolve schema reference '#/array/10'.", - () => - { - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - builder.Read(new JsonTextReader(new StringReader(json))); - }); - } + ExceptionAssert.Throws( + "Could not resolve schema reference '#/array/10'.", + () => + { + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + builder.Read(new JsonTextReader(new StringReader(json))); + }); + } - [Test] - public void References_IndexNegative() - { - string json = @"{ + [Test] + public void References_IndexNegative() + { + string json = @"{ ""array"": [{""type"": ""integer""},{""prop"":{""type"": ""object""}}], ""properties"": { ""array"": {""$ref"": ""#/array/0""}, @@ -617,19 +617,19 @@ namespace Newtonsoft.Json.Tests.Schema } }"; - ExceptionAssert.Throws( - "Could not resolve schema reference '#/array/-1'.", - () => - { - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - builder.Read(new JsonTextReader(new StringReader(json))); - }); - } + ExceptionAssert.Throws( + "Could not resolve schema reference '#/array/-1'.", + () => + { + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + builder.Read(new JsonTextReader(new StringReader(json))); + }); + } - [Test] - public void References_IndexNotInteger() - { - string json = @"{ + [Test] + public void References_IndexNotInteger() + { + string json = @"{ ""array"": [{""type"": ""integer""},{""prop"":{""type"": ""object""}}], ""properties"": { ""array"": {""$ref"": ""#/array/0""}, @@ -637,13 +637,13 @@ namespace Newtonsoft.Json.Tests.Schema } }"; - ExceptionAssert.Throws( - "Could not resolve schema reference '#/array/one'.", - () => - { - JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); - builder.Read(new JsonTextReader(new StringReader(json))); - }); + ExceptionAssert.Throws( + "Could not resolve schema reference '#/array/one'.", + () => + { + JsonSchemaBuilder builder = new JsonSchemaBuilder(new JsonSchemaResolver()); + builder.Read(new JsonTextReader(new StringReader(json))); + }); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaGeneratorTests.cs b/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaGeneratorTests.cs index f8d21202..57fda964 100644 --- a/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaGeneratorTests.cs +++ b/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaGeneratorTests.cs @@ -42,27 +42,28 @@ using Newtonsoft.Json.Schema; using System.IO; using Newtonsoft.Json.Linq; using System.Text; -using Extensions=Newtonsoft.Json.Schema.Extensions; +using Extensions = Newtonsoft.Json.Schema.Extensions; #if NET20 using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json.Tests.Schema { - [TestFixture] - public class JsonSchemaGeneratorTests : TestFixtureBase - { - [Test] - public void Generate_GenericDictionary() + [TestFixture] + public class JsonSchemaGeneratorTests : TestFixtureBase { - JsonSchemaGenerator generator = new JsonSchemaGenerator(); - JsonSchema schema = generator.Generate(typeof (Dictionary>)); + [Test] + public void Generate_GenericDictionary() + { + JsonSchemaGenerator generator = new JsonSchemaGenerator(); + JsonSchema schema = generator.Generate(typeof(Dictionary>)); - string json = schema.ToString(); + string json = schema.ToString(); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""type"": ""object"", ""additionalProperties"": { ""type"": [ @@ -78,28 +79,28 @@ namespace Newtonsoft.Json.Tests.Schema } }", json); - Dictionary> value = new Dictionary> - { - {"HasValue", new List() { "first", "second", null }}, - {"NoValue", null} - }; + Dictionary> value = new Dictionary> + { + { "HasValue", new List() { "first", "second", null } }, + { "NoValue", null } + }; - string valueJson = JsonConvert.SerializeObject(value, Formatting.Indented); - JObject o = JObject.Parse(valueJson); + string valueJson = JsonConvert.SerializeObject(value, Formatting.Indented); + JObject o = JObject.Parse(valueJson); - Assert.IsTrue(o.IsValid(schema)); - } + Assert.IsTrue(o.IsValid(schema)); + } #if !(NETFX_CORE || PORTABLE || PORTABLE40) - [Test] - public void Generate_DefaultValueAttributeTestClass() - { - JsonSchemaGenerator generator = new JsonSchemaGenerator(); - JsonSchema schema = generator.Generate(typeof(DefaultValueAttributeTestClass)); + [Test] + public void Generate_DefaultValueAttributeTestClass() + { + JsonSchemaGenerator generator = new JsonSchemaGenerator(); + JsonSchema schema = generator.Generate(typeof(DefaultValueAttributeTestClass)); - string json = schema.ToString(); + string json = schema.ToString(); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""description"": ""DefaultValueAttributeTestClass description!"", ""type"": ""object"", ""additionalProperties"": false, @@ -119,18 +120,18 @@ namespace Newtonsoft.Json.Tests.Schema } } }", json); - } + } #endif - [Test] - public void Generate_Person() - { - JsonSchemaGenerator generator = new JsonSchemaGenerator(); - JsonSchema schema = generator.Generate(typeof(Person)); + [Test] + public void Generate_Person() + { + JsonSchemaGenerator generator = new JsonSchemaGenerator(); + JsonSchema schema = generator.Generate(typeof(Person)); - string json = schema.ToString(); + string json = schema.ToString(); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""id"": ""Person"", ""title"": ""Title!"", ""description"": ""JsonObjectAttribute description!"", @@ -153,17 +154,17 @@ namespace Newtonsoft.Json.Tests.Schema } } }", json); - } + } - [Test] - public void Generate_UserNullable() - { - JsonSchemaGenerator generator = new JsonSchemaGenerator(); - JsonSchema schema = generator.Generate(typeof(UserNullable)); + [Test] + public void Generate_UserNullable() + { + JsonSchemaGenerator generator = new JsonSchemaGenerator(); + JsonSchema schema = generator.Generate(typeof(UserNullable)); - string json = schema.ToString(); + string json = schema.ToString(); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""type"": ""object"", ""properties"": { ""Id"": { @@ -211,175 +212,175 @@ namespace Newtonsoft.Json.Tests.Schema } } }", json); - } + } - [Test] - public void Generate_RequiredMembersClass() - { - JsonSchemaGenerator generator = new JsonSchemaGenerator(); - JsonSchema schema = generator.Generate(typeof(RequiredMembersClass)); + [Test] + public void Generate_RequiredMembersClass() + { + JsonSchemaGenerator generator = new JsonSchemaGenerator(); + JsonSchema schema = generator.Generate(typeof(RequiredMembersClass)); - Assert.AreEqual(JsonSchemaType.String, schema.Properties["FirstName"].Type); - Assert.AreEqual(JsonSchemaType.String | JsonSchemaType.Null, schema.Properties["MiddleName"].Type); - Assert.AreEqual(JsonSchemaType.String | JsonSchemaType.Null, schema.Properties["LastName"].Type); - Assert.AreEqual(JsonSchemaType.String, schema.Properties["BirthDate"].Type); - } + Assert.AreEqual(JsonSchemaType.String, schema.Properties["FirstName"].Type); + Assert.AreEqual(JsonSchemaType.String | JsonSchemaType.Null, schema.Properties["MiddleName"].Type); + Assert.AreEqual(JsonSchemaType.String | JsonSchemaType.Null, schema.Properties["LastName"].Type); + Assert.AreEqual(JsonSchemaType.String, schema.Properties["BirthDate"].Type); + } - [Test] - public void Generate_Store() - { - JsonSchemaGenerator generator = new JsonSchemaGenerator(); - JsonSchema schema = generator.Generate(typeof(Store)); + [Test] + public void Generate_Store() + { + JsonSchemaGenerator generator = new JsonSchemaGenerator(); + JsonSchema schema = generator.Generate(typeof(Store)); - Assert.AreEqual(11, schema.Properties.Count); + Assert.AreEqual(11, schema.Properties.Count); - JsonSchema productArraySchema = schema.Properties["product"]; - JsonSchema productSchema = productArraySchema.Items[0]; + JsonSchema productArraySchema = schema.Properties["product"]; + JsonSchema productSchema = productArraySchema.Items[0]; - Assert.AreEqual(4, productSchema.Properties.Count); - } + Assert.AreEqual(4, productSchema.Properties.Count); + } - [Test] - public void MissingSchemaIdHandlingTest() - { - JsonSchemaGenerator generator = new JsonSchemaGenerator(); + [Test] + public void MissingSchemaIdHandlingTest() + { + JsonSchemaGenerator generator = new JsonSchemaGenerator(); - JsonSchema schema = generator.Generate(typeof(Store)); - Assert.AreEqual(null, schema.Id); + JsonSchema schema = generator.Generate(typeof(Store)); + Assert.AreEqual(null, schema.Id); - generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName; - schema = generator.Generate(typeof (Store)); - Assert.AreEqual(typeof(Store).FullName, schema.Id); + generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName; + schema = generator.Generate(typeof(Store)); + Assert.AreEqual(typeof(Store).FullName, schema.Id); - generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseAssemblyQualifiedName; - schema = generator.Generate(typeof(Store)); - Assert.AreEqual(typeof(Store).AssemblyQualifiedName, schema.Id); - } + generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseAssemblyQualifiedName; + schema = generator.Generate(typeof(Store)); + Assert.AreEqual(typeof(Store).AssemblyQualifiedName, schema.Id); + } - [Test] - public void CircularReferenceError() - { - ExceptionAssert.Throws(@"Unresolved circular reference for type 'Newtonsoft.Json.Tests.TestObjects.CircularReferenceClass'. Explicitly define an Id for the type using a JsonObject/JsonArray attribute or automatically generate a type Id using the UndefinedSchemaIdHandling property.", - () => - { - JsonSchemaGenerator generator = new JsonSchemaGenerator(); - generator.Generate(typeof(CircularReferenceClass)); - }); - } + [Test] + public void CircularReferenceError() + { + ExceptionAssert.Throws(@"Unresolved circular reference for type 'Newtonsoft.Json.Tests.TestObjects.CircularReferenceClass'. Explicitly define an Id for the type using a JsonObject/JsonArray attribute or automatically generate a type Id using the UndefinedSchemaIdHandling property.", + () => + { + JsonSchemaGenerator generator = new JsonSchemaGenerator(); + generator.Generate(typeof(CircularReferenceClass)); + }); + } - [Test] - public void CircularReferenceWithTypeNameId() - { - JsonSchemaGenerator generator = new JsonSchemaGenerator(); - generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName; + [Test] + public void CircularReferenceWithTypeNameId() + { + JsonSchemaGenerator generator = new JsonSchemaGenerator(); + generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName; - JsonSchema schema = generator.Generate(typeof(CircularReferenceClass), true); + JsonSchema schema = generator.Generate(typeof(CircularReferenceClass), true); - Assert.AreEqual(JsonSchemaType.String, schema.Properties["Name"].Type); - Assert.AreEqual(typeof(CircularReferenceClass).FullName, schema.Id); - Assert.AreEqual(JsonSchemaType.Object | JsonSchemaType.Null, schema.Properties["Child"].Type); - Assert.AreEqual(schema, schema.Properties["Child"]); - } + Assert.AreEqual(JsonSchemaType.String, schema.Properties["Name"].Type); + Assert.AreEqual(typeof(CircularReferenceClass).FullName, schema.Id); + Assert.AreEqual(JsonSchemaType.Object | JsonSchemaType.Null, schema.Properties["Child"].Type); + Assert.AreEqual(schema, schema.Properties["Child"]); + } - [Test] - public void CircularReferenceWithExplicitId() - { - JsonSchemaGenerator generator = new JsonSchemaGenerator(); + [Test] + public void CircularReferenceWithExplicitId() + { + JsonSchemaGenerator generator = new JsonSchemaGenerator(); - JsonSchema schema = generator.Generate(typeof(CircularReferenceWithIdClass)); + JsonSchema schema = generator.Generate(typeof(CircularReferenceWithIdClass)); - Assert.AreEqual(JsonSchemaType.String | JsonSchemaType.Null, schema.Properties["Name"].Type); - Assert.AreEqual("MyExplicitId", schema.Id); - Assert.AreEqual(JsonSchemaType.Object | JsonSchemaType.Null, schema.Properties["Child"].Type); - Assert.AreEqual(schema, schema.Properties["Child"]); - } + Assert.AreEqual(JsonSchemaType.String | JsonSchemaType.Null, schema.Properties["Name"].Type); + Assert.AreEqual("MyExplicitId", schema.Id); + Assert.AreEqual(JsonSchemaType.Object | JsonSchemaType.Null, schema.Properties["Child"].Type); + Assert.AreEqual(schema, schema.Properties["Child"]); + } - [Test] - public void GenerateSchemaForType() - { - JsonSchemaGenerator generator = new JsonSchemaGenerator(); - generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName; + [Test] + public void GenerateSchemaForType() + { + JsonSchemaGenerator generator = new JsonSchemaGenerator(); + generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName; - JsonSchema schema = generator.Generate(typeof(Type)); + JsonSchema schema = generator.Generate(typeof(Type)); - Assert.AreEqual(JsonSchemaType.String, schema.Type); + Assert.AreEqual(JsonSchemaType.String, schema.Type); - string json = JsonConvert.SerializeObject(typeof(Version), Formatting.Indented); + string json = JsonConvert.SerializeObject(typeof(Version), Formatting.Indented); - JValue v = new JValue(json); - Assert.IsTrue(v.IsValid(schema)); - } + JValue v = new JValue(json); + Assert.IsTrue(v.IsValid(schema)); + } #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - [Test] - public void GenerateSchemaForISerializable() - { - JsonSchemaGenerator generator = new JsonSchemaGenerator(); - generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName; + [Test] + public void GenerateSchemaForISerializable() + { + JsonSchemaGenerator generator = new JsonSchemaGenerator(); + generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName; - JsonSchema schema = generator.Generate(typeof(Exception)); + JsonSchema schema = generator.Generate(typeof(Exception)); - Assert.AreEqual(JsonSchemaType.Object, schema.Type); - Assert.AreEqual(true, schema.AllowAdditionalProperties); - Assert.AreEqual(null, schema.Properties); - } + Assert.AreEqual(JsonSchemaType.Object, schema.Type); + Assert.AreEqual(true, schema.AllowAdditionalProperties); + Assert.AreEqual(null, schema.Properties); + } #endif #if !(NETFX_CORE || PORTABLE || PORTABLE40) - [Test] - public void GenerateSchemaForDBNull() - { - JsonSchemaGenerator generator = new JsonSchemaGenerator(); - generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName; - - JsonSchema schema = generator.Generate(typeof(DBNull)); - - Assert.AreEqual(JsonSchemaType.Null, schema.Type); - } - - public class CustomDirectoryInfoMapper : DefaultContractResolver - { - public CustomDirectoryInfoMapper() - : base(true) - { - } - - protected override JsonContract CreateContract(Type objectType) - { - if (objectType == typeof(DirectoryInfo)) - return base.CreateObjectContract(objectType); - - return base.CreateContract(objectType); - } - - protected override IList CreateProperties(Type type, MemberSerialization memberSerialization) - { - IList properties = base.CreateProperties(type, memberSerialization); - - JsonPropertyCollection c = new JsonPropertyCollection(type); - c.AddRange(properties.Where(m => m.PropertyName != "Root")); - - return c; - } - } - - [Test] - public void GenerateSchemaForDirectoryInfo() - { - JsonSchemaGenerator generator = new JsonSchemaGenerator(); - generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName; - generator.ContractResolver = new CustomDirectoryInfoMapper + [Test] + public void GenerateSchemaForDBNull() { + JsonSchemaGenerator generator = new JsonSchemaGenerator(); + generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName; + + JsonSchema schema = generator.Generate(typeof(DBNull)); + + Assert.AreEqual(JsonSchemaType.Null, schema.Type); + } + + public class CustomDirectoryInfoMapper : DefaultContractResolver + { + public CustomDirectoryInfoMapper() + : base(true) + { + } + + protected override JsonContract CreateContract(Type objectType) + { + if (objectType == typeof(DirectoryInfo)) + return base.CreateObjectContract(objectType); + + return base.CreateContract(objectType); + } + + protected override IList CreateProperties(Type type, MemberSerialization memberSerialization) + { + IList properties = base.CreateProperties(type, memberSerialization); + + JsonPropertyCollection c = new JsonPropertyCollection(type); + c.AddRange(properties.Where(m => m.PropertyName != "Root")); + + return c; + } + } + + [Test] + public void GenerateSchemaForDirectoryInfo() + { + JsonSchemaGenerator generator = new JsonSchemaGenerator(); + generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName; + generator.ContractResolver = new CustomDirectoryInfoMapper + { #if !(SILVERLIGHT || NETFX_CORE || PORTABLE) - IgnoreSerializableAttribute = true + IgnoreSerializableAttribute = true #endif - }; + }; - JsonSchema schema = generator.Generate(typeof(DirectoryInfo), true); + JsonSchema schema = generator.Generate(typeof(DirectoryInfo), true); - string json = schema.ToString(); - - Assert.AreEqual(@"{ + string json = schema.ToString(); + + Assert.AreEqual(@"{ ""id"": ""System.IO.DirectoryInfo"", ""required"": true, ""type"": [ @@ -447,43 +448,43 @@ namespace Newtonsoft.Json.Tests.Schema } }", json); - DirectoryInfo temp = new DirectoryInfo(@"c:\temp"); + DirectoryInfo temp = new DirectoryInfo(@"c:\temp"); - JTokenWriter jsonWriter = new JTokenWriter(); - JsonSerializer serializer = new JsonSerializer(); - serializer.Converters.Add(new IsoDateTimeConverter()); - serializer.ContractResolver = new CustomDirectoryInfoMapper - { + JTokenWriter jsonWriter = new JTokenWriter(); + JsonSerializer serializer = new JsonSerializer(); + serializer.Converters.Add(new IsoDateTimeConverter()); + serializer.ContractResolver = new CustomDirectoryInfoMapper + { #if !(SILVERLIGHT || NETFX_CORE || PORTABLE) - IgnoreSerializableInterface = true + IgnoreSerializableInterface = true #endif - }; - serializer.Serialize(jsonWriter, temp); + }; + serializer.Serialize(jsonWriter, temp); - List errors = new List(); - jsonWriter.Token.Validate(schema, (sender, args) => errors.Add(args.Message)); + List errors = new List(); + jsonWriter.Token.Validate(schema, (sender, args) => errors.Add(args.Message)); - Assert.AreEqual(0, errors.Count); - } + Assert.AreEqual(0, errors.Count); + } #endif - [Test] - public void GenerateSchemaCamelCase() - { - JsonSchemaGenerator generator = new JsonSchemaGenerator(); - generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName; - generator.ContractResolver = new CamelCasePropertyNamesContractResolver() - { + [Test] + public void GenerateSchemaCamelCase() + { + JsonSchemaGenerator generator = new JsonSchemaGenerator(); + generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName; + generator.ContractResolver = new CamelCasePropertyNamesContractResolver() + { #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - IgnoreSerializableAttribute = true + IgnoreSerializableAttribute = true #endif - }; + }; - JsonSchema schema = generator.Generate(typeof(Version), true); + JsonSchema schema = generator.Generate(typeof(Version), true); - string json = schema.ToString(); + string json = schema.ToString(); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""id"": ""System.Version"", ""type"": [ ""object"", @@ -517,24 +518,24 @@ namespace Newtonsoft.Json.Tests.Schema } } }", json); - } + } #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - [Test] - public void GenerateSchemaSerializable() - { - JsonSchemaGenerator generator = new JsonSchemaGenerator(); - generator.ContractResolver = new DefaultContractResolver + [Test] + public void GenerateSchemaSerializable() { - IgnoreSerializableAttribute = false - }; - generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName; + JsonSchemaGenerator generator = new JsonSchemaGenerator(); + generator.ContractResolver = new DefaultContractResolver + { + IgnoreSerializableAttribute = false + }; + generator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName; - JsonSchema schema = generator.Generate(typeof (Version), true); + JsonSchema schema = generator.Generate(typeof(Version), true); - string json = schema.ToString(); + string json = schema.ToString(); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""id"": ""System.Version"", ""type"": [ ""object"", @@ -561,55 +562,55 @@ namespace Newtonsoft.Json.Tests.Schema } }", json); - JTokenWriter jsonWriter = new JTokenWriter(); - JsonSerializer serializer = new JsonSerializer(); - serializer.ContractResolver = new DefaultContractResolver - { - IgnoreSerializableAttribute = false - }; - serializer.Serialize(jsonWriter, new Version(1, 2, 3, 4)); + JTokenWriter jsonWriter = new JTokenWriter(); + JsonSerializer serializer = new JsonSerializer(); + serializer.ContractResolver = new DefaultContractResolver + { + IgnoreSerializableAttribute = false + }; + serializer.Serialize(jsonWriter, new Version(1, 2, 3, 4)); - List errors = new List(); - jsonWriter.Token.Validate(schema, (sender, args) => errors.Add(args.Message)); + List errors = new List(); + jsonWriter.Token.Validate(schema, (sender, args) => errors.Add(args.Message)); - Assert.AreEqual(0, errors.Count); + Assert.AreEqual(0, errors.Count); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""_Major"": 1, ""_Minor"": 2, ""_Build"": 3, ""_Revision"": 4 }", jsonWriter.Token.ToString()); - Version version = jsonWriter.Token.ToObject(serializer); - Assert.AreEqual(1, version.Major); - Assert.AreEqual(2, version.Minor); - Assert.AreEqual(3, version.Build); - Assert.AreEqual(4, version.Revision); - } + Version version = jsonWriter.Token.ToObject(serializer); + Assert.AreEqual(1, version.Major); + Assert.AreEqual(2, version.Minor); + Assert.AreEqual(3, version.Build); + Assert.AreEqual(4, version.Revision); + } #endif - public enum SortTypeFlag - { - No = 0, - Asc = 1, - Desc = -1 - } + public enum SortTypeFlag + { + No = 0, + Asc = 1, + Desc = -1 + } - public class X - { - public SortTypeFlag x; - } + public class X + { + public SortTypeFlag x; + } - [Test] - public void GenerateSchemaWithNegativeEnum() - { - JsonSchemaGenerator jsonSchemaGenerator = new JsonSchemaGenerator(); - JsonSchema schema = jsonSchemaGenerator.Generate(typeof(X)); + [Test] + public void GenerateSchemaWithNegativeEnum() + { + JsonSchemaGenerator jsonSchemaGenerator = new JsonSchemaGenerator(); + JsonSchema schema = jsonSchemaGenerator.Generate(typeof(X)); - string json = schema.ToString(); + string json = schema.ToString(); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""type"": ""object"", ""properties"": { ""x"": { @@ -623,31 +624,31 @@ namespace Newtonsoft.Json.Tests.Schema } } }", json); - } + } - [Test] - public void CircularCollectionReferences() - { - Type type = typeof (Workspace); - JsonSchemaGenerator jsonSchemaGenerator = new JsonSchemaGenerator(); + [Test] + public void CircularCollectionReferences() + { + Type type = typeof(Workspace); + JsonSchemaGenerator jsonSchemaGenerator = new JsonSchemaGenerator(); - jsonSchemaGenerator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName; - JsonSchema jsonSchema = jsonSchemaGenerator.Generate(type); + jsonSchemaGenerator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName; + JsonSchema jsonSchema = jsonSchemaGenerator.Generate(type); - // should succeed - Assert.IsNotNull(jsonSchema); - } + // should succeed + Assert.IsNotNull(jsonSchema); + } - [Test] - public void CircularReferenceWithMixedRequires() - { - JsonSchemaGenerator jsonSchemaGenerator = new JsonSchemaGenerator(); + [Test] + public void CircularReferenceWithMixedRequires() + { + JsonSchemaGenerator jsonSchemaGenerator = new JsonSchemaGenerator(); - jsonSchemaGenerator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName; - JsonSchema jsonSchema = jsonSchemaGenerator.Generate(typeof(CircularReferenceClass)); - string json = jsonSchema.ToString(); + jsonSchemaGenerator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName; + JsonSchema jsonSchema = jsonSchemaGenerator.Generate(typeof(CircularReferenceClass)); + string json = jsonSchema.ToString(); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""id"": ""Newtonsoft.Json.Tests.TestObjects.CircularReferenceClass"", ""type"": [ ""object"", @@ -663,18 +664,18 @@ namespace Newtonsoft.Json.Tests.Schema } } }", json); - } + } - [Test] - public void JsonPropertyWithHandlingValues() - { - JsonSchemaGenerator jsonSchemaGenerator = new JsonSchemaGenerator(); + [Test] + public void JsonPropertyWithHandlingValues() + { + JsonSchemaGenerator jsonSchemaGenerator = new JsonSchemaGenerator(); - jsonSchemaGenerator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName; - JsonSchema jsonSchema = jsonSchemaGenerator.Generate(typeof(JsonPropertyWithHandlingValues)); - string json = jsonSchema.ToString(); + jsonSchemaGenerator.UndefinedSchemaIdHandling = UndefinedSchemaIdHandling.UseTypeName; + JsonSchema jsonSchema = jsonSchemaGenerator.Generate(typeof(JsonPropertyWithHandlingValues)); + string json = jsonSchema.ToString(); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""id"": ""Newtonsoft.Json.Tests.TestObjects.JsonPropertyWithHandlingValues"", ""required"": true, ""type"": [ @@ -736,17 +737,17 @@ namespace Newtonsoft.Json.Tests.Schema } } }", json); - } + } - [Test] - public void GenerateForNullableInt32() - { - JsonSchemaGenerator jsonSchemaGenerator = new JsonSchemaGenerator(); + [Test] + public void GenerateForNullableInt32() + { + JsonSchemaGenerator jsonSchemaGenerator = new JsonSchemaGenerator(); - JsonSchema jsonSchema = jsonSchemaGenerator.Generate(typeof(NullableInt32TestClass)); - string json = jsonSchema.ToString(); + JsonSchema jsonSchema = jsonSchemaGenerator.Generate(typeof(NullableInt32TestClass)); + string json = jsonSchema.ToString(); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""type"": ""object"", ""properties"": { ""Value"": { @@ -758,75 +759,75 @@ namespace Newtonsoft.Json.Tests.Schema } } }", json); + } } - } - public class NullableInt32TestClass - { - public int? Value { get; set; } - } + public class NullableInt32TestClass + { + public int? Value { get; set; } + } - public class DMDSLBase - { - public String Comment; - } + public class DMDSLBase + { + public String Comment; + } - public class Workspace : DMDSLBase - { - public ControlFlowItemCollection Jobs = new ControlFlowItemCollection(); - } + public class Workspace : DMDSLBase + { + public ControlFlowItemCollection Jobs = new ControlFlowItemCollection(); + } - public class ControlFlowItemBase : DMDSLBase - { - public String Name; - } + public class ControlFlowItemBase : DMDSLBase + { + public String Name; + } - public class ControlFlowItem : ControlFlowItemBase//A Job - { - public TaskCollection Tasks = new TaskCollection(); - public ContainerCollection Containers = new ContainerCollection(); - } + public class ControlFlowItem : ControlFlowItemBase //A Job + { + public TaskCollection Tasks = new TaskCollection(); + public ContainerCollection Containers = new ContainerCollection(); + } - public class ControlFlowItemCollection : List - { - } + public class ControlFlowItemCollection : List + { + } - public class Task : ControlFlowItemBase - { - public DataFlowTaskCollection DataFlowTasks = new DataFlowTaskCollection(); - public BulkInsertTaskCollection BulkInsertTask = new BulkInsertTaskCollection(); - } + public class Task : ControlFlowItemBase + { + public DataFlowTaskCollection DataFlowTasks = new DataFlowTaskCollection(); + public BulkInsertTaskCollection BulkInsertTask = new BulkInsertTaskCollection(); + } - public class TaskCollection : List - { - } + public class TaskCollection : List + { + } - public class Container : ControlFlowItemBase - { - public ControlFlowItemCollection ContainerJobs = new ControlFlowItemCollection(); - } + public class Container : ControlFlowItemBase + { + public ControlFlowItemCollection ContainerJobs = new ControlFlowItemCollection(); + } - public class ContainerCollection : List - { - } + public class ContainerCollection : List + { + } - public class DataFlowTask_DSL : ControlFlowItemBase - { - } + public class DataFlowTask_DSL : ControlFlowItemBase + { + } - public class DataFlowTaskCollection : List - { - } + public class DataFlowTaskCollection : List + { + } - public class SequenceContainer_DSL : Container - { - } + public class SequenceContainer_DSL : Container + { + } - public class BulkInsertTaskCollection : List - { - } + public class BulkInsertTaskCollection : List + { + } - public class BulkInsertTask_DSL - { - } + public class BulkInsertTask_DSL + { + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaModelBuilderTests.cs b/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaModelBuilderTests.cs index 23cc0aea..e793c92c 100644 --- a/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaModelBuilderTests.cs +++ b/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaModelBuilderTests.cs @@ -26,6 +26,7 @@ using Newtonsoft.Json.Schema; #if !NETFX_CORE using NUnit.Framework; + #else using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; @@ -34,13 +35,13 @@ using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAtt namespace Newtonsoft.Json.Tests.Schema { - [TestFixture] - public class JsonSchemaModelBuilderTests : TestFixtureBase - { - [Test] - public void ExtendedComplex() + [TestFixture] + public class JsonSchemaModelBuilderTests : TestFixtureBase { - string first = @"{ + [Test] + public void ExtendedComplex() + { + string first = @"{ ""id"":""first"", ""type"":""object"", ""properties"": @@ -58,7 +59,7 @@ namespace Newtonsoft.Json.Tests.Schema ""additionalProperties"":{} }"; - string second = @"{ + string second = @"{ ""id"":""second"", ""type"":""object"", ""extends"":{""$ref"":""first""}, @@ -85,65 +86,65 @@ namespace Newtonsoft.Json.Tests.Schema ""additionalProperties"":false }"; - JsonSchemaResolver resolver = new JsonSchemaResolver(); - JsonSchema firstSchema = JsonSchema.Parse(first, resolver); - JsonSchema secondSchema = JsonSchema.Parse(second, resolver); + JsonSchemaResolver resolver = new JsonSchemaResolver(); + JsonSchema firstSchema = JsonSchema.Parse(first, resolver); + JsonSchema secondSchema = JsonSchema.Parse(second, resolver); - JsonSchemaModelBuilder modelBuilder = new JsonSchemaModelBuilder(); + JsonSchemaModelBuilder modelBuilder = new JsonSchemaModelBuilder(); - JsonSchemaModel model = modelBuilder.Build(secondSchema); + JsonSchemaModel model = modelBuilder.Build(secondSchema); - Assert.AreEqual(4, model.Properties.Count); + Assert.AreEqual(4, model.Properties.Count); - Assert.AreEqual(JsonSchemaType.String, model.Properties["firstproperty"].Type); + Assert.AreEqual(JsonSchemaType.String, model.Properties["firstproperty"].Type); - Assert.AreEqual(JsonSchemaType.String, model.Properties["secondproperty"].Type); - Assert.AreEqual(10, model.Properties["secondproperty"].MaximumLength); - Assert.AreEqual(null, model.Properties["secondproperty"].Enum); - Assert.AreEqual(null, model.Properties["secondproperty"].Patterns); + Assert.AreEqual(JsonSchemaType.String, model.Properties["secondproperty"].Type); + Assert.AreEqual(10, model.Properties["secondproperty"].MaximumLength); + Assert.AreEqual(null, model.Properties["secondproperty"].Enum); + Assert.AreEqual(null, model.Properties["secondproperty"].Patterns); - Assert.AreEqual(JsonSchemaType.Object, model.Properties["thirdproperty"].Type); - Assert.AreEqual(3, model.Properties["thirdproperty"].AdditionalProperties.Enum.Count); - Assert.AreEqual("two", (string)model.Properties["thirdproperty"].AdditionalProperties.Enum[0]); - Assert.AreEqual("three", (string)model.Properties["thirdproperty"].AdditionalProperties.Enum[1]); - Assert.AreEqual("one", (string)model.Properties["thirdproperty"].AdditionalProperties.Enum[2]); + Assert.AreEqual(JsonSchemaType.Object, model.Properties["thirdproperty"].Type); + Assert.AreEqual(3, model.Properties["thirdproperty"].AdditionalProperties.Enum.Count); + Assert.AreEqual("two", (string)model.Properties["thirdproperty"].AdditionalProperties.Enum[0]); + Assert.AreEqual("three", (string)model.Properties["thirdproperty"].AdditionalProperties.Enum[1]); + Assert.AreEqual("one", (string)model.Properties["thirdproperty"].AdditionalProperties.Enum[2]); - Assert.AreEqual(JsonSchemaType.String, model.Properties["thirdproperty"].Properties["thirdproperty_firstproperty"].Type); - Assert.AreEqual(9, model.Properties["thirdproperty"].Properties["thirdproperty_firstproperty"].MaximumLength); - Assert.AreEqual(7, model.Properties["thirdproperty"].Properties["thirdproperty_firstproperty"].MinimumLength); - Assert.AreEqual(2, model.Properties["thirdproperty"].Properties["thirdproperty_firstproperty"].Patterns.Count); - Assert.AreEqual("hi", model.Properties["thirdproperty"].Properties["thirdproperty_firstproperty"].Patterns[0]); - Assert.AreEqual("hi2u", model.Properties["thirdproperty"].Properties["thirdproperty_firstproperty"].Patterns[1]); - Assert.AreEqual(null, model.Properties["thirdproperty"].Properties["thirdproperty_firstproperty"].Properties); - Assert.AreEqual(null, model.Properties["thirdproperty"].Properties["thirdproperty_firstproperty"].Items); - Assert.AreEqual(null, model.Properties["thirdproperty"].Properties["thirdproperty_firstproperty"].AdditionalProperties); - } + Assert.AreEqual(JsonSchemaType.String, model.Properties["thirdproperty"].Properties["thirdproperty_firstproperty"].Type); + Assert.AreEqual(9, model.Properties["thirdproperty"].Properties["thirdproperty_firstproperty"].MaximumLength); + Assert.AreEqual(7, model.Properties["thirdproperty"].Properties["thirdproperty_firstproperty"].MinimumLength); + Assert.AreEqual(2, model.Properties["thirdproperty"].Properties["thirdproperty_firstproperty"].Patterns.Count); + Assert.AreEqual("hi", model.Properties["thirdproperty"].Properties["thirdproperty_firstproperty"].Patterns[0]); + Assert.AreEqual("hi2u", model.Properties["thirdproperty"].Properties["thirdproperty_firstproperty"].Patterns[1]); + Assert.AreEqual(null, model.Properties["thirdproperty"].Properties["thirdproperty_firstproperty"].Properties); + Assert.AreEqual(null, model.Properties["thirdproperty"].Properties["thirdproperty_firstproperty"].Items); + Assert.AreEqual(null, model.Properties["thirdproperty"].Properties["thirdproperty_firstproperty"].AdditionalProperties); + } - [Test] - public void CircularReference() - { - string json = @"{ + [Test] + public void CircularReference() + { + string json = @"{ ""id"":""CircularReferenceArray"", ""description"":""CircularReference"", ""type"":[""array""], ""items"":{""$ref"":""CircularReferenceArray""} }"; - JsonSchema schema = JsonSchema.Parse(json); + JsonSchema schema = JsonSchema.Parse(json); - JsonSchemaModelBuilder modelBuilder = new JsonSchemaModelBuilder(); + JsonSchemaModelBuilder modelBuilder = new JsonSchemaModelBuilder(); - JsonSchemaModel model = modelBuilder.Build(schema); + JsonSchemaModel model = modelBuilder.Build(schema); - Assert.AreEqual(JsonSchemaType.Array, model.Type); + Assert.AreEqual(JsonSchemaType.Array, model.Type); - Assert.AreEqual(model, model.Items[0]); - } + Assert.AreEqual(model, model.Items[0]); + } - [Test] - public void Required() - { - string schemaJson = @"{ + [Test] + public void Required() + { + string schemaJson = @"{ ""description"":""A person"", ""type"":""object"", ""properties"": @@ -154,15 +155,15 @@ namespace Newtonsoft.Json.Tests.Schema } }"; - JsonSchema schema = JsonSchema.Parse(schemaJson); - JsonSchemaModelBuilder modelBuilder = new JsonSchemaModelBuilder(); - JsonSchemaModel model = modelBuilder.Build(schema); + JsonSchema schema = JsonSchema.Parse(schemaJson); + JsonSchemaModelBuilder modelBuilder = new JsonSchemaModelBuilder(); + JsonSchemaModel model = modelBuilder.Build(schema); - Assert.AreEqual(JsonSchemaType.Object, model.Type); - Assert.AreEqual(3, model.Properties.Count); - Assert.AreEqual(false, model.Properties["name"].Required); - Assert.AreEqual(true, model.Properties["hobbies"].Required); - Assert.AreEqual(true, model.Properties["age"].Required); + Assert.AreEqual(JsonSchemaType.Object, model.Type); + Assert.AreEqual(3, model.Properties.Count); + Assert.AreEqual(false, model.Properties["name"].Required); + Assert.AreEqual(true, model.Properties["hobbies"].Required); + Assert.AreEqual(true, model.Properties["age"].Required); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaNodeTests.cs b/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaNodeTests.cs index 82a78743..b622f841 100644 --- a/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaNodeTests.cs +++ b/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaNodeTests.cs @@ -26,6 +26,7 @@ using Newtonsoft.Json.Schema; #if !NETFX_CORE using NUnit.Framework; + #else using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; @@ -34,13 +35,13 @@ using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAtt namespace Newtonsoft.Json.Tests.Schema { - [TestFixture] - public class JsonSchemaNodeTests : TestFixtureBase - { - [Test] - public void AddSchema() + [TestFixture] + public class JsonSchemaNodeTests : TestFixtureBase { - string first = @"{ + [Test] + public void AddSchema() + { + string first = @"{ ""id"":""first"", ""type"":""object"", ""properties"": @@ -57,7 +58,7 @@ namespace Newtonsoft.Json.Tests.Schema ""additionalProperties"":{} }"; - string second = @"{ + string second = @"{ ""id"":""second"", ""type"":""object"", ""extends"":{""$ref"":""first""}, @@ -82,40 +83,39 @@ namespace Newtonsoft.Json.Tests.Schema ""additionalProperties"":false }"; - JsonSchemaResolver resolver = new JsonSchemaResolver(); - JsonSchema firstSchema = JsonSchema.Parse(first, resolver); - JsonSchema secondSchema = JsonSchema.Parse(second, resolver); + JsonSchemaResolver resolver = new JsonSchemaResolver(); + JsonSchema firstSchema = JsonSchema.Parse(first, resolver); + JsonSchema secondSchema = JsonSchema.Parse(second, resolver); - JsonSchemaModelBuilder modelBuilder = new JsonSchemaModelBuilder(); + JsonSchemaModelBuilder modelBuilder = new JsonSchemaModelBuilder(); - JsonSchemaNode node = modelBuilder.AddSchema(null, secondSchema); + JsonSchemaNode node = modelBuilder.AddSchema(null, secondSchema); - Assert.AreEqual(2, node.Schemas.Count); - Assert.AreEqual(2, node.Properties["firstproperty"].Schemas.Count); - Assert.AreEqual(3, node.Properties["secondproperty"].Schemas.Count); - Assert.AreEqual(3, node.Properties["secondproperty"].Properties["secondproperty_firstproperty"].Schemas.Count); - } + Assert.AreEqual(2, node.Schemas.Count); + Assert.AreEqual(2, node.Properties["firstproperty"].Schemas.Count); + Assert.AreEqual(3, node.Properties["secondproperty"].Schemas.Count); + Assert.AreEqual(3, node.Properties["secondproperty"].Properties["secondproperty_firstproperty"].Schemas.Count); + } - [Test] - public void CircularReference() - { - string json = @"{ + [Test] + public void CircularReference() + { + string json = @"{ ""id"":""CircularReferenceArray"", ""description"":""CircularReference"", ""type"":[""array""], ""items"":{""$ref"":""CircularReferenceArray""} }"; - JsonSchema schema = JsonSchema.Parse(json); + JsonSchema schema = JsonSchema.Parse(json); - JsonSchemaModelBuilder modelBuilder = new JsonSchemaModelBuilder(); + JsonSchemaModelBuilder modelBuilder = new JsonSchemaModelBuilder(); - JsonSchemaNode node = modelBuilder.AddSchema(null, schema); + JsonSchemaNode node = modelBuilder.AddSchema(null, schema); - Assert.AreEqual(1, node.Schemas.Count); + Assert.AreEqual(1, node.Schemas.Count); - Assert.AreEqual(node, node.Items[0]); + Assert.AreEqual(node, node.Items[0]); + } } - - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaSpecTests.cs b/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaSpecTests.cs index 515e450a..d1baf692 100644 --- a/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaSpecTests.cs +++ b/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaSpecTests.cs @@ -10,86 +10,86 @@ using Newtonsoft.Json.Schema; namespace Newtonsoft.Json.Tests.Schema { - public class JsonSchemaSpecTest - { - public string FileName { get; set; } - public string TestCaseDescription { get; set; } - public JObject Schema { get; set; } - public string TestDescription { get; set; } - public JToken Data { get; set; } - public bool IsValid { get; set; } - public int TestNumber { get; set; } - - public override string ToString() + public class JsonSchemaSpecTest { - return FileName + " - " + TestCaseDescription + " - " + TestDescription; - } - } + public string FileName { get; set; } + public string TestCaseDescription { get; set; } + public JObject Schema { get; set; } + public string TestDescription { get; set; } + public JToken Data { get; set; } + public bool IsValid { get; set; } + public int TestNumber { get; set; } - [TestFixture] - public class JsonSchemaSpecTests : TestFixtureBase - { - [TestCaseSourceAttribute("GetSpecTestDetails")] - public void SpecTest(JsonSchemaSpecTest jsonSchemaSpecTest) - { - //if (jsonSchemaSpecTest.ToString() == "enum.json - simple enum validation - something else is invalid") - { - Console.WriteLine("Running JSON Schema test " + jsonSchemaSpecTest.TestNumber + ": " + jsonSchemaSpecTest); - - JsonSchema s = JsonSchema.Read(jsonSchemaSpecTest.Schema.CreateReader()); - - IList errorMessages; - bool v = jsonSchemaSpecTest.Data.IsValid(s, out errorMessages); - errorMessages = errorMessages ?? new List(); - - Assert.AreEqual(jsonSchemaSpecTest.IsValid, v, jsonSchemaSpecTest.TestCaseDescription + " - " + jsonSchemaSpecTest.TestDescription + " - errors: " + string.Join(", ", errorMessages)); - } - } - - public IList GetSpecTestDetails() - { - IList specTests = new List(); - - // get test files location relative to the test project dll - string baseDirectory = AppDomain.CurrentDomain.BaseDirectory; - string baseTestPath = Path.Combine(baseDirectory, "Schema", "Specs"); - - string[] testFiles = Directory.GetFiles(baseTestPath, "*.json", SearchOption.AllDirectories); - - // read through each of the *.json test files and extract the test details - foreach (string testFile in testFiles) - { - string testJson = System.IO.File.ReadAllText(testFile); - - JArray a = JArray.Parse(testJson); - - foreach (JObject testCase in a) + public override string ToString() { - foreach (JObject test in testCase["tests"]) - { - JsonSchemaSpecTest jsonSchemaSpecTest = new JsonSchemaSpecTest(); + return FileName + " - " + TestCaseDescription + " - " + TestDescription; + } + } - jsonSchemaSpecTest.FileName = Path.GetFileName(testFile); - jsonSchemaSpecTest.TestCaseDescription = (string) testCase["description"]; - jsonSchemaSpecTest.Schema = (JObject) testCase["schema"]; + [TestFixture] + public class JsonSchemaSpecTests : TestFixtureBase + { + [TestCaseSourceAttribute("GetSpecTestDetails")] + public void SpecTest(JsonSchemaSpecTest jsonSchemaSpecTest) + { + //if (jsonSchemaSpecTest.ToString() == "enum.json - simple enum validation - something else is invalid") + { + Console.WriteLine("Running JSON Schema test " + jsonSchemaSpecTest.TestNumber + ": " + jsonSchemaSpecTest); - jsonSchemaSpecTest.TestDescription = (string) test["description"]; - jsonSchemaSpecTest.Data = test["data"]; - jsonSchemaSpecTest.IsValid = (bool) test["valid"]; - jsonSchemaSpecTest.TestNumber = specTests.Count + 1; + JsonSchema s = JsonSchema.Read(jsonSchemaSpecTest.Schema.CreateReader()); - specTests.Add(jsonSchemaSpecTest); - } + IList errorMessages; + bool v = jsonSchemaSpecTest.Data.IsValid(s, out errorMessages); + errorMessages = errorMessages ?? new List(); + + Assert.AreEqual(jsonSchemaSpecTest.IsValid, v, jsonSchemaSpecTest.TestCaseDescription + " - " + jsonSchemaSpecTest.TestDescription + " - errors: " + string.Join(", ", errorMessages)); + } + } + + public IList GetSpecTestDetails() + { + IList specTests = new List(); + + // get test files location relative to the test project dll + string baseDirectory = AppDomain.CurrentDomain.BaseDirectory; + string baseTestPath = Path.Combine(baseDirectory, "Schema", "Specs"); + + string[] testFiles = Directory.GetFiles(baseTestPath, "*.json", SearchOption.AllDirectories); + + // read through each of the *.json test files and extract the test details + foreach (string testFile in testFiles) + { + string testJson = System.IO.File.ReadAllText(testFile); + + JArray a = JArray.Parse(testJson); + + foreach (JObject testCase in a) + { + foreach (JObject test in testCase["tests"]) + { + JsonSchemaSpecTest jsonSchemaSpecTest = new JsonSchemaSpecTest(); + + jsonSchemaSpecTest.FileName = Path.GetFileName(testFile); + jsonSchemaSpecTest.TestCaseDescription = (string)testCase["description"]; + jsonSchemaSpecTest.Schema = (JObject)testCase["schema"]; + + jsonSchemaSpecTest.TestDescription = (string)test["description"]; + jsonSchemaSpecTest.Data = test["data"]; + jsonSchemaSpecTest.IsValid = (bool)test["valid"]; + jsonSchemaSpecTest.TestNumber = specTests.Count + 1; + + specTests.Add(jsonSchemaSpecTest); + } + } + } + + specTests = specTests.Where(s => s.FileName != "dependencies.json" + && s.TestCaseDescription != "multiple disallow subschema" + && s.TestCaseDescription != "types from separate schemas are merged" + && s.TestCaseDescription != "when types includes a schema it should fully validate the schema" + && s.TestCaseDescription != "types can include schemas").ToList(); + + return specTests; } - } - - specTests = specTests.Where(s => s.FileName != "dependencies.json" - && s.TestCaseDescription != "multiple disallow subschema" - && s.TestCaseDescription != "types from separate schemas are merged" - && s.TestCaseDescription != "when types includes a schema it should fully validate the schema" - && s.TestCaseDescription != "types can include schemas").ToList(); - - return specTests; } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaTests.cs b/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaTests.cs index 90fa9522..3ab843b1 100644 --- a/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaTests.cs +++ b/Src/Newtonsoft.Json.Tests/Schema/JsonSchemaTests.cs @@ -30,6 +30,7 @@ using Newtonsoft.Json.Linq; using Newtonsoft.Json.Schema; #if !NETFX_CORE using NUnit.Framework; + #else using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; @@ -38,54 +39,54 @@ using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAtt namespace Newtonsoft.Json.Tests.Schema { - [TestFixture] - public class JsonSchemaTests : TestFixtureBase - { - [Test] - public void Extends() + [TestFixture] + public class JsonSchemaTests : TestFixtureBase { - string json; - JsonSchemaResolver resolver = new JsonSchemaResolver(); + [Test] + public void Extends() + { + string json; + JsonSchemaResolver resolver = new JsonSchemaResolver(); - json = @"{ + json = @"{ ""id"":""first"", ""type"":""object"", ""additionalProperties"":{} }"; - JsonSchema first = JsonSchema.Parse(json, resolver); + JsonSchema first = JsonSchema.Parse(json, resolver); - json = - @"{ + json = + @"{ ""id"":""second"", ""type"":""object"", ""extends"":{""$ref"":""first""}, ""additionalProperties"":{""type"":""string""} }"; - JsonSchema second = JsonSchema.Parse(json, resolver); - Assert.AreEqual(first, second.Extends[0]); + JsonSchema second = JsonSchema.Parse(json, resolver); + Assert.AreEqual(first, second.Extends[0]); - json = - @"{ + json = + @"{ ""id"":""third"", ""type"":""object"", ""extends"":{""$ref"":""second""}, ""additionalProperties"":false }"; - JsonSchema third = JsonSchema.Parse(json, resolver); - Assert.AreEqual(second, third.Extends[0]); - Assert.AreEqual(first, third.Extends[0].Extends[0]); + JsonSchema third = JsonSchema.Parse(json, resolver); + Assert.AreEqual(second, third.Extends[0]); + Assert.AreEqual(first, third.Extends[0].Extends[0]); - StringWriter writer = new StringWriter(); - JsonTextWriter jsonWriter = new JsonTextWriter(writer); - jsonWriter.Formatting = Formatting.Indented; + StringWriter writer = new StringWriter(); + JsonTextWriter jsonWriter = new JsonTextWriter(writer); + jsonWriter.Formatting = Formatting.Indented; - third.WriteTo(jsonWriter, resolver); + third.WriteTo(jsonWriter, resolver); - string writtenJson = writer.ToString(); - Assert.AreEqual(@"{ + string writtenJson = writer.ToString(); + Assert.AreEqual(@"{ ""id"": ""third"", ""type"": ""object"", ""additionalProperties"": false, @@ -94,14 +95,14 @@ namespace Newtonsoft.Json.Tests.Schema } }", writtenJson); - StringWriter writer1 = new StringWriter(); - JsonTextWriter jsonWriter1 = new JsonTextWriter(writer1); - jsonWriter1.Formatting = Formatting.Indented; + StringWriter writer1 = new StringWriter(); + JsonTextWriter jsonWriter1 = new JsonTextWriter(writer1); + jsonWriter1.Formatting = Formatting.Indented; - third.WriteTo(jsonWriter1); + third.WriteTo(jsonWriter1); - writtenJson = writer1.ToString(); - Assert.AreEqual(@"{ + writtenJson = writer1.ToString(); + Assert.AreEqual(@"{ ""id"": ""third"", ""type"": ""object"", ""additionalProperties"": false, @@ -118,26 +119,26 @@ namespace Newtonsoft.Json.Tests.Schema } } }", writtenJson); - } + } - [Test] - public void Extends_Multiple() - { - string json = @"{ + [Test] + public void Extends_Multiple() + { + string json = @"{ ""type"":""object"", ""extends"":{""type"":""string""}, ""additionalProperties"":{""type"":""string""} }"; - JsonSchema s = JsonSchema.Parse(json); + JsonSchema s = JsonSchema.Parse(json); - StringWriter writer = new StringWriter(); - JsonTextWriter jsonWriter = new JsonTextWriter(writer); - jsonWriter.Formatting = Formatting.Indented; + StringWriter writer = new StringWriter(); + JsonTextWriter jsonWriter = new JsonTextWriter(writer); + jsonWriter.Formatting = Formatting.Indented; - string newJson = s.ToString(); + string newJson = s.ToString(); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""type"": ""object"", ""additionalProperties"": { ""type"": ""string"" @@ -146,23 +147,23 @@ namespace Newtonsoft.Json.Tests.Schema ""type"": ""string"" } }", newJson); - - json = @"{ + + json = @"{ ""type"":""object"", ""extends"":[{""type"":""string""}], ""additionalProperties"":{""type"":""string""} }"; - s = JsonSchema.Parse(json); + s = JsonSchema.Parse(json); - writer = new StringWriter(); - jsonWriter = new JsonTextWriter(writer); - jsonWriter.Formatting = Formatting.Indented; + writer = new StringWriter(); + jsonWriter = new JsonTextWriter(writer); + jsonWriter.Formatting = Formatting.Indented; - newJson = s.ToString(); + newJson = s.ToString(); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""type"": ""object"", ""additionalProperties"": { ""type"": ""string"" @@ -173,21 +174,21 @@ namespace Newtonsoft.Json.Tests.Schema }", newJson); - json = @"{ + json = @"{ ""type"":""object"", ""extends"":[{""type"":""string""},{""type"":""object""}], ""additionalProperties"":{""type"":""string""} }"; - s = JsonSchema.Parse(json); + s = JsonSchema.Parse(json); - writer = new StringWriter(); - jsonWriter = new JsonTextWriter(writer); - jsonWriter.Formatting = Formatting.Indented; + writer = new StringWriter(); + jsonWriter = new JsonTextWriter(writer); + jsonWriter.Formatting = Formatting.Indented; - newJson = s.ToString(); + newJson = s.ToString(); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""type"": ""object"", ""additionalProperties"": { ""type"": ""string"" @@ -201,26 +202,26 @@ namespace Newtonsoft.Json.Tests.Schema } ] }", newJson); - } + } - [Test] - public void WriteTo_AdditionalProperties() - { - StringWriter writer = new StringWriter(); - JsonTextWriter jsonWriter = new JsonTextWriter(writer); - jsonWriter.Formatting = Formatting.Indented; + [Test] + public void WriteTo_AdditionalProperties() + { + StringWriter writer = new StringWriter(); + JsonTextWriter jsonWriter = new JsonTextWriter(writer); + jsonWriter.Formatting = Formatting.Indented; - JsonSchema schema = JsonSchema.Parse(@"{ + JsonSchema schema = JsonSchema.Parse(@"{ ""description"":""AdditionalProperties"", ""type"":[""string"", ""integer""], ""additionalProperties"":{""type"":[""object"", ""boolean""]} }"); - schema.WriteTo(jsonWriter); + schema.WriteTo(jsonWriter); - string json = writer.ToString(); + string json = writer.ToString(); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""description"": ""AdditionalProperties"", ""type"": [ ""string"", @@ -233,12 +234,12 @@ namespace Newtonsoft.Json.Tests.Schema ] } }", json); - } + } - [Test] - public void WriteTo_Properties() - { - JsonSchema schema = JsonSchema.Parse(@"{ + [Test] + public void WriteTo_Properties() + { + JsonSchema schema = JsonSchema.Parse(@"{ ""description"":""A person"", ""type"":""object"", ""properties"": @@ -252,15 +253,15 @@ namespace Newtonsoft.Json.Tests.Schema } }"); - StringWriter writer = new StringWriter(); - JsonTextWriter jsonWriter = new JsonTextWriter(writer); - jsonWriter.Formatting = Formatting.Indented; + StringWriter writer = new StringWriter(); + JsonTextWriter jsonWriter = new JsonTextWriter(writer); + jsonWriter.Formatting = Formatting.Indented; - schema.WriteTo(jsonWriter); + schema.WriteTo(jsonWriter); - string json = writer.ToString(); + string json = writer.ToString(); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""description"": ""A person"", ""type"": ""object"", ""properties"": { @@ -275,28 +276,27 @@ namespace Newtonsoft.Json.Tests.Schema } } }", json); + } - } - - [Test] - public void WriteTo_Enum() - { - JsonSchema schema = JsonSchema.Parse(@"{ + [Test] + public void WriteTo_Enum() + { + JsonSchema schema = JsonSchema.Parse(@"{ ""description"":""Type"", ""type"":[""string"",""array""], ""items"":{}, ""enum"":[""string"",""object"",""array"",""boolean"",""number"",""integer"",""null"",""any""] }"); - StringWriter writer = new StringWriter(); - JsonTextWriter jsonWriter = new JsonTextWriter(writer); - jsonWriter.Formatting = Formatting.Indented; + StringWriter writer = new StringWriter(); + JsonTextWriter jsonWriter = new JsonTextWriter(writer); + jsonWriter.Formatting = Formatting.Indented; - schema.WriteTo(jsonWriter); + schema.WriteTo(jsonWriter); - string json = writer.ToString(); + string json = writer.ToString(); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""description"": ""Type"", ""type"": [ ""string"", @@ -314,29 +314,29 @@ namespace Newtonsoft.Json.Tests.Schema ""any"" ] }", json); - } + } - [Test] - public void WriteTo_CircularReference() - { - string json = @"{ + [Test] + public void WriteTo_CircularReference() + { + string json = @"{ ""id"":""CircularReferenceArray"", ""description"":""CircularReference"", ""type"":[""array""], ""items"":{""$ref"":""CircularReferenceArray""} }"; - JsonSchema schema = JsonSchema.Parse(json); + JsonSchema schema = JsonSchema.Parse(json); - StringWriter writer = new StringWriter(); - JsonTextWriter jsonWriter = new JsonTextWriter(writer); - jsonWriter.Formatting = Formatting.Indented; + StringWriter writer = new StringWriter(); + JsonTextWriter jsonWriter = new JsonTextWriter(writer); + jsonWriter.Formatting = Formatting.Indented; - schema.WriteTo(jsonWriter); + schema.WriteTo(jsonWriter); - string writtenJson = writer.ToString(); + string writtenJson = writer.ToString(); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""id"": ""CircularReferenceArray"", ""description"": ""CircularReference"", ""type"": ""array"", @@ -344,27 +344,27 @@ namespace Newtonsoft.Json.Tests.Schema ""$ref"": ""CircularReferenceArray"" } }", writtenJson); - } + } - [Test] - public void WriteTo_DisallowMultiple() - { - JsonSchema schema = JsonSchema.Parse(@"{ + [Test] + public void WriteTo_DisallowMultiple() + { + JsonSchema schema = JsonSchema.Parse(@"{ ""description"":""Type"", ""type"":[""string"",""array""], ""items"":{}, ""disallow"":[""string"",""object"",""array""] }"); - StringWriter writer = new StringWriter(); - JsonTextWriter jsonWriter = new JsonTextWriter(writer); - jsonWriter.Formatting = Formatting.Indented; + StringWriter writer = new StringWriter(); + JsonTextWriter jsonWriter = new JsonTextWriter(writer); + jsonWriter.Formatting = Formatting.Indented; - schema.WriteTo(jsonWriter); + schema.WriteTo(jsonWriter); - string json = writer.ToString(); + string json = writer.ToString(); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""description"": ""Type"", ""type"": [ ""string"", @@ -377,27 +377,27 @@ namespace Newtonsoft.Json.Tests.Schema ""array"" ] }", json); - } + } - [Test] - public void WriteTo_DisallowSingle() - { - JsonSchema schema = JsonSchema.Parse(@"{ + [Test] + public void WriteTo_DisallowSingle() + { + JsonSchema schema = JsonSchema.Parse(@"{ ""description"":""Type"", ""type"":[""string"",""array""], ""items"":{}, ""disallow"":""any"" }"); - StringWriter writer = new StringWriter(); - JsonTextWriter jsonWriter = new JsonTextWriter(writer); - jsonWriter.Formatting = Formatting.Indented; + StringWriter writer = new StringWriter(); + JsonTextWriter jsonWriter = new JsonTextWriter(writer); + jsonWriter.Formatting = Formatting.Indented; - schema.WriteTo(jsonWriter); + schema.WriteTo(jsonWriter); - string json = writer.ToString(); + string json = writer.ToString(); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""description"": ""Type"", ""type"": [ ""string"", @@ -406,160 +406,160 @@ namespace Newtonsoft.Json.Tests.Schema ""items"": {}, ""disallow"": ""any"" }", json); - } + } - [Test] - public void WriteTo_MultipleItems() - { - JsonSchema schema = JsonSchema.Parse(@"{ + [Test] + public void WriteTo_MultipleItems() + { + JsonSchema schema = JsonSchema.Parse(@"{ ""items"":[{},{}] }"); - StringWriter writer = new StringWriter(); - JsonTextWriter jsonWriter = new JsonTextWriter(writer); - jsonWriter.Formatting = Formatting.Indented; + StringWriter writer = new StringWriter(); + JsonTextWriter jsonWriter = new JsonTextWriter(writer); + jsonWriter.Formatting = Formatting.Indented; - schema.WriteTo(jsonWriter); + schema.WriteTo(jsonWriter); - string json = writer.ToString(); + string json = writer.ToString(); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""items"": [ {}, {} ] }", json); - } + } - [Test] - public void WriteTo_ExclusiveMinimum_ExclusiveMaximum() - { - JsonSchema schema = new JsonSchema(); - schema.ExclusiveMinimum = true; - schema.ExclusiveMaximum = true; + [Test] + public void WriteTo_ExclusiveMinimum_ExclusiveMaximum() + { + JsonSchema schema = new JsonSchema(); + schema.ExclusiveMinimum = true; + schema.ExclusiveMaximum = true; - StringWriter writer = new StringWriter(); - JsonTextWriter jsonWriter = new JsonTextWriter(writer); - jsonWriter.Formatting = Formatting.Indented; + StringWriter writer = new StringWriter(); + JsonTextWriter jsonWriter = new JsonTextWriter(writer); + jsonWriter.Formatting = Formatting.Indented; - schema.WriteTo(jsonWriter); + schema.WriteTo(jsonWriter); - string json = writer.ToString(); + string json = writer.ToString(); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""exclusiveMinimum"": true, ""exclusiveMaximum"": true }", json); - } + } - [Test] - public void WriteTo_PatternProperties() - { - JsonSchema schema = new JsonSchema(); - schema.PatternProperties = new Dictionary + [Test] + public void WriteTo_PatternProperties() { - { "[abc]", new JsonSchema() } - }; + JsonSchema schema = new JsonSchema(); + schema.PatternProperties = new Dictionary + { + { "[abc]", new JsonSchema() } + }; - StringWriter writer = new StringWriter(); - JsonTextWriter jsonWriter = new JsonTextWriter(writer); - jsonWriter.Formatting = Formatting.Indented; + StringWriter writer = new StringWriter(); + JsonTextWriter jsonWriter = new JsonTextWriter(writer); + jsonWriter.Formatting = Formatting.Indented; - schema.WriteTo(jsonWriter); + schema.WriteTo(jsonWriter); - string json = writer.ToString(); + string json = writer.ToString(); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""patternProperties"": { ""[abc]"": {} } }", json); - } + } - [Test] - public void ToString_AdditionalItems() - { - JsonSchema schema = JsonSchema.Parse(@"{ + [Test] + public void ToString_AdditionalItems() + { + JsonSchema schema = JsonSchema.Parse(@"{ ""additionalItems"": {""type"": ""integer""} }"); - string json = schema.ToString(); + string json = schema.ToString(); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""additionalItems"": { ""type"": ""integer"" } }", json); - } + } - [Test] - public void WriteTo_PositionalItemsValidation_True() - { - JsonSchema schema = new JsonSchema(); - schema.PositionalItemsValidation = true; + [Test] + public void WriteTo_PositionalItemsValidation_True() + { + JsonSchema schema = new JsonSchema(); + schema.PositionalItemsValidation = true; - StringWriter writer = new StringWriter(); - JsonTextWriter jsonWriter = new JsonTextWriter(writer); - jsonWriter.Formatting = Formatting.Indented; + StringWriter writer = new StringWriter(); + JsonTextWriter jsonWriter = new JsonTextWriter(writer); + jsonWriter.Formatting = Formatting.Indented; - schema.WriteTo(jsonWriter); + schema.WriteTo(jsonWriter); - string json = writer.ToString(); + string json = writer.ToString(); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""items"": [] }", json); - } + } - [Test] - public void WriteTo_PositionalItemsValidation_TrueWithItemsSchema() - { - JsonSchema schema = new JsonSchema(); - schema.PositionalItemsValidation = true; - schema.Items = new List { new JsonSchema { Type = JsonSchemaType.String }}; + [Test] + public void WriteTo_PositionalItemsValidation_TrueWithItemsSchema() + { + JsonSchema schema = new JsonSchema(); + schema.PositionalItemsValidation = true; + schema.Items = new List { new JsonSchema { Type = JsonSchemaType.String } }; - StringWriter writer = new StringWriter(); - JsonTextWriter jsonWriter = new JsonTextWriter(writer); - jsonWriter.Formatting = Formatting.Indented; + StringWriter writer = new StringWriter(); + JsonTextWriter jsonWriter = new JsonTextWriter(writer); + jsonWriter.Formatting = Formatting.Indented; - schema.WriteTo(jsonWriter); + schema.WriteTo(jsonWriter); - string json = writer.ToString(); + string json = writer.ToString(); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""items"": [ { ""type"": ""string"" } ] }", json); - } + } - [Test] - public void WriteTo_PositionalItemsValidation_FalseWithItemsSchema() - { - JsonSchema schema = new JsonSchema(); - schema.Items = new List { new JsonSchema { Type = JsonSchemaType.String } }; + [Test] + public void WriteTo_PositionalItemsValidation_FalseWithItemsSchema() + { + JsonSchema schema = new JsonSchema(); + schema.Items = new List { new JsonSchema { Type = JsonSchemaType.String } }; - StringWriter writer = new StringWriter(); - JsonTextWriter jsonWriter = new JsonTextWriter(writer); - jsonWriter.Formatting = Formatting.Indented; + StringWriter writer = new StringWriter(); + JsonTextWriter jsonWriter = new JsonTextWriter(writer); + jsonWriter.Formatting = Formatting.Indented; - schema.WriteTo(jsonWriter); + schema.WriteTo(jsonWriter); - string json = writer.ToString(); + string json = writer.ToString(); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""items"": { ""type"": ""string"" } }", json); - } + } - [Test] - public void IntegerValidatesAgainstFloatFlags() - { - JsonSchema schema = JsonSchema.Parse(@"{ + [Test] + public void IntegerValidatesAgainstFloatFlags() + { + JsonSchema schema = JsonSchema.Parse(@"{ ""type"": ""object"", ""$schema"": ""http://json-schema.org/draft-03/schema"", ""required"": false, @@ -574,11 +574,11 @@ namespace Newtonsoft.Json.Tests.Schema } }"); - JObject json = JObject.Parse(@"{ + JObject json = JObject.Parse(@"{ ""NumberProperty"": 23 }"); - Assert.IsTrue(json.IsValid(schema)); + Assert.IsTrue(json.IsValid(schema)); + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Serialization/CamelCasePropertyNamesContractResolverTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/CamelCasePropertyNamesContractResolverTests.cs index aaec1787..2a3668ab 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/CamelCasePropertyNamesContractResolverTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/CamelCasePropertyNamesContractResolverTests.cs @@ -40,132 +40,131 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Tests.Serialization { - [TestFixture] - public class CamelCasePropertyNamesContractResolverTests : TestFixtureBase - { - [Test] - public void JsonConvertSerializerSettings() + [TestFixture] + public class CamelCasePropertyNamesContractResolverTests : TestFixtureBase { - Person person = new Person(); - person.BirthDate = new DateTime(2000, 11, 20, 23, 55, 44, DateTimeKind.Utc); - person.LastModified = new DateTime(2000, 11, 20, 23, 55, 44, DateTimeKind.Utc); - person.Name = "Name!"; + [Test] + public void JsonConvertSerializerSettings() + { + Person person = new Person(); + person.BirthDate = new DateTime(2000, 11, 20, 23, 55, 44, DateTimeKind.Utc); + person.LastModified = new DateTime(2000, 11, 20, 23, 55, 44, DateTimeKind.Utc); + person.Name = "Name!"; - string json = JsonConvert.SerializeObject(person, Formatting.Indented, new JsonSerializerSettings - { - ContractResolver = new CamelCasePropertyNamesContractResolver() - }); + string json = JsonConvert.SerializeObject(person, Formatting.Indented, new JsonSerializerSettings + { + ContractResolver = new CamelCasePropertyNamesContractResolver() + }); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""name"": ""Name!"", ""birthDate"": ""2000-11-20T23:55:44Z"", ""lastModified"": ""2000-11-20T23:55:44Z"" }", json); - Person deserializedPerson = JsonConvert.DeserializeObject(json, new JsonSerializerSettings - { - ContractResolver = new CamelCasePropertyNamesContractResolver() - }); + Person deserializedPerson = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + ContractResolver = new CamelCasePropertyNamesContractResolver() + }); - Assert.AreEqual(person.BirthDate, deserializedPerson.BirthDate); - Assert.AreEqual(person.LastModified, deserializedPerson.LastModified); - Assert.AreEqual(person.Name, deserializedPerson.Name); + Assert.AreEqual(person.BirthDate, deserializedPerson.BirthDate); + Assert.AreEqual(person.LastModified, deserializedPerson.LastModified); + Assert.AreEqual(person.Name, deserializedPerson.Name); - json = JsonConvert.SerializeObject(person, Formatting.Indented); - Assert.AreEqual(@"{ + json = JsonConvert.SerializeObject(person, Formatting.Indented); + Assert.AreEqual(@"{ ""Name"": ""Name!"", ""BirthDate"": ""2000-11-20T23:55:44Z"", ""LastModified"": ""2000-11-20T23:55:44Z"" }", json); + } - } + [Test] + public void JTokenWriter() + { + JsonIgnoreAttributeOnClassTestClass ignoreAttributeOnClassTestClass = new JsonIgnoreAttributeOnClassTestClass(); + ignoreAttributeOnClassTestClass.Field = int.MinValue; - [Test] - public void JTokenWriter() - { - JsonIgnoreAttributeOnClassTestClass ignoreAttributeOnClassTestClass = new JsonIgnoreAttributeOnClassTestClass(); - ignoreAttributeOnClassTestClass.Field = int.MinValue; + JsonSerializer serializer = new JsonSerializer(); + serializer.ContractResolver = new CamelCasePropertyNamesContractResolver(); - JsonSerializer serializer = new JsonSerializer(); - serializer.ContractResolver = new CamelCasePropertyNamesContractResolver(); + JTokenWriter writer = new JTokenWriter(); - JTokenWriter writer = new JTokenWriter(); + serializer.Serialize(writer, ignoreAttributeOnClassTestClass); - serializer.Serialize(writer, ignoreAttributeOnClassTestClass); + JObject o = (JObject)writer.Token; + JProperty p = o.Property("theField"); - JObject o = (JObject) writer.Token; - JProperty p = o.Property("theField"); + Assert.IsNotNull(p); + Assert.AreEqual(int.MinValue, (int)p.Value); - Assert.IsNotNull(p); - Assert.AreEqual(int.MinValue, (int)p.Value); - - string json = o.ToString(); - } + string json = o.ToString(); + } #if !(NETFX_CORE || PORTABLE || PORTABLE40) - [Test] - public void MemberSearchFlags() - { - PrivateMembersClass privateMembersClass = new PrivateMembersClass("PrivateString!", "InternalString!"); + [Test] + public void MemberSearchFlags() + { + PrivateMembersClass privateMembersClass = new PrivateMembersClass("PrivateString!", "InternalString!"); - string json = JsonConvert.SerializeObject(privateMembersClass, Formatting.Indented, new JsonSerializerSettings - { - ContractResolver = new CamelCasePropertyNamesContractResolver { DefaultMembersSearchFlags = BindingFlags.NonPublic | BindingFlags.Instance } - }); + string json = JsonConvert.SerializeObject(privateMembersClass, Formatting.Indented, new JsonSerializerSettings + { + ContractResolver = new CamelCasePropertyNamesContractResolver { DefaultMembersSearchFlags = BindingFlags.NonPublic | BindingFlags.Instance } + }); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""_privateString"": ""PrivateString!"", ""i"": 0, ""_internalString"": ""InternalString!"" }", json); - PrivateMembersClass deserializedPrivateMembersClass = JsonConvert.DeserializeObject(@"{ + PrivateMembersClass deserializedPrivateMembersClass = JsonConvert.DeserializeObject(@"{ ""_privateString"": ""Private!"", ""i"": -2, ""_internalString"": ""Internal!"" }", new JsonSerializerSettings - { - ContractResolver = new CamelCasePropertyNamesContractResolver { DefaultMembersSearchFlags = BindingFlags.NonPublic | BindingFlags.Instance } - }); + { + ContractResolver = new CamelCasePropertyNamesContractResolver { DefaultMembersSearchFlags = BindingFlags.NonPublic | BindingFlags.Instance } + }); - Assert.AreEqual("Private!", ReflectionUtils.GetMemberValue(typeof(PrivateMembersClass).GetField("_privateString", BindingFlags.Instance | BindingFlags.NonPublic), deserializedPrivateMembersClass)); - Assert.AreEqual("Internal!", ReflectionUtils.GetMemberValue(typeof(PrivateMembersClass).GetField("_internalString", BindingFlags.Instance | BindingFlags.NonPublic), deserializedPrivateMembersClass)); + Assert.AreEqual("Private!", ReflectionUtils.GetMemberValue(typeof(PrivateMembersClass).GetField("_privateString", BindingFlags.Instance | BindingFlags.NonPublic), deserializedPrivateMembersClass)); + Assert.AreEqual("Internal!", ReflectionUtils.GetMemberValue(typeof(PrivateMembersClass).GetField("_internalString", BindingFlags.Instance | BindingFlags.NonPublic), deserializedPrivateMembersClass)); - // readonly - Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(PrivateMembersClass).GetField("i", BindingFlags.Instance | BindingFlags.NonPublic), deserializedPrivateMembersClass)); - } + // readonly + Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(PrivateMembersClass).GetField("i", BindingFlags.Instance | BindingFlags.NonPublic), deserializedPrivateMembersClass)); + } #endif - [Test] - public void BlogPostExample() - { - Product product = new Product - { - ExpiryDate = new DateTime(2010, 12, 20, 18, 1, 0, DateTimeKind.Utc), - Name = "Widget", - Price = 9.99m, - Sizes = new[] {"Small", "Medium", "Large"} - }; + [Test] + public void BlogPostExample() + { + Product product = new Product + { + ExpiryDate = new DateTime(2010, 12, 20, 18, 1, 0, DateTimeKind.Utc), + Name = "Widget", + Price = 9.99m, + Sizes = new[] { "Small", "Medium", "Large" } + }; - string json = - JsonConvert.SerializeObject( - product, - Formatting.Indented, - new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() } - ); + string json = + JsonConvert.SerializeObject( + product, + Formatting.Indented, + new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() } + ); - //{ - // "name": "Widget", - // "expiryDate": "\/Date(1292868060000)\/", - // "price": 9.99, - // "sizes": [ - // "Small", - // "Medium", - // "Large" - // ] - //} + //{ + // "name": "Widget", + // "expiryDate": "\/Date(1292868060000)\/", + // "price": 9.99, + // "sizes": [ + // "Small", + // "Medium", + // "Large" + // ] + //} - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""name"": ""Widget"", ""expiryDate"": ""2010-12-20T18:01:00Z"", ""price"": 9.99, @@ -175,51 +174,51 @@ namespace Newtonsoft.Json.Tests.Serialization ""Large"" ] }", json); - } + } #if !(NET35 || NET20 || PORTABLE40) - [Test] - public void DynamicCamelCasePropertyNames() - { - dynamic o = new TestDynamicObject(); - o.Text = "Text!"; - o.Integer = int.MaxValue; - - string json = JsonConvert.SerializeObject(o, Formatting.Indented, - new JsonSerializerSettings + [Test] + public void DynamicCamelCasePropertyNames() { - ContractResolver = new CamelCasePropertyNamesContractResolver() - }); + dynamic o = new TestDynamicObject(); + o.Text = "Text!"; + o.Integer = int.MaxValue; - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(o, Formatting.Indented, + new JsonSerializerSettings + { + ContractResolver = new CamelCasePropertyNamesContractResolver() + }); + + Assert.AreEqual(@"{ ""explicit"": false, ""text"": ""Text!"", ""integer"": 2147483647, ""int"": 0, ""childObject"": null }", json); - } + } #endif - [Test] - public void DictionaryCamelCasePropertyNames() - { - Dictionary values = new Dictionary + [Test] + public void DictionaryCamelCasePropertyNames() { - {"First", "Value1!"}, - {"Second", "Value2!"} - }; + Dictionary values = new Dictionary + { + { "First", "Value1!" }, + { "Second", "Value2!" } + }; - string json = JsonConvert.SerializeObject(values, Formatting.Indented, - new JsonSerializerSettings - { - ContractResolver = new CamelCasePropertyNamesContractResolver() - }); + string json = JsonConvert.SerializeObject(values, Formatting.Indented, + new JsonSerializerSettings + { + ContractResolver = new CamelCasePropertyNamesContractResolver() + }); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""first"": ""Value1!"", ""second"": ""Value2!"" }", json); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Serialization/ConstructorHandlingTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/ConstructorHandlingTests.cs index 78e80fb8..a4442356 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/ConstructorHandlingTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/ConstructorHandlingTests.cs @@ -27,6 +27,7 @@ using System.Reflection; using Newtonsoft.Json.Tests.TestObjects; #if !NETFX_CORE using NUnit.Framework; + #else using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; @@ -35,129 +36,129 @@ using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAtt namespace Newtonsoft.Json.Tests.Serialization { - [TestFixture] - public class ConstructorHandlingTests : TestFixtureBase - { - [Test] - public void UsePrivateConstructorIfThereAreMultipleConstructorsWithParametersAndNothingToFallbackTo() + [TestFixture] + public class ConstructorHandlingTests : TestFixtureBase { - string json = @"{Name:""Name!""}"; - - var c = JsonConvert.DeserializeObject(json); - - Assert.AreEqual("Name!", c.Name); - } - - [Test] - public void SuccessWithPrivateConstructorAndAllowNonPublic() - { - string json = @"{Name:""Name!""}"; - - PrivateConstructorTestClass c = JsonConvert.DeserializeObject(json, - new JsonSerializerSettings - { - ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor - }); - Assert.IsNotNull(c); - Assert.AreEqual("Name!", c.Name); - } - - [Test] - public void FailWithPrivateConstructorPlusParametizedAndDefault() - { - ExceptionAssert.Throws( - null, - () => + [Test] + public void UsePrivateConstructorIfThereAreMultipleConstructorsWithParametersAndNothingToFallbackTo() { - string json = @"{Name:""Name!""}"; + string json = @"{Name:""Name!""}"; - PrivateConstructorWithPublicParametizedConstructorTestClass c = JsonConvert.DeserializeObject(json); - }); - } + var c = JsonConvert.DeserializeObject(json); - [Test] - public void SuccessWithPrivateConstructorPlusParametizedAndAllowNonPublic() - { - string json = @"{Name:""Name!""}"; + Assert.AreEqual("Name!", c.Name); + } - PrivateConstructorWithPublicParametizedConstructorTestClass c = JsonConvert.DeserializeObject(json, - new JsonSerializerSettings + [Test] + public void SuccessWithPrivateConstructorAndAllowNonPublic() { - ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor - }); - Assert.IsNotNull(c); - Assert.AreEqual("Name!", c.Name); - Assert.AreEqual(1, c.Age); + string json = @"{Name:""Name!""}"; + + PrivateConstructorTestClass c = JsonConvert.DeserializeObject(json, + new JsonSerializerSettings + { + ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor + }); + Assert.IsNotNull(c); + Assert.AreEqual("Name!", c.Name); + } + + [Test] + public void FailWithPrivateConstructorPlusParametizedAndDefault() + { + ExceptionAssert.Throws( + null, + () => + { + string json = @"{Name:""Name!""}"; + + PrivateConstructorWithPublicParametizedConstructorTestClass c = JsonConvert.DeserializeObject(json); + }); + } + + [Test] + public void SuccessWithPrivateConstructorPlusParametizedAndAllowNonPublic() + { + string json = @"{Name:""Name!""}"; + + PrivateConstructorWithPublicParametizedConstructorTestClass c = JsonConvert.DeserializeObject(json, + new JsonSerializerSettings + { + ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor + }); + Assert.IsNotNull(c); + Assert.AreEqual("Name!", c.Name); + Assert.AreEqual(1, c.Age); + } + + [Test] + public void SuccessWithPublicParametizedConstructor() + { + string json = @"{Name:""Name!""}"; + + var c = JsonConvert.DeserializeObject(json); + Assert.IsNotNull(c); + Assert.AreEqual("Name!", c.Name); + } + + [Test] + public void SuccessWithPublicParametizedConstructorWhenParamaterIsNotAProperty() + { + string json = @"{nameParameter:""Name!""}"; + + PublicParametizedConstructorWithNonPropertyParameterTestClass c = JsonConvert.DeserializeObject(json); + Assert.IsNotNull(c); + Assert.AreEqual("Name!", c.Name); + } + + [Test] + public void SuccessWithPublicParametizedConstructorWhenParamaterRequiresAConverter() + { + string json = @"{nameParameter:""Name!""}"; + + PublicParametizedConstructorRequiringConverterTestClass c = JsonConvert.DeserializeObject(json, new NameContainerConverter()); + Assert.IsNotNull(c); + Assert.AreEqual("Name!", c.Name.Value); + } + + [Test] + public void SuccessWithPublicParametizedConstructorWhenParamaterRequiresAConverterWithParameterAttribute() + { + string json = @"{nameParameter:""Name!""}"; + + PublicParametizedConstructorRequiringConverterWithParameterAttributeTestClass c = JsonConvert.DeserializeObject(json); + Assert.IsNotNull(c); + Assert.AreEqual("Name!", c.Name.Value); + } + + [Test] + public void SuccessWithPublicParametizedConstructorWhenParamaterRequiresAConverterWithPropertyAttribute() + { + string json = @"{name:""Name!""}"; + + PublicParametizedConstructorRequiringConverterWithPropertyAttributeTestClass c = JsonConvert.DeserializeObject(json); + Assert.IsNotNull(c); + Assert.AreEqual("Name!", c.Name.Value); + } + + [Test] + public void SuccessWithPublicParametizedConstructorWhenParamaterNameConflictsWithPropertyName() + { + string json = @"{name:""1""}"; + + PublicParametizedConstructorWithPropertyNameConflict c = JsonConvert.DeserializeObject(json); + Assert.IsNotNull(c); + Assert.AreEqual(1, c.Name); + } + + [Test] + public void PublicParametizedConstructorWithPropertyNameConflictWithAttribute() + { + string json = @"{name:""1""}"; + + PublicParametizedConstructorWithPropertyNameConflictWithAttribute c = JsonConvert.DeserializeObject(json); + Assert.IsNotNull(c); + Assert.AreEqual(1, c.Name); + } } - - [Test] - public void SuccessWithPublicParametizedConstructor() - { - string json = @"{Name:""Name!""}"; - - var c = JsonConvert.DeserializeObject(json); - Assert.IsNotNull(c); - Assert.AreEqual("Name!", c.Name); - } - - [Test] - public void SuccessWithPublicParametizedConstructorWhenParamaterIsNotAProperty() - { - string json = @"{nameParameter:""Name!""}"; - - PublicParametizedConstructorWithNonPropertyParameterTestClass c = JsonConvert.DeserializeObject(json); - Assert.IsNotNull(c); - Assert.AreEqual("Name!", c.Name); - } - - [Test] - public void SuccessWithPublicParametizedConstructorWhenParamaterRequiresAConverter() - { - string json = @"{nameParameter:""Name!""}"; - - PublicParametizedConstructorRequiringConverterTestClass c = JsonConvert.DeserializeObject(json, new NameContainerConverter()); - Assert.IsNotNull(c); - Assert.AreEqual("Name!", c.Name.Value); - } - - [Test] - public void SuccessWithPublicParametizedConstructorWhenParamaterRequiresAConverterWithParameterAttribute() - { - string json = @"{nameParameter:""Name!""}"; - - PublicParametizedConstructorRequiringConverterWithParameterAttributeTestClass c = JsonConvert.DeserializeObject(json); - Assert.IsNotNull(c); - Assert.AreEqual("Name!", c.Name.Value); - } - - [Test] - public void SuccessWithPublicParametizedConstructorWhenParamaterRequiresAConverterWithPropertyAttribute() - { - string json = @"{name:""Name!""}"; - - PublicParametizedConstructorRequiringConverterWithPropertyAttributeTestClass c = JsonConvert.DeserializeObject(json); - Assert.IsNotNull(c); - Assert.AreEqual("Name!", c.Name.Value); - } - - [Test] - public void SuccessWithPublicParametizedConstructorWhenParamaterNameConflictsWithPropertyName() - { - string json = @"{name:""1""}"; - - PublicParametizedConstructorWithPropertyNameConflict c = JsonConvert.DeserializeObject(json); - Assert.IsNotNull(c); - Assert.AreEqual(1, c.Name); - } - - [Test] - public void PublicParametizedConstructorWithPropertyNameConflictWithAttribute() - { - string json = @"{name:""1""}"; - - PublicParametizedConstructorWithPropertyNameConflictWithAttribute c = JsonConvert.DeserializeObject(json); - Assert.IsNotNull(c); - Assert.AreEqual(1, c.Name); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Serialization/ContractResolverTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/ContractResolverTests.cs index 0ebdeb8a..49aa618a 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/ContractResolverTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/ContractResolverTests.cs @@ -47,208 +47,209 @@ using System.Globalization; namespace Newtonsoft.Json.Tests.Serialization { - public class DynamicContractResolver : DefaultContractResolver - { - private readonly char _startingWithChar; - public DynamicContractResolver(char startingWithChar) - : base(false) + public class DynamicContractResolver : DefaultContractResolver { - _startingWithChar = startingWithChar; + private readonly char _startingWithChar; + + public DynamicContractResolver(char startingWithChar) + : base(false) + { + _startingWithChar = startingWithChar; + } + + protected override IList CreateProperties(Type type, MemberSerialization memberSerialization) + { + IList properties = base.CreateProperties(type, memberSerialization); + + // only serializer properties that start with the specified character + properties = + properties.Where(p => p.PropertyName.StartsWith(_startingWithChar.ToString())).ToList(); + + return properties; + } } - protected override IList CreateProperties(Type type, MemberSerialization memberSerialization) + public class EscapedPropertiesContractResolver : DefaultContractResolver { - IList properties = base.CreateProperties(type, memberSerialization); - - // only serializer properties that start with the specified character - properties = - properties.Where(p => p.PropertyName.StartsWith(_startingWithChar.ToString())).ToList(); - - return properties; + protected internal override string ResolvePropertyName(string propertyName) + { + return base.ResolvePropertyName(propertyName + @"-'-""-"); + } } - } - public class EscapedPropertiesContractResolver : DefaultContractResolver - { - protected internal override string ResolvePropertyName(string propertyName) + public class Book { - return base.ResolvePropertyName(propertyName + @"-'-""-"); + public string BookName { get; set; } + public decimal BookPrice { get; set; } + public string AuthorName { get; set; } + public int AuthorAge { get; set; } + public string AuthorCountry { get; set; } } - } - public class Book - { - public string BookName { get; set; } - public decimal BookPrice { get; set; } - public string AuthorName { get; set; } - public int AuthorAge { get; set; } - public string AuthorCountry { get; set; } - } - - public class IPersonContractResolver : DefaultContractResolver - { - protected override JsonContract CreateContract(Type objectType) + public class IPersonContractResolver : DefaultContractResolver { - if (objectType == typeof(Employee)) - objectType = typeof(IPerson); + protected override JsonContract CreateContract(Type objectType) + { + if (objectType == typeof(Employee)) + objectType = typeof(IPerson); - return base.CreateContract(objectType); + return base.CreateContract(objectType); + } } - } - public class AddressWithDataMember - { + public class AddressWithDataMember + { #if !NET20 - [DataMember(Name = "CustomerAddress1")] + [DataMember(Name = "CustomerAddress1")] #endif - public string AddressLine1 { get; set; } - } - - [TestFixture] - public class ContractResolverTests : TestFixtureBase - { - [Test] - public void SerializeWithEscapedPropertyName() - { - string json = JsonConvert.SerializeObject( - new AddressWithDataMember - { - AddressLine1 = "value!" - }, - new JsonSerializerSettings - { - ContractResolver = new EscapedPropertiesContractResolver() - }); - - Assert.AreEqual(@"{""AddressLine1-'-\""-"":""value!""}", json); - - JsonTextReader reader = new JsonTextReader(new StringReader(json)); - reader.Read(); - reader.Read(); - - Assert.AreEqual(@"AddressLine1-'-""-", reader.Value); + public string AddressLine1 { get; set; } } + [TestFixture] + public class ContractResolverTests : TestFixtureBase + { + [Test] + public void SerializeWithEscapedPropertyName() + { + string json = JsonConvert.SerializeObject( + new AddressWithDataMember + { + AddressLine1 = "value!" + }, + new JsonSerializerSettings + { + ContractResolver = new EscapedPropertiesContractResolver() + }); + + Assert.AreEqual(@"{""AddressLine1-'-\""-"":""value!""}", json); + + JsonTextReader reader = new JsonTextReader(new StringReader(json)); + reader.Read(); + reader.Read(); + + Assert.AreEqual(@"AddressLine1-'-""-", reader.Value); + } + #if !NET20 - [Test] - public void DeserializeDataMemberClassWithNoDataContract() - { - var resolver = new DefaultContractResolver(); - var contract = (JsonObjectContract)resolver.ResolveContract(typeof(AddressWithDataMember)); + [Test] + public void DeserializeDataMemberClassWithNoDataContract() + { + var resolver = new DefaultContractResolver(); + var contract = (JsonObjectContract)resolver.ResolveContract(typeof(AddressWithDataMember)); - Assert.AreEqual("AddressLine1", contract.Properties[0].PropertyName); - } + Assert.AreEqual("AddressLine1", contract.Properties[0].PropertyName); + } #endif - [Test] - public void ResolveProperties_IgnoreStatic() - { - var resolver = new DefaultContractResolver(); - var contract = (JsonObjectContract)resolver.ResolveContract(typeof(NumberFormatInfo)); + [Test] + public void ResolveProperties_IgnoreStatic() + { + var resolver = new DefaultContractResolver(); + var contract = (JsonObjectContract)resolver.ResolveContract(typeof(NumberFormatInfo)); - Assert.IsFalse(contract.Properties.Any(c => c.PropertyName == "InvariantInfo")); - } + Assert.IsFalse(contract.Properties.Any(c => c.PropertyName == "InvariantInfo")); + } - [Test] - public void SerializeInterface() - { - Employee employee = new Employee - { - BirthDate = new DateTime(1977, 12, 30, 1, 1, 1, DateTimeKind.Utc), - FirstName = "Maurice", - LastName = "Moss", - Department = "IT", - JobTitle = "Support" - }; + [Test] + public void SerializeInterface() + { + Employee employee = new Employee + { + BirthDate = new DateTime(1977, 12, 30, 1, 1, 1, DateTimeKind.Utc), + FirstName = "Maurice", + LastName = "Moss", + Department = "IT", + JobTitle = "Support" + }; - string iPersonJson = JsonConvert.SerializeObject(employee, Formatting.Indented, - new JsonSerializerSettings { ContractResolver = new IPersonContractResolver() }); + string iPersonJson = JsonConvert.SerializeObject(employee, Formatting.Indented, + new JsonSerializerSettings { ContractResolver = new IPersonContractResolver() }); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""FirstName"": ""Maurice"", ""LastName"": ""Moss"", ""BirthDate"": ""1977-12-30T01:01:01Z"" }", iPersonJson); - } + } - [Test] - public void SingleTypeWithMultipleContractResolvers() - { - Book book = new Book - { - BookName = "The Gathering Storm", - BookPrice = 16.19m, - AuthorName = "Brandon Sanderson", - AuthorAge = 34, - AuthorCountry = "United States of America" - }; + [Test] + public void SingleTypeWithMultipleContractResolvers() + { + Book book = new Book + { + BookName = "The Gathering Storm", + BookPrice = 16.19m, + AuthorName = "Brandon Sanderson", + AuthorAge = 34, + AuthorCountry = "United States of America" + }; - string startingWithA = JsonConvert.SerializeObject(book, Formatting.Indented, - new JsonSerializerSettings { ContractResolver = new DynamicContractResolver('A') }); + string startingWithA = JsonConvert.SerializeObject(book, Formatting.Indented, + new JsonSerializerSettings { ContractResolver = new DynamicContractResolver('A') }); - // { - // "AuthorName": "Brandon Sanderson", - // "AuthorAge": 34, - // "AuthorCountry": "United States of America" - // } + // { + // "AuthorName": "Brandon Sanderson", + // "AuthorAge": 34, + // "AuthorCountry": "United States of America" + // } - string startingWithB = JsonConvert.SerializeObject(book, Formatting.Indented, - new JsonSerializerSettings { ContractResolver = new DynamicContractResolver('B') }); + string startingWithB = JsonConvert.SerializeObject(book, Formatting.Indented, + new JsonSerializerSettings { ContractResolver = new DynamicContractResolver('B') }); - // { - // "BookName": "The Gathering Storm", - // "BookPrice": 16.19 - // } + // { + // "BookName": "The Gathering Storm", + // "BookPrice": 16.19 + // } - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""AuthorName"": ""Brandon Sanderson"", ""AuthorAge"": 34, ""AuthorCountry"": ""United States of America"" }", startingWithA); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""BookName"": ""The Gathering Storm"", ""BookPrice"": 16.19 }", startingWithB); - } + } #if !(NETFX_CORE || PORTABLE || PORTABLE40) - [Test] - public void SerializeCompilerGeneratedMembers() - { - StructTest structTest = new StructTest + [Test] + public void SerializeCompilerGeneratedMembers() { - IntField = 1, - IntProperty = 2, - StringField = "Field", - StringProperty = "Property" - }; + StructTest structTest = new StructTest + { + IntField = 1, + IntProperty = 2, + StringField = "Field", + StringProperty = "Property" + }; - DefaultContractResolver skipCompilerGeneratedResolver = new DefaultContractResolver - { - DefaultMembersSearchFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public - }; + DefaultContractResolver skipCompilerGeneratedResolver = new DefaultContractResolver + { + DefaultMembersSearchFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public + }; - string skipCompilerGeneratedJson = JsonConvert.SerializeObject(structTest, Formatting.Indented, - new JsonSerializerSettings { ContractResolver = skipCompilerGeneratedResolver }); + string skipCompilerGeneratedJson = JsonConvert.SerializeObject(structTest, Formatting.Indented, + new JsonSerializerSettings { ContractResolver = skipCompilerGeneratedResolver }); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""StringField"": ""Field"", ""IntField"": 1, ""StringProperty"": ""Property"", ""IntProperty"": 2 }", skipCompilerGeneratedJson); - DefaultContractResolver includeCompilerGeneratedResolver = new DefaultContractResolver - { - DefaultMembersSearchFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, - SerializeCompilerGeneratedMembers = true - }; + DefaultContractResolver includeCompilerGeneratedResolver = new DefaultContractResolver + { + DefaultMembersSearchFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, + SerializeCompilerGeneratedMembers = true + }; - string includeCompilerGeneratedJson = JsonConvert.SerializeObject(structTest, Formatting.Indented, - new JsonSerializerSettings { ContractResolver = includeCompilerGeneratedResolver }); + string includeCompilerGeneratedJson = JsonConvert.SerializeObject(structTest, Formatting.Indented, + new JsonSerializerSettings { ContractResolver = includeCompilerGeneratedResolver }); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""StringField"": ""Field"", ""IntField"": 1, ""k__BackingField"": ""Property"", @@ -256,7 +257,7 @@ namespace Newtonsoft.Json.Tests.Serialization ""StringProperty"": ""Property"", ""IntProperty"": 2 }", includeCompilerGeneratedJson); - } + } #endif - } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Serialization/DefaultValueHandlingTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/DefaultValueHandlingTests.cs index 0c9dc869..53015ad9 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/DefaultValueHandlingTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/DefaultValueHandlingTests.cs @@ -43,27 +43,27 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Tests.Serialization { - [TestFixture] - public class DefaultValueHandlingTests : TestFixtureBase - { - [Test] - public void Include() + [TestFixture] + public class DefaultValueHandlingTests : TestFixtureBase { - Invoice invoice = new Invoice - { - Company = "Acme Ltd.", - Amount = 50.0m, - Paid = false, - FollowUpDays = 30, - FollowUpEmailAddress = string.Empty, - PaidDate = null - }; + [Test] + public void Include() + { + Invoice invoice = new Invoice + { + Company = "Acme Ltd.", + Amount = 50.0m, + Paid = false, + FollowUpDays = 30, + FollowUpEmailAddress = string.Empty, + PaidDate = null + }; - string included = JsonConvert.SerializeObject(invoice, - Formatting.Indented, - new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Include }); + string included = JsonConvert.SerializeObject(invoice, + Formatting.Indented, + new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Include }); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Company"": ""Acme Ltd."", ""Amount"": 50.0, ""Paid"": false, @@ -71,26 +71,26 @@ namespace Newtonsoft.Json.Tests.Serialization ""FollowUpDays"": 30, ""FollowUpEmailAddress"": """" }", included); - } + } - [Test] - public void SerializeInvoice() - { - Invoice invoice = new Invoice - { - Company = "Acme Ltd.", - Amount = 50.0m, - Paid = false, - FollowUpDays = 30, - FollowUpEmailAddress = string.Empty, - PaidDate = null - }; + [Test] + public void SerializeInvoice() + { + Invoice invoice = new Invoice + { + Company = "Acme Ltd.", + Amount = 50.0m, + Paid = false, + FollowUpDays = 30, + FollowUpEmailAddress = string.Empty, + PaidDate = null + }; - string included = JsonConvert.SerializeObject(invoice, - Formatting.Indented, - new JsonSerializerSettings { }); + string included = JsonConvert.SerializeObject(invoice, + Formatting.Indented, + new JsonSerializerSettings { }); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Company"": ""Acme Ltd."", ""Amount"": 50.0, ""Paid"": false, @@ -99,356 +99,379 @@ namespace Newtonsoft.Json.Tests.Serialization ""FollowUpEmailAddress"": """" }", included); - string ignored = JsonConvert.SerializeObject(invoice, - Formatting.Indented, - new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore }); + string ignored = JsonConvert.SerializeObject(invoice, + Formatting.Indented, + new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore }); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Company"": ""Acme Ltd."", ""Amount"": 50.0 }", ignored); - } + } - [Test] - public void SerializeDefaultValueAttributeTest() - { - string json = JsonConvert.SerializeObject(new DefaultValueAttributeTestClass(), - Formatting.None, new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore }); - Assert.AreEqual(@"{""TestField1"":0,""TestProperty1"":null}", json); - - json = JsonConvert.SerializeObject(new DefaultValueAttributeTestClass { TestField1 = int.MinValue, TestProperty1 = "NotDefault" }, - Formatting.None, new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore }); - Assert.AreEqual(@"{""TestField1"":-2147483648,""TestProperty1"":""NotDefault""}", json); - - json = JsonConvert.SerializeObject(new DefaultValueAttributeTestClass { TestField1 = 21, TestProperty1 = "NotDefault" }, - Formatting.None, new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore }); - Assert.AreEqual(@"{""TestProperty1"":""NotDefault""}", json); - - json = JsonConvert.SerializeObject(new DefaultValueAttributeTestClass { TestField1 = 21, TestProperty1 = "TestProperty1Value" }, - Formatting.None, new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore }); - Assert.AreEqual(@"{}", json); - } - - [Test] - public void DeserializeDefaultValueAttributeTest() - { - string json = "{}"; - - DefaultValueAttributeTestClass c = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + [Test] + public void SerializeDefaultValueAttributeTest() { - DefaultValueHandling = DefaultValueHandling.Populate - }); - Assert.AreEqual("TestProperty1Value", c.TestProperty1); + string json = JsonConvert.SerializeObject(new DefaultValueAttributeTestClass(), + Formatting.None, new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore }); + Assert.AreEqual(@"{""TestField1"":0,""TestProperty1"":null}", json); - c = JsonConvert.DeserializeObject(json, new JsonSerializerSettings - { - DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate - }); - Assert.AreEqual("TestProperty1Value", c.TestProperty1); - } + json = JsonConvert.SerializeObject(new DefaultValueAttributeTestClass { TestField1 = int.MinValue, TestProperty1 = "NotDefault" }, + Formatting.None, new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore }); + Assert.AreEqual(@"{""TestField1"":-2147483648,""TestProperty1"":""NotDefault""}", json); - public class DefaultHandler - { - [DefaultValue(-1)] - public int field1; + json = JsonConvert.SerializeObject(new DefaultValueAttributeTestClass { TestField1 = 21, TestProperty1 = "NotDefault" }, + Formatting.None, new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore }); + Assert.AreEqual(@"{""TestProperty1"":""NotDefault""}", json); - [DefaultValue("default")] - public string field2; - } + json = JsonConvert.SerializeObject(new DefaultValueAttributeTestClass { TestField1 = 21, TestProperty1 = "TestProperty1Value" }, + Formatting.None, new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore }); + Assert.AreEqual(@"{}", json); + } - [Test] - public void DeserializeIgnoreAndPopulate() - { - DefaultHandler c1 = JsonConvert.DeserializeObject("{}", new JsonSerializerSettings - { - DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate - }); - Assert.AreEqual(-1, c1.field1); - Assert.AreEqual("default", c1.field2); + [Test] + public void DeserializeDefaultValueAttributeTest() + { + string json = "{}"; - DefaultHandler c2 = JsonConvert.DeserializeObject("{'field1':-1,'field2':'default'}", new JsonSerializerSettings - { - DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate - }); - Assert.AreEqual(-1, c2.field1); - Assert.AreEqual("default", c2.field2); - } + DefaultValueAttributeTestClass c = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + DefaultValueHandling = DefaultValueHandling.Populate + }); + Assert.AreEqual("TestProperty1Value", c.TestProperty1); - [JsonObject] - public class NetworkUser - { - [JsonProperty(PropertyName = "userId")] - [DefaultValue(-1)] - public long GlobalId { get; set; } + c = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate + }); + Assert.AreEqual("TestProperty1Value", c.TestProperty1); + } - [JsonProperty(PropertyName = "age")] - [DefaultValue(0)] - public int Age { get; set; } + public class DefaultHandler + { + [DefaultValue(-1)] + public int field1; - [JsonProperty(PropertyName = "amount")] - [DefaultValue(0.0)] - public decimal Amount { get; set; } + [DefaultValue("default")] + public string field2; + } - [JsonProperty(PropertyName = "floatUserId")] - [DefaultValue(-1.0d)] - public float FloatGlobalId { get; set; } + [Test] + public void DeserializeIgnoreAndPopulate() + { + DefaultHandler c1 = JsonConvert.DeserializeObject("{}", new JsonSerializerSettings + { + DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate + }); + Assert.AreEqual(-1, c1.field1); + Assert.AreEqual("default", c1.field2); - [JsonProperty(PropertyName = "firstName")] - public string Firstname { get; set; } - [JsonProperty(PropertyName = "lastName")] - public string Lastname { get; set; } + DefaultHandler c2 = JsonConvert.DeserializeObject("{'field1':-1,'field2':'default'}", new JsonSerializerSettings + { + DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate + }); + Assert.AreEqual(-1, c2.field1); + Assert.AreEqual("default", c2.field2); + } - public NetworkUser() - { - GlobalId = -1; - FloatGlobalId = -1.0f; - Amount = 0.0m; - Age = 0; - } - } + [JsonObject] + public class NetworkUser + { + [JsonProperty(PropertyName = "userId")] + [DefaultValue(-1)] + public long GlobalId { get; set; } - [Test] - public void IgnoreNumberTypeDifferencesWithDefaultValue() - { - NetworkUser user = new NetworkUser - { - Firstname = "blub" - }; + [JsonProperty(PropertyName = "age")] + [DefaultValue(0)] + public int Age { get; set; } - string json = JsonConvert.SerializeObject(user, Formatting.None, new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore, NullValueHandling = NullValueHandling.Ignore }); + [JsonProperty(PropertyName = "amount")] + [DefaultValue(0.0)] + public decimal Amount { get; set; } - Assert.AreEqual(@"{""firstName"":""blub""}", json); - } + [JsonProperty(PropertyName = "floatUserId")] + [DefaultValue(-1.0d)] + public float FloatGlobalId { get; set; } - [Test] - public void ApproxEquals() - { - Assert.IsTrue(MathUtils.ApproxEquals(0.0, 0.0)); - Assert.IsTrue(MathUtils.ApproxEquals(1000.0, 1000.0000000000001)); + [JsonProperty(PropertyName = "firstName")] + public string Firstname { get; set; } - Assert.IsFalse(MathUtils.ApproxEquals(1000.0, 1000.000000000001)); - Assert.IsFalse(MathUtils.ApproxEquals(0.0, 0.00001)); - } + [JsonProperty(PropertyName = "lastName")] + public string Lastname { get; set; } + + public NetworkUser() + { + GlobalId = -1; + FloatGlobalId = -1.0f; + Amount = 0.0m; + Age = 0; + } + } + + [Test] + public void IgnoreNumberTypeDifferencesWithDefaultValue() + { + NetworkUser user = new NetworkUser + { + Firstname = "blub" + }; + + string json = JsonConvert.SerializeObject(user, Formatting.None, new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore, NullValueHandling = NullValueHandling.Ignore }); + + Assert.AreEqual(@"{""firstName"":""blub""}", json); + } + + [Test] + public void ApproxEquals() + { + Assert.IsTrue(MathUtils.ApproxEquals(0.0, 0.0)); + Assert.IsTrue(MathUtils.ApproxEquals(1000.0, 1000.0000000000001)); + + Assert.IsFalse(MathUtils.ApproxEquals(1000.0, 1000.000000000001)); + Assert.IsFalse(MathUtils.ApproxEquals(0.0, 0.00001)); + } #if !NET20 - [Test] - public void EmitDefaultValueTest() - { - EmitDefaultValueClass c = new EmitDefaultValueClass(); + [Test] + public void EmitDefaultValueTest() + { + EmitDefaultValueClass c = new EmitDefaultValueClass(); #if !(SILVERLIGHT || NET20 || NET35 || NETFX_CORE || PORTABLE) - DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(EmitDefaultValueClass)); + DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(EmitDefaultValueClass)); - MemoryStream ms = new MemoryStream(); - jsonSerializer.WriteObject(ms, c); + MemoryStream ms = new MemoryStream(); + jsonSerializer.WriteObject(ms, c); - Assert.AreEqual("{}", Encoding.UTF8.GetString(ms.ToArray())); + Assert.AreEqual("{}", Encoding.UTF8.GetString(ms.ToArray())); #endif - string json = JsonConvert.SerializeObject(c); + string json = JsonConvert.SerializeObject(c); - Assert.AreEqual("{}", json); - } + Assert.AreEqual("{}", json); + } #endif - [Test] - public void DefaultValueHandlingPropertyTest() - { - DefaultValueHandlingPropertyClass c = new DefaultValueHandlingPropertyClass(); + [Test] + public void DefaultValueHandlingPropertyTest() + { + DefaultValueHandlingPropertyClass c = new DefaultValueHandlingPropertyClass(); - string json = JsonConvert.SerializeObject(c, Formatting.Indented); + string json = JsonConvert.SerializeObject(c, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""IntInclude"": 0, ""IntDefault"": 0 }", json); - json = JsonConvert.SerializeObject(c, Formatting.Indented, new JsonSerializerSettings - { - DefaultValueHandling = DefaultValueHandling.Ignore - }); + json = JsonConvert.SerializeObject(c, Formatting.Indented, new JsonSerializerSettings + { + DefaultValueHandling = DefaultValueHandling.Ignore + }); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""IntInclude"": 0 }", json); - json = JsonConvert.SerializeObject(c, Formatting.Indented, new JsonSerializerSettings - { - DefaultValueHandling = DefaultValueHandling.Include - }); + json = JsonConvert.SerializeObject(c, Formatting.Indented, new JsonSerializerSettings + { + DefaultValueHandling = DefaultValueHandling.Include + }); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""IntInclude"": 0, ""IntDefault"": 0 }", json); - } + } - [Test] - public void DeserializeWithIgnore() - { - string json = @"{'Value':null,'IntValue1':1,'IntValue2':0,'IntValue3':null}"; - - var o = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + [Test] + public void DeserializeWithIgnore() { - DefaultValueHandling = DefaultValueHandling.Ignore - }); + string json = @"{'Value':null,'IntValue1':1,'IntValue2':0,'IntValue3':null}"; - Assert.AreEqual(int.MaxValue, o.IntValue1); - Assert.AreEqual(int.MinValue, o.IntValue2); - Assert.AreEqual(int.MaxValue, o.IntValue3); - Assert.AreEqual("Derp!", o.ClassValue.Derp); - } + var o = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + DefaultValueHandling = DefaultValueHandling.Ignore + }); - [Test] - public void DeserializeWithPopulate() - { - string json = @"{}"; + Assert.AreEqual(int.MaxValue, o.IntValue1); + Assert.AreEqual(int.MinValue, o.IntValue2); + Assert.AreEqual(int.MaxValue, o.IntValue3); + Assert.AreEqual("Derp!", o.ClassValue.Derp); + } - var o = JsonConvert.DeserializeObject(json, new JsonSerializerSettings - { - DefaultValueHandling = DefaultValueHandling.Populate - }); + [Test] + public void DeserializeWithPopulate() + { + string json = @"{}"; - Assert.AreEqual(1, o.IntValue1); - Assert.AreEqual(0, o.IntValue2); - Assert.AreEqual(null, o.ClassValue); + var o = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + DefaultValueHandling = DefaultValueHandling.Populate + }); + + Assert.AreEqual(1, o.IntValue1); + 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 - [Test] - public void EmitDefaultValueIgnoreAndPopulate() + [DataContract] + public class TestClass { - string str = "{}"; - TestClass obj = JsonConvert.DeserializeObject(str, new JsonSerializerSettings - { - DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate - }); - - Assert.AreEqual("fff", obj.Field1); + [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] + [DataMember(EmitDefaultValue = false)] + [DefaultValue("fff")] + public string Field1 { set; get; } } #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; } - } - - public class DefaultValueHandlingDeserializeHolder - { - public DefaultValueHandlingDeserializeHolder() + public class DefaultValueHandlingDeserialize { - ClassValue = new DefaultValueHandlingDeserialize + public string Derp { get; set; } + } + + public class DefaultValueHandlingDeserializeHolder + { + public DefaultValueHandlingDeserializeHolder() { - Derp = "Derp!" - }; - IntValue1 = int.MaxValue; - IntValue2 = int.MinValue; - IntValue3 = int.MaxValue; + ClassValue = new DefaultValueHandlingDeserialize + { + Derp = "Derp!" + }; + IntValue1 = int.MaxValue; + IntValue2 = int.MinValue; + IntValue3 = int.MaxValue; + } + + [DefaultValue(1)] + public int IntValue1 { get; set; } + + public int IntValue2 { get; set; } + + [DefaultValue(null)] + public int IntValue3 { get; set; } + + public DefaultValueHandlingDeserialize ClassValue { get; set; } } - [DefaultValue(1)] - public int IntValue1 { get; set; } - public int IntValue2 { get; set; } - [DefaultValue(null)] - public int IntValue3 { get; set; } - public DefaultValueHandlingDeserialize ClassValue { get; set; } - } - - public class DefaultValueHandlingDeserializePopulate - { - public DefaultValueHandlingDeserializePopulate() + public class DefaultValueHandlingDeserializePopulate { - ClassValue = new DefaultValueHandlingDeserialize - { - Derp = "Derp!" - }; - IntValue1 = int.MaxValue; - IntValue2 = int.MinValue; + public DefaultValueHandlingDeserializePopulate() + { + ClassValue = new DefaultValueHandlingDeserialize + { + Derp = "Derp!" + }; + IntValue1 = int.MaxValue; + IntValue2 = int.MinValue; + } + + [DefaultValue(1)] + public int IntValue1 { get; set; } + + public int IntValue2 { get; set; } + public DefaultValueHandlingDeserialize ClassValue { get; set; } } - [DefaultValue(1)] - public int IntValue1 { get; set; } - public int IntValue2 { get; set; } - public DefaultValueHandlingDeserialize ClassValue { get; set; } - } + public struct DefaultStruct + { + public string Default { get; set; } + } - public struct DefaultStruct - { - public string Default { get; set; } - } + public class DefaultValueHandlingPropertyClass + { + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public int IntIgnore { get; set; } - public class DefaultValueHandlingPropertyClass - { - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public int IntIgnore { get; set; } + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Include)] + public int IntInclude { get; set; } - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Include)] - public int IntInclude { get; set; } - - [JsonProperty] - public int IntDefault { get; set; } - } + [JsonProperty] + public int IntDefault { get; set; } + } #if !NET20 - [DataContract] - public class EmitDefaultValueClass - { - [DataMember(EmitDefaultValue = false)] - public Guid Guid { get; set; } - [DataMember(EmitDefaultValue = false)] - public TimeSpan TimeSpan { get; set; } - [DataMember(EmitDefaultValue = false)] - public DateTime DateTime { get; set; } - [DataMember(EmitDefaultValue = false)] - public DateTimeOffset DateTimeOffset { get; set; } - [DataMember(EmitDefaultValue = false)] - public decimal Decimal { get; set; } - [DataMember(EmitDefaultValue = false)] - public int Integer { get; set; } - [DataMember(EmitDefaultValue = false)] - public double Double { get; set; } - [DataMember(EmitDefaultValue = false)] - public bool Boolean { get; set; } - [DataMember(EmitDefaultValue = false)] - public DefaultStruct Struct { get; set; } - [DataMember(EmitDefaultValue = false)] - public StringComparison Enum { get; set; } + [DataContract] + public class EmitDefaultValueClass + { + [DataMember(EmitDefaultValue = false)] + public Guid Guid { get; set; } - [DataMember(EmitDefaultValue = false)] - public Guid? NullableGuid { get; set; } - [DataMember(EmitDefaultValue = false)] - public TimeSpan? NullableTimeSpan { get; set; } - [DataMember(EmitDefaultValue = false)] - public DateTime? NullableDateTime { get; set; } - [DataMember(EmitDefaultValue = false)] - public DateTimeOffset? NullableDateTimeOffset { get; set; } - [DataMember(EmitDefaultValue = false)] - public decimal? NullableDecimal { get; set; } - [DataMember(EmitDefaultValue = false)] - public int? NullableInteger { get; set; } - [DataMember(EmitDefaultValue = false)] - public double? NullableDouble { get; set; } - [DataMember(EmitDefaultValue = false)] - public bool? NullableBoolean { get; set; } - [DataMember(EmitDefaultValue = false)] - public DefaultStruct? NullableStruct { get; set; } - [DataMember(EmitDefaultValue = false)] - public StringComparison? NullableEnum { get; set; } + [DataMember(EmitDefaultValue = false)] + public TimeSpan TimeSpan { get; set; } - [DataMember(EmitDefaultValue = false)] - public object Object { get; set; } - } + [DataMember(EmitDefaultValue = false)] + public DateTime DateTime { get; set; } + + [DataMember(EmitDefaultValue = false)] + public DateTimeOffset DateTimeOffset { get; set; } + + [DataMember(EmitDefaultValue = false)] + public decimal Decimal { get; set; } + + [DataMember(EmitDefaultValue = false)] + public int Integer { get; set; } + + [DataMember(EmitDefaultValue = false)] + public double Double { get; set; } + + [DataMember(EmitDefaultValue = false)] + public bool Boolean { get; set; } + + [DataMember(EmitDefaultValue = false)] + public DefaultStruct Struct { get; set; } + + [DataMember(EmitDefaultValue = false)] + public StringComparison Enum { get; set; } + + [DataMember(EmitDefaultValue = false)] + public Guid? NullableGuid { get; set; } + + [DataMember(EmitDefaultValue = false)] + public TimeSpan? NullableTimeSpan { get; set; } + + [DataMember(EmitDefaultValue = false)] + public DateTime? NullableDateTime { get; set; } + + [DataMember(EmitDefaultValue = false)] + public DateTimeOffset? NullableDateTimeOffset { get; set; } + + [DataMember(EmitDefaultValue = false)] + public decimal? NullableDecimal { get; set; } + + [DataMember(EmitDefaultValue = false)] + public int? NullableInteger { get; set; } + + [DataMember(EmitDefaultValue = false)] + public double? NullableDouble { get; set; } + + [DataMember(EmitDefaultValue = false)] + public bool? NullableBoolean { get; set; } + + [DataMember(EmitDefaultValue = false)] + public DefaultStruct? NullableStruct { get; set; } + + [DataMember(EmitDefaultValue = false)] + public StringComparison? NullableEnum { get; set; } + + [DataMember(EmitDefaultValue = false)] + public object Object { get; set; } + } #endif } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Serialization/DynamicTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/DynamicTests.cs index 50c74494..49b91cc2 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/DynamicTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/DynamicTests.cs @@ -39,6 +39,7 @@ using Newtonsoft.Json.Tests.TestObjects; using Newtonsoft.Json.Utilities; #if !NETFX_CORE using NUnit.Framework; + #else using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; @@ -47,39 +48,39 @@ using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAtt namespace Newtonsoft.Json.Tests.Serialization { - [TestFixture] - public class DynamicTests : TestFixtureBase - { - [Test] - public void SerializeDynamicObject() + [TestFixture] + public class DynamicTests : TestFixtureBase { - TestDynamicObject dynamicObject = new TestDynamicObject(); - dynamicObject.Explicit = true; + [Test] + public void SerializeDynamicObject() + { + TestDynamicObject dynamicObject = new TestDynamicObject(); + dynamicObject.Explicit = true; - dynamic d = dynamicObject; - d.Int = 1; - d.Decimal = 99.9d; - d.ChildObject = new DynamicChildObject(); + dynamic d = dynamicObject; + d.Int = 1; + d.Decimal = 99.9d; + d.ChildObject = new DynamicChildObject(); - Dictionary values = new Dictionary(); + Dictionary values = new Dictionary(); - IContractResolver c = DefaultContractResolver.Instance; - JsonDynamicContract dynamicContract = (JsonDynamicContract)c.ResolveContract(dynamicObject.GetType()); + IContractResolver c = DefaultContractResolver.Instance; + JsonDynamicContract dynamicContract = (JsonDynamicContract)c.ResolveContract(dynamicObject.GetType()); - foreach (string memberName in dynamicObject.GetDynamicMemberNames()) - { - object value; - dynamicContract.TryGetMember(dynamicObject, memberName, out value); + foreach (string memberName in dynamicObject.GetDynamicMemberNames()) + { + object value; + dynamicContract.TryGetMember(dynamicObject, memberName, out value); - values.Add(memberName, value); - } + values.Add(memberName, value); + } - Assert.AreEqual(d.Int, values["Int"]); - Assert.AreEqual(d.Decimal, values["Decimal"]); - Assert.AreEqual(d.ChildObject, values["ChildObject"]); + Assert.AreEqual(d.Int, values["Int"]); + Assert.AreEqual(d.Decimal, values["Decimal"]); + Assert.AreEqual(d.ChildObject, values["ChildObject"]); - string json = JsonConvert.SerializeObject(dynamicObject, Formatting.Indented); - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(dynamicObject, Formatting.Indented); + Assert.AreEqual(@"{ ""Explicit"": true, ""Decimal"": 99.9, ""Int"": 1, @@ -89,42 +90,42 @@ namespace Newtonsoft.Json.Tests.Serialization } }", json); - TestDynamicObject newDynamicObject = JsonConvert.DeserializeObject(json); - Assert.AreEqual(true, newDynamicObject.Explicit); + TestDynamicObject newDynamicObject = JsonConvert.DeserializeObject(json); + Assert.AreEqual(true, newDynamicObject.Explicit); - d = newDynamicObject; + d = newDynamicObject; - Assert.AreEqual(99.9, d.Decimal); - Assert.AreEqual(1, d.Int); - Assert.AreEqual(dynamicObject.ChildObject.Integer, d.ChildObject.Integer); - Assert.AreEqual(dynamicObject.ChildObject.Text, d.ChildObject.Text); - } + Assert.AreEqual(99.9, d.Decimal); + Assert.AreEqual(1, d.Int); + Assert.AreEqual(dynamicObject.ChildObject.Integer, d.ChildObject.Integer); + Assert.AreEqual(dynamicObject.ChildObject.Text, d.ChildObject.Text); + } #if !(PORTABLE || PORTABLE40) - [Test] - public void SerializeDynamicObjectWithObjectTracking() - { - dynamic o = new ExpandoObject(); - o.Text = "Text!"; - o.Integer = int.MaxValue; - o.DynamicChildObject = new DynamicChildObject + [Test] + public void SerializeDynamicObjectWithObjectTracking() { - Integer = int.MinValue, - Text = "Child text!" - }; + dynamic o = new ExpandoObject(); + o.Text = "Text!"; + o.Integer = int.MaxValue; + o.DynamicChildObject = new DynamicChildObject + { + Integer = int.MinValue, + Text = "Child text!" + }; - string json = JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings - { - TypeNameHandling = TypeNameHandling.All, - TypeNameAssemblyFormat = FormatterAssemblyStyle.Full - }); + string json = JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.All, + TypeNameAssemblyFormat = FormatterAssemblyStyle.Full + }); - Console.WriteLine(json); + Console.WriteLine(json); - string dynamicChildObjectTypeName = ReflectionUtils.GetTypeName(typeof(DynamicChildObject), FormatterAssemblyStyle.Full, null); - string expandoObjectTypeName = ReflectionUtils.GetTypeName(typeof(ExpandoObject), FormatterAssemblyStyle.Full, null); + string dynamicChildObjectTypeName = ReflectionUtils.GetTypeName(typeof(DynamicChildObject), FormatterAssemblyStyle.Full, null); + string expandoObjectTypeName = ReflectionUtils.GetTypeName(typeof(ExpandoObject), FormatterAssemblyStyle.Full, null); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""$type"": """ + expandoObjectTypeName + @""", ""Text"": ""Text!"", ""Integer"": 2147483647, @@ -135,61 +136,61 @@ namespace Newtonsoft.Json.Tests.Serialization } }", json); - dynamic n = JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings - { - TypeNameHandling = TypeNameHandling.All, - TypeNameAssemblyFormat = FormatterAssemblyStyle.Full - }); + dynamic n = JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.All, + TypeNameAssemblyFormat = FormatterAssemblyStyle.Full + }); - CustomAssert.IsInstanceOfType(typeof(ExpandoObject), n); - Assert.AreEqual("Text!", n.Text); - Assert.AreEqual(int.MaxValue, n.Integer); + CustomAssert.IsInstanceOfType(typeof(ExpandoObject), n); + Assert.AreEqual("Text!", n.Text); + Assert.AreEqual(int.MaxValue, n.Integer); - CustomAssert.IsInstanceOfType(typeof(DynamicChildObject), n.DynamicChildObject); - Assert.AreEqual("Child text!", n.DynamicChildObject.Text); - Assert.AreEqual(int.MinValue, n.DynamicChildObject.Integer); - } + CustomAssert.IsInstanceOfType(typeof(DynamicChildObject), n.DynamicChildObject); + Assert.AreEqual("Child text!", n.DynamicChildObject.Text); + Assert.AreEqual(int.MinValue, n.DynamicChildObject.Integer); + } #endif - [Test] - public void NoPublicDefaultConstructor() - { - ExceptionAssert.Throws("Unable to find a default constructor to use for type System.Dynamic.DynamicObject. Path 'contributors', line 2, position 18.", - () => - { - var settings = new JsonSerializerSettings(); - settings.NullValueHandling = NullValueHandling.Ignore; - var json = @"{ + [Test] + public void NoPublicDefaultConstructor() + { + ExceptionAssert.Throws("Unable to find a default constructor to use for type System.Dynamic.DynamicObject. Path 'contributors', line 2, position 18.", + () => + { + var settings = new JsonSerializerSettings(); + settings.NullValueHandling = NullValueHandling.Ignore; + var json = @"{ ""contributors"": null }"; - JsonConvert.DeserializeObject(json, settings); - }); - } + JsonConvert.DeserializeObject(json, settings); + }); + } - public class DictionaryDynamicObject : DynamicObject - { - public IDictionary Values { get; private set; } + public class DictionaryDynamicObject : DynamicObject + { + public IDictionary Values { get; private set; } - protected DictionaryDynamicObject() - { - Values = new Dictionary(); - } + protected DictionaryDynamicObject() + { + Values = new Dictionary(); + } - public override bool TrySetMember(SetMemberBinder binder, object value) - { - Values[binder.Name] = value; - return true; - } - } + public override bool TrySetMember(SetMemberBinder binder, object value) + { + Values[binder.Name] = value; + return true; + } + } - [Test] - public void AllowNonPublicDefaultConstructor() - { - var settings = new JsonSerializerSettings(); - settings.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor; + [Test] + public void AllowNonPublicDefaultConstructor() + { + var settings = new JsonSerializerSettings(); + settings.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor; - var json = @"{ + var json = @"{ ""contributors"": null, ""retweeted"": false, ""text"": ""Guys SX4 diesel is launched.what are your plans?catch us at #facebook http://bit.ly/dV3H1a #auto #car #maruti #india #delhi"", @@ -246,153 +247,156 @@ namespace Newtonsoft.Json.Tests.Serialization ""in_reply_to_user_id"": null }"; - DictionaryDynamicObject foo = JsonConvert.DeserializeObject(json, settings); + DictionaryDynamicObject foo = JsonConvert.DeserializeObject(json, settings); - Assert.AreEqual(false, foo.Values["retweeted"]); - } + Assert.AreEqual(false, foo.Values["retweeted"]); + } - [Test] - public void SerializeDynamicObjectWithNullValueHandlingIgnore() - { - dynamic o = new TestDynamicObject(); - o.Text = "Text!"; - o.Int = int.MaxValue; - o.ChildObject = null; // Tests an explicitly defined property of a dynamic object with a null value. - o.DynamicChildObject = null; // vs. a completely dynamic defined property. - - string json = JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings + [Test] + public void SerializeDynamicObjectWithNullValueHandlingIgnore() { - NullValueHandling = NullValueHandling.Ignore, - }); + dynamic o = new TestDynamicObject(); + o.Text = "Text!"; + o.Int = int.MaxValue; + o.ChildObject = null; // Tests an explicitly defined property of a dynamic object with a null value. + o.DynamicChildObject = null; // vs. a completely dynamic defined property. - Console.WriteLine(json); + string json = JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings + { + NullValueHandling = NullValueHandling.Ignore, + }); - Assert.AreEqual(@"{ + Console.WriteLine(json); + + Assert.AreEqual(@"{ ""Explicit"": false, ""Text"": ""Text!"", ""Int"": 2147483647 }", json); - } + } - [Test] - public void SerializeDynamicObjectWithNullValueHandlingInclude() - { - dynamic o = new TestDynamicObject(); - o.Text = "Text!"; - o.Int = int.MaxValue; - o.ChildObject = null; // Tests an explicitly defined property of a dynamic object with a null value. - o.DynamicChildObject = null; // vs. a completely dynamic defined property. - - string json = JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings + [Test] + public void SerializeDynamicObjectWithNullValueHandlingInclude() { - NullValueHandling = NullValueHandling.Include, - }); + dynamic o = new TestDynamicObject(); + o.Text = "Text!"; + o.Int = int.MaxValue; + o.ChildObject = null; // Tests an explicitly defined property of a dynamic object with a null value. + o.DynamicChildObject = null; // vs. a completely dynamic defined property. - Console.WriteLine(json); + string json = JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings + { + NullValueHandling = NullValueHandling.Include, + }); - Assert.AreEqual(@"{ + Console.WriteLine(json); + + Assert.AreEqual(@"{ ""Explicit"": false, ""Text"": ""Text!"", ""DynamicChildObject"": null, ""Int"": 2147483647, ""ChildObject"": null }", json); - } + } - [Test] - public void SerializeDynamicObjectWithDefaultValueHandlingIgnore() - { - dynamic o = new TestDynamicObject(); - o.Text = "Text!"; - o.Int = int.MaxValue; - o.IntDefault = 0; - o.NUllableIntDefault = default(int?); - o.ChildObject = null; // Tests an explicitly defined property of a dynamic object with a null value. - o.DynamicChildObject = null; // vs. a completely dynamic defined property. + [Test] + public void SerializeDynamicObjectWithDefaultValueHandlingIgnore() + { + dynamic o = new TestDynamicObject(); + o.Text = "Text!"; + o.Int = int.MaxValue; + o.IntDefault = 0; + o.NUllableIntDefault = default(int?); + o.ChildObject = null; // Tests an explicitly defined property of a dynamic object with a null value. + o.DynamicChildObject = null; // vs. a completely dynamic defined property. - string json = JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings - { - DefaultValueHandling = DefaultValueHandling.Ignore, - }); + string json = JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings + { + DefaultValueHandling = DefaultValueHandling.Ignore, + }); - Console.WriteLine(json); + Console.WriteLine(json); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Text"": ""Text!"", ""Int"": 2147483647 }", json); + } } - } - public class DynamicChildObject - { - public string Text { get; set; } - public int Integer { get; set; } - } - - public class TestDynamicObject : DynamicObject - { - private readonly Dictionary _members; - - public int Int; - [JsonProperty] - public bool Explicit; - public DynamicChildObject ChildObject { get; set; } - - internal Dictionary Members + public class DynamicChildObject { - get { return _members; } + public string Text { get; set; } + public int Integer { get; set; } } - public TestDynamicObject() + public class TestDynamicObject : DynamicObject { - _members = new Dictionary(); + private readonly Dictionary _members; + + public int Int; + + [JsonProperty] + public bool Explicit; + + public DynamicChildObject ChildObject { get; set; } + + internal Dictionary Members + { + get { return _members; } + } + + public TestDynamicObject() + { + _members = new Dictionary(); + } + + public override IEnumerable GetDynamicMemberNames() + { + return _members.Keys.Union(new[] { "Int", "ChildObject" }); + } + + public override bool TryConvert(ConvertBinder binder, out object result) + { + Type targetType = binder.Type; + + if (targetType == typeof(IDictionary) || + targetType == typeof(IDictionary)) + { + result = new Dictionary(_members); + return true; + } + else + { + return base.TryConvert(binder, out result); + } + } + + public override bool TryDeleteMember(DeleteMemberBinder binder) + { + return _members.Remove(binder.Name); + } + + public override bool TryGetMember(GetMemberBinder binder, out object result) + { + return _members.TryGetValue(binder.Name, out result); + } + + public override bool TrySetMember(SetMemberBinder binder, object value) + { + _members[binder.Name] = value; + return true; + } } - public override IEnumerable GetDynamicMemberNames() + public class ErrorSettingDynamicObject : DynamicObject { - return _members.Keys.Union(new[] { "Int", "ChildObject" }); + public override bool TrySetMember(SetMemberBinder binder, object value) + { + return false; + } } - - public override bool TryConvert(ConvertBinder binder, out object result) - { - Type targetType = binder.Type; - - if (targetType == typeof(IDictionary) || - targetType == typeof(IDictionary)) - { - result = new Dictionary(_members); - return true; - } - else - { - return base.TryConvert(binder, out result); - } - } - - public override bool TryDeleteMember(DeleteMemberBinder binder) - { - return _members.Remove(binder.Name); - } - - public override bool TryGetMember(GetMemberBinder binder, out object result) - { - return _members.TryGetValue(binder.Name, out result); - } - - public override bool TrySetMember(SetMemberBinder binder, object value) - { - _members[binder.Name] = value; - return true; - } - } - - public class ErrorSettingDynamicObject : DynamicObject - { - public override bool TrySetMember(SetMemberBinder binder, object value) - { - return false; - } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Serialization/EntitiesSerializationTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/EntitiesSerializationTests.cs index 7e946d99..aeecea62 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/EntitiesSerializationTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/EntitiesSerializationTests.cs @@ -32,6 +32,7 @@ using System.Text; using Newtonsoft.Json.Converters; #if !NETFX_CORE using NUnit.Framework; + #else using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; @@ -40,17 +41,17 @@ using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAtt namespace Newtonsoft.Json.Tests.Serialization { - [TestFixture] - public class EntitiesSerializationTests : TestFixtureBase - { - [Test] - public void SerializeEntity() + [TestFixture] + public class EntitiesSerializationTests : TestFixtureBase { - Folder rootFolder = CreateEntitiesTestData(); + [Test] + public void SerializeEntity() + { + Folder rootFolder = CreateEntitiesTestData(); - string json = JsonConvert.SerializeObject(rootFolder, Formatting.Indented, new IsoDateTimeConverter()); + string json = JsonConvert.SerializeObject(rootFolder, Formatting.Indented, new IsoDateTimeConverter()); - string expected = @"{ + string expected = @"{ ""$id"": ""1"", ""FolderId"": ""a4e8ba80-eb24-4591-bb1c-62d3ad83701e"", ""Name"": ""Root folder"", @@ -121,13 +122,13 @@ namespace Newtonsoft.Json.Tests.Serialization } }"; - Assert.AreEqual(expected, json); - } + Assert.AreEqual(expected, json); + } - [Test] - public void DeserializeEntity() - { - string json = @"{ + [Test] + public void DeserializeEntity() + { + string json = @"{ ""$id"": ""1"", ""FolderId"": ""a4e8ba80-eb24-4591-bb1c-62d3ad83701e"", ""Name"": ""Root folder"", @@ -198,48 +199,48 @@ namespace Newtonsoft.Json.Tests.Serialization } }"; - Folder f = JsonConvert.DeserializeObject(json, new IsoDateTimeConverter()); + Folder f = JsonConvert.DeserializeObject(json, new IsoDateTimeConverter()); - Assert.IsNotNull(f); - Assert.AreEqual(new Guid("A4E8BA80-EB24-4591-BB1C-62D3AD83701E"), f.FolderId); - Assert.AreEqual("Folder", f.EntityKey.EntitySetName); - Assert.AreEqual("DataServicesTestDatabaseEntities", f.EntityKey.EntityContainerName); - Assert.AreEqual("Folder", f.EntityKey.EntitySetName); - Assert.AreEqual(false, f.EntityKey.IsTemporary); - Assert.AreEqual(1, f.EntityKey.EntityKeyValues.Length); - Assert.AreEqual("FolderId", f.EntityKey.EntityKeyValues[0].Key); - Assert.AreEqual(new Guid("A4E8BA80-EB24-4591-BB1C-62D3AD83701E"), f.EntityKey.EntityKeyValues[0].Value); - Assert.AreEqual("Root folder", f.Name); - Assert.AreEqual(new DateTime(2000, 12, 10, 10, 50, 0, DateTimeKind.Utc), f.CreatedDate); - Assert.AreEqual(null, f.ParentFolder); - Assert.AreEqual(1, f.ChildFolders.Count); + Assert.IsNotNull(f); + Assert.AreEqual(new Guid("A4E8BA80-EB24-4591-BB1C-62D3AD83701E"), f.FolderId); + Assert.AreEqual("Folder", f.EntityKey.EntitySetName); + Assert.AreEqual("DataServicesTestDatabaseEntities", f.EntityKey.EntityContainerName); + Assert.AreEqual("Folder", f.EntityKey.EntitySetName); + Assert.AreEqual(false, f.EntityKey.IsTemporary); + Assert.AreEqual(1, f.EntityKey.EntityKeyValues.Length); + Assert.AreEqual("FolderId", f.EntityKey.EntityKeyValues[0].Key); + Assert.AreEqual(new Guid("A4E8BA80-EB24-4591-BB1C-62D3AD83701E"), f.EntityKey.EntityKeyValues[0].Value); + Assert.AreEqual("Root folder", f.Name); + Assert.AreEqual(new DateTime(2000, 12, 10, 10, 50, 0, DateTimeKind.Utc), f.CreatedDate); + Assert.AreEqual(null, f.ParentFolder); + Assert.AreEqual(1, f.ChildFolders.Count); - Folder childFolder = f.ChildFolders.ElementAt(0); + Folder childFolder = f.ChildFolders.ElementAt(0); - Assert.AreEqual("Child folder", childFolder.Name); - Assert.AreEqual("Description!", childFolder.Description); - Assert.AreEqual(f, childFolder.ParentFolder); - Assert.AreEqual(f, childFolder.ParentFolderReference.Value); - // is this a problem? - Assert.AreEqual(null, childFolder.ParentFolderReference.EntityKey); - } + Assert.AreEqual("Child folder", childFolder.Name); + Assert.AreEqual("Description!", childFolder.Description); + Assert.AreEqual(f, childFolder.ParentFolder); + Assert.AreEqual(f, childFolder.ParentFolderReference.Value); + // is this a problem? + Assert.AreEqual(null, childFolder.ParentFolderReference.EntityKey); + } - [Test] - public void SerializeMultiValueEntityKey() - { - EntityKey e = new EntityKey("DataServicesTestDatabaseEntities.Folder", - new List - { - new EntityKeyMember("GuidId", new Guid("A4E8BA80-EB24-4591-BB1C-62D3AD83701E")), - new EntityKeyMember("IntId", int.MaxValue), - new EntityKeyMember("LongId", long.MaxValue), - new EntityKeyMember("StringId", "String!"), - new EntityKeyMember("DateTimeId", new DateTime(2000, 12, 10, 10, 50, 0, DateTimeKind.Utc)) - }); + [Test] + public void SerializeMultiValueEntityKey() + { + EntityKey e = new EntityKey("DataServicesTestDatabaseEntities.Folder", + new List + { + new EntityKeyMember("GuidId", new Guid("A4E8BA80-EB24-4591-BB1C-62D3AD83701E")), + new EntityKeyMember("IntId", int.MaxValue), + new EntityKeyMember("LongId", long.MaxValue), + new EntityKeyMember("StringId", "String!"), + new EntityKeyMember("DateTimeId", new DateTime(2000, 12, 10, 10, 50, 0, DateTimeKind.Utc)) + }); - string json = JsonConvert.SerializeObject(e, Formatting.Indented); + string json = JsonConvert.SerializeObject(e, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""$id"": ""1"", ""EntitySetName"": ""Folder"", ""EntityContainerName"": ""DataServicesTestDatabaseEntities"", @@ -272,50 +273,51 @@ namespace Newtonsoft.Json.Tests.Serialization ] }", json); - EntityKey newKey = JsonConvert.DeserializeObject(json); - Assert.IsFalse(ReferenceEquals(e, newKey)); + EntityKey newKey = JsonConvert.DeserializeObject(json); + Assert.IsFalse(ReferenceEquals(e, newKey)); - Assert.AreEqual(5, newKey.EntityKeyValues.Length); - Assert.AreEqual("GuidId", newKey.EntityKeyValues[0].Key); - Assert.AreEqual(new Guid("A4E8BA80-EB24-4591-BB1C-62D3AD83701E"), newKey.EntityKeyValues[0].Value); - Assert.AreEqual("IntId", newKey.EntityKeyValues[1].Key); - Assert.AreEqual(int.MaxValue, newKey.EntityKeyValues[1].Value); - Assert.AreEqual("LongId", newKey.EntityKeyValues[2].Key); - Assert.AreEqual(long.MaxValue, newKey.EntityKeyValues[2].Value); - Assert.AreEqual("StringId", newKey.EntityKeyValues[3].Key); - Assert.AreEqual("String!", newKey.EntityKeyValues[3].Value); - Assert.AreEqual("DateTimeId", newKey.EntityKeyValues[4].Key); - Assert.AreEqual(new DateTime(2000, 12, 10, 10, 50, 0, DateTimeKind.Utc), newKey.EntityKeyValues[4].Value); + Assert.AreEqual(5, newKey.EntityKeyValues.Length); + Assert.AreEqual("GuidId", newKey.EntityKeyValues[0].Key); + Assert.AreEqual(new Guid("A4E8BA80-EB24-4591-BB1C-62D3AD83701E"), newKey.EntityKeyValues[0].Value); + Assert.AreEqual("IntId", newKey.EntityKeyValues[1].Key); + Assert.AreEqual(int.MaxValue, newKey.EntityKeyValues[1].Value); + Assert.AreEqual("LongId", newKey.EntityKeyValues[2].Key); + Assert.AreEqual(long.MaxValue, newKey.EntityKeyValues[2].Value); + Assert.AreEqual("StringId", newKey.EntityKeyValues[3].Key); + Assert.AreEqual("String!", newKey.EntityKeyValues[3].Value); + Assert.AreEqual("DateTimeId", newKey.EntityKeyValues[4].Key); + Assert.AreEqual(new DateTime(2000, 12, 10, 10, 50, 0, DateTimeKind.Utc), newKey.EntityKeyValues[4].Value); + } + + private Folder CreateEntitiesTestData() + { + Folder folder = new Folder(); + folder.FolderId = new Guid("A4E8BA80-EB24-4591-BB1C-62D3AD83701E"); + folder.EntityKey = new EntityKey("DataServicesTestDatabaseEntities.Folder", "FolderId", folder.FolderId); + folder.Name = "Root folder"; + folder.Description = "Description!"; + folder.CreatedDate = new DateTime(2000, 12, 10, 10, 50, 0, DateTimeKind.Utc); + + Folder childFolder = new Folder(); + childFolder.FolderId = new Guid("484936E2-7CBB-4592-93FF-B2103E5705E4"); + childFolder.EntityKey = new EntityKey("DataServicesTestDatabaseEntities.Folder", "FolderId", childFolder.FolderId); + childFolder.Name = "Child folder"; + childFolder.Description = "Description!"; + childFolder.CreatedDate = new DateTime(2001, 11, 20, 10, 50, 0, DateTimeKind.Utc); + + folder.ChildFolders.Add(childFolder); + + File file1 = new File(); + file1.FileId = new Guid("CC76D734-49F1-4616-BB38-41514228AC6C"); + file1.EntityKey = new EntityKey("DataServicesTestDatabaseEntities.File", "FileId", file1.FileId); + file1.Name = "File 1"; + file1.Description = "Description!"; + file1.CreatedDate = new DateTime(2002, 10, 30, 10, 50, 0, DateTimeKind.Utc); + + childFolder.Files.Add(file1); + return folder; + } } - - private Folder CreateEntitiesTestData() - { - Folder folder = new Folder(); - folder.FolderId = new Guid("A4E8BA80-EB24-4591-BB1C-62D3AD83701E"); - folder.EntityKey = new EntityKey("DataServicesTestDatabaseEntities.Folder", "FolderId", folder.FolderId); - folder.Name = "Root folder"; - folder.Description = "Description!"; - folder.CreatedDate = new DateTime(2000, 12, 10, 10, 50, 0, DateTimeKind.Utc); - - Folder childFolder = new Folder(); - childFolder.FolderId = new Guid("484936E2-7CBB-4592-93FF-B2103E5705E4"); - childFolder.EntityKey = new EntityKey("DataServicesTestDatabaseEntities.Folder", "FolderId", childFolder.FolderId); - childFolder.Name = "Child folder"; - childFolder.Description = "Description!"; - childFolder.CreatedDate = new DateTime(2001, 11, 20, 10, 50, 0, DateTimeKind.Utc); - - folder.ChildFolders.Add(childFolder); - - File file1 = new File(); - file1.FileId = new Guid("CC76D734-49F1-4616-BB38-41514228AC6C"); - file1.EntityKey = new EntityKey("DataServicesTestDatabaseEntities.File", "FileId", file1.FileId); - file1.Name = "File 1"; - file1.Description = "Description!"; - file1.CreatedDate = new DateTime(2002, 10, 30, 10, 50, 0, DateTimeKind.Utc); - - childFolder.Files.Add(file1); - return folder; - } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Serialization/ImmutableCollectionsTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/ImmutableCollectionsTests.cs index ecb1f935..d3124e08 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/ImmutableCollectionsTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/ImmutableCollectionsTests.cs @@ -41,394 +41,395 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.Serialization { - [TestFixture] - public class ImmutableCollectionsTests : TestFixtureBase - { - #region List - [Test] - public void SerializeList() + [TestFixture] + public class ImmutableCollectionsTests : TestFixtureBase { - ImmutableList l = ImmutableList.CreateRange(new List + #region List + [Test] + public void SerializeList() { - "One", - "II", - "3" - }); + ImmutableList l = ImmutableList.CreateRange(new List + { + "One", + "II", + "3" + }); - string json = JsonConvert.SerializeObject(l, Formatting.Indented); - Assert.AreEqual(@"[ + string json = JsonConvert.SerializeObject(l, Formatting.Indented); + Assert.AreEqual(@"[ ""One"", ""II"", ""3"" ]", json); - } + } - [Test] - public void DeserializeList() - { - string json = @"[ + [Test] + public void DeserializeList() + { + string json = @"[ ""One"", ""II"", ""3"" ]"; - ImmutableList l = JsonConvert.DeserializeObject>(json); + ImmutableList l = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(3, l.Count); - Assert.AreEqual("One", l[0]); - Assert.AreEqual("II", l[1]); - Assert.AreEqual("3", l[2]); - } + Assert.AreEqual(3, l.Count); + Assert.AreEqual("One", l[0]); + Assert.AreEqual("II", l[1]); + Assert.AreEqual("3", l[2]); + } - [Test] - public void DeserializeListInterface() - { - string json = @"[ + [Test] + public void DeserializeListInterface() + { + string json = @"[ 'Volibear', 'Teemo', 'Katarina' ]"; - // what sorcery is this?! - IImmutableList champions = JsonConvert.DeserializeObject>(json); + // what sorcery is this?! + IImmutableList champions = JsonConvert.DeserializeObject>(json); - Console.WriteLine(champions[0]); - // Volibear + Console.WriteLine(champions[0]); + // Volibear - Assert.AreEqual(3, champions.Count); - Assert.AreEqual("Volibear", champions[0]); - Assert.AreEqual("Teemo", champions[1]); - Assert.AreEqual("Katarina", champions[2]); - } - #endregion + Assert.AreEqual(3, champions.Count); + Assert.AreEqual("Volibear", champions[0]); + Assert.AreEqual("Teemo", champions[1]); + Assert.AreEqual("Katarina", champions[2]); + } + #endregion -// #region Array -// [Test] -// public void SerializeArray() -// { -// ImmutableArray l = ImmutableArray.From(new List -// { -// "One", -// "II", -// "3" -// }); + // #region Array + // [Test] + // public void SerializeArray() + // { + // ImmutableArray l = ImmutableArray.From(new List + // { + // "One", + // "II", + // "3" + // }); -// string json = JsonConvert.SerializeObject(l, Formatting.Indented); -// Assert.AreEqual(@"[ -// ""One"", -// ""II"", -// ""3"" -//]", json); -// } + // string json = JsonConvert.SerializeObject(l, Formatting.Indented); + // Assert.AreEqual(@"[ + // ""One"", + // ""II"", + // ""3"" + //]", json); + // } -// [Test] -// public void DeserializeArray() -// { -// string json = @"[ -// ""One"", -// ""II"", -// ""3"" -//]"; + // [Test] + // public void DeserializeArray() + // { + // string json = @"[ + // ""One"", + // ""II"", + // ""3"" + //]"; -// ImmutableArray l = JsonConvert.DeserializeObject>(json); + // ImmutableArray l = JsonConvert.DeserializeObject>(json); -// Assert.AreEqual(3, l.Length); -// Assert.AreEqual("One", l[0]); -// Assert.AreEqual("II", l[1]); -// Assert.AreEqual("3", l[2]); -// } -// #endregion + // Assert.AreEqual(3, l.Length); + // Assert.AreEqual("One", l[0]); + // Assert.AreEqual("II", l[1]); + // Assert.AreEqual("3", l[2]); + // } + // #endregion - #region Queue - [Test] - public void SerializeQueue() - { - ImmutableQueue l = ImmutableQueue.CreateRange(new List + #region Queue + [Test] + public void SerializeQueue() { - "One", - "II", - "3" - }); + ImmutableQueue l = ImmutableQueue.CreateRange(new List + { + "One", + "II", + "3" + }); - string json = JsonConvert.SerializeObject(l, Formatting.Indented); - Assert.AreEqual(@"[ + string json = JsonConvert.SerializeObject(l, Formatting.Indented); + Assert.AreEqual(@"[ ""One"", ""II"", ""3"" ]", json); - } + } - [Test] - public void DeserializeQueue() - { - string json = @"[ - ""One"", - ""II"", - ""3"" -]"; - - ImmutableQueue l = JsonConvert.DeserializeObject>(json); - - Assert.AreEqual(3, l.Count()); - Assert.AreEqual("One", l.ElementAt(0)); - Assert.AreEqual("II", l.ElementAt(1)); - Assert.AreEqual("3", l.ElementAt(2)); - } - - [Test] - public void DeserializeQueueInterface() - { - string json = @"[ - ""One"", - ""II"", - ""3"" -]"; - - IImmutableQueue l = JsonConvert.DeserializeObject>(json); - - Assert.AreEqual(3, l.Count()); - Assert.AreEqual("One", l.ElementAt(0)); - Assert.AreEqual("II", l.ElementAt(1)); - Assert.AreEqual("3", l.ElementAt(2)); - } - #endregion - - #region Stack - [Test] - public void SerializeStack() - { - ImmutableStack l = ImmutableStack.CreateRange(new List + [Test] + public void DeserializeQueue() { - "One", - "II", - "3" - }); + string json = @"[ + ""One"", + ""II"", + ""3"" +]"; - string json = JsonConvert.SerializeObject(l, Formatting.Indented); - Assert.AreEqual(@"[ + ImmutableQueue l = JsonConvert.DeserializeObject>(json); + + Assert.AreEqual(3, l.Count()); + Assert.AreEqual("One", l.ElementAt(0)); + Assert.AreEqual("II", l.ElementAt(1)); + Assert.AreEqual("3", l.ElementAt(2)); + } + + [Test] + public void DeserializeQueueInterface() + { + string json = @"[ + ""One"", + ""II"", + ""3"" +]"; + + IImmutableQueue l = JsonConvert.DeserializeObject>(json); + + Assert.AreEqual(3, l.Count()); + Assert.AreEqual("One", l.ElementAt(0)); + Assert.AreEqual("II", l.ElementAt(1)); + Assert.AreEqual("3", l.ElementAt(2)); + } + #endregion + + #region Stack + [Test] + public void SerializeStack() + { + ImmutableStack l = ImmutableStack.CreateRange(new List + { + "One", + "II", + "3" + }); + + string json = JsonConvert.SerializeObject(l, Formatting.Indented); + Assert.AreEqual(@"[ ""3"", ""II"", ""One"" ]", json); - } + } - [Test] - public void DeserializeStack() - { - string json = @"[ - ""One"", - ""II"", - ""3"" -]"; - - ImmutableStack l = JsonConvert.DeserializeObject>(json); - - Assert.AreEqual(3, l.Count()); - Assert.AreEqual("3", l.ElementAt(0)); - Assert.AreEqual("II", l.ElementAt(1)); - Assert.AreEqual("One", l.ElementAt(2)); - } - - [Test] - public void DeserializeStackInterface() - { - string json = @"[ - ""One"", - ""II"", - ""3"" -]"; - - IImmutableStack l = JsonConvert.DeserializeObject>(json); - - Assert.AreEqual(3, l.Count()); - Assert.AreEqual("3", l.ElementAt(0)); - Assert.AreEqual("II", l.ElementAt(1)); - Assert.AreEqual("One", l.ElementAt(2)); - } - #endregion - - #region HashSet - [Test] - public void SerializeHashSet() - { - ImmutableHashSet l = ImmutableHashSet.CreateRange(new List + [Test] + public void DeserializeStack() { - "One", - "II", - "3" - }); - - string json = JsonConvert.SerializeObject(l, Formatting.Indented); - - JArray a = JArray.Parse(json); - Assert.AreEqual(3, a.Count); - Assert.IsTrue(a.Any(t => t.DeepEquals("One"))); - Assert.IsTrue(a.Any(t => t.DeepEquals("II"))); - Assert.IsTrue(a.Any(t => t.DeepEquals("3"))); - } - - [Test] - public void DeserializeHashSet() - { - string json = @"[ + string json = @"[ ""One"", ""II"", ""3"" ]"; - ImmutableHashSet l = JsonConvert.DeserializeObject>(json); + ImmutableStack l = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(3, l.Count()); - Assert.IsTrue(l.Contains("3")); - Assert.IsTrue(l.Contains("II")); - Assert.IsTrue(l.Contains("One")); - } + Assert.AreEqual(3, l.Count()); + Assert.AreEqual("3", l.ElementAt(0)); + Assert.AreEqual("II", l.ElementAt(1)); + Assert.AreEqual("One", l.ElementAt(2)); + } - [Test] - public void DeserializeHashSetInterface() - { - string json = @"[ - ""One"", - ""II"", - ""3"" -]"; - - IImmutableSet l = JsonConvert.DeserializeObject>(json); - - Assert.AreEqual(3, l.Count()); - Assert.IsTrue(l.Contains("3")); - Assert.IsTrue(l.Contains("II")); - Assert.IsTrue(l.Contains("One")); - } - #endregion - - #region SortedSet - [Test] - public void SerializeSortedSet() - { - ImmutableSortedSet l = ImmutableSortedSet.CreateRange(new List + [Test] + public void DeserializeStackInterface() { - "One", - "II", - "3" - }); + string json = @"[ + ""One"", + ""II"", + ""3"" +]"; - string json = JsonConvert.SerializeObject(l, Formatting.Indented); - Assert.AreEqual(@"[ + IImmutableStack l = JsonConvert.DeserializeObject>(json); + + Assert.AreEqual(3, l.Count()); + Assert.AreEqual("3", l.ElementAt(0)); + Assert.AreEqual("II", l.ElementAt(1)); + Assert.AreEqual("One", l.ElementAt(2)); + } + #endregion + + #region HashSet + [Test] + public void SerializeHashSet() + { + ImmutableHashSet l = ImmutableHashSet.CreateRange(new List + { + "One", + "II", + "3" + }); + + string json = JsonConvert.SerializeObject(l, Formatting.Indented); + + JArray a = JArray.Parse(json); + Assert.AreEqual(3, a.Count); + Assert.IsTrue(a.Any(t => t.DeepEquals("One"))); + Assert.IsTrue(a.Any(t => t.DeepEquals("II"))); + Assert.IsTrue(a.Any(t => t.DeepEquals("3"))); + } + + [Test] + public void DeserializeHashSet() + { + string json = @"[ + ""One"", + ""II"", + ""3"" +]"; + + ImmutableHashSet l = JsonConvert.DeserializeObject>(json); + + Assert.AreEqual(3, l.Count()); + Assert.IsTrue(l.Contains("3")); + Assert.IsTrue(l.Contains("II")); + Assert.IsTrue(l.Contains("One")); + } + + [Test] + public void DeserializeHashSetInterface() + { + string json = @"[ + ""One"", + ""II"", + ""3"" +]"; + + IImmutableSet l = JsonConvert.DeserializeObject>(json); + + Assert.AreEqual(3, l.Count()); + Assert.IsTrue(l.Contains("3")); + Assert.IsTrue(l.Contains("II")); + Assert.IsTrue(l.Contains("One")); + } + #endregion + + #region SortedSet + [Test] + public void SerializeSortedSet() + { + ImmutableSortedSet l = ImmutableSortedSet.CreateRange(new List + { + "One", + "II", + "3" + }); + + string json = JsonConvert.SerializeObject(l, Formatting.Indented); + Assert.AreEqual(@"[ ""3"", ""II"", ""One"" ]", json); - } + } - [Test] - public void DeserializeSortedSet() - { - string json = @"[ + [Test] + public void DeserializeSortedSet() + { + string json = @"[ ""One"", ""II"", ""3"" ]"; - ImmutableSortedSet l = JsonConvert.DeserializeObject>(json); + ImmutableSortedSet l = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(3, l.Count()); - Assert.IsTrue(l.Contains("3")); - Assert.IsTrue(l.Contains("II")); - Assert.IsTrue(l.Contains("One")); - } - #endregion + Assert.AreEqual(3, l.Count()); + Assert.IsTrue(l.Contains("3")); + Assert.IsTrue(l.Contains("II")); + Assert.IsTrue(l.Contains("One")); + } + #endregion - #region Dictionary - [Test] - public void SerializeDictionary() - { - ImmutableDictionary l = ImmutableDictionary.CreateRange(new Dictionary + #region Dictionary + [Test] + public void SerializeDictionary() { - {1, "One"}, - {2, "II"}, - {3, "3"} - }); + ImmutableDictionary l = ImmutableDictionary.CreateRange(new Dictionary + { + { 1, "One" }, + { 2, "II" }, + { 3, "3" } + }); - string json = JsonConvert.SerializeObject(l, Formatting.Indented); - JObject a = JObject.Parse(json); - Assert.AreEqual(3, a.Count); - Assert.AreEqual("One", (string)a["1"]); - Assert.AreEqual("II", (string)a["2"]); - Assert.AreEqual("3", (string)a["3"]); - } + string json = JsonConvert.SerializeObject(l, Formatting.Indented); + JObject a = JObject.Parse(json); + Assert.AreEqual(3, a.Count); + Assert.AreEqual("One", (string)a["1"]); + Assert.AreEqual("II", (string)a["2"]); + Assert.AreEqual("3", (string)a["3"]); + } - [Test] - public void DeserializeDictionary() - { - string json = @"{ + [Test] + public void DeserializeDictionary() + { + string json = @"{ ""1"": ""One"", ""2"": ""II"", ""3"": ""3"" }"; - ImmutableDictionary l = JsonConvert.DeserializeObject>(json); + ImmutableDictionary l = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(3, l.Count); - Assert.AreEqual("One", l[1]); - Assert.AreEqual("II", l[2]); - Assert.AreEqual("3", l[3]); - } + Assert.AreEqual(3, l.Count); + Assert.AreEqual("One", l[1]); + Assert.AreEqual("II", l[2]); + Assert.AreEqual("3", l[3]); + } - [Test] - public void DeserializeDictionaryInterface() - { - string json = @"{ + [Test] + public void DeserializeDictionaryInterface() + { + string json = @"{ ""1"": ""One"", ""2"": ""II"", ""3"": ""3"" }"; - IImmutableDictionary l = JsonConvert.DeserializeObject>(json); + IImmutableDictionary l = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(3, l.Count); - Assert.AreEqual("One", l[1]); - Assert.AreEqual("II", l[2]); - Assert.AreEqual("3", l[3]); - } - #endregion + Assert.AreEqual(3, l.Count); + Assert.AreEqual("One", l[1]); + Assert.AreEqual("II", l[2]); + Assert.AreEqual("3", l[3]); + } + #endregion - #region SortedDictionary - [Test] - public void SerializeSortedDictionary() - { - ImmutableSortedDictionary l = ImmutableSortedDictionary.CreateRange(new SortedDictionary + #region SortedDictionary + [Test] + public void SerializeSortedDictionary() { - {1, "One"}, - {2, "II"}, - {3, "3"} - }); + ImmutableSortedDictionary l = ImmutableSortedDictionary.CreateRange(new SortedDictionary + { + { 1, "One" }, + { 2, "II" }, + { 3, "3" } + }); - string json = JsonConvert.SerializeObject(l, Formatting.Indented); - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(l, Formatting.Indented); + Assert.AreEqual(@"{ ""1"": ""One"", ""2"": ""II"", ""3"": ""3"" }", json); - } + } - [Test] - public void DeserializeSortedDictionary() - { - string json = @"{ + [Test] + public void DeserializeSortedDictionary() + { + string json = @"{ ""1"": ""One"", ""2"": ""II"", ""3"": ""3"" }"; - ImmutableSortedDictionary l = JsonConvert.DeserializeObject>(json); + ImmutableSortedDictionary l = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(3, l.Count); - Assert.AreEqual("One", l[1]); - Assert.AreEqual("II", l[2]); - Assert.AreEqual("3", l[3]); + Assert.AreEqual(3, l.Count); + Assert.AreEqual("One", l[1]); + Assert.AreEqual("II", l[2]); + Assert.AreEqual("3", l[3]); + } + #endregion } - #endregion - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonPropertyCollectionTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonPropertyCollectionTests.cs index a025ef6f..2edf003f 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/JsonPropertyCollectionTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonPropertyCollectionTests.cs @@ -35,26 +35,26 @@ using Newtonsoft.Json.Tests.TestObjects; namespace Newtonsoft.Json.Tests.Serialization { - [TestFixture] - public class JsonPropertyCollectionTests : TestFixtureBase - { - [Test] - public void AddPropertyIncludesPrivateImplementations() + [TestFixture] + public class JsonPropertyCollectionTests : TestFixtureBase { - var value = new PrivateImplementationBClass + [Test] + public void AddPropertyIncludesPrivateImplementations() { - OverriddenProperty = "OverriddenProperty", - PropertyA = "PropertyA", - PropertyB = "PropertyB" - }; + var value = new PrivateImplementationBClass + { + OverriddenProperty = "OverriddenProperty", + PropertyA = "PropertyA", + PropertyB = "PropertyB" + }; - var resolver = new DefaultContractResolver(); - var contract = (JsonObjectContract) resolver.ResolveContract(value.GetType()); + var resolver = new DefaultContractResolver(); + var contract = (JsonObjectContract)resolver.ResolveContract(value.GetType()); - Assert.AreEqual(3, contract.Properties.Count); - Assert.IsTrue(contract.Properties.Contains("OverriddenProperty"), "Contract is missing property 'OverriddenProperty'"); - Assert.IsTrue(contract.Properties.Contains("PropertyA"), "Contract is missing property 'PropertyA'"); - Assert.IsTrue(contract.Properties.Contains("PropertyB"), "Contract is missing property 'PropertyB'"); + Assert.AreEqual(3, contract.Properties.Count); + Assert.IsTrue(contract.Properties.Contains("OverriddenProperty"), "Contract is missing property 'OverriddenProperty'"); + Assert.IsTrue(contract.Properties.Contains("PropertyA"), "Contract is missing property 'PropertyA'"); + Assert.IsTrue(contract.Properties.Contains("PropertyB"), "Contract is missing property 'PropertyB'"); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs index ad1b08a3..38ddd09f 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs @@ -84,463 +84,468 @@ using System.Linq; #if !(SILVERLIGHT || NETFX_CORE) using System.Drawing; using System.Diagnostics; + #endif namespace Newtonsoft.Json.Tests.Serialization { - [TestFixture] - public class JsonSerializerTest : TestFixtureBase - { - public class GenericItem + [TestFixture] + public class JsonSerializerTest : TestFixtureBase { - public T Value { get; set; } - } - - public class NonGenericItem : GenericItem - { - - } - - public class GenericClass : IEnumerable - where T : GenericItem, new() - { - public IList Items { get; set; } - - public GenericClass() - { - Items = new List(); - } - - public IEnumerator GetEnumerator() - { - if (Items != null) + public class GenericItem { - foreach (T item in Items) - { - yield return item; - } + public T Value { get; set; } } - else - yield break; - } - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } + public class NonGenericItem : GenericItem + { + } - public class NonGenericClass : GenericClass, string> - { + public class GenericClass : IEnumerable + where T : GenericItem, new() + { + public IList Items { get; set; } - } + public GenericClass() + { + Items = new List(); + } + + public IEnumerator GetEnumerator() + { + if (Items != null) + { + foreach (T item in Items) + { + yield return item; + } + } + else + yield break; + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } + + public class NonGenericClass : GenericClass, string> + { + } #pragma warning disable 169 - public class CustomerInvoice - { - // we're only modifing the tax rate - public decimal TaxRate { get; set; } + public class CustomerInvoice + { + // we're only modifing the tax rate + public decimal TaxRate { get; set; } - // everything else gets stored here - [JsonExtensionData] - private IDictionary _additionalData; - } + // everything else gets stored here + [JsonExtensionData] + private IDictionary _additionalData; + } #pragma warning restore 169 - [Test] - public void ExtensionDataExample() - { - string json = @"{ + [Test] + public void ExtensionDataExample() + { + string json = @"{ 'HourlyRate': 150, 'Hours': 40, 'TaxRate': 0.125 }"; - var invoice = JsonConvert.DeserializeObject(json); + var invoice = JsonConvert.DeserializeObject(json); - // increase tax to 15% - invoice.TaxRate = 0.15m; + // increase tax to 15% + invoice.TaxRate = 0.15m; - string result = JsonConvert.SerializeObject(invoice); - // { - // 'TaxRate': 0.15, - // 'HourlyRate': 150, - // 'Hours': 40 - // } + string result = JsonConvert.SerializeObject(invoice); + // { + // 'TaxRate': 0.15, + // 'HourlyRate': 150, + // 'Hours': 40 + // } - Assert.AreEqual(@"{""TaxRate"":0.15,""HourlyRate"":150,""Hours"":40}", result); - } + Assert.AreEqual(@"{""TaxRate"":0.15,""HourlyRate"":150,""Hours"":40}", result); + } - public class ExtensionDataTestClass - { - public string Name { get; set; } - [JsonProperty("custom_name")] - public string CustomName { get; set; } - [JsonIgnore] - public IList Ignored { get; set; } - public bool GetPrivate { get; internal set; } - public bool GetOnly - { - get { return true; } - } - public readonly string Readonly = "Readonly"; - public IList Ints { get; set; } - - [JsonExtensionData] - internal IDictionary ExtensionData { get; set; } - - public ExtensionDataTestClass() - { - Ints = new List { 0 }; - } - } - - public class JObjectExtensionDataTestClass - { - public string Name { get; set; } - [JsonExtensionData] - public JObject ExtensionData { get; set; } - } - - [Test] - public void RoundTripJObjectExtensionData() - { - JObjectExtensionDataTestClass c = new JObjectExtensionDataTestClass(); - c.Name = "Name!"; - c.ExtensionData = new JObject + public class ExtensionDataTestClass { - {"one",1}, - {"two","II"}, - {"three",new JArray(1,1,1)} - }; + public string Name { get; set; } - string json = JsonConvert.SerializeObject(c, Formatting.Indented); + [JsonProperty("custom_name")] + public string CustomName { get; set; } - JObjectExtensionDataTestClass c2 = JsonConvert.DeserializeObject(json); + [JsonIgnore] + public IList Ignored { get; set; } - Assert.AreEqual("Name!", c2.Name); - Assert.IsTrue(JToken.DeepEquals(c.ExtensionData, c2.ExtensionData)); - } + public bool GetPrivate { get; internal set; } - [Test] - public void JsonSerializerProperties() - { - JsonSerializer serializer = new JsonSerializer(); + public bool GetOnly + { + get { return true; } + } - DefaultSerializationBinder customBinder = new DefaultSerializationBinder(); - serializer.Binder = customBinder; - Assert.AreEqual(customBinder, serializer.Binder); + public readonly string Readonly = "Readonly"; + public IList Ints { get; set; } - serializer.CheckAdditionalContent = true; - Assert.AreEqual(true, serializer.CheckAdditionalContent); + [JsonExtensionData] + internal IDictionary ExtensionData { get; set; } - serializer.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor; - Assert.AreEqual(ConstructorHandling.AllowNonPublicDefaultConstructor, serializer.ConstructorHandling); + public ExtensionDataTestClass() + { + Ints = new List { 0 }; + } + } + + public class JObjectExtensionDataTestClass + { + public string Name { get; set; } + + [JsonExtensionData] + public JObject ExtensionData { get; set; } + } + + [Test] + public void RoundTripJObjectExtensionData() + { + JObjectExtensionDataTestClass c = new JObjectExtensionDataTestClass(); + c.Name = "Name!"; + c.ExtensionData = new JObject + { + { "one", 1 }, + { "two", "II" }, + { "three", new JArray(1, 1, 1) } + }; + + string json = JsonConvert.SerializeObject(c, Formatting.Indented); + + JObjectExtensionDataTestClass c2 = JsonConvert.DeserializeObject(json); + + Assert.AreEqual("Name!", c2.Name); + Assert.IsTrue(JToken.DeepEquals(c.ExtensionData, c2.ExtensionData)); + } + + [Test] + public void JsonSerializerProperties() + { + JsonSerializer serializer = new JsonSerializer(); + + DefaultSerializationBinder customBinder = new DefaultSerializationBinder(); + serializer.Binder = customBinder; + Assert.AreEqual(customBinder, serializer.Binder); + + serializer.CheckAdditionalContent = true; + Assert.AreEqual(true, serializer.CheckAdditionalContent); + + serializer.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor; + Assert.AreEqual(ConstructorHandling.AllowNonPublicDefaultConstructor, serializer.ConstructorHandling); #if !NETFX_CORE - serializer.Context = new StreamingContext(StreamingContextStates.Other); - Assert.AreEqual(new StreamingContext(StreamingContextStates.Other), serializer.Context); + serializer.Context = new StreamingContext(StreamingContextStates.Other); + Assert.AreEqual(new StreamingContext(StreamingContextStates.Other), serializer.Context); #endif - CamelCasePropertyNamesContractResolver resolver = new CamelCasePropertyNamesContractResolver(); - serializer.ContractResolver = resolver; - Assert.AreEqual(resolver, serializer.ContractResolver); + CamelCasePropertyNamesContractResolver resolver = new CamelCasePropertyNamesContractResolver(); + serializer.ContractResolver = resolver; + Assert.AreEqual(resolver, serializer.ContractResolver); - serializer.Converters.Add(new StringEnumConverter()); - Assert.AreEqual(1, serializer.Converters.Count); + serializer.Converters.Add(new StringEnumConverter()); + Assert.AreEqual(1, serializer.Converters.Count); - serializer.Culture = new CultureInfo("en-nz"); - Assert.AreEqual("en-NZ", serializer.Culture.ToString()); + serializer.Culture = new CultureInfo("en-nz"); + Assert.AreEqual("en-NZ", serializer.Culture.ToString()); - serializer.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat; - Assert.AreEqual(DateFormatHandling.MicrosoftDateFormat, serializer.DateFormatHandling); + serializer.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat; + Assert.AreEqual(DateFormatHandling.MicrosoftDateFormat, serializer.DateFormatHandling); - serializer.DateFormatString = "yyyy"; - Assert.AreEqual("yyyy", serializer.DateFormatString); + serializer.DateFormatString = "yyyy"; + Assert.AreEqual("yyyy", serializer.DateFormatString); - serializer.DateParseHandling = DateParseHandling.None; - Assert.AreEqual(DateParseHandling.None, serializer.DateParseHandling); + serializer.DateParseHandling = DateParseHandling.None; + Assert.AreEqual(DateParseHandling.None, serializer.DateParseHandling); - serializer.DateTimeZoneHandling = DateTimeZoneHandling.Utc; - Assert.AreEqual(DateTimeZoneHandling.Utc, serializer.DateTimeZoneHandling); + serializer.DateTimeZoneHandling = DateTimeZoneHandling.Utc; + Assert.AreEqual(DateTimeZoneHandling.Utc, serializer.DateTimeZoneHandling); - serializer.DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate; - Assert.AreEqual(DefaultValueHandling.IgnoreAndPopulate, serializer.DefaultValueHandling); + serializer.DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate; + Assert.AreEqual(DefaultValueHandling.IgnoreAndPopulate, serializer.DefaultValueHandling); - serializer.FloatFormatHandling = FloatFormatHandling.Symbol; - Assert.AreEqual(FloatFormatHandling.Symbol, serializer.FloatFormatHandling); + serializer.FloatFormatHandling = FloatFormatHandling.Symbol; + Assert.AreEqual(FloatFormatHandling.Symbol, serializer.FloatFormatHandling); - serializer.FloatParseHandling = FloatParseHandling.Decimal; - Assert.AreEqual(FloatParseHandling.Decimal, serializer.FloatParseHandling); + serializer.FloatParseHandling = FloatParseHandling.Decimal; + Assert.AreEqual(FloatParseHandling.Decimal, serializer.FloatParseHandling); - serializer.Formatting = Formatting.Indented; - Assert.AreEqual(Formatting.Indented, serializer.Formatting); + serializer.Formatting = Formatting.Indented; + Assert.AreEqual(Formatting.Indented, serializer.Formatting); - serializer.MaxDepth = 9001; - Assert.AreEqual(9001, serializer.MaxDepth); + serializer.MaxDepth = 9001; + Assert.AreEqual(9001, serializer.MaxDepth); - serializer.MissingMemberHandling = MissingMemberHandling.Error; - Assert.AreEqual(MissingMemberHandling.Error, serializer.MissingMemberHandling); + serializer.MissingMemberHandling = MissingMemberHandling.Error; + Assert.AreEqual(MissingMemberHandling.Error, serializer.MissingMemberHandling); - serializer.NullValueHandling = NullValueHandling.Ignore; - Assert.AreEqual(NullValueHandling.Ignore, serializer.NullValueHandling); + serializer.NullValueHandling = NullValueHandling.Ignore; + Assert.AreEqual(NullValueHandling.Ignore, serializer.NullValueHandling); - serializer.ObjectCreationHandling = ObjectCreationHandling.Replace; - Assert.AreEqual(ObjectCreationHandling.Replace, serializer.ObjectCreationHandling); + serializer.ObjectCreationHandling = ObjectCreationHandling.Replace; + Assert.AreEqual(ObjectCreationHandling.Replace, serializer.ObjectCreationHandling); - serializer.PreserveReferencesHandling = PreserveReferencesHandling.All; - Assert.AreEqual(PreserveReferencesHandling.All, serializer.PreserveReferencesHandling); + serializer.PreserveReferencesHandling = PreserveReferencesHandling.All; + Assert.AreEqual(PreserveReferencesHandling.All, serializer.PreserveReferencesHandling); - serializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; - Assert.AreEqual(ReferenceLoopHandling.Ignore, serializer.ReferenceLoopHandling); + serializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; + Assert.AreEqual(ReferenceLoopHandling.Ignore, serializer.ReferenceLoopHandling); - IdReferenceResolver referenceResolver = new IdReferenceResolver(); - serializer.ReferenceResolver = referenceResolver; - Assert.AreEqual(referenceResolver, serializer.ReferenceResolver); + IdReferenceResolver referenceResolver = new IdReferenceResolver(); + serializer.ReferenceResolver = referenceResolver; + Assert.AreEqual(referenceResolver, serializer.ReferenceResolver); - serializer.StringEscapeHandling = StringEscapeHandling.EscapeNonAscii; - Assert.AreEqual(StringEscapeHandling.EscapeNonAscii, serializer.StringEscapeHandling); + serializer.StringEscapeHandling = StringEscapeHandling.EscapeNonAscii; + Assert.AreEqual(StringEscapeHandling.EscapeNonAscii, serializer.StringEscapeHandling); - MemoryTraceWriter traceWriter = new MemoryTraceWriter(); - serializer.TraceWriter = traceWriter; - Assert.AreEqual(traceWriter, serializer.TraceWriter); + MemoryTraceWriter traceWriter = new MemoryTraceWriter(); + serializer.TraceWriter = traceWriter; + Assert.AreEqual(traceWriter, serializer.TraceWriter); #if !(PORTABLE || PORTABLE40 || NETFX_CORE || NET20) - serializer.TypeNameAssemblyFormat = FormatterAssemblyStyle.Full; - Assert.AreEqual(FormatterAssemblyStyle.Full, serializer.TypeNameAssemblyFormat); + serializer.TypeNameAssemblyFormat = FormatterAssemblyStyle.Full; + Assert.AreEqual(FormatterAssemblyStyle.Full, serializer.TypeNameAssemblyFormat); #endif - serializer.TypeNameHandling = TypeNameHandling.All; - Assert.AreEqual(TypeNameHandling.All, serializer.TypeNameHandling); - } + serializer.TypeNameHandling = TypeNameHandling.All; + Assert.AreEqual(TypeNameHandling.All, serializer.TypeNameHandling); + } - [Test] - public void JsonSerializerSettingsProperties() - { - JsonSerializerSettings settings = new JsonSerializerSettings(); + [Test] + public void JsonSerializerSettingsProperties() + { + JsonSerializerSettings settings = new JsonSerializerSettings(); - DefaultSerializationBinder customBinder = new DefaultSerializationBinder(); - settings.Binder = customBinder; - Assert.AreEqual(customBinder, settings.Binder); + DefaultSerializationBinder customBinder = new DefaultSerializationBinder(); + settings.Binder = customBinder; + Assert.AreEqual(customBinder, settings.Binder); - settings.CheckAdditionalContent = true; - Assert.AreEqual(true, settings.CheckAdditionalContent); + settings.CheckAdditionalContent = true; + Assert.AreEqual(true, settings.CheckAdditionalContent); - settings.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor; - Assert.AreEqual(ConstructorHandling.AllowNonPublicDefaultConstructor, settings.ConstructorHandling); + settings.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor; + Assert.AreEqual(ConstructorHandling.AllowNonPublicDefaultConstructor, settings.ConstructorHandling); #if !NETFX_CORE - settings.Context = new StreamingContext(StreamingContextStates.Other); - Assert.AreEqual(new StreamingContext(StreamingContextStates.Other), settings.Context); + settings.Context = new StreamingContext(StreamingContextStates.Other); + Assert.AreEqual(new StreamingContext(StreamingContextStates.Other), settings.Context); #endif - CamelCasePropertyNamesContractResolver resolver = new CamelCasePropertyNamesContractResolver(); - settings.ContractResolver = resolver; - Assert.AreEqual(resolver, settings.ContractResolver); + CamelCasePropertyNamesContractResolver resolver = new CamelCasePropertyNamesContractResolver(); + settings.ContractResolver = resolver; + Assert.AreEqual(resolver, settings.ContractResolver); - settings.Converters.Add(new StringEnumConverter()); - Assert.AreEqual(1, settings.Converters.Count); + settings.Converters.Add(new StringEnumConverter()); + Assert.AreEqual(1, settings.Converters.Count); - settings.Culture = new CultureInfo("en-nz"); - Assert.AreEqual("en-NZ", settings.Culture.ToString()); + settings.Culture = new CultureInfo("en-nz"); + Assert.AreEqual("en-NZ", settings.Culture.ToString()); - settings.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat; - Assert.AreEqual(DateFormatHandling.MicrosoftDateFormat, settings.DateFormatHandling); + settings.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat; + Assert.AreEqual(DateFormatHandling.MicrosoftDateFormat, settings.DateFormatHandling); - settings.DateFormatString = "yyyy"; - Assert.AreEqual("yyyy", settings.DateFormatString); + settings.DateFormatString = "yyyy"; + Assert.AreEqual("yyyy", settings.DateFormatString); - settings.DateParseHandling = DateParseHandling.None; - Assert.AreEqual(DateParseHandling.None, settings.DateParseHandling); + settings.DateParseHandling = DateParseHandling.None; + Assert.AreEqual(DateParseHandling.None, settings.DateParseHandling); - settings.DateTimeZoneHandling = DateTimeZoneHandling.Utc; - Assert.AreEqual(DateTimeZoneHandling.Utc, settings.DateTimeZoneHandling); + settings.DateTimeZoneHandling = DateTimeZoneHandling.Utc; + Assert.AreEqual(DateTimeZoneHandling.Utc, settings.DateTimeZoneHandling); - settings.DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate; - Assert.AreEqual(DefaultValueHandling.IgnoreAndPopulate, settings.DefaultValueHandling); + settings.DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate; + Assert.AreEqual(DefaultValueHandling.IgnoreAndPopulate, settings.DefaultValueHandling); - settings.FloatFormatHandling = FloatFormatHandling.Symbol; - Assert.AreEqual(FloatFormatHandling.Symbol, settings.FloatFormatHandling); + settings.FloatFormatHandling = FloatFormatHandling.Symbol; + Assert.AreEqual(FloatFormatHandling.Symbol, settings.FloatFormatHandling); - settings.FloatParseHandling = FloatParseHandling.Decimal; - Assert.AreEqual(FloatParseHandling.Decimal, settings.FloatParseHandling); + settings.FloatParseHandling = FloatParseHandling.Decimal; + Assert.AreEqual(FloatParseHandling.Decimal, settings.FloatParseHandling); - settings.Formatting = Formatting.Indented; - Assert.AreEqual(Formatting.Indented, settings.Formatting); + settings.Formatting = Formatting.Indented; + Assert.AreEqual(Formatting.Indented, settings.Formatting); - settings.MaxDepth = 9001; - Assert.AreEqual(9001, settings.MaxDepth); + settings.MaxDepth = 9001; + Assert.AreEqual(9001, settings.MaxDepth); - settings.MissingMemberHandling = MissingMemberHandling.Error; - Assert.AreEqual(MissingMemberHandling.Error, settings.MissingMemberHandling); + settings.MissingMemberHandling = MissingMemberHandling.Error; + Assert.AreEqual(MissingMemberHandling.Error, settings.MissingMemberHandling); - settings.NullValueHandling = NullValueHandling.Ignore; - Assert.AreEqual(NullValueHandling.Ignore, settings.NullValueHandling); + settings.NullValueHandling = NullValueHandling.Ignore; + Assert.AreEqual(NullValueHandling.Ignore, settings.NullValueHandling); - settings.ObjectCreationHandling = ObjectCreationHandling.Replace; - Assert.AreEqual(ObjectCreationHandling.Replace, settings.ObjectCreationHandling); + settings.ObjectCreationHandling = ObjectCreationHandling.Replace; + Assert.AreEqual(ObjectCreationHandling.Replace, settings.ObjectCreationHandling); - settings.PreserveReferencesHandling = PreserveReferencesHandling.All; - Assert.AreEqual(PreserveReferencesHandling.All, settings.PreserveReferencesHandling); + settings.PreserveReferencesHandling = PreserveReferencesHandling.All; + Assert.AreEqual(PreserveReferencesHandling.All, settings.PreserveReferencesHandling); - settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; - Assert.AreEqual(ReferenceLoopHandling.Ignore, settings.ReferenceLoopHandling); + settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; + Assert.AreEqual(ReferenceLoopHandling.Ignore, settings.ReferenceLoopHandling); - IdReferenceResolver referenceResolver = new IdReferenceResolver(); - settings.ReferenceResolver = referenceResolver; - Assert.AreEqual(referenceResolver, settings.ReferenceResolver); + IdReferenceResolver referenceResolver = new IdReferenceResolver(); + settings.ReferenceResolver = referenceResolver; + Assert.AreEqual(referenceResolver, settings.ReferenceResolver); - settings.StringEscapeHandling = StringEscapeHandling.EscapeNonAscii; - Assert.AreEqual(StringEscapeHandling.EscapeNonAscii, settings.StringEscapeHandling); + settings.StringEscapeHandling = StringEscapeHandling.EscapeNonAscii; + Assert.AreEqual(StringEscapeHandling.EscapeNonAscii, settings.StringEscapeHandling); - MemoryTraceWriter traceWriter = new MemoryTraceWriter(); - settings.TraceWriter = traceWriter; - Assert.AreEqual(traceWriter, settings.TraceWriter); + MemoryTraceWriter traceWriter = new MemoryTraceWriter(); + settings.TraceWriter = traceWriter; + Assert.AreEqual(traceWriter, settings.TraceWriter); #if !(PORTABLE || PORTABLE40 || NETFX_CORE || NET20) - settings.TypeNameAssemblyFormat = FormatterAssemblyStyle.Full; - Assert.AreEqual(FormatterAssemblyStyle.Full, settings.TypeNameAssemblyFormat); + settings.TypeNameAssemblyFormat = FormatterAssemblyStyle.Full; + Assert.AreEqual(FormatterAssemblyStyle.Full, settings.TypeNameAssemblyFormat); #endif - settings.TypeNameHandling = TypeNameHandling.All; - Assert.AreEqual(TypeNameHandling.All, settings.TypeNameHandling); - } + settings.TypeNameHandling = TypeNameHandling.All; + Assert.AreEqual(TypeNameHandling.All, settings.TypeNameHandling); + } - [Test] - public void JsonSerializerProxyProperties() - { - JsonSerializerProxy serializerProxy = new JsonSerializerProxy(new JsonSerializerInternalReader(new JsonSerializer())); + [Test] + public void JsonSerializerProxyProperties() + { + JsonSerializerProxy serializerProxy = new JsonSerializerProxy(new JsonSerializerInternalReader(new JsonSerializer())); - DefaultSerializationBinder customBinder = new DefaultSerializationBinder(); - serializerProxy.Binder = customBinder; - Assert.AreEqual(customBinder, serializerProxy.Binder); + DefaultSerializationBinder customBinder = new DefaultSerializationBinder(); + serializerProxy.Binder = customBinder; + Assert.AreEqual(customBinder, serializerProxy.Binder); - serializerProxy.CheckAdditionalContent = true; - Assert.AreEqual(true, serializerProxy.CheckAdditionalContent); + serializerProxy.CheckAdditionalContent = true; + Assert.AreEqual(true, serializerProxy.CheckAdditionalContent); - serializerProxy.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor; - Assert.AreEqual(ConstructorHandling.AllowNonPublicDefaultConstructor, serializerProxy.ConstructorHandling); + serializerProxy.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor; + Assert.AreEqual(ConstructorHandling.AllowNonPublicDefaultConstructor, serializerProxy.ConstructorHandling); #if !NETFX_CORE - serializerProxy.Context = new StreamingContext(StreamingContextStates.Other); - Assert.AreEqual(new StreamingContext(StreamingContextStates.Other), serializerProxy.Context); + serializerProxy.Context = new StreamingContext(StreamingContextStates.Other); + Assert.AreEqual(new StreamingContext(StreamingContextStates.Other), serializerProxy.Context); #endif - CamelCasePropertyNamesContractResolver resolver = new CamelCasePropertyNamesContractResolver(); - serializerProxy.ContractResolver = resolver; - Assert.AreEqual(resolver, serializerProxy.ContractResolver); + CamelCasePropertyNamesContractResolver resolver = new CamelCasePropertyNamesContractResolver(); + serializerProxy.ContractResolver = resolver; + Assert.AreEqual(resolver, serializerProxy.ContractResolver); - serializerProxy.Converters.Add(new StringEnumConverter()); - Assert.AreEqual(1, serializerProxy.Converters.Count); + serializerProxy.Converters.Add(new StringEnumConverter()); + Assert.AreEqual(1, serializerProxy.Converters.Count); - serializerProxy.Culture = new CultureInfo("en-nz"); - Assert.AreEqual("en-NZ", serializerProxy.Culture.ToString()); + serializerProxy.Culture = new CultureInfo("en-nz"); + Assert.AreEqual("en-NZ", serializerProxy.Culture.ToString()); - serializerProxy.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat; - Assert.AreEqual(DateFormatHandling.MicrosoftDateFormat, serializerProxy.DateFormatHandling); + serializerProxy.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat; + Assert.AreEqual(DateFormatHandling.MicrosoftDateFormat, serializerProxy.DateFormatHandling); - serializerProxy.DateFormatString = "yyyy"; - Assert.AreEqual("yyyy", serializerProxy.DateFormatString); + serializerProxy.DateFormatString = "yyyy"; + Assert.AreEqual("yyyy", serializerProxy.DateFormatString); - serializerProxy.DateParseHandling = DateParseHandling.None; - Assert.AreEqual(DateParseHandling.None, serializerProxy.DateParseHandling); + serializerProxy.DateParseHandling = DateParseHandling.None; + Assert.AreEqual(DateParseHandling.None, serializerProxy.DateParseHandling); - serializerProxy.DateTimeZoneHandling = DateTimeZoneHandling.Utc; - Assert.AreEqual(DateTimeZoneHandling.Utc, serializerProxy.DateTimeZoneHandling); + serializerProxy.DateTimeZoneHandling = DateTimeZoneHandling.Utc; + Assert.AreEqual(DateTimeZoneHandling.Utc, serializerProxy.DateTimeZoneHandling); - serializerProxy.DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate; - Assert.AreEqual(DefaultValueHandling.IgnoreAndPopulate, serializerProxy.DefaultValueHandling); + serializerProxy.DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate; + Assert.AreEqual(DefaultValueHandling.IgnoreAndPopulate, serializerProxy.DefaultValueHandling); - serializerProxy.FloatFormatHandling = FloatFormatHandling.Symbol; - Assert.AreEqual(FloatFormatHandling.Symbol, serializerProxy.FloatFormatHandling); + serializerProxy.FloatFormatHandling = FloatFormatHandling.Symbol; + Assert.AreEqual(FloatFormatHandling.Symbol, serializerProxy.FloatFormatHandling); - serializerProxy.FloatParseHandling = FloatParseHandling.Decimal; - Assert.AreEqual(FloatParseHandling.Decimal, serializerProxy.FloatParseHandling); + serializerProxy.FloatParseHandling = FloatParseHandling.Decimal; + Assert.AreEqual(FloatParseHandling.Decimal, serializerProxy.FloatParseHandling); - serializerProxy.Formatting = Formatting.Indented; - Assert.AreEqual(Formatting.Indented, serializerProxy.Formatting); + serializerProxy.Formatting = Formatting.Indented; + Assert.AreEqual(Formatting.Indented, serializerProxy.Formatting); - serializerProxy.MaxDepth = 9001; - Assert.AreEqual(9001, serializerProxy.MaxDepth); + serializerProxy.MaxDepth = 9001; + Assert.AreEqual(9001, serializerProxy.MaxDepth); - serializerProxy.MissingMemberHandling = MissingMemberHandling.Error; - Assert.AreEqual(MissingMemberHandling.Error, serializerProxy.MissingMemberHandling); + serializerProxy.MissingMemberHandling = MissingMemberHandling.Error; + Assert.AreEqual(MissingMemberHandling.Error, serializerProxy.MissingMemberHandling); - serializerProxy.NullValueHandling = NullValueHandling.Ignore; - Assert.AreEqual(NullValueHandling.Ignore, serializerProxy.NullValueHandling); + serializerProxy.NullValueHandling = NullValueHandling.Ignore; + Assert.AreEqual(NullValueHandling.Ignore, serializerProxy.NullValueHandling); - serializerProxy.ObjectCreationHandling = ObjectCreationHandling.Replace; - Assert.AreEqual(ObjectCreationHandling.Replace, serializerProxy.ObjectCreationHandling); + serializerProxy.ObjectCreationHandling = ObjectCreationHandling.Replace; + Assert.AreEqual(ObjectCreationHandling.Replace, serializerProxy.ObjectCreationHandling); - serializerProxy.PreserveReferencesHandling = PreserveReferencesHandling.All; - Assert.AreEqual(PreserveReferencesHandling.All, serializerProxy.PreserveReferencesHandling); + serializerProxy.PreserveReferencesHandling = PreserveReferencesHandling.All; + Assert.AreEqual(PreserveReferencesHandling.All, serializerProxy.PreserveReferencesHandling); - serializerProxy.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; - Assert.AreEqual(ReferenceLoopHandling.Ignore, serializerProxy.ReferenceLoopHandling); + serializerProxy.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; + Assert.AreEqual(ReferenceLoopHandling.Ignore, serializerProxy.ReferenceLoopHandling); - IdReferenceResolver referenceResolver = new IdReferenceResolver(); - serializerProxy.ReferenceResolver = referenceResolver; - Assert.AreEqual(referenceResolver, serializerProxy.ReferenceResolver); + IdReferenceResolver referenceResolver = new IdReferenceResolver(); + serializerProxy.ReferenceResolver = referenceResolver; + Assert.AreEqual(referenceResolver, serializerProxy.ReferenceResolver); - serializerProxy.StringEscapeHandling = StringEscapeHandling.EscapeNonAscii; - Assert.AreEqual(StringEscapeHandling.EscapeNonAscii, serializerProxy.StringEscapeHandling); + serializerProxy.StringEscapeHandling = StringEscapeHandling.EscapeNonAscii; + Assert.AreEqual(StringEscapeHandling.EscapeNonAscii, serializerProxy.StringEscapeHandling); - MemoryTraceWriter traceWriter = new MemoryTraceWriter(); - serializerProxy.TraceWriter = traceWriter; - Assert.AreEqual(traceWriter, serializerProxy.TraceWriter); + MemoryTraceWriter traceWriter = new MemoryTraceWriter(); + serializerProxy.TraceWriter = traceWriter; + Assert.AreEqual(traceWriter, serializerProxy.TraceWriter); #if !(PORTABLE || PORTABLE40 || NETFX_CORE || NET20) - serializerProxy.TypeNameAssemblyFormat = FormatterAssemblyStyle.Full; - Assert.AreEqual(FormatterAssemblyStyle.Full, serializerProxy.TypeNameAssemblyFormat); + serializerProxy.TypeNameAssemblyFormat = FormatterAssemblyStyle.Full; + Assert.AreEqual(FormatterAssemblyStyle.Full, serializerProxy.TypeNameAssemblyFormat); #endif - serializerProxy.TypeNameHandling = TypeNameHandling.All; - Assert.AreEqual(TypeNameHandling.All, serializerProxy.TypeNameHandling); - } + serializerProxy.TypeNameHandling = TypeNameHandling.All; + Assert.AreEqual(TypeNameHandling.All, serializerProxy.TypeNameHandling); + } #if !(NETFX_CORE || PORTABLE || PORTABLE40) - [Test] - public void DeserializeISerializableIConvertible() - { - Ratio ratio = new Ratio(2, 1); - string json = JsonConvert.SerializeObject(ratio); + [Test] + public void DeserializeISerializableIConvertible() + { + Ratio ratio = new Ratio(2, 1); + string json = JsonConvert.SerializeObject(ratio); - Assert.AreEqual(@"{""n"":2,""d"":1}", json); + Assert.AreEqual(@"{""n"":2,""d"":1}", json); - Ratio ratio2 = JsonConvert.DeserializeObject(json); + Ratio ratio2 = JsonConvert.DeserializeObject(json); - Assert.AreEqual(ratio.Denominator, ratio2.Denominator); - Assert.AreEqual(ratio.Numerator, ratio2.Numerator); - } + Assert.AreEqual(ratio.Denominator, ratio2.Denominator); + Assert.AreEqual(ratio.Numerator, ratio2.Numerator); + } #endif - [Test] - public void DeserializeLargeFloat() - { - object o = JsonConvert.DeserializeObject("100000000000000000000000000000000000000.0"); + [Test] + public void DeserializeLargeFloat() + { + object o = JsonConvert.DeserializeObject("100000000000000000000000000000000000000.0"); - CustomAssert.IsInstanceOfType(typeof(double), o); + CustomAssert.IsInstanceOfType(typeof(double), o); - Assert.IsTrue(MathUtils.ApproxEquals(1E+38, (double)o)); - } + Assert.IsTrue(MathUtils.ApproxEquals(1E+38, (double)o)); + } - [Test] - public void SerializeDeserializeRegex() - { - Regex regex = new Regex("(hi)", RegexOptions.CultureInvariant); + [Test] + public void SerializeDeserializeRegex() + { + Regex regex = new Regex("(hi)", RegexOptions.CultureInvariant); - string json = JsonConvert.SerializeObject(regex, Formatting.Indented); + string json = JsonConvert.SerializeObject(regex, Formatting.Indented); - Regex r2 = JsonConvert.DeserializeObject(json); + Regex r2 = JsonConvert.DeserializeObject(json); - Assert.AreEqual("(hi)", r2.ToString()); - Assert.AreEqual(RegexOptions.CultureInvariant, r2.Options); - } + Assert.AreEqual("(hi)", r2.ToString()); + Assert.AreEqual(RegexOptions.CultureInvariant, r2.Options); + } - [Test] - public void ExtensionDataTest() - { - string json = @"{ + [Test] + public void ExtensionDataTest() + { + string json = @"{ ""Ints"": [1,2,3], ""Ignored"": [1,2,3], ""Readonly"": ""Readonly"", @@ -552,152 +557,158 @@ namespace Newtonsoft.Json.Tests.Serialization ""NewValueComplex"": [1,2,3] }"; - ExtensionDataTestClass c = JsonConvert.DeserializeObject(json); + ExtensionDataTestClass c = JsonConvert.DeserializeObject(json); - Assert.AreEqual("Actually set!", c.Name); - Assert.AreEqual(4, c.Ints.Count); - - Assert.AreEqual("Readonly", (string)c.ExtensionData["Readonly"]); - Assert.AreEqual("Wrong name!", (string)c.ExtensionData["CustomName"]); - Assert.AreEqual(true, (bool)c.ExtensionData["GetPrivate"]); - Assert.AreEqual(true, (bool)c.ExtensionData["GetOnly"]); - Assert.AreEqual(true, (bool)c.ExtensionData["NewValueSimple"]); - Assert.IsTrue(JToken.DeepEquals(new JArray(1, 2, 3), c.ExtensionData["NewValueComplex"])); - Assert.IsTrue(JToken.DeepEquals(new JArray(1, 2, 3), c.ExtensionData["Ignored"])); + Assert.AreEqual("Actually set!", c.Name); + Assert.AreEqual(4, c.Ints.Count); - Assert.AreEqual(7, c.ExtensionData.Count); - } + Assert.AreEqual("Readonly", (string)c.ExtensionData["Readonly"]); + Assert.AreEqual("Wrong name!", (string)c.ExtensionData["CustomName"]); + Assert.AreEqual(true, (bool)c.ExtensionData["GetPrivate"]); + Assert.AreEqual(true, (bool)c.ExtensionData["GetOnly"]); + Assert.AreEqual(true, (bool)c.ExtensionData["NewValueSimple"]); + Assert.IsTrue(JToken.DeepEquals(new JArray(1, 2, 3), c.ExtensionData["NewValueComplex"])); + Assert.IsTrue(JToken.DeepEquals(new JArray(1, 2, 3), c.ExtensionData["Ignored"])); - public class MultipleExtensionDataAttributesTestClass - { - public string Name { get; set; } - [JsonExtensionData] - internal IDictionary ExtensionData1 { get; set; } - [JsonExtensionData] - internal IDictionary ExtensionData2 { get; set; } - } + Assert.AreEqual(7, c.ExtensionData.Count); + } - public class ExtensionDataAttributesInheritanceTestClass : MultipleExtensionDataAttributesTestClass - { - [JsonExtensionData] - internal IDictionary ExtensionData0 { get; set; } - } - - public class FieldExtensionDataAttributeTestClass - { - [JsonExtensionData] - internal IDictionary ExtensionData; - } - - public class PublicExtensionDataAttributeTestClass - { - public string Name { get; set; } - [JsonExtensionData] - public IDictionary ExtensionData; - } - - public class PublicNoReadExtensionDataAttributeTestClass - { - public string Name { get; set; } - [JsonExtensionData(ReadData = false)] - public IDictionary ExtensionData; - } - - public class PublicNoWriteExtensionDataAttributeTestClass - { - public string Name { get; set; } - [JsonExtensionData(WriteData = false)] - public IDictionary ExtensionData; - } - - public class PublicJTokenExtensionDataAttributeTestClass - { - public string Name { get; set; } - [JsonExtensionData] - public IDictionary ExtensionData; - } - - [Test] - public void DeserializeDirectoryAccount() - { - string json = @"{'DisplayName':'John Smith', 'SAMAccountName':'contoso\\johns'}"; - - DirectoryAccount account = JsonConvert.DeserializeObject(json); - - Assert.AreEqual("John Smith", account.DisplayName); - Assert.AreEqual("contoso", account.Domain); - Assert.AreEqual("johns", account.UserName); - } - - [Test] - public void SerializePublicExtensionData() - { - string json = JsonConvert.SerializeObject(new PublicExtensionDataAttributeTestClass + public class MultipleExtensionDataAttributesTestClass { - Name = "Name!", - ExtensionData = new Dictionary - { - { "Test", 1 } - } - }); + public string Name { get; set; } - Assert.AreEqual(@"{""Name"":""Name!"",""Test"":1}", json); - } + [JsonExtensionData] + internal IDictionary ExtensionData1 { get; set; } - [Test] - public void SerializePublicExtensionDataNull() - { - string json = JsonConvert.SerializeObject(new PublicExtensionDataAttributeTestClass - { - Name = "Name!" - }); + [JsonExtensionData] + internal IDictionary ExtensionData2 { get; set; } + } - Assert.AreEqual(@"{""Name"":""Name!""}", json); - } - - [Test] - public void SerializePublicNoWriteExtensionData() - { - string json = JsonConvert.SerializeObject(new PublicNoWriteExtensionDataAttributeTestClass - { - Name = "Name!", - ExtensionData = new Dictionary - { - { "Test", 1 } - } - }); - - Assert.AreEqual(@"{""Name"":""Name!""}", json); - } - - [Test] - public void DeserializeNoReadPublicExtensionData() - { - PublicNoReadExtensionDataAttributeTestClass c = JsonConvert.DeserializeObject(@"{""Name"":""Name!"",""Test"":1}"); - - Assert.AreEqual(null, c.ExtensionData); - } - - [Test] - public void SerializePublicExtensionDataCircularReference() - { - var c = new PublicExtensionDataAttributeTestClass + public class ExtensionDataAttributesInheritanceTestClass : MultipleExtensionDataAttributesTestClass { - Name = "Name!", - ExtensionData = new Dictionary - { - { "Test", 1 } - } - }; - c.ExtensionData["Self"] = c; + [JsonExtensionData] + internal IDictionary ExtensionData0 { get; set; } + } - string json = JsonConvert.SerializeObject(c, new JsonSerializerSettings + public class FieldExtensionDataAttributeTestClass { - PreserveReferencesHandling = PreserveReferencesHandling.All, - Formatting = Formatting.Indented - }); + [JsonExtensionData] + internal IDictionary ExtensionData; + } - Assert.AreEqual(@"{ + public class PublicExtensionDataAttributeTestClass + { + public string Name { get; set; } + + [JsonExtensionData] + public IDictionary ExtensionData; + } + + public class PublicNoReadExtensionDataAttributeTestClass + { + public string Name { get; set; } + + [JsonExtensionData(ReadData = false)] + public IDictionary ExtensionData; + } + + public class PublicNoWriteExtensionDataAttributeTestClass + { + public string Name { get; set; } + + [JsonExtensionData(WriteData = false)] + public IDictionary ExtensionData; + } + + public class PublicJTokenExtensionDataAttributeTestClass + { + public string Name { get; set; } + + [JsonExtensionData] + public IDictionary ExtensionData; + } + + [Test] + public void DeserializeDirectoryAccount() + { + string json = @"{'DisplayName':'John Smith', 'SAMAccountName':'contoso\\johns'}"; + + DirectoryAccount account = JsonConvert.DeserializeObject(json); + + Assert.AreEqual("John Smith", account.DisplayName); + Assert.AreEqual("contoso", account.Domain); + Assert.AreEqual("johns", account.UserName); + } + + [Test] + public void SerializePublicExtensionData() + { + string json = JsonConvert.SerializeObject(new PublicExtensionDataAttributeTestClass + { + Name = "Name!", + ExtensionData = new Dictionary + { + { "Test", 1 } + } + }); + + Assert.AreEqual(@"{""Name"":""Name!"",""Test"":1}", json); + } + + [Test] + public void SerializePublicExtensionDataNull() + { + string json = JsonConvert.SerializeObject(new PublicExtensionDataAttributeTestClass + { + Name = "Name!" + }); + + Assert.AreEqual(@"{""Name"":""Name!""}", json); + } + + [Test] + public void SerializePublicNoWriteExtensionData() + { + string json = JsonConvert.SerializeObject(new PublicNoWriteExtensionDataAttributeTestClass + { + Name = "Name!", + ExtensionData = new Dictionary + { + { "Test", 1 } + } + }); + + Assert.AreEqual(@"{""Name"":""Name!""}", json); + } + + [Test] + public void DeserializeNoReadPublicExtensionData() + { + PublicNoReadExtensionDataAttributeTestClass c = JsonConvert.DeserializeObject(@"{""Name"":""Name!"",""Test"":1}"); + + Assert.AreEqual(null, c.ExtensionData); + } + + [Test] + public void SerializePublicExtensionDataCircularReference() + { + var c = new PublicExtensionDataAttributeTestClass + { + Name = "Name!", + ExtensionData = new Dictionary + { + { "Test", 1 } + } + }; + c.ExtensionData["Self"] = c; + + string json = JsonConvert.SerializeObject(c, new JsonSerializerSettings + { + PreserveReferencesHandling = PreserveReferencesHandling.All, + Formatting = Formatting.Indented + }); + + Assert.AreEqual(@"{ ""$id"": ""1"", ""Name"": ""Name!"", ""Test"": 1, @@ -706,23 +717,23 @@ namespace Newtonsoft.Json.Tests.Serialization } }", json); - var c2 = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + var c2 = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + PreserveReferencesHandling = PreserveReferencesHandling.All + }); + + Assert.AreEqual("Name!", c2.Name); + + PublicExtensionDataAttributeTestClass bizzaroC2 = (PublicExtensionDataAttributeTestClass)c2.ExtensionData["Self"]; + + Assert.AreEqual(c2, bizzaroC2); + Assert.AreEqual(1, (long)bizzaroC2.ExtensionData["Test"]); + } + + [Test] + public void DeserializePublicJTokenExtensionDataCircularReference() { - PreserveReferencesHandling = PreserveReferencesHandling.All - }); - - Assert.AreEqual("Name!", c2.Name); - - PublicExtensionDataAttributeTestClass bizzaroC2 = (PublicExtensionDataAttributeTestClass)c2.ExtensionData["Self"]; - - Assert.AreEqual(c2, bizzaroC2); - Assert.AreEqual(1, (long)bizzaroC2.ExtensionData["Test"]); - } - - [Test] - public void DeserializePublicJTokenExtensionDataCircularReference() - { - string json = @"{ + string json = @"{ ""$id"": ""1"", ""Name"": ""Name!"", ""Test"": 1, @@ -731,25 +742,25 @@ namespace Newtonsoft.Json.Tests.Serialization } }"; - var c2 = JsonConvert.DeserializeObject(json, new JsonSerializerSettings - { - PreserveReferencesHandling = PreserveReferencesHandling.All - }); + var c2 = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + PreserveReferencesHandling = PreserveReferencesHandling.All + }); - Assert.AreEqual("Name!", c2.Name); + Assert.AreEqual("Name!", c2.Name); - JObject bizzaroC2 = (JObject)c2.ExtensionData["Self"]; + JObject bizzaroC2 = (JObject)c2.ExtensionData["Self"]; - Assert.AreEqual("Name!", (string)bizzaroC2["Name"]); - Assert.AreEqual(1, (int)bizzaroC2["Test"]); + Assert.AreEqual("Name!", (string)bizzaroC2["Name"]); + Assert.AreEqual(1, (int)bizzaroC2["Test"]); - Assert.AreEqual(1, (int)c2.ExtensionData["Test"]); - } + Assert.AreEqual(1, (int)c2.ExtensionData["Test"]); + } - [Test] - public void DeserializePublicExtensionDataTypeNamdHandling() - { - string json = @"{ + [Test] + public void DeserializePublicExtensionDataTypeNamdHandling() + { + string json = @"{ ""$id"": ""1"", ""Name"": ""Name!"", ""Test"": 1, @@ -762,42 +773,42 @@ namespace Newtonsoft.Json.Tests.Serialization } }"; - PublicExtensionDataAttributeTestClass c2 = JsonConvert.DeserializeObject(json, new JsonSerializerSettings - { - TypeNameHandling = TypeNameHandling.Objects - }); - - Assert.AreEqual("Name!", c2.Name); - - WagePerson bizzaroC2 = (WagePerson)c2.ExtensionData["Self"]; - - Assert.AreEqual(2m, bizzaroC2.HourlyWage); - } - - [Test] - public void SerializePublicExtensionDataTypeNamdHandling() - { - PublicExtensionDataAttributeTestClass c = new PublicExtensionDataAttributeTestClass - { - Name = "Name!", - ExtensionData = new Dictionary + PublicExtensionDataAttributeTestClass c2 = JsonConvert.DeserializeObject(json, new JsonSerializerSettings { - { - "Test", new WagePerson - { - HourlyWage = 2.1m - } - } - } - }; + TypeNameHandling = TypeNameHandling.Objects + }); - string json = JsonConvert.SerializeObject(c, new JsonSerializerSettings + Assert.AreEqual("Name!", c2.Name); + + WagePerson bizzaroC2 = (WagePerson)c2.ExtensionData["Self"]; + + Assert.AreEqual(2m, bizzaroC2.HourlyWage); + } + + [Test] + public void SerializePublicExtensionDataTypeNamdHandling() { - TypeNameHandling = TypeNameHandling.Objects, - Formatting = Formatting.Indented - }); + PublicExtensionDataAttributeTestClass c = new PublicExtensionDataAttributeTestClass + { + Name = "Name!", + ExtensionData = new Dictionary + { + { + "Test", new WagePerson + { + HourlyWage = 2.1m + } + } + } + }; - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(c, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Objects, + Formatting = Formatting.Indented + }); + + Assert.AreEqual(@"{ ""$type"": ""Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+PublicExtensionDataAttributeTestClass, Newtonsoft.Json.Tests"", ""Name"": ""Name!"", ""Test"": { @@ -808,223 +819,237 @@ namespace Newtonsoft.Json.Tests.Serialization ""LastModified"": ""0001-01-01T00:00:00"" } }", json); - } + } - [Test] - public void DeserializePublicExtensionData() - { - string json = @"{ + [Test] + public void DeserializePublicExtensionData() + { + string json = @"{ 'Name':'Name!', 'NoMatch':'NoMatch!', 'ExtensionData':{'HAI':true} }"; - var c = JsonConvert.DeserializeObject(json); + var c = JsonConvert.DeserializeObject(json); - Assert.AreEqual("Name!", c.Name); - Assert.AreEqual(2, c.ExtensionData.Count); + Assert.AreEqual("Name!", c.Name); + Assert.AreEqual(2, c.ExtensionData.Count); - Assert.AreEqual("NoMatch!", (string)c.ExtensionData["NoMatch"]); + Assert.AreEqual("NoMatch!", (string)c.ExtensionData["NoMatch"]); - // the ExtensionData property is put into the extension data - // inception - var o = (JObject)c.ExtensionData["ExtensionData"]; - Assert.AreEqual(1, o.Count); - Assert.IsTrue(JToken.DeepEquals(new JObject { { "HAI", true } }, o)); - } + // the ExtensionData property is put into the extension data + // inception + var o = (JObject)c.ExtensionData["ExtensionData"]; + Assert.AreEqual(1, o.Count); + Assert.IsTrue(JToken.DeepEquals(new JObject { { "HAI", true } }, o)); + } - [Test] - public void FieldExtensionDataAttributeTest_Serialize() - { - FieldExtensionDataAttributeTestClass c = new FieldExtensionDataAttributeTestClass + [Test] + public void FieldExtensionDataAttributeTest_Serialize() { - ExtensionData = new Dictionary() - }; + FieldExtensionDataAttributeTestClass c = new FieldExtensionDataAttributeTestClass + { + ExtensionData = new Dictionary() + }; - string json = JsonConvert.SerializeObject(c); + string json = JsonConvert.SerializeObject(c); - Assert.AreEqual("{}", json); - } + Assert.AreEqual("{}", json); + } - [Test] - public void FieldExtensionDataAttributeTest_Deserialize() - { - var c = JsonConvert.DeserializeObject("{'first':1,'second':2}"); + [Test] + public void FieldExtensionDataAttributeTest_Deserialize() + { + var c = JsonConvert.DeserializeObject("{'first':1,'second':2}"); - Assert.AreEqual(2, c.ExtensionData.Count); - Assert.AreEqual(1, (long)c.ExtensionData["first"]); - Assert.AreEqual(2, (long)c.ExtensionData["second"]); - } + Assert.AreEqual(2, c.ExtensionData.Count); + Assert.AreEqual(1, (long)c.ExtensionData["first"]); + Assert.AreEqual(2, (long)c.ExtensionData["second"]); + } - [Test] - public void MultipleExtensionDataAttributesTest() - { - var c = JsonConvert.DeserializeObject("{'first':[1],'second':[2]}"); + [Test] + public void MultipleExtensionDataAttributesTest() + { + var c = JsonConvert.DeserializeObject("{'first':[1],'second':[2]}"); - Assert.AreEqual(null, c.ExtensionData1); - Assert.AreEqual(2, c.ExtensionData2.Count); - Assert.AreEqual(1, (int)((JArray)c.ExtensionData2["first"])[0]); - Assert.AreEqual(2, (int)((JArray)c.ExtensionData2["second"])[0]); - } + Assert.AreEqual(null, c.ExtensionData1); + Assert.AreEqual(2, c.ExtensionData2.Count); + Assert.AreEqual(1, (int)((JArray)c.ExtensionData2["first"])[0]); + Assert.AreEqual(2, (int)((JArray)c.ExtensionData2["second"])[0]); + } - [Test] - public void ExtensionDataAttributesInheritanceTest() - { - var c = JsonConvert.DeserializeObject("{'first':1,'second':2}"); + [Test] + public void ExtensionDataAttributesInheritanceTest() + { + var c = JsonConvert.DeserializeObject("{'first':1,'second':2}"); - Assert.AreEqual(null, c.ExtensionData1); - Assert.AreEqual(null, c.ExtensionData2); - Assert.AreEqual(2, c.ExtensionData0.Count); - Assert.AreEqual(1, (int)c.ExtensionData0["first"]); - Assert.AreEqual(2, (int)c.ExtensionData0["second"]); - } + Assert.AreEqual(null, c.ExtensionData1); + Assert.AreEqual(null, c.ExtensionData2); + Assert.AreEqual(2, c.ExtensionData0.Count); + Assert.AreEqual(1, (int)c.ExtensionData0["first"]); + Assert.AreEqual(2, (int)c.ExtensionData0["second"]); + } - [Test] - public void GenericCollectionInheritance() - { - string json; + [Test] + public void GenericCollectionInheritance() + { + string json; - GenericClass, string> foo1 = new GenericClass, string>(); - foo1.Items.Add(new GenericItem {Value = "Hello"}); + GenericClass, string> foo1 = new GenericClass, string>(); + foo1.Items.Add(new GenericItem { Value = "Hello" }); - json = JsonConvert.SerializeObject(new {selectList = foo1}); - Assert.AreEqual(@"{""selectList"":[{""Value"":""Hello""}]}", json); + json = JsonConvert.SerializeObject(new { selectList = foo1 }); + Assert.AreEqual(@"{""selectList"":[{""Value"":""Hello""}]}", json); - GenericClass foo2 = new GenericClass(); - foo2.Items.Add(new NonGenericItem {Value = "Hello"}); + GenericClass foo2 = new GenericClass(); + foo2.Items.Add(new NonGenericItem { Value = "Hello" }); - json = JsonConvert.SerializeObject(new { selectList = foo2 }); - Assert.AreEqual(@"{""selectList"":[{""Value"":""Hello""}]}", json); + json = JsonConvert.SerializeObject(new { selectList = foo2 }); + Assert.AreEqual(@"{""selectList"":[{""Value"":""Hello""}]}", json); - NonGenericClass foo3 = new NonGenericClass(); - foo3.Items.Add(new NonGenericItem {Value = "Hello"}); + NonGenericClass foo3 = new NonGenericClass(); + foo3.Items.Add(new NonGenericItem { Value = "Hello" }); - json = JsonConvert.SerializeObject(new { selectList = foo3 }); - Assert.AreEqual(@"{""selectList"":[{""Value"":""Hello""}]}", json); - } + json = JsonConvert.SerializeObject(new { selectList = foo3 }); + Assert.AreEqual(@"{""selectList"":[{""Value"":""Hello""}]}", json); + } #if !NET20 - [DataContract] - public class BaseDataContractWithHidden - { - [DataMember(Name = "virtualMember")] - public virtual string VirtualMember { get; set; } + [DataContract] + public class BaseDataContractWithHidden + { + [DataMember(Name = "virtualMember")] + public virtual string VirtualMember { get; set; } - [DataMember(Name = "nonVirtualMember")] - public string NonVirtualMember { get; set; } + [DataMember(Name = "nonVirtualMember")] + public string NonVirtualMember { get; set; } - public virtual object NewMember { get; set; } - } + public virtual object NewMember { get; set; } + } - public class ChildDataContractWithHidden : BaseDataContractWithHidden - { - [DataMember(Name = "NewMember")] - public virtual new string NewMember { get; set; } - public override string VirtualMember { get; set; } - public string AddedMember { get; set; } - } + public class ChildDataContractWithHidden : BaseDataContractWithHidden + { + [DataMember(Name = "NewMember")] + public new virtual string NewMember { get; set; } - [Test] - public void ChildDataContractTestWithHidden() - { - var cc = new ChildDataContractWithHidden - { - VirtualMember = "VirtualMember!", - NonVirtualMember = "NonVirtualMember!", - NewMember = "NewMember!" - }; + public override string VirtualMember { get; set; } + public string AddedMember { get; set; } + } - string result = JsonConvert.SerializeObject(cc); - Assert.AreEqual(@"{""NewMember"":""NewMember!"",""virtualMember"":""VirtualMember!"",""nonVirtualMember"":""NonVirtualMember!""}", result); - } + [Test] + public void ChildDataContractTestWithHidden() + { + var cc = new ChildDataContractWithHidden + { + VirtualMember = "VirtualMember!", + NonVirtualMember = "NonVirtualMember!", + NewMember = "NewMember!" + }; - // ignore hiding members compiler warning + string result = JsonConvert.SerializeObject(cc); + Assert.AreEqual(@"{""NewMember"":""NewMember!"",""virtualMember"":""VirtualMember!"",""nonVirtualMember"":""NonVirtualMember!""}", result); + } + + // ignore hiding members compiler warning #pragma warning disable 108,114 - [DataContract] - public class BaseWithContract - { - [DataMember(Name = "VirtualWithDataMemberBase")] - public virtual string VirtualWithDataMember { get; set; } - [DataMember] - public virtual string Virtual { get; set; } - [DataMember(Name = "WithDataMemberBase")] - public string WithDataMember { get; set; } - [DataMember] - public string JustAProperty { get; set; } - } + [DataContract] + public class BaseWithContract + { + [DataMember(Name = "VirtualWithDataMemberBase")] + public virtual string VirtualWithDataMember { get; set; } - [DataContract] - public class BaseWithoutContract - { - [DataMember(Name = "VirtualWithDataMemberBase")] - public virtual string VirtualWithDataMember { get; set; } - [DataMember] - public virtual string Virtual { get; set; } - [DataMember(Name = "WithDataMemberBase")] - public string WithDataMember { get; set; } - [DataMember] - public string JustAProperty { get; set; } - } + [DataMember] + public virtual string Virtual { get; set; } - [DataContract] - public class SubWithoutContractNewProperties : BaseWithContract - { - [DataMember(Name = "VirtualWithDataMemberSub")] - public string VirtualWithDataMember { get; set; } - public string Virtual { get; set; } - [DataMember(Name = "WithDataMemberSub")] - public string WithDataMember { get; set; } - public string JustAProperty { get; set; } - } + [DataMember(Name = "WithDataMemberBase")] + public string WithDataMember { get; set; } - [DataContract] - public class SubWithoutContractVirtualProperties : BaseWithContract - { - public override string VirtualWithDataMember { get; set; } - [DataMember(Name = "VirtualSub")] - public override string Virtual { get; set; } - } + [DataMember] + public string JustAProperty { get; set; } + } - [DataContract] - public class SubWithContractNewProperties : BaseWithContract - { - [DataMember(Name = "VirtualWithDataMemberSub")] - public string VirtualWithDataMember { get; set; } - [DataMember(Name = "Virtual2")] - public string Virtual { get; set; } - [DataMember(Name = "WithDataMemberSub")] - public string WithDataMember { get; set; } - [DataMember(Name = "JustAProperty2")] - public string JustAProperty { get; set; } - } + [DataContract] + public class BaseWithoutContract + { + [DataMember(Name = "VirtualWithDataMemberBase")] + public virtual string VirtualWithDataMember { get; set; } - [DataContract] - public class SubWithContractVirtualProperties : BaseWithContract - { - [DataMember(Name = "VirtualWithDataMemberSub")] - public virtual string VirtualWithDataMember { get; set; } - } + [DataMember] + public virtual string Virtual { get; set; } + + [DataMember(Name = "WithDataMemberBase")] + public string WithDataMember { get; set; } + + [DataMember] + public string JustAProperty { get; set; } + } + + [DataContract] + public class SubWithoutContractNewProperties : BaseWithContract + { + [DataMember(Name = "VirtualWithDataMemberSub")] + public string VirtualWithDataMember { get; set; } + + public string Virtual { get; set; } + + [DataMember(Name = "WithDataMemberSub")] + public string WithDataMember { get; set; } + + public string JustAProperty { get; set; } + } + + [DataContract] + public class SubWithoutContractVirtualProperties : BaseWithContract + { + public override string VirtualWithDataMember { get; set; } + + [DataMember(Name = "VirtualSub")] + public override string Virtual { get; set; } + } + + [DataContract] + public class SubWithContractNewProperties : BaseWithContract + { + [DataMember(Name = "VirtualWithDataMemberSub")] + public string VirtualWithDataMember { get; set; } + + [DataMember(Name = "Virtual2")] + public string Virtual { get; set; } + + [DataMember(Name = "WithDataMemberSub")] + public string WithDataMember { get; set; } + + [DataMember(Name = "JustAProperty2")] + public string JustAProperty { get; set; } + } + + [DataContract] + public class SubWithContractVirtualProperties : BaseWithContract + { + [DataMember(Name = "VirtualWithDataMemberSub")] + public virtual string VirtualWithDataMember { get; set; } + } #pragma warning restore 108,114 - [Test] - public void SubWithoutContractNewPropertiesTest() - { - BaseWithContract baseWith = new SubWithoutContractNewProperties + [Test] + public void SubWithoutContractNewPropertiesTest() { - JustAProperty = "JustAProperty!", - Virtual = "Virtual!", - VirtualWithDataMember = "VirtualWithDataMember!", - WithDataMember = "WithDataMember!" - }; + BaseWithContract baseWith = new SubWithoutContractNewProperties + { + JustAProperty = "JustAProperty!", + Virtual = "Virtual!", + VirtualWithDataMember = "VirtualWithDataMember!", + WithDataMember = "WithDataMember!" + }; - baseWith.JustAProperty = "JustAProperty2!"; - baseWith.Virtual = "Virtual2!"; - baseWith.VirtualWithDataMember = "VirtualWithDataMember2!"; - baseWith.WithDataMember = "WithDataMember2!"; + baseWith.JustAProperty = "JustAProperty2!"; + baseWith.Virtual = "Virtual2!"; + baseWith.VirtualWithDataMember = "VirtualWithDataMember2!"; + baseWith.WithDataMember = "WithDataMember2!"; - string json = AssertSerializeDeserializeEqual(baseWith); + string json = AssertSerializeDeserializeEqual(baseWith); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""JustAProperty"": ""JustAProperty2!"", ""Virtual"": ""Virtual2!"", ""VirtualWithDataMemberBase"": ""VirtualWithDataMember2!"", @@ -1032,55 +1057,55 @@ namespace Newtonsoft.Json.Tests.Serialization ""WithDataMemberBase"": ""WithDataMember2!"", ""WithDataMemberSub"": ""WithDataMember!"" }", json); - } + } - [Test] - public void SubWithoutContractVirtualPropertiesTest() - { - BaseWithContract baseWith = new SubWithoutContractVirtualProperties - { - JustAProperty = "JustAProperty!", - Virtual = "Virtual!", - VirtualWithDataMember = "VirtualWithDataMember!", - WithDataMember = "WithDataMember!" - }; + [Test] + public void SubWithoutContractVirtualPropertiesTest() + { + BaseWithContract baseWith = new SubWithoutContractVirtualProperties + { + JustAProperty = "JustAProperty!", + Virtual = "Virtual!", + VirtualWithDataMember = "VirtualWithDataMember!", + WithDataMember = "WithDataMember!" + }; - baseWith.JustAProperty = "JustAProperty2!"; - baseWith.Virtual = "Virtual2!"; - baseWith.VirtualWithDataMember = "VirtualWithDataMember2!"; - baseWith.WithDataMember = "WithDataMember2!"; + baseWith.JustAProperty = "JustAProperty2!"; + baseWith.Virtual = "Virtual2!"; + baseWith.VirtualWithDataMember = "VirtualWithDataMember2!"; + baseWith.WithDataMember = "WithDataMember2!"; - string json = JsonConvert.SerializeObject(baseWith, Formatting.Indented); + string json = JsonConvert.SerializeObject(baseWith, Formatting.Indented); - Console.WriteLine(json); + Console.WriteLine(json); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""VirtualWithDataMemberBase"": ""VirtualWithDataMember2!"", ""VirtualSub"": ""Virtual2!"", ""WithDataMemberBase"": ""WithDataMember2!"", ""JustAProperty"": ""JustAProperty2!"" }", json); - } + } - [Test] - public void SubWithContractNewPropertiesTest() - { - BaseWithContract baseWith = new SubWithContractNewProperties - { - JustAProperty = "JustAProperty!", - Virtual = "Virtual!", - VirtualWithDataMember = "VirtualWithDataMember!", - WithDataMember = "WithDataMember!" - }; + [Test] + public void SubWithContractNewPropertiesTest() + { + BaseWithContract baseWith = new SubWithContractNewProperties + { + JustAProperty = "JustAProperty!", + Virtual = "Virtual!", + VirtualWithDataMember = "VirtualWithDataMember!", + WithDataMember = "WithDataMember!" + }; - baseWith.JustAProperty = "JustAProperty2!"; - baseWith.Virtual = "Virtual2!"; - baseWith.VirtualWithDataMember = "VirtualWithDataMember2!"; - baseWith.WithDataMember = "WithDataMember2!"; + baseWith.JustAProperty = "JustAProperty2!"; + baseWith.Virtual = "Virtual2!"; + baseWith.VirtualWithDataMember = "VirtualWithDataMember2!"; + baseWith.WithDataMember = "WithDataMember2!"; - string json = AssertSerializeDeserializeEqual(baseWith); + string json = AssertSerializeDeserializeEqual(baseWith); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""JustAProperty"": ""JustAProperty2!"", ""JustAProperty2"": ""JustAProperty!"", ""Virtual"": ""Virtual2!"", @@ -1090,245 +1115,245 @@ namespace Newtonsoft.Json.Tests.Serialization ""WithDataMemberBase"": ""WithDataMember2!"", ""WithDataMemberSub"": ""WithDataMember!"" }", json); - } + } - [Test] - public void SubWithContractVirtualPropertiesTest() - { - BaseWithContract baseWith = new SubWithContractVirtualProperties - { - JustAProperty = "JustAProperty!", - Virtual = "Virtual!", - VirtualWithDataMember = "VirtualWithDataMember!", - WithDataMember = "WithDataMember!" - }; + [Test] + public void SubWithContractVirtualPropertiesTest() + { + BaseWithContract baseWith = new SubWithContractVirtualProperties + { + JustAProperty = "JustAProperty!", + Virtual = "Virtual!", + VirtualWithDataMember = "VirtualWithDataMember!", + WithDataMember = "WithDataMember!" + }; - baseWith.JustAProperty = "JustAProperty2!"; - baseWith.Virtual = "Virtual2!"; - baseWith.VirtualWithDataMember = "VirtualWithDataMember2!"; - baseWith.WithDataMember = "WithDataMember2!"; + baseWith.JustAProperty = "JustAProperty2!"; + baseWith.Virtual = "Virtual2!"; + baseWith.VirtualWithDataMember = "VirtualWithDataMember2!"; + baseWith.WithDataMember = "WithDataMember2!"; - string json = AssertSerializeDeserializeEqual(baseWith); + string json = AssertSerializeDeserializeEqual(baseWith); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""JustAProperty"": ""JustAProperty2!"", ""Virtual"": ""Virtual2!"", ""VirtualWithDataMemberBase"": ""VirtualWithDataMember2!"", ""VirtualWithDataMemberSub"": ""VirtualWithDataMember!"", ""WithDataMemberBase"": ""WithDataMember2!"" }", json); - } + } - private string AssertSerializeDeserializeEqual(object o) - { - MemoryStream ms = new MemoryStream(); - DataContractJsonSerializer s = new DataContractJsonSerializer(o.GetType()); - s.WriteObject(ms, o); + private string AssertSerializeDeserializeEqual(object o) + { + MemoryStream ms = new MemoryStream(); + DataContractJsonSerializer s = new DataContractJsonSerializer(o.GetType()); + s.WriteObject(ms, o); - var data = ms.ToArray(); - JObject dataContractJson = JObject.Parse(Encoding.UTF8.GetString(data, 0, data.Length)); - dataContractJson = new JObject(dataContractJson.Properties().OrderBy(p => p.Name)); + var data = ms.ToArray(); + JObject dataContractJson = JObject.Parse(Encoding.UTF8.GetString(data, 0, data.Length)); + dataContractJson = new JObject(dataContractJson.Properties().OrderBy(p => p.Name)); - JObject jsonNetJson = JObject.Parse(JsonConvert.SerializeObject(o)); - jsonNetJson = new JObject(jsonNetJson.Properties().OrderBy(p => p.Name)); + JObject jsonNetJson = JObject.Parse(JsonConvert.SerializeObject(o)); + jsonNetJson = new JObject(jsonNetJson.Properties().OrderBy(p => p.Name)); - Console.WriteLine("Results for " + o.GetType().Name); - Console.WriteLine("DataContractJsonSerializer: " + dataContractJson); - Console.WriteLine("JsonDotNetSerializer : " + jsonNetJson); + Console.WriteLine("Results for " + o.GetType().Name); + Console.WriteLine("DataContractJsonSerializer: " + dataContractJson); + Console.WriteLine("JsonDotNetSerializer : " + jsonNetJson); - Assert.AreEqual(dataContractJson.Count, jsonNetJson.Count); - foreach (KeyValuePair property in dataContractJson) - { - Assert.IsTrue(JToken.DeepEquals(jsonNetJson[property.Key], property.Value), "Property not equal: " + property.Key); - } + Assert.AreEqual(dataContractJson.Count, jsonNetJson.Count); + foreach (KeyValuePair property in dataContractJson) + { + Assert.IsTrue(JToken.DeepEquals(jsonNetJson[property.Key], property.Value), "Property not equal: " + property.Key); + } - return jsonNetJson.ToString(); - } + return jsonNetJson.ToString(); + } #endif - [Test] - public void PersonTypedObjectDeserialization() - { - Store store = new Store(); + [Test] + public void PersonTypedObjectDeserialization() + { + Store store = new Store(); - string jsonText = JsonConvert.SerializeObject(store); + string jsonText = JsonConvert.SerializeObject(store); - Store deserializedStore = (Store)JsonConvert.DeserializeObject(jsonText, typeof(Store)); + Store deserializedStore = (Store)JsonConvert.DeserializeObject(jsonText, typeof(Store)); - Assert.AreEqual(store.Establised, deserializedStore.Establised); - Assert.AreEqual(store.product.Count, deserializedStore.product.Count); + Assert.AreEqual(store.Establised, deserializedStore.Establised); + Assert.AreEqual(store.product.Count, deserializedStore.product.Count); - Console.WriteLine(jsonText); - } + Console.WriteLine(jsonText); + } - [Test] - public void TypedObjectDeserialization() - { - Product product = new Product(); + [Test] + public void TypedObjectDeserialization() + { + Product product = new Product(); - product.Name = "Apple"; - product.ExpiryDate = new DateTime(2008, 12, 28); - product.Price = 3.99M; - product.Sizes = new string[] { "Small", "Medium", "Large" }; + product.Name = "Apple"; + product.ExpiryDate = new DateTime(2008, 12, 28); + product.Price = 3.99M; + product.Sizes = new string[] { "Small", "Medium", "Large" }; - string output = JsonConvert.SerializeObject(product); - //{ - // "Name": "Apple", - // "ExpiryDate": "\/Date(1230375600000+1300)\/", - // "Price": 3.99, - // "Sizes": [ - // "Small", - // "Medium", - // "Large" - // ] - //} + string output = JsonConvert.SerializeObject(product); + //{ + // "Name": "Apple", + // "ExpiryDate": "\/Date(1230375600000+1300)\/", + // "Price": 3.99, + // "Sizes": [ + // "Small", + // "Medium", + // "Large" + // ] + //} - Product deserializedProduct = (Product)JsonConvert.DeserializeObject(output, typeof(Product)); + Product deserializedProduct = (Product)JsonConvert.DeserializeObject(output, typeof(Product)); - Assert.AreEqual("Apple", deserializedProduct.Name); - Assert.AreEqual(new DateTime(2008, 12, 28), deserializedProduct.ExpiryDate); - Assert.AreEqual(3.99m, deserializedProduct.Price); - Assert.AreEqual("Small", deserializedProduct.Sizes[0]); - Assert.AreEqual("Medium", deserializedProduct.Sizes[1]); - Assert.AreEqual("Large", deserializedProduct.Sizes[2]); - } + Assert.AreEqual("Apple", deserializedProduct.Name); + Assert.AreEqual(new DateTime(2008, 12, 28), deserializedProduct.ExpiryDate); + Assert.AreEqual(3.99m, deserializedProduct.Price); + Assert.AreEqual("Small", deserializedProduct.Sizes[0]); + Assert.AreEqual("Medium", deserializedProduct.Sizes[1]); + Assert.AreEqual("Large", deserializedProduct.Sizes[2]); + } - //[Test] - //public void Advanced() - //{ - // Product product = new Product(); - // product.ExpiryDate = new DateTime(2008, 12, 28); + //[Test] + //public void Advanced() + //{ + // Product product = new Product(); + // product.ExpiryDate = new DateTime(2008, 12, 28); - // JsonSerializer serializer = new JsonSerializer(); - // serializer.Converters.Add(new JavaScriptDateTimeConverter()); - // serializer.NullValueHandling = NullValueHandling.Ignore; + // JsonSerializer serializer = new JsonSerializer(); + // serializer.Converters.Add(new JavaScriptDateTimeConverter()); + // serializer.NullValueHandling = NullValueHandling.Ignore; - // using (StreamWriter sw = new StreamWriter(@"c:\json.txt")) - // using (JsonWriter writer = new JsonTextWriter(sw)) - // { - // serializer.Serialize(writer, product); - // // {"ExpiryDate":new Date(1230375600000),"Price":0} - // } - //} + // using (StreamWriter sw = new StreamWriter(@"c:\json.txt")) + // using (JsonWriter writer = new JsonTextWriter(sw)) + // { + // serializer.Serialize(writer, product); + // // {"ExpiryDate":new Date(1230375600000),"Price":0} + // } + //} - [Test] - public void JsonConvertSerializer() - { - string value = @"{""Name"":""Orange"", ""Price"":3.99, ""ExpiryDate"":""01/24/2010 12:00:00""}"; + [Test] + public void JsonConvertSerializer() + { + string value = @"{""Name"":""Orange"", ""Price"":3.99, ""ExpiryDate"":""01/24/2010 12:00:00""}"; - Product p = JsonConvert.DeserializeObject(value, typeof(Product)) as Product; + Product p = JsonConvert.DeserializeObject(value, typeof(Product)) as Product; - Assert.AreEqual("Orange", p.Name); - Assert.AreEqual(new DateTime(2010, 1, 24, 12, 0, 0), p.ExpiryDate); - Assert.AreEqual(3.99m, p.Price); - } + Assert.AreEqual("Orange", p.Name); + Assert.AreEqual(new DateTime(2010, 1, 24, 12, 0, 0), p.ExpiryDate); + Assert.AreEqual(3.99m, p.Price); + } - [Test] - public void DeserializeJavaScriptDate() - { - DateTime dateValue = new DateTime(2010, 3, 30); - Dictionary testDictionary = new Dictionary(); - testDictionary["date"] = dateValue; + [Test] + public void DeserializeJavaScriptDate() + { + DateTime dateValue = new DateTime(2010, 3, 30); + Dictionary testDictionary = new Dictionary(); + testDictionary["date"] = dateValue; - string jsonText = JsonConvert.SerializeObject(testDictionary); + string jsonText = JsonConvert.SerializeObject(testDictionary); #if !NET20 - MemoryStream ms = new MemoryStream(); - DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Dictionary)); - serializer.WriteObject(ms, testDictionary); + MemoryStream ms = new MemoryStream(); + DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Dictionary)); + serializer.WriteObject(ms, testDictionary); - byte[] data = ms.ToArray(); - string output = Encoding.UTF8.GetString(data, 0, data.Length); + byte[] data = ms.ToArray(); + string output = Encoding.UTF8.GetString(data, 0, data.Length); #endif - Dictionary deserializedDictionary = (Dictionary)JsonConvert.DeserializeObject(jsonText, typeof(Dictionary)); - DateTime deserializedDate = (DateTime)deserializedDictionary["date"]; + Dictionary deserializedDictionary = (Dictionary)JsonConvert.DeserializeObject(jsonText, typeof(Dictionary)); + DateTime deserializedDate = (DateTime)deserializedDictionary["date"]; - Assert.AreEqual(dateValue, deserializedDate); - } + Assert.AreEqual(dateValue, deserializedDate); + } - [Test] - public void TestMethodExecutorObject() - { - MethodExecutorObject executorObject = new MethodExecutorObject(); - executorObject.serverClassName = "BanSubs"; - executorObject.serverMethodParams = new object[] { "21321546", "101", "1236", "D:\\1.txt" }; - executorObject.clientGetResultFunction = "ClientBanSubsCB"; + [Test] + public void TestMethodExecutorObject() + { + MethodExecutorObject executorObject = new MethodExecutorObject(); + executorObject.serverClassName = "BanSubs"; + executorObject.serverMethodParams = new object[] { "21321546", "101", "1236", "D:\\1.txt" }; + executorObject.clientGetResultFunction = "ClientBanSubsCB"; - string output = JsonConvert.SerializeObject(executorObject); + string output = JsonConvert.SerializeObject(executorObject); - MethodExecutorObject executorObject2 = JsonConvert.DeserializeObject(output, typeof(MethodExecutorObject)) as MethodExecutorObject; + MethodExecutorObject executorObject2 = JsonConvert.DeserializeObject(output, typeof(MethodExecutorObject)) as MethodExecutorObject; - Assert.AreNotSame(executorObject, executorObject2); - Assert.AreEqual(executorObject2.serverClassName, "BanSubs"); - Assert.AreEqual(executorObject2.serverMethodParams.Length, 4); - CustomAssert.Contains(executorObject2.serverMethodParams, "101"); - Assert.AreEqual(executorObject2.clientGetResultFunction, "ClientBanSubsCB"); - } + Assert.AreNotSame(executorObject, executorObject2); + Assert.AreEqual(executorObject2.serverClassName, "BanSubs"); + Assert.AreEqual(executorObject2.serverMethodParams.Length, 4); + CustomAssert.Contains(executorObject2.serverMethodParams, "101"); + Assert.AreEqual(executorObject2.clientGetResultFunction, "ClientBanSubsCB"); + } #if !SILVERLIGHT && !NETFX_CORE - [Test] - public void HashtableDeserialization() - { - string value = @"{""Name"":""Orange"", ""Price"":3.99, ""ExpiryDate"":""01/24/2010 12:00:00""}"; + [Test] + public void HashtableDeserialization() + { + string value = @"{""Name"":""Orange"", ""Price"":3.99, ""ExpiryDate"":""01/24/2010 12:00:00""}"; - Hashtable p = JsonConvert.DeserializeObject(value, typeof(Hashtable)) as Hashtable; + Hashtable p = JsonConvert.DeserializeObject(value, typeof(Hashtable)) as Hashtable; - Assert.AreEqual("Orange", p["Name"].ToString()); - } + Assert.AreEqual("Orange", p["Name"].ToString()); + } - [Test] - public void TypedHashtableDeserialization() - { - string value = @"{""Name"":""Orange"", ""Hash"":{""ExpiryDate"":""01/24/2010 12:00:00"",""UntypedArray"":[""01/24/2010 12:00:00""]}}"; + [Test] + public void TypedHashtableDeserialization() + { + string value = @"{""Name"":""Orange"", ""Hash"":{""ExpiryDate"":""01/24/2010 12:00:00"",""UntypedArray"":[""01/24/2010 12:00:00""]}}"; - TypedSubHashtable p = JsonConvert.DeserializeObject(value, typeof(TypedSubHashtable)) as TypedSubHashtable; + TypedSubHashtable p = JsonConvert.DeserializeObject(value, typeof(TypedSubHashtable)) as TypedSubHashtable; - Assert.AreEqual("01/24/2010 12:00:00", p.Hash["ExpiryDate"].ToString()); - Assert.AreEqual(@"[ + Assert.AreEqual("01/24/2010 12:00:00", p.Hash["ExpiryDate"].ToString()); + Assert.AreEqual(@"[ ""01/24/2010 12:00:00"" ]", p.Hash["UntypedArray"].ToString()); - } + } #endif - [Test] - public void SerializeDeserializeGetOnlyProperty() - { - string value = JsonConvert.SerializeObject(new GetOnlyPropertyClass()); + [Test] + public void SerializeDeserializeGetOnlyProperty() + { + string value = JsonConvert.SerializeObject(new GetOnlyPropertyClass()); - GetOnlyPropertyClass c = JsonConvert.DeserializeObject(value); + GetOnlyPropertyClass c = JsonConvert.DeserializeObject(value); - Assert.AreEqual(c.Field, "Field"); - Assert.AreEqual(c.GetOnlyProperty, "GetOnlyProperty"); - } + Assert.AreEqual(c.Field, "Field"); + Assert.AreEqual(c.GetOnlyProperty, "GetOnlyProperty"); + } - [Test] - public void SerializeDeserializeSetOnlyProperty() - { - string value = JsonConvert.SerializeObject(new SetOnlyPropertyClass()); + [Test] + public void SerializeDeserializeSetOnlyProperty() + { + string value = JsonConvert.SerializeObject(new SetOnlyPropertyClass()); - SetOnlyPropertyClass c = JsonConvert.DeserializeObject(value); + SetOnlyPropertyClass c = JsonConvert.DeserializeObject(value); - Assert.AreEqual(c.Field, "Field"); - } + Assert.AreEqual(c.Field, "Field"); + } - [Test] - public void JsonIgnoreAttributeTest() - { - string json = JsonConvert.SerializeObject(new JsonIgnoreAttributeTestClass()); + [Test] + public void JsonIgnoreAttributeTest() + { + string json = JsonConvert.SerializeObject(new JsonIgnoreAttributeTestClass()); - Assert.AreEqual(@"{""Field"":0,""Property"":21}", json); + Assert.AreEqual(@"{""Field"":0,""Property"":21}", json); - JsonIgnoreAttributeTestClass c = JsonConvert.DeserializeObject(@"{""Field"":99,""Property"":-1,""IgnoredField"":-1,""IgnoredObject"":[1,2,3,4,5]}"); + JsonIgnoreAttributeTestClass c = JsonConvert.DeserializeObject(@"{""Field"":99,""Property"":-1,""IgnoredField"":-1,""IgnoredObject"":[1,2,3,4,5]}"); - Assert.AreEqual(0, c.IgnoredField); - Assert.AreEqual(99, c.Field); - } + Assert.AreEqual(0, c.IgnoredField); + Assert.AreEqual(99, c.Field); + } - [Test] - public void GoogleSearchAPI() - { - string json = @"{ + [Test] + public void GoogleSearchAPI() + { + string json = @"{ results: [ { @@ -1406,15 +1431,15 @@ keyword such as type of business."" ] } "; - object o = JsonConvert.DeserializeObject(json); - string s = string.Empty; - s += s; - } + object o = JsonConvert.DeserializeObject(json); + string s = string.Empty; + s += s; + } - [Test] - public void TorrentDeserializeTest() - { - string jsonText = @"{ + [Test] + public void TorrentDeserializeTest() + { + string jsonText = @"{ """":"""", ""label"": [ [""SomeName"",6] @@ -1425,357 +1450,351 @@ keyword such as type of business."" ""torrentc"": ""1816000723"" }"; - JObject o = (JObject)JsonConvert.DeserializeObject(jsonText); - Assert.AreEqual(4, o.Children().Count()); + JObject o = (JObject)JsonConvert.DeserializeObject(jsonText); + Assert.AreEqual(4, o.Children().Count()); - JToken torrentsArray = (JToken)o["torrents"]; - JToken nestedTorrentsArray = (JToken)torrentsArray[0]; - Assert.AreEqual(nestedTorrentsArray.Children().Count(), 19); - } + JToken torrentsArray = (JToken)o["torrents"]; + JToken nestedTorrentsArray = (JToken)torrentsArray[0]; + Assert.AreEqual(nestedTorrentsArray.Children().Count(), 19); + } - [Test] - public void JsonPropertyClassSerialize() - { - JsonPropertyClass test = new JsonPropertyClass(); - test.Pie = "Delicious"; - test.SweetCakesCount = int.MaxValue; - - string jsonText = JsonConvert.SerializeObject(test); - - Assert.AreEqual(@"{""pie"":""Delicious"",""pie1"":""PieChart!"",""sweet_cakes_count"":2147483647}", jsonText); - - JsonPropertyClass test2 = JsonConvert.DeserializeObject(jsonText); - - Assert.AreEqual(test.Pie, test2.Pie); - Assert.AreEqual(test.SweetCakesCount, test2.SweetCakesCount); - } - - [Test] - public void BadJsonPropertyClassSerialize() - { - ExceptionAssert.Throws( - @"A member with the name 'pie' already exists on 'Newtonsoft.Json.Tests.TestObjects.BadJsonPropertyClass'. Use the JsonPropertyAttribute to specify another name.", - () => + [Test] + public void JsonPropertyClassSerialize() { - JsonConvert.SerializeObject(new BadJsonPropertyClass()); - }); - } + JsonPropertyClass test = new JsonPropertyClass(); + test.Pie = "Delicious"; + test.SweetCakesCount = int.MaxValue; - [Test] - public void InheritedListSerialize() - { - Article a1 = new Article("a1"); - Article a2 = new Article("a2"); + string jsonText = JsonConvert.SerializeObject(test); - ArticleCollection articles1 = new ArticleCollection(); - articles1.Add(a1); - articles1.Add(a2); + Assert.AreEqual(@"{""pie"":""Delicious"",""pie1"":""PieChart!"",""sweet_cakes_count"":2147483647}", jsonText); - string jsonText = JsonConvert.SerializeObject(articles1); + JsonPropertyClass test2 = JsonConvert.DeserializeObject(jsonText); - ArticleCollection articles2 = JsonConvert.DeserializeObject(jsonText); + Assert.AreEqual(test.Pie, test2.Pie); + Assert.AreEqual(test.SweetCakesCount, test2.SweetCakesCount); + } - Assert.AreEqual(articles1.Count, articles2.Count); - Assert.AreEqual(articles1[0].Name, articles2[0].Name); - } + [Test] + public void BadJsonPropertyClassSerialize() + { + ExceptionAssert.Throws( + @"A member with the name 'pie' already exists on 'Newtonsoft.Json.Tests.TestObjects.BadJsonPropertyClass'. Use the JsonPropertyAttribute to specify another name.", + () => { JsonConvert.SerializeObject(new BadJsonPropertyClass()); }); + } - [Test] - public void ReadOnlyCollectionSerialize() - { - ReadOnlyCollection r1 = new ReadOnlyCollection(new int[] { 0, 1, 2, 3, 4 }); + [Test] + public void InheritedListSerialize() + { + Article a1 = new Article("a1"); + Article a2 = new Article("a2"); - string jsonText = JsonConvert.SerializeObject(r1); + ArticleCollection articles1 = new ArticleCollection(); + articles1.Add(a1); + articles1.Add(a2); - Assert.AreEqual("[0,1,2,3,4]", jsonText); + string jsonText = JsonConvert.SerializeObject(articles1); - ReadOnlyCollection r2 = JsonConvert.DeserializeObject>(jsonText); + ArticleCollection articles2 = JsonConvert.DeserializeObject(jsonText); - CollectionAssert.AreEqual(r1, r2); - } + Assert.AreEqual(articles1.Count, articles2.Count); + Assert.AreEqual(articles1[0].Name, articles2[0].Name); + } + + [Test] + public void ReadOnlyCollectionSerialize() + { + ReadOnlyCollection r1 = new ReadOnlyCollection(new int[] { 0, 1, 2, 3, 4 }); + + string jsonText = JsonConvert.SerializeObject(r1); + + Assert.AreEqual("[0,1,2,3,4]", jsonText); + + ReadOnlyCollection r2 = JsonConvert.DeserializeObject>(jsonText); + + CollectionAssert.AreEqual(r1, r2); + } #if !NET20 - [Test] - public void Unicode() - { - string json = @"[""PRE\u003cPOST""]"; + [Test] + public void Unicode() + { + string json = @"[""PRE\u003cPOST""]"; - DataContractJsonSerializer s = new DataContractJsonSerializer(typeof(List)); - List dataContractResult = (List)s.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(json))); + DataContractJsonSerializer s = new DataContractJsonSerializer(typeof(List)); + List dataContractResult = (List)s.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(json))); - List jsonNetResult = JsonConvert.DeserializeObject>(json); + List jsonNetResult = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(1, jsonNetResult.Count); - Assert.AreEqual(dataContractResult[0], jsonNetResult[0]); - } + Assert.AreEqual(1, jsonNetResult.Count); + Assert.AreEqual(dataContractResult[0], jsonNetResult[0]); + } - [Test] - public void BackslashEqivilence() - { - string json = @"[""vvv\/vvv\tvvv\""vvv\bvvv\nvvv\rvvv\\vvv\fvvv""]"; + [Test] + public void BackslashEqivilence() + { + string json = @"[""vvv\/vvv\tvvv\""vvv\bvvv\nvvv\rvvv\\vvv\fvvv""]"; #if !SILVERLIGHT && !NETFX_CORE - JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer(); - List javaScriptSerializerResult = javaScriptSerializer.Deserialize>(json); + JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer(); + List javaScriptSerializerResult = javaScriptSerializer.Deserialize>(json); #endif - DataContractJsonSerializer s = new DataContractJsonSerializer(typeof(List)); - List dataContractResult = (List)s.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(json))); + DataContractJsonSerializer s = new DataContractJsonSerializer(typeof(List)); + List dataContractResult = (List)s.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(json))); - List jsonNetResult = JsonConvert.DeserializeObject>(json); + List jsonNetResult = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(1, jsonNetResult.Count); - Assert.AreEqual(dataContractResult[0], jsonNetResult[0]); + Assert.AreEqual(1, jsonNetResult.Count); + Assert.AreEqual(dataContractResult[0], jsonNetResult[0]); #if !SILVERLIGHT && !NETFX_CORE - Assert.AreEqual(javaScriptSerializerResult[0], jsonNetResult[0]); + Assert.AreEqual(javaScriptSerializerResult[0], jsonNetResult[0]); #endif - } + } - [Test] - public void InvalidBackslash() - { - string json = @"[""vvv\jvvv""]"; - - ExceptionAssert.Throws( - @"Bad JSON escape sequence: \j. Path '', line 1, position 7.", - () => + [Test] + public void InvalidBackslash() { - JsonConvert.DeserializeObject>(json); - }); - } + string json = @"[""vvv\jvvv""]"; - [Test] - public void DateTimeTest() - { - List testDates = new List + ExceptionAssert.Throws( + @"Bad JSON escape sequence: \j. Path '', line 1, position 7.", + () => { JsonConvert.DeserializeObject>(json); }); + } + + [Test] + public void DateTimeTest() { - new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Local), - new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Unspecified), - new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Utc), - new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Local), - new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Unspecified), - new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc), - }; + List testDates = new List + { + new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Local), + new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Unspecified), + new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Utc), + new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Local), + new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Unspecified), + new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc), + }; - MemoryStream ms = new MemoryStream(); - DataContractJsonSerializer s = new DataContractJsonSerializer(typeof(List)); - s.WriteObject(ms, testDates); - ms.Seek(0, SeekOrigin.Begin); - StreamReader sr = new StreamReader(ms); + MemoryStream ms = new MemoryStream(); + DataContractJsonSerializer s = new DataContractJsonSerializer(typeof(List)); + s.WriteObject(ms, testDates); + ms.Seek(0, SeekOrigin.Begin); + StreamReader sr = new StreamReader(ms); - string expected = sr.ReadToEnd(); + string expected = sr.ReadToEnd(); - string result = JsonConvert.SerializeObject(testDates, new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.MicrosoftDateFormat }); - Assert.AreEqual(expected, result); - } + string result = JsonConvert.SerializeObject(testDates, new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.MicrosoftDateFormat }); + Assert.AreEqual(expected, result); + } - [Test] - public void DateTimeOffsetIso() - { - List testDates = new List + [Test] + public void DateTimeOffsetIso() { - new DateTimeOffset(new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Utc)), - new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero), - new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(13)), - new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(-3.5)), - }; + List testDates = new List + { + new DateTimeOffset(new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Utc)), + new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero), + new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(13)), + new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(-3.5)), + }; - string result = JsonConvert.SerializeObject(testDates); - Assert.AreEqual(@"[""0100-01-01T01:01:01+00:00"",""2000-01-01T01:01:01+00:00"",""2000-01-01T01:01:01+13:00"",""2000-01-01T01:01:01-03:30""]", result); - } + string result = JsonConvert.SerializeObject(testDates); + Assert.AreEqual(@"[""0100-01-01T01:01:01+00:00"",""2000-01-01T01:01:01+00:00"",""2000-01-01T01:01:01+13:00"",""2000-01-01T01:01:01-03:30""]", result); + } - [Test] - public void DateTimeOffsetMsAjax() - { - List testDates = new List + [Test] + public void DateTimeOffsetMsAjax() { - new DateTimeOffset(new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Utc)), - new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero), - new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(13)), - new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(-3.5)), - }; + List testDates = new List + { + new DateTimeOffset(new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Utc)), + new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero), + new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(13)), + new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(-3.5)), + }; - string result = JsonConvert.SerializeObject(testDates, new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.MicrosoftDateFormat }); - Assert.AreEqual(@"[""\/Date(-59011455539000+0000)\/"",""\/Date(946688461000+0000)\/"",""\/Date(946641661000+1300)\/"",""\/Date(946701061000-0330)\/""]", result); - } + string result = JsonConvert.SerializeObject(testDates, new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.MicrosoftDateFormat }); + Assert.AreEqual(@"[""\/Date(-59011455539000+0000)\/"",""\/Date(946688461000+0000)\/"",""\/Date(946641661000+1300)\/"",""\/Date(946701061000-0330)\/""]", result); + } #endif - [Test] - public void NonStringKeyDictionary() - { - Dictionary values = new Dictionary(); - values.Add(-5, 6); - values.Add(int.MinValue, int.MaxValue); - - string json = JsonConvert.SerializeObject(values); - - Assert.AreEqual(@"{""-5"":6,""-2147483648"":2147483647}", json); - - Dictionary newValues = JsonConvert.DeserializeObject>(json); - - CollectionAssert.AreEqual(values, newValues); - } - - [Test] - public void AnonymousObjectSerialization() - { - var anonymous = - new - { - StringValue = "I am a string", - IntValue = int.MaxValue, - NestedAnonymous = new { NestedValue = byte.MaxValue }, - NestedArray = new[] { 1, 2 }, - Product = new Product() { Name = "TestProduct" } - }; - - string json = JsonConvert.SerializeObject(anonymous); - Assert.AreEqual(@"{""StringValue"":""I am a string"",""IntValue"":2147483647,""NestedAnonymous"":{""NestedValue"":255},""NestedArray"":[1,2],""Product"":{""Name"":""TestProduct"",""ExpiryDate"":""2000-01-01T00:00:00Z"",""Price"":0.0,""Sizes"":null}}", json); - - anonymous = JsonConvert.DeserializeAnonymousType(json, anonymous); - Assert.AreEqual("I am a string", anonymous.StringValue); - Assert.AreEqual(int.MaxValue, anonymous.IntValue); - Assert.AreEqual(255, anonymous.NestedAnonymous.NestedValue); - Assert.AreEqual(2, anonymous.NestedArray.Length); - Assert.AreEqual(1, anonymous.NestedArray[0]); - Assert.AreEqual(2, anonymous.NestedArray[1]); - Assert.AreEqual("TestProduct", anonymous.Product.Name); - } - - [Test] - public void AnonymousObjectSerializationWithSetting() - { - DateTime d = new DateTime(2000, 1, 1); - - var anonymous = - new + [Test] + public void NonStringKeyDictionary() { - DateValue = d - }; + Dictionary values = new Dictionary(); + values.Add(-5, 6); + values.Add(int.MinValue, int.MaxValue); - JsonSerializerSettings settings = new JsonSerializerSettings(); - settings.Converters.Add(new IsoDateTimeConverter + string json = JsonConvert.SerializeObject(values); + + Assert.AreEqual(@"{""-5"":6,""-2147483648"":2147483647}", json); + + Dictionary newValues = JsonConvert.DeserializeObject>(json); + + CollectionAssert.AreEqual(values, newValues); + } + + [Test] + public void AnonymousObjectSerialization() { - DateTimeFormat = "yyyy" - }); + var anonymous = + new + { + StringValue = "I am a string", + IntValue = int.MaxValue, + NestedAnonymous = new { NestedValue = byte.MaxValue }, + NestedArray = new[] { 1, 2 }, + Product = new Product() { Name = "TestProduct" } + }; - string json = JsonConvert.SerializeObject(anonymous, settings); - Assert.AreEqual(@"{""DateValue"":""2000""}", json); + string json = JsonConvert.SerializeObject(anonymous); + Assert.AreEqual(@"{""StringValue"":""I am a string"",""IntValue"":2147483647,""NestedAnonymous"":{""NestedValue"":255},""NestedArray"":[1,2],""Product"":{""Name"":""TestProduct"",""ExpiryDate"":""2000-01-01T00:00:00Z"",""Price"":0.0,""Sizes"":null}}", json); - anonymous = JsonConvert.DeserializeAnonymousType(json, anonymous, settings); - Assert.AreEqual(d, anonymous.DateValue); - } + anonymous = JsonConvert.DeserializeAnonymousType(json, anonymous); + Assert.AreEqual("I am a string", anonymous.StringValue); + Assert.AreEqual(int.MaxValue, anonymous.IntValue); + Assert.AreEqual(255, anonymous.NestedAnonymous.NestedValue); + Assert.AreEqual(2, anonymous.NestedArray.Length); + Assert.AreEqual(1, anonymous.NestedArray[0]); + Assert.AreEqual(2, anonymous.NestedArray[1]); + Assert.AreEqual("TestProduct", anonymous.Product.Name); + } - [Test] - public void CustomCollectionSerialization() - { - ProductCollection collection = new ProductCollection() + [Test] + public void AnonymousObjectSerializationWithSetting() { - new Product() {Name = "Test1"}, - new Product() {Name = "Test2"}, - new Product() {Name = "Test3"} - }; + DateTime d = new DateTime(2000, 1, 1); - JsonSerializer jsonSerializer = new JsonSerializer(); - jsonSerializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; + var anonymous = + new + { + DateValue = d + }; - StringWriter sw = new StringWriter(); + JsonSerializerSettings settings = new JsonSerializerSettings(); + settings.Converters.Add(new IsoDateTimeConverter + { + DateTimeFormat = "yyyy" + }); - jsonSerializer.Serialize(sw, collection); + string json = JsonConvert.SerializeObject(anonymous, settings); + Assert.AreEqual(@"{""DateValue"":""2000""}", json); - Assert.AreEqual(@"[{""Name"":""Test1"",""ExpiryDate"":""2000-01-01T00:00:00Z"",""Price"":0.0,""Sizes"":null},{""Name"":""Test2"",""ExpiryDate"":""2000-01-01T00:00:00Z"",""Price"":0.0,""Sizes"":null},{""Name"":""Test3"",""ExpiryDate"":""2000-01-01T00:00:00Z"",""Price"":0.0,""Sizes"":null}]", - sw.GetStringBuilder().ToString()); + anonymous = JsonConvert.DeserializeAnonymousType(json, anonymous, settings); + Assert.AreEqual(d, anonymous.DateValue); + } - ProductCollection collectionNew = (ProductCollection)jsonSerializer.Deserialize(new JsonTextReader(new StringReader(sw.GetStringBuilder().ToString())), typeof(ProductCollection)); + [Test] + public void CustomCollectionSerialization() + { + ProductCollection collection = new ProductCollection() + { + new Product() { Name = "Test1" }, + new Product() { Name = "Test2" }, + new Product() { Name = "Test3" } + }; - CollectionAssert.AreEqual(collection, collectionNew); - } + JsonSerializer jsonSerializer = new JsonSerializer(); + jsonSerializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; - [Test] - public void SerializeObject() - { - string json = JsonConvert.SerializeObject(new object()); - Assert.AreEqual("{}", json); - } + StringWriter sw = new StringWriter(); - [Test] - public void SerializeNull() - { - string json = JsonConvert.SerializeObject(null); - Assert.AreEqual("null", json); - } + jsonSerializer.Serialize(sw, collection); - [Test] - public void CanDeserializeIntArrayWhenNotFirstPropertyInJson() - { - string json = "{foo:'hello',bar:[1,2,3]}"; - ClassWithArray wibble = JsonConvert.DeserializeObject(json); - Assert.AreEqual("hello", wibble.Foo); + Assert.AreEqual(@"[{""Name"":""Test1"",""ExpiryDate"":""2000-01-01T00:00:00Z"",""Price"":0.0,""Sizes"":null},{""Name"":""Test2"",""ExpiryDate"":""2000-01-01T00:00:00Z"",""Price"":0.0,""Sizes"":null},{""Name"":""Test3"",""ExpiryDate"":""2000-01-01T00:00:00Z"",""Price"":0.0,""Sizes"":null}]", + sw.GetStringBuilder().ToString()); - Assert.AreEqual(4, wibble.Bar.Count); - Assert.AreEqual(int.MaxValue, wibble.Bar[0]); - Assert.AreEqual(1, wibble.Bar[1]); - Assert.AreEqual(2, wibble.Bar[2]); - Assert.AreEqual(3, wibble.Bar[3]); - } + ProductCollection collectionNew = (ProductCollection)jsonSerializer.Deserialize(new JsonTextReader(new StringReader(sw.GetStringBuilder().ToString())), typeof(ProductCollection)); - [Test] - public void CanDeserializeIntArray_WhenArrayIsFirstPropertyInJson() - { - string json = "{bar:[1,2,3], foo:'hello'}"; - ClassWithArray wibble = JsonConvert.DeserializeObject(json); - Assert.AreEqual("hello", wibble.Foo); + CollectionAssert.AreEqual(collection, collectionNew); + } - Assert.AreEqual(4, wibble.Bar.Count); - Assert.AreEqual(int.MaxValue, wibble.Bar[0]); - Assert.AreEqual(1, wibble.Bar[1]); - Assert.AreEqual(2, wibble.Bar[2]); - Assert.AreEqual(3, wibble.Bar[3]); - } + [Test] + public void SerializeObject() + { + string json = JsonConvert.SerializeObject(new object()); + Assert.AreEqual("{}", json); + } - [Test] - public void ObjectCreationHandlingReplace() - { - string json = "{bar:[1,2,3], foo:'hello'}"; + [Test] + public void SerializeNull() + { + string json = JsonConvert.SerializeObject(null); + Assert.AreEqual("null", json); + } - JsonSerializer s = new JsonSerializer(); - s.ObjectCreationHandling = ObjectCreationHandling.Replace; + [Test] + public void CanDeserializeIntArrayWhenNotFirstPropertyInJson() + { + string json = "{foo:'hello',bar:[1,2,3]}"; + ClassWithArray wibble = JsonConvert.DeserializeObject(json); + Assert.AreEqual("hello", wibble.Foo); - ClassWithArray wibble = (ClassWithArray)s.Deserialize(new StringReader(json), typeof(ClassWithArray)); + Assert.AreEqual(4, wibble.Bar.Count); + Assert.AreEqual(int.MaxValue, wibble.Bar[0]); + Assert.AreEqual(1, wibble.Bar[1]); + Assert.AreEqual(2, wibble.Bar[2]); + Assert.AreEqual(3, wibble.Bar[3]); + } - Assert.AreEqual("hello", wibble.Foo); + [Test] + public void CanDeserializeIntArray_WhenArrayIsFirstPropertyInJson() + { + string json = "{bar:[1,2,3], foo:'hello'}"; + ClassWithArray wibble = JsonConvert.DeserializeObject(json); + Assert.AreEqual("hello", wibble.Foo); - Assert.AreEqual(1, wibble.Bar.Count); - } + Assert.AreEqual(4, wibble.Bar.Count); + Assert.AreEqual(int.MaxValue, wibble.Bar[0]); + Assert.AreEqual(1, wibble.Bar[1]); + Assert.AreEqual(2, wibble.Bar[2]); + Assert.AreEqual(3, wibble.Bar[3]); + } - [Test] - public void CanDeserializeSerializedJson() - { - ClassWithArray wibble = new ClassWithArray(); - wibble.Foo = "hello"; - wibble.Bar.Add(1); - wibble.Bar.Add(2); - wibble.Bar.Add(3); - string json = JsonConvert.SerializeObject(wibble); + [Test] + public void ObjectCreationHandlingReplace() + { + string json = "{bar:[1,2,3], foo:'hello'}"; - ClassWithArray wibbleOut = JsonConvert.DeserializeObject(json); - Assert.AreEqual("hello", wibbleOut.Foo); + JsonSerializer s = new JsonSerializer(); + s.ObjectCreationHandling = ObjectCreationHandling.Replace; - Assert.AreEqual(5, wibbleOut.Bar.Count); - Assert.AreEqual(int.MaxValue, wibbleOut.Bar[0]); - Assert.AreEqual(int.MaxValue, wibbleOut.Bar[1]); - Assert.AreEqual(1, wibbleOut.Bar[2]); - Assert.AreEqual(2, wibbleOut.Bar[3]); - Assert.AreEqual(3, wibbleOut.Bar[4]); - } + ClassWithArray wibble = (ClassWithArray)s.Deserialize(new StringReader(json), typeof(ClassWithArray)); - [Test] - public void SerializeConverableObjects() - { - string json = JsonConvert.SerializeObject(new ConverableMembers(), Formatting.Indented); + Assert.AreEqual("hello", wibble.Foo); - string expected = null; + Assert.AreEqual(1, wibble.Bar.Count); + } + + [Test] + public void CanDeserializeSerializedJson() + { + ClassWithArray wibble = new ClassWithArray(); + wibble.Foo = "hello"; + wibble.Bar.Add(1); + wibble.Bar.Add(2); + wibble.Bar.Add(3); + string json = JsonConvert.SerializeObject(wibble); + + ClassWithArray wibbleOut = JsonConvert.DeserializeObject(json); + Assert.AreEqual("hello", wibbleOut.Foo); + + Assert.AreEqual(5, wibbleOut.Bar.Count); + Assert.AreEqual(int.MaxValue, wibbleOut.Bar[0]); + Assert.AreEqual(int.MaxValue, wibbleOut.Bar[1]); + Assert.AreEqual(1, wibbleOut.Bar[2]); + Assert.AreEqual(2, wibbleOut.Bar[3]); + Assert.AreEqual(3, wibbleOut.Bar[4]); + } + + [Test] + public void SerializeConverableObjects() + { + string json = JsonConvert.SerializeObject(new ConverableMembers(), Formatting.Indented); + + string expected = null; #if !(NETFX_CORE || PORTABLE) - expected = @"{ + expected = @"{ ""String"": ""string"", ""Int32"": 2147483647, ""UInt32"": 4294967295, @@ -1809,109 +1828,109 @@ keyword such as type of business."" }"; #endif - Assert.AreEqual(expected, json); + Assert.AreEqual(expected, json); - ConverableMembers c = JsonConvert.DeserializeObject(json); - Assert.AreEqual("string", c.String); - Assert.AreEqual(double.MaxValue, c.Double); + ConverableMembers c = JsonConvert.DeserializeObject(json); + Assert.AreEqual("string", c.String); + Assert.AreEqual(double.MaxValue, c.Double); #if !(NETFX_CORE || PORTABLE || PORTABLE40) - Assert.AreEqual(DBNull.Value, c.DBNull); + Assert.AreEqual(DBNull.Value, c.DBNull); #endif - } + } - [Test] - public void SerializeStack() - { - Stack s = new Stack(); - s.Push(1); - s.Push(2); - s.Push(3); + [Test] + public void SerializeStack() + { + Stack s = new Stack(); + s.Push(1); + s.Push(2); + s.Push(3); - string json = JsonConvert.SerializeObject(s); - Assert.AreEqual("[3,2,1]", json); - } + string json = JsonConvert.SerializeObject(s); + Assert.AreEqual("[3,2,1]", json); + } - [Test] - public void GuidTest() - { - Guid guid = new Guid("BED7F4EA-1A96-11d2-8F08-00A0C9A6186D"); + [Test] + public void GuidTest() + { + Guid guid = new Guid("BED7F4EA-1A96-11d2-8F08-00A0C9A6186D"); - string json = JsonConvert.SerializeObject(new ClassWithGuid { GuidField = guid }); - Assert.AreEqual(@"{""GuidField"":""bed7f4ea-1a96-11d2-8f08-00a0c9a6186d""}", json); + string json = JsonConvert.SerializeObject(new ClassWithGuid { GuidField = guid }); + Assert.AreEqual(@"{""GuidField"":""bed7f4ea-1a96-11d2-8f08-00a0c9a6186d""}", json); - ClassWithGuid c = JsonConvert.DeserializeObject(json); - Assert.AreEqual(guid, c.GuidField); - } + ClassWithGuid c = JsonConvert.DeserializeObject(json); + Assert.AreEqual(guid, c.GuidField); + } - [Test] - public void EnumTest() - { - string json = JsonConvert.SerializeObject(StringComparison.CurrentCultureIgnoreCase); - Assert.AreEqual(@"1", json); + [Test] + public void EnumTest() + { + string json = JsonConvert.SerializeObject(StringComparison.CurrentCultureIgnoreCase); + Assert.AreEqual(@"1", json); - StringComparison s = JsonConvert.DeserializeObject(json); - Assert.AreEqual(StringComparison.CurrentCultureIgnoreCase, s); - } + StringComparison s = JsonConvert.DeserializeObject(json); + Assert.AreEqual(StringComparison.CurrentCultureIgnoreCase, s); + } - public class ClassWithTimeSpan - { - public TimeSpan TimeSpanField; - } + public class ClassWithTimeSpan + { + public TimeSpan TimeSpanField; + } - [Test] - public void TimeSpanTest() - { - TimeSpan ts = new TimeSpan(00, 23, 59, 1); + [Test] + public void TimeSpanTest() + { + TimeSpan ts = new TimeSpan(00, 23, 59, 1); - string json = JsonConvert.SerializeObject(new ClassWithTimeSpan { TimeSpanField = ts }, Formatting.Indented); - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(new ClassWithTimeSpan { TimeSpanField = ts }, Formatting.Indented); + Assert.AreEqual(@"{ ""TimeSpanField"": ""23:59:01"" }", json); - ClassWithTimeSpan c = JsonConvert.DeserializeObject(json); - Assert.AreEqual(ts, c.TimeSpanField); - } + ClassWithTimeSpan c = JsonConvert.DeserializeObject(json); + Assert.AreEqual(ts, c.TimeSpanField); + } - [Test] - public void JsonIgnoreAttributeOnClassTest() - { - string json = JsonConvert.SerializeObject(new JsonIgnoreAttributeOnClassTestClass()); + [Test] + public void JsonIgnoreAttributeOnClassTest() + { + string json = JsonConvert.SerializeObject(new JsonIgnoreAttributeOnClassTestClass()); - Assert.AreEqual(@"{""TheField"":0,""Property"":21}", json); + Assert.AreEqual(@"{""TheField"":0,""Property"":21}", json); - JsonIgnoreAttributeOnClassTestClass c = JsonConvert.DeserializeObject(@"{""TheField"":99,""Property"":-1,""IgnoredField"":-1}"); + JsonIgnoreAttributeOnClassTestClass c = JsonConvert.DeserializeObject(@"{""TheField"":99,""Property"":-1,""IgnoredField"":-1}"); - Assert.AreEqual(0, c.IgnoredField); - Assert.AreEqual(99, c.Field); - } + Assert.AreEqual(0, c.IgnoredField); + Assert.AreEqual(99, c.Field); + } #if !SILVERLIGHT && !NETFX_CORE - [Test] - public void SerializeArrayAsArrayList() - { - string jsonText = @"[3, ""somestring"",[1,2,3],{}]"; - ArrayList o = JsonConvert.DeserializeObject(jsonText); + [Test] + public void SerializeArrayAsArrayList() + { + string jsonText = @"[3, ""somestring"",[1,2,3],{}]"; + ArrayList o = JsonConvert.DeserializeObject(jsonText); - Assert.AreEqual(4, o.Count); - Assert.AreEqual(3, ((JArray)o[2]).Count); - Assert.AreEqual(0, ((JObject)o[3]).Count); - } + Assert.AreEqual(4, o.Count); + Assert.AreEqual(3, ((JArray)o[2]).Count); + Assert.AreEqual(0, ((JObject)o[3]).Count); + } #endif - [Test] - public void SerializeMemberGenericList() - { - Name name = new Name("The Idiot in Next To Me"); + [Test] + public void SerializeMemberGenericList() + { + Name name = new Name("The Idiot in Next To Me"); - PhoneNumber p1 = new PhoneNumber("555-1212"); - PhoneNumber p2 = new PhoneNumber("444-1212"); + PhoneNumber p1 = new PhoneNumber("555-1212"); + PhoneNumber p2 = new PhoneNumber("444-1212"); - name.pNumbers.Add(p1); - name.pNumbers.Add(p2); + name.pNumbers.Add(p1); + name.pNumbers.Add(p2); - string json = JsonConvert.SerializeObject(name, Formatting.Indented); + string json = JsonConvert.SerializeObject(name, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""personsName"": ""The Idiot in Next To Me"", ""pNumbers"": [ { @@ -1923,433 +1942,433 @@ keyword such as type of business."" ] }", json); - Name newName = JsonConvert.DeserializeObject(json); + Name newName = JsonConvert.DeserializeObject(json); - Assert.AreEqual("The Idiot in Next To Me", newName.personsName); + Assert.AreEqual("The Idiot in Next To Me", newName.personsName); - // not passed in as part of the constructor but assigned to pNumbers property - Assert.AreEqual(2, newName.pNumbers.Count); - Assert.AreEqual("555-1212", newName.pNumbers[0].phoneNumber); - Assert.AreEqual("444-1212", newName.pNumbers[1].phoneNumber); - } + // not passed in as part of the constructor but assigned to pNumbers property + Assert.AreEqual(2, newName.pNumbers.Count); + Assert.AreEqual("555-1212", newName.pNumbers[0].phoneNumber); + Assert.AreEqual("444-1212", newName.pNumbers[1].phoneNumber); + } - [Test] - public void ConstructorCaseSensitivity() - { - ConstructorCaseSensitivityClass c = new ConstructorCaseSensitivityClass("param1", "Param1", "Param2"); - - string json = JsonConvert.SerializeObject(c); - - ConstructorCaseSensitivityClass deserialized = JsonConvert.DeserializeObject(json); - - Assert.AreEqual("param1", deserialized.param1); - Assert.AreEqual("Param1", deserialized.Param1); - Assert.AreEqual("Param2", deserialized.Param2); - } - - [Test] - public void SerializerShouldUseClassConverter() - { - ConverterPrecedenceClass c1 = new ConverterPrecedenceClass("!Test!"); - - string json = JsonConvert.SerializeObject(c1); - Assert.AreEqual(@"[""Class"",""!Test!""]", json); - - ConverterPrecedenceClass c2 = JsonConvert.DeserializeObject(json); - - Assert.AreEqual("!Test!", c2.TestValue); - } - - [Test] - public void SerializerShouldUseClassConverterOverArgumentConverter() - { - ConverterPrecedenceClass c1 = new ConverterPrecedenceClass("!Test!"); - - string json = JsonConvert.SerializeObject(c1, new ArgumentConverterPrecedenceClassConverter()); - Assert.AreEqual(@"[""Class"",""!Test!""]", json); - - ConverterPrecedenceClass c2 = JsonConvert.DeserializeObject(json, new ArgumentConverterPrecedenceClassConverter()); - - Assert.AreEqual("!Test!", c2.TestValue); - } - - [Test] - public void SerializerShouldUseMemberConverter_IsoDate() - { - DateTime testDate = new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc); - MemberConverterClass m1 = new MemberConverterClass { DefaultConverter = testDate, MemberConverter = testDate }; - - string json = JsonConvert.SerializeObject(m1); - Assert.AreEqual(@"{""DefaultConverter"":""1970-01-01T00:00:00Z"",""MemberConverter"":""1970-01-01T00:00:00Z""}", json); - - MemberConverterClass m2 = JsonConvert.DeserializeObject(json); - - Assert.AreEqual(testDate, m2.DefaultConverter); - Assert.AreEqual(testDate, m2.MemberConverter); - } - - [Test] - public void SerializerShouldUseMemberConverter_MsDate() - { - DateTime testDate = new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc); - MemberConverterClass m1 = new MemberConverterClass { DefaultConverter = testDate, MemberConverter = testDate }; - - string json = JsonConvert.SerializeObject(m1, new JsonSerializerSettings + [Test] + public void ConstructorCaseSensitivity() { - DateFormatHandling = DateFormatHandling.MicrosoftDateFormat - }); - Assert.AreEqual(@"{""DefaultConverter"":""\/Date(0)\/"",""MemberConverter"":""1970-01-01T00:00:00Z""}", json); + ConstructorCaseSensitivityClass c = new ConstructorCaseSensitivityClass("param1", "Param1", "Param2"); - MemberConverterClass m2 = JsonConvert.DeserializeObject(json); + string json = JsonConvert.SerializeObject(c); - Assert.AreEqual(testDate, m2.DefaultConverter); - Assert.AreEqual(testDate, m2.MemberConverter); - } + ConstructorCaseSensitivityClass deserialized = JsonConvert.DeserializeObject(json); - [Test] - public void SerializerShouldUseMemberConverter_MsDate_DateParseNone() - { - DateTime testDate = new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc); - MemberConverterClass m1 = new MemberConverterClass { DefaultConverter = testDate, MemberConverter = testDate }; + Assert.AreEqual("param1", deserialized.param1); + Assert.AreEqual("Param1", deserialized.Param1); + Assert.AreEqual("Param2", deserialized.Param2); + } - string json = JsonConvert.SerializeObject(m1, new JsonSerializerSettings - { - DateFormatHandling = DateFormatHandling.MicrosoftDateFormat, - }); - Assert.AreEqual(@"{""DefaultConverter"":""\/Date(0)\/"",""MemberConverter"":""1970-01-01T00:00:00Z""}", json); - - ExceptionAssert.Throws( - "Could not convert string to DateTime: /Date(0)/. Path 'DefaultConverter', line 1, position 33.", - () => - { - JsonConvert.DeserializeObject(json, new JsonSerializerSettings - { - DateParseHandling = DateParseHandling.None - }); - }); - } - - [Test] - public void SerializerShouldUseMemberConverter_IsoDate_DateParseNone() - { - DateTime testDate = new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc); - MemberConverterClass m1 = new MemberConverterClass { DefaultConverter = testDate, MemberConverter = testDate }; - - string json = JsonConvert.SerializeObject(m1, new JsonSerializerSettings - { - DateFormatHandling = DateFormatHandling.IsoDateFormat, - }); - Assert.AreEqual(@"{""DefaultConverter"":""1970-01-01T00:00:00Z"",""MemberConverter"":""1970-01-01T00:00:00Z""}", json); - - MemberConverterClass m2 = JsonConvert.DeserializeObject(json); - - Assert.AreEqual(testDate, m2.DefaultConverter); - Assert.AreEqual(testDate, m2.MemberConverter); - } - - [Test] - public void SerializerShouldUseMemberConverterOverArgumentConverter() - { - DateTime testDate = new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc); - MemberConverterClass m1 = new MemberConverterClass { DefaultConverter = testDate, MemberConverter = testDate }; - - string json = JsonConvert.SerializeObject(m1, new JavaScriptDateTimeConverter()); - Assert.AreEqual(@"{""DefaultConverter"":new Date(0),""MemberConverter"":""1970-01-01T00:00:00Z""}", json); - - MemberConverterClass m2 = JsonConvert.DeserializeObject(json, new JavaScriptDateTimeConverter()); - - Assert.AreEqual(testDate, m2.DefaultConverter); - Assert.AreEqual(testDate, m2.MemberConverter); - } - - [Test] - public void ConverterAttributeExample() - { - DateTime date = Convert.ToDateTime("1970-01-01T00:00:00Z").ToUniversalTime(); - - MemberConverterClass c = new MemberConverterClass + [Test] + public void SerializerShouldUseClassConverter() { - DefaultConverter = date, - MemberConverter = date - }; + ConverterPrecedenceClass c1 = new ConverterPrecedenceClass("!Test!"); - string json = JsonConvert.SerializeObject(c, Formatting.Indented); + string json = JsonConvert.SerializeObject(c1); + Assert.AreEqual(@"[""Class"",""!Test!""]", json); - Console.WriteLine(json); - //{ - // "DefaultConverter": "\/Date(0)\/", - // "MemberConverter": "1970-01-01T00:00:00Z" - //} - } + ConverterPrecedenceClass c2 = JsonConvert.DeserializeObject(json); - [Test] - public void SerializerShouldUseMemberConverterOverClassAndArgumentConverter() - { - ClassAndMemberConverterClass c1 = new ClassAndMemberConverterClass(); - c1.DefaultConverter = new ConverterPrecedenceClass("DefaultConverterValue"); - c1.MemberConverter = new ConverterPrecedenceClass("MemberConverterValue"); + Assert.AreEqual("!Test!", c2.TestValue); + } - string json = JsonConvert.SerializeObject(c1, new ArgumentConverterPrecedenceClassConverter()); - Assert.AreEqual(@"{""DefaultConverter"":[""Class"",""DefaultConverterValue""],""MemberConverter"":[""Member"",""MemberConverterValue""]}", json); - - ClassAndMemberConverterClass c2 = JsonConvert.DeserializeObject(json, new ArgumentConverterPrecedenceClassConverter()); - - Assert.AreEqual("DefaultConverterValue", c2.DefaultConverter.TestValue); - Assert.AreEqual("MemberConverterValue", c2.MemberConverter.TestValue); - } - - [Test] - public void IncompatibleJsonAttributeShouldThrow() - { - ExceptionAssert.Throws( - "Unexpected value when converting date. Expected DateTime or DateTimeOffset, got Newtonsoft.Json.Tests.TestObjects.IncompatibleJsonAttributeClass.", - () => + [Test] + public void SerializerShouldUseClassConverterOverArgumentConverter() { - IncompatibleJsonAttributeClass c = new IncompatibleJsonAttributeClass(); - JsonConvert.SerializeObject(c); - }); - } + ConverterPrecedenceClass c1 = new ConverterPrecedenceClass("!Test!"); - [Test] - public void GenericAbstractProperty() - { - string json = JsonConvert.SerializeObject(new GenericImpl()); - Assert.AreEqual(@"{""Id"":0}", json); - } + string json = JsonConvert.SerializeObject(c1, new ArgumentConverterPrecedenceClassConverter()); + Assert.AreEqual(@"[""Class"",""!Test!""]", json); - [Test] - public void DeserializeNullable() - { - string json; + ConverterPrecedenceClass c2 = JsonConvert.DeserializeObject(json, new ArgumentConverterPrecedenceClassConverter()); - json = JsonConvert.SerializeObject((int?)null); - Assert.AreEqual("null", json); + Assert.AreEqual("!Test!", c2.TestValue); + } - json = JsonConvert.SerializeObject((int?)1); - Assert.AreEqual("1", json); - } - - [Test] - public void SerializeJsonRaw() - { - PersonRaw personRaw = new PersonRaw + [Test] + public void SerializerShouldUseMemberConverter_IsoDate() { - FirstName = "FirstNameValue", - RawContent = new JRaw("[1,2,3,4,5]"), - LastName = "LastNameValue" - }; + DateTime testDate = new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc); + MemberConverterClass m1 = new MemberConverterClass { DefaultConverter = testDate, MemberConverter = testDate }; - string json; + string json = JsonConvert.SerializeObject(m1); + Assert.AreEqual(@"{""DefaultConverter"":""1970-01-01T00:00:00Z"",""MemberConverter"":""1970-01-01T00:00:00Z""}", json); - json = JsonConvert.SerializeObject(personRaw); - Assert.AreEqual(@"{""first_name"":""FirstNameValue"",""RawContent"":[1,2,3,4,5],""last_name"":""LastNameValue""}", json); - } + MemberConverterClass m2 = JsonConvert.DeserializeObject(json); - [Test] - public void DeserializeJsonRaw() - { - string json = @"{""first_name"":""FirstNameValue"",""RawContent"":[1,2,3,4,5],""last_name"":""LastNameValue""}"; + Assert.AreEqual(testDate, m2.DefaultConverter); + Assert.AreEqual(testDate, m2.MemberConverter); + } - PersonRaw personRaw = JsonConvert.DeserializeObject(json); - - Assert.AreEqual("FirstNameValue", personRaw.FirstName); - Assert.AreEqual("[1,2,3,4,5]", personRaw.RawContent.ToString()); - Assert.AreEqual("LastNameValue", personRaw.LastName); - } - - - [Test] - public void DeserializeNullableMember() - { - UserNullable userNullablle = new UserNullable + [Test] + public void SerializerShouldUseMemberConverter_MsDate() { - Id = new Guid("AD6205E8-0DF4-465d-AEA6-8BA18E93A7E7"), - FName = "FirstValue", - LName = "LastValue", - RoleId = 5, - NullableRoleId = 6, - NullRoleId = null, - Active = true - }; + DateTime testDate = new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc); + MemberConverterClass m1 = new MemberConverterClass { DefaultConverter = testDate, MemberConverter = testDate }; - string json = JsonConvert.SerializeObject(userNullablle); + string json = JsonConvert.SerializeObject(m1, new JsonSerializerSettings + { + DateFormatHandling = DateFormatHandling.MicrosoftDateFormat + }); + Assert.AreEqual(@"{""DefaultConverter"":""\/Date(0)\/"",""MemberConverter"":""1970-01-01T00:00:00Z""}", json); - Assert.AreEqual(@"{""Id"":""ad6205e8-0df4-465d-aea6-8ba18e93a7e7"",""FName"":""FirstValue"",""LName"":""LastValue"",""RoleId"":5,""NullableRoleId"":6,""NullRoleId"":null,""Active"":true}", json); + MemberConverterClass m2 = JsonConvert.DeserializeObject(json); - UserNullable userNullablleDeserialized = JsonConvert.DeserializeObject(json); + Assert.AreEqual(testDate, m2.DefaultConverter); + Assert.AreEqual(testDate, m2.MemberConverter); + } - Assert.AreEqual(new Guid("AD6205E8-0DF4-465d-AEA6-8BA18E93A7E7"), userNullablleDeserialized.Id); - Assert.AreEqual("FirstValue", userNullablleDeserialized.FName); - Assert.AreEqual("LastValue", userNullablleDeserialized.LName); - Assert.AreEqual(5, userNullablleDeserialized.RoleId); - Assert.AreEqual(6, userNullablleDeserialized.NullableRoleId); - Assert.AreEqual(null, userNullablleDeserialized.NullRoleId); - Assert.AreEqual(true, userNullablleDeserialized.Active); - } - - [Test] - public void DeserializeInt64ToNullableDouble() - { - string json = @"{""Height"":1}"; - - DoubleClass c = JsonConvert.DeserializeObject(json); - Assert.AreEqual(1, c.Height); - } - - [Test] - public void SerializeTypeProperty() - { - string boolRef = typeof(bool).AssemblyQualifiedName; - TypeClass typeClass = new TypeClass { TypeProperty = typeof(bool) }; - - string json = JsonConvert.SerializeObject(typeClass); - Assert.AreEqual(@"{""TypeProperty"":""" + boolRef + @"""}", json); - - TypeClass typeClass2 = JsonConvert.DeserializeObject(json); - Assert.AreEqual(typeof(bool), typeClass2.TypeProperty); - - string jsonSerializerTestRef = typeof(JsonSerializerTest).AssemblyQualifiedName; - typeClass = new TypeClass { TypeProperty = typeof(JsonSerializerTest) }; - - json = JsonConvert.SerializeObject(typeClass); - Assert.AreEqual(@"{""TypeProperty"":""" + jsonSerializerTestRef + @"""}", json); - - typeClass2 = JsonConvert.DeserializeObject(json); - Assert.AreEqual(typeof(JsonSerializerTest), typeClass2.TypeProperty); - } - - [Test] - public void RequiredMembersClass() - { - RequiredMembersClass c = new RequiredMembersClass() + [Test] + public void SerializerShouldUseMemberConverter_MsDate_DateParseNone() { - BirthDate = new DateTime(2000, 12, 20, 10, 55, 55, DateTimeKind.Utc), - FirstName = "Bob", - LastName = "Smith", - MiddleName = "Cosmo" - }; + DateTime testDate = new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc); + MemberConverterClass m1 = new MemberConverterClass { DefaultConverter = testDate, MemberConverter = testDate }; - string json = JsonConvert.SerializeObject(c, Formatting.Indented); + string json = JsonConvert.SerializeObject(m1, new JsonSerializerSettings + { + DateFormatHandling = DateFormatHandling.MicrosoftDateFormat, + }); + Assert.AreEqual(@"{""DefaultConverter"":""\/Date(0)\/"",""MemberConverter"":""1970-01-01T00:00:00Z""}", json); - Assert.AreEqual(@"{ + ExceptionAssert.Throws( + "Could not convert string to DateTime: /Date(0)/. Path 'DefaultConverter', line 1, position 33.", + () => + { + JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + DateParseHandling = DateParseHandling.None + }); + }); + } + + [Test] + public void SerializerShouldUseMemberConverter_IsoDate_DateParseNone() + { + DateTime testDate = new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc); + MemberConverterClass m1 = new MemberConverterClass { DefaultConverter = testDate, MemberConverter = testDate }; + + string json = JsonConvert.SerializeObject(m1, new JsonSerializerSettings + { + DateFormatHandling = DateFormatHandling.IsoDateFormat, + }); + Assert.AreEqual(@"{""DefaultConverter"":""1970-01-01T00:00:00Z"",""MemberConverter"":""1970-01-01T00:00:00Z""}", json); + + MemberConverterClass m2 = JsonConvert.DeserializeObject(json); + + Assert.AreEqual(testDate, m2.DefaultConverter); + Assert.AreEqual(testDate, m2.MemberConverter); + } + + [Test] + public void SerializerShouldUseMemberConverterOverArgumentConverter() + { + DateTime testDate = new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc); + MemberConverterClass m1 = new MemberConverterClass { DefaultConverter = testDate, MemberConverter = testDate }; + + string json = JsonConvert.SerializeObject(m1, new JavaScriptDateTimeConverter()); + Assert.AreEqual(@"{""DefaultConverter"":new Date(0),""MemberConverter"":""1970-01-01T00:00:00Z""}", json); + + MemberConverterClass m2 = JsonConvert.DeserializeObject(json, new JavaScriptDateTimeConverter()); + + Assert.AreEqual(testDate, m2.DefaultConverter); + Assert.AreEqual(testDate, m2.MemberConverter); + } + + [Test] + public void ConverterAttributeExample() + { + DateTime date = Convert.ToDateTime("1970-01-01T00:00:00Z").ToUniversalTime(); + + MemberConverterClass c = new MemberConverterClass + { + DefaultConverter = date, + MemberConverter = date + }; + + string json = JsonConvert.SerializeObject(c, Formatting.Indented); + + Console.WriteLine(json); + //{ + // "DefaultConverter": "\/Date(0)\/", + // "MemberConverter": "1970-01-01T00:00:00Z" + //} + } + + [Test] + public void SerializerShouldUseMemberConverterOverClassAndArgumentConverter() + { + ClassAndMemberConverterClass c1 = new ClassAndMemberConverterClass(); + c1.DefaultConverter = new ConverterPrecedenceClass("DefaultConverterValue"); + c1.MemberConverter = new ConverterPrecedenceClass("MemberConverterValue"); + + string json = JsonConvert.SerializeObject(c1, new ArgumentConverterPrecedenceClassConverter()); + Assert.AreEqual(@"{""DefaultConverter"":[""Class"",""DefaultConverterValue""],""MemberConverter"":[""Member"",""MemberConverterValue""]}", json); + + ClassAndMemberConverterClass c2 = JsonConvert.DeserializeObject(json, new ArgumentConverterPrecedenceClassConverter()); + + Assert.AreEqual("DefaultConverterValue", c2.DefaultConverter.TestValue); + Assert.AreEqual("MemberConverterValue", c2.MemberConverter.TestValue); + } + + [Test] + public void IncompatibleJsonAttributeShouldThrow() + { + ExceptionAssert.Throws( + "Unexpected value when converting date. Expected DateTime or DateTimeOffset, got Newtonsoft.Json.Tests.TestObjects.IncompatibleJsonAttributeClass.", + () => + { + IncompatibleJsonAttributeClass c = new IncompatibleJsonAttributeClass(); + JsonConvert.SerializeObject(c); + }); + } + + [Test] + public void GenericAbstractProperty() + { + string json = JsonConvert.SerializeObject(new GenericImpl()); + Assert.AreEqual(@"{""Id"":0}", json); + } + + [Test] + public void DeserializeNullable() + { + string json; + + json = JsonConvert.SerializeObject((int?)null); + Assert.AreEqual("null", json); + + json = JsonConvert.SerializeObject((int?)1); + Assert.AreEqual("1", json); + } + + [Test] + public void SerializeJsonRaw() + { + PersonRaw personRaw = new PersonRaw + { + FirstName = "FirstNameValue", + RawContent = new JRaw("[1,2,3,4,5]"), + LastName = "LastNameValue" + }; + + string json; + + json = JsonConvert.SerializeObject(personRaw); + Assert.AreEqual(@"{""first_name"":""FirstNameValue"",""RawContent"":[1,2,3,4,5],""last_name"":""LastNameValue""}", json); + } + + [Test] + public void DeserializeJsonRaw() + { + string json = @"{""first_name"":""FirstNameValue"",""RawContent"":[1,2,3,4,5],""last_name"":""LastNameValue""}"; + + PersonRaw personRaw = JsonConvert.DeserializeObject(json); + + Assert.AreEqual("FirstNameValue", personRaw.FirstName); + Assert.AreEqual("[1,2,3,4,5]", personRaw.RawContent.ToString()); + Assert.AreEqual("LastNameValue", personRaw.LastName); + } + + + [Test] + public void DeserializeNullableMember() + { + UserNullable userNullablle = new UserNullable + { + Id = new Guid("AD6205E8-0DF4-465d-AEA6-8BA18E93A7E7"), + FName = "FirstValue", + LName = "LastValue", + RoleId = 5, + NullableRoleId = 6, + NullRoleId = null, + Active = true + }; + + string json = JsonConvert.SerializeObject(userNullablle); + + Assert.AreEqual(@"{""Id"":""ad6205e8-0df4-465d-aea6-8ba18e93a7e7"",""FName"":""FirstValue"",""LName"":""LastValue"",""RoleId"":5,""NullableRoleId"":6,""NullRoleId"":null,""Active"":true}", json); + + UserNullable userNullablleDeserialized = JsonConvert.DeserializeObject(json); + + Assert.AreEqual(new Guid("AD6205E8-0DF4-465d-AEA6-8BA18E93A7E7"), userNullablleDeserialized.Id); + Assert.AreEqual("FirstValue", userNullablleDeserialized.FName); + Assert.AreEqual("LastValue", userNullablleDeserialized.LName); + Assert.AreEqual(5, userNullablleDeserialized.RoleId); + Assert.AreEqual(6, userNullablleDeserialized.NullableRoleId); + Assert.AreEqual(null, userNullablleDeserialized.NullRoleId); + Assert.AreEqual(true, userNullablleDeserialized.Active); + } + + [Test] + public void DeserializeInt64ToNullableDouble() + { + string json = @"{""Height"":1}"; + + DoubleClass c = JsonConvert.DeserializeObject(json); + Assert.AreEqual(1, c.Height); + } + + [Test] + public void SerializeTypeProperty() + { + string boolRef = typeof(bool).AssemblyQualifiedName; + TypeClass typeClass = new TypeClass { TypeProperty = typeof(bool) }; + + string json = JsonConvert.SerializeObject(typeClass); + Assert.AreEqual(@"{""TypeProperty"":""" + boolRef + @"""}", json); + + TypeClass typeClass2 = JsonConvert.DeserializeObject(json); + Assert.AreEqual(typeof(bool), typeClass2.TypeProperty); + + string jsonSerializerTestRef = typeof(JsonSerializerTest).AssemblyQualifiedName; + typeClass = new TypeClass { TypeProperty = typeof(JsonSerializerTest) }; + + json = JsonConvert.SerializeObject(typeClass); + Assert.AreEqual(@"{""TypeProperty"":""" + jsonSerializerTestRef + @"""}", json); + + typeClass2 = JsonConvert.DeserializeObject(json); + Assert.AreEqual(typeof(JsonSerializerTest), typeClass2.TypeProperty); + } + + [Test] + public void RequiredMembersClass() + { + RequiredMembersClass c = new RequiredMembersClass() + { + BirthDate = new DateTime(2000, 12, 20, 10, 55, 55, DateTimeKind.Utc), + FirstName = "Bob", + LastName = "Smith", + MiddleName = "Cosmo" + }; + + string json = JsonConvert.SerializeObject(c, Formatting.Indented); + + Assert.AreEqual(@"{ ""FirstName"": ""Bob"", ""MiddleName"": ""Cosmo"", ""LastName"": ""Smith"", ""BirthDate"": ""2000-12-20T10:55:55Z"" }", json); - RequiredMembersClass c2 = JsonConvert.DeserializeObject(json); + RequiredMembersClass c2 = JsonConvert.DeserializeObject(json); - Assert.AreEqual("Bob", c2.FirstName); - Assert.AreEqual(new DateTime(2000, 12, 20, 10, 55, 55, DateTimeKind.Utc), c2.BirthDate); - } + Assert.AreEqual("Bob", c2.FirstName); + Assert.AreEqual(new DateTime(2000, 12, 20, 10, 55, 55, DateTimeKind.Utc), c2.BirthDate); + } - [Test] - public void DeserializeRequiredMembersClassWithNullValues() - { - string json = @"{ + [Test] + public void DeserializeRequiredMembersClassWithNullValues() + { + string json = @"{ ""FirstName"": ""I can't be null bro!"", ""MiddleName"": null, ""LastName"": null, ""BirthDate"": ""\/Date(977309755000)\/"" }"; - RequiredMembersClass c = JsonConvert.DeserializeObject(json); + RequiredMembersClass c = JsonConvert.DeserializeObject(json); - Assert.AreEqual("I can't be null bro!", c.FirstName); - Assert.AreEqual(null, c.MiddleName); - Assert.AreEqual(null, c.LastName); - } + Assert.AreEqual("I can't be null bro!", c.FirstName); + Assert.AreEqual(null, c.MiddleName); + Assert.AreEqual(null, c.LastName); + } - [Test] - public void DeserializeRequiredMembersClassNullRequiredValueProperty() - { - ExceptionAssert.Throws( - "Required property 'FirstName' expects a value but got null. Path '', line 6, position 2.", - () => + [Test] + public void DeserializeRequiredMembersClassNullRequiredValueProperty() { - string json = @"{ + ExceptionAssert.Throws( + "Required property 'FirstName' expects a value but got null. Path '', line 6, position 2.", + () => + { + string json = @"{ ""FirstName"": null, ""MiddleName"": null, ""LastName"": null, ""BirthDate"": ""\/Date(977309755000)\/"" }"; - JsonConvert.DeserializeObject(json); - }); - } + JsonConvert.DeserializeObject(json); + }); + } - [Test] - public void SerializeRequiredMembersClassNullRequiredValueProperty() - { - ExceptionAssert.Throws( - "Cannot write a null value for property 'FirstName'. Property requires a value. Path ''.", - () => + [Test] + public void SerializeRequiredMembersClassNullRequiredValueProperty() { - RequiredMembersClass requiredMembersClass = new RequiredMembersClass - { - FirstName = null, - BirthDate = new DateTime(2000, 10, 10, 10, 10, 10, DateTimeKind.Utc), - LastName = null, - MiddleName = null - }; + ExceptionAssert.Throws( + "Cannot write a null value for property 'FirstName'. Property requires a value. Path ''.", + () => + { + RequiredMembersClass requiredMembersClass = new RequiredMembersClass + { + FirstName = null, + BirthDate = new DateTime(2000, 10, 10, 10, 10, 10, DateTimeKind.Utc), + LastName = null, + MiddleName = null + }; - string json = JsonConvert.SerializeObject(requiredMembersClass); - Console.WriteLine(json); - }); - } + string json = JsonConvert.SerializeObject(requiredMembersClass); + Console.WriteLine(json); + }); + } - [Test] - public void RequiredMembersClassMissingRequiredProperty() - { - ExceptionAssert.Throws( - "Required property 'LastName' not found in JSON. Path '', line 3, position 2.", - () => + [Test] + public void RequiredMembersClassMissingRequiredProperty() { - string json = @"{ + ExceptionAssert.Throws( + "Required property 'LastName' not found in JSON. Path '', line 3, position 2.", + () => + { + string json = @"{ ""FirstName"": ""Bob"" }"; - JsonConvert.DeserializeObject(json); - }); - } + JsonConvert.DeserializeObject(json); + }); + } - [Test] - public void SerializeJaggedArray() - { - JaggedArray aa = new JaggedArray(); - aa.Before = "Before!"; - aa.After = "After!"; - aa.Coordinates = new[] { new[] { 1, 1 }, new[] { 1, 2 }, new[] { 2, 1 }, new[] { 2, 2 } }; + [Test] + public void SerializeJaggedArray() + { + JaggedArray aa = new JaggedArray(); + aa.Before = "Before!"; + aa.After = "After!"; + aa.Coordinates = new[] { new[] { 1, 1 }, new[] { 1, 2 }, new[] { 2, 1 }, new[] { 2, 2 } }; - string json = JsonConvert.SerializeObject(aa); + string json = JsonConvert.SerializeObject(aa); - Assert.AreEqual(@"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2],[2,1],[2,2]],""After"":""After!""}", json); - } + Assert.AreEqual(@"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2],[2,1],[2,2]],""After"":""After!""}", json); + } - [Test] - public void DeserializeJaggedArray() - { - string json = @"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2],[2,1],[2,2]],""After"":""After!""}"; + [Test] + public void DeserializeJaggedArray() + { + string json = @"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2],[2,1],[2,2]],""After"":""After!""}"; - JaggedArray aa = JsonConvert.DeserializeObject(json); + JaggedArray aa = JsonConvert.DeserializeObject(json); - Assert.AreEqual("Before!", aa.Before); - Assert.AreEqual("After!", aa.After); - Assert.AreEqual(4, aa.Coordinates.Length); - Assert.AreEqual(2, aa.Coordinates[0].Length); - Assert.AreEqual(1, aa.Coordinates[0][0]); - Assert.AreEqual(2, aa.Coordinates[1][1]); + Assert.AreEqual("Before!", aa.Before); + Assert.AreEqual("After!", aa.After); + Assert.AreEqual(4, aa.Coordinates.Length); + Assert.AreEqual(2, aa.Coordinates[0].Length); + Assert.AreEqual(1, aa.Coordinates[0][0]); + Assert.AreEqual(2, aa.Coordinates[1][1]); - string after = JsonConvert.SerializeObject(aa); + string after = JsonConvert.SerializeObject(aa); - Assert.AreEqual(json, after); - } + Assert.AreEqual(json, after); + } - [Test] - public void DeserializeGoogleGeoCode() - { - string json = @"{ + [Test] + public void DeserializeGoogleGeoCode() + { + string json = @"{ ""name"": ""1600 Amphitheatre Parkway, Mountain View, CA, USA"", ""Status"": { ""code"": 200, @@ -2386,80 +2405,77 @@ keyword such as type of business."" ] }"; - GoogleMapGeocoderStructure jsonGoogleMapGeocoder = JsonConvert.DeserializeObject(json); - } + GoogleMapGeocoderStructure jsonGoogleMapGeocoder = JsonConvert.DeserializeObject(json); + } - [Test] - public void DeserializeInterfaceProperty() - { - InterfacePropertyTestClass testClass = new InterfacePropertyTestClass(); - testClass.co = new Co(); - String strFromTest = JsonConvert.SerializeObject(testClass); - - ExceptionAssert.Throws( - @"Could not create an instance of type Newtonsoft.Json.Tests.TestObjects.ICo. Type is an interface or abstract class and cannot be instantiated. Path 'co.Name', line 1, position 14.", - () => + [Test] + public void DeserializeInterfaceProperty() { - InterfacePropertyTestClass testFromDe = (InterfacePropertyTestClass)JsonConvert.DeserializeObject(strFromTest, typeof(InterfacePropertyTestClass)); - }); - } + InterfacePropertyTestClass testClass = new InterfacePropertyTestClass(); + testClass.co = new Co(); + String strFromTest = JsonConvert.SerializeObject(testClass); - private Person GetPerson() - { - Person person = new Person + ExceptionAssert.Throws( + @"Could not create an instance of type Newtonsoft.Json.Tests.TestObjects.ICo. Type is an interface or abstract class and cannot be instantiated. Path 'co.Name', line 1, position 14.", + () => { InterfacePropertyTestClass testFromDe = (InterfacePropertyTestClass)JsonConvert.DeserializeObject(strFromTest, typeof(InterfacePropertyTestClass)); }); + } + + private Person GetPerson() { - Name = "Mike Manager", - BirthDate = new DateTime(1983, 8, 3, 0, 0, 0, DateTimeKind.Utc), - Department = "IT", - LastModified = new DateTime(2009, 2, 15, 0, 0, 0, DateTimeKind.Utc) - }; - return person; - } + Person person = new Person + { + Name = "Mike Manager", + BirthDate = new DateTime(1983, 8, 3, 0, 0, 0, DateTimeKind.Utc), + Department = "IT", + LastModified = new DateTime(2009, 2, 15, 0, 0, 0, DateTimeKind.Utc) + }; + return person; + } - [Test] - public void WriteJsonDates() - { - LogEntry entry = new LogEntry + [Test] + public void WriteJsonDates() { - LogDate = new DateTime(2009, 2, 15, 0, 0, 0, DateTimeKind.Utc), - Details = "Application started." - }; + LogEntry entry = new LogEntry + { + LogDate = new DateTime(2009, 2, 15, 0, 0, 0, DateTimeKind.Utc), + Details = "Application started." + }; - string defaultJson = JsonConvert.SerializeObject(entry); - // {"Details":"Application started.","LogDate":"\/Date(1234656000000)\/"} + string defaultJson = JsonConvert.SerializeObject(entry); + // {"Details":"Application started.","LogDate":"\/Date(1234656000000)\/"} - string isoJson = JsonConvert.SerializeObject(entry, new IsoDateTimeConverter()); - // {"Details":"Application started.","LogDate":"2009-02-15T00:00:00.0000000Z"} + string isoJson = JsonConvert.SerializeObject(entry, new IsoDateTimeConverter()); + // {"Details":"Application started.","LogDate":"2009-02-15T00:00:00.0000000Z"} - string javascriptJson = JsonConvert.SerializeObject(entry, new JavaScriptDateTimeConverter()); - // {"Details":"Application started.","LogDate":new Date(1234656000000)} + string javascriptJson = JsonConvert.SerializeObject(entry, new JavaScriptDateTimeConverter()); + // {"Details":"Application started.","LogDate":new Date(1234656000000)} - Console.WriteLine(defaultJson); - Console.WriteLine(isoJson); - Console.WriteLine(javascriptJson); - } + Console.WriteLine(defaultJson); + Console.WriteLine(isoJson); + Console.WriteLine(javascriptJson); + } - public void GenericListAndDictionaryInterfaceProperties() - { - GenericListAndDictionaryInterfaceProperties o = new GenericListAndDictionaryInterfaceProperties(); - o.IDictionaryProperty = new Dictionary + public void GenericListAndDictionaryInterfaceProperties() { - {"one", 1}, - {"two", 2}, - {"three", 3} - }; - o.IListProperty = new List - { - 1, 2, 3 - }; - o.IEnumerableProperty = new List - { - 4, 5, 6 - }; + GenericListAndDictionaryInterfaceProperties o = new GenericListAndDictionaryInterfaceProperties(); + o.IDictionaryProperty = new Dictionary + { + { "one", 1 }, + { "two", 2 }, + { "three", 3 } + }; + o.IListProperty = new List + { + 1, 2, 3 + }; + o.IEnumerableProperty = new List + { + 4, 5, 6 + }; - string json = JsonConvert.SerializeObject(o, Formatting.Indented); + string json = JsonConvert.SerializeObject(o, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""IEnumerableProperty"": [ 4, 5, @@ -2477,141 +2493,140 @@ keyword such as type of business."" } }", json); - GenericListAndDictionaryInterfaceProperties deserializedObject = JsonConvert.DeserializeObject(json); - Assert.IsNotNull(deserializedObject); + GenericListAndDictionaryInterfaceProperties deserializedObject = JsonConvert.DeserializeObject(json); + Assert.IsNotNull(deserializedObject); - CollectionAssert.AreEqual(o.IListProperty.ToArray(), deserializedObject.IListProperty.ToArray()); - CollectionAssert.AreEqual(o.IEnumerableProperty.ToArray(), deserializedObject.IEnumerableProperty.ToArray()); - CollectionAssert.AreEqual(o.IDictionaryProperty.ToArray(), deserializedObject.IDictionaryProperty.ToArray()); - } + CollectionAssert.AreEqual(o.IListProperty.ToArray(), deserializedObject.IListProperty.ToArray()); + CollectionAssert.AreEqual(o.IEnumerableProperty.ToArray(), deserializedObject.IEnumerableProperty.ToArray()); + CollectionAssert.AreEqual(o.IDictionaryProperty.ToArray(), deserializedObject.IDictionaryProperty.ToArray()); + } - [Test] - public void DeserializeBestMatchPropertyCase() - { - string json = @"{ + [Test] + public void DeserializeBestMatchPropertyCase() + { + string json = @"{ ""firstName"": ""firstName"", ""FirstName"": ""FirstName"", ""LastName"": ""LastName"", ""lastName"": ""lastName"", }"; - PropertyCase o = JsonConvert.DeserializeObject(json); - Assert.IsNotNull(o); + PropertyCase o = JsonConvert.DeserializeObject(json); + Assert.IsNotNull(o); - Assert.AreEqual("firstName", o.firstName); - Assert.AreEqual("FirstName", o.FirstName); - Assert.AreEqual("LastName", o.LastName); - Assert.AreEqual("lastName", o.lastName); - } + Assert.AreEqual("firstName", o.firstName); + Assert.AreEqual("FirstName", o.FirstName); + Assert.AreEqual("LastName", o.LastName); + Assert.AreEqual("lastName", o.lastName); + } - public sealed class ConstructorAndDefaultValueAttributeTestClass - { - public ConstructorAndDefaultValueAttributeTestClass(string testProperty1) - { - this.TestProperty1 = testProperty1; - } - - public string TestProperty1 { get; set; } - - [DefaultValue(21)] - public int TestProperty2 { get; set; } - - } - - [Test] - public void PopulateDefaultValueWhenUsingConstructor() - { - string json = "{ 'testProperty1': 'value' }"; - - ConstructorAndDefaultValueAttributeTestClass c = JsonConvert.DeserializeObject(json, new JsonSerializerSettings - { - DefaultValueHandling = DefaultValueHandling.Populate - }); - Assert.AreEqual("value", c.TestProperty1); - Assert.AreEqual(21, c.TestProperty2); - - c = JsonConvert.DeserializeObject(json, new JsonSerializerSettings - { - DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate - }); - Assert.AreEqual("value", c.TestProperty1); - Assert.AreEqual(21, c.TestProperty2); - } - - public sealed class ConstructorAndRequiredTestClass - { - public ConstructorAndRequiredTestClass(string testProperty1) - { - this.TestProperty1 = testProperty1; - } - - public string TestProperty1 { get; set; } - - [JsonProperty(Required = Required.AllowNull)] - public int TestProperty2 { get; set; } - } - - [Test] - public void RequiredWhenUsingConstructor() - { - string json = "{ 'testProperty1': 'value' }"; - - ExceptionAssert.Throws("Required property 'TestProperty2' not found in JSON. Path '', line 1, position 28.", - () => JsonConvert.DeserializeObject(json)); - } - - [Test] - public void DeserializePropertiesOnToNonDefaultConstructor() - { - SubKlass i = new SubKlass("my subprop"); - i.SuperProp = "overrided superprop"; - - string json = JsonConvert.SerializeObject(i); - Assert.AreEqual(@"{""SubProp"":""my subprop"",""SuperProp"":""overrided superprop""}", json); - - SubKlass ii = JsonConvert.DeserializeObject(json); - - string newJson = JsonConvert.SerializeObject(ii); - Assert.AreEqual(@"{""SubProp"":""my subprop"",""SuperProp"":""overrided superprop""}", newJson); - } - - [Test] - public void DeserializePropertiesOnToNonDefaultConstructorWithReferenceTracking() - { - SubKlass i = new SubKlass("my subprop"); - i.SuperProp = "overrided superprop"; - - string json = JsonConvert.SerializeObject(i, new JsonSerializerSettings + public sealed class ConstructorAndDefaultValueAttributeTestClass { - PreserveReferencesHandling = PreserveReferencesHandling.Objects - }); + public ConstructorAndDefaultValueAttributeTestClass(string testProperty1) + { + TestProperty1 = testProperty1; + } - Assert.AreEqual(@"{""$id"":""1"",""SubProp"":""my subprop"",""SuperProp"":""overrided superprop""}", json); + public string TestProperty1 { get; set; } - SubKlass ii = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + [DefaultValue(21)] + public int TestProperty2 { get; set; } + } + + [Test] + public void PopulateDefaultValueWhenUsingConstructor() { - PreserveReferencesHandling = PreserveReferencesHandling.Objects - }); + string json = "{ 'testProperty1': 'value' }"; - string newJson = JsonConvert.SerializeObject(ii, new JsonSerializerSettings - { - PreserveReferencesHandling = PreserveReferencesHandling.Objects - }); - Assert.AreEqual(@"{""$id"":""1"",""SubProp"":""my subprop"",""SuperProp"":""overrided superprop""}", newJson); - } + ConstructorAndDefaultValueAttributeTestClass c = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + DefaultValueHandling = DefaultValueHandling.Populate + }); + Assert.AreEqual("value", c.TestProperty1); + Assert.AreEqual(21, c.TestProperty2); - [Test] - public void SerializeJsonPropertyWithHandlingValues() - { - JsonPropertyWithHandlingValues o = new JsonPropertyWithHandlingValues(); - o.DefaultValueHandlingIgnoreProperty = "Default!"; - o.DefaultValueHandlingIncludeProperty = "Default!"; - o.DefaultValueHandlingPopulateProperty = "Default!"; - o.DefaultValueHandlingIgnoreAndPopulateProperty = "Default!"; + c = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate + }); + Assert.AreEqual("value", c.TestProperty1); + Assert.AreEqual(21, c.TestProperty2); + } - string json = JsonConvert.SerializeObject(o, Formatting.Indented); + public sealed class ConstructorAndRequiredTestClass + { + public ConstructorAndRequiredTestClass(string testProperty1) + { + TestProperty1 = testProperty1; + } - Assert.AreEqual(@"{ + public string TestProperty1 { get; set; } + + [JsonProperty(Required = Required.AllowNull)] + public int TestProperty2 { get; set; } + } + + [Test] + public void RequiredWhenUsingConstructor() + { + string json = "{ 'testProperty1': 'value' }"; + + ExceptionAssert.Throws("Required property 'TestProperty2' not found in JSON. Path '', line 1, position 28.", + () => JsonConvert.DeserializeObject(json)); + } + + [Test] + public void DeserializePropertiesOnToNonDefaultConstructor() + { + SubKlass i = new SubKlass("my subprop"); + i.SuperProp = "overrided superprop"; + + string json = JsonConvert.SerializeObject(i); + Assert.AreEqual(@"{""SubProp"":""my subprop"",""SuperProp"":""overrided superprop""}", json); + + SubKlass ii = JsonConvert.DeserializeObject(json); + + string newJson = JsonConvert.SerializeObject(ii); + Assert.AreEqual(@"{""SubProp"":""my subprop"",""SuperProp"":""overrided superprop""}", newJson); + } + + [Test] + public void DeserializePropertiesOnToNonDefaultConstructorWithReferenceTracking() + { + SubKlass i = new SubKlass("my subprop"); + i.SuperProp = "overrided superprop"; + + string json = JsonConvert.SerializeObject(i, new JsonSerializerSettings + { + PreserveReferencesHandling = PreserveReferencesHandling.Objects + }); + + Assert.AreEqual(@"{""$id"":""1"",""SubProp"":""my subprop"",""SuperProp"":""overrided superprop""}", json); + + SubKlass ii = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + PreserveReferencesHandling = PreserveReferencesHandling.Objects + }); + + string newJson = JsonConvert.SerializeObject(ii, new JsonSerializerSettings + { + PreserveReferencesHandling = PreserveReferencesHandling.Objects + }); + Assert.AreEqual(@"{""$id"":""1"",""SubProp"":""my subprop"",""SuperProp"":""overrided superprop""}", newJson); + } + + [Test] + public void SerializeJsonPropertyWithHandlingValues() + { + JsonPropertyWithHandlingValues o = new JsonPropertyWithHandlingValues(); + o.DefaultValueHandlingIgnoreProperty = "Default!"; + o.DefaultValueHandlingIncludeProperty = "Default!"; + o.DefaultValueHandlingPopulateProperty = "Default!"; + o.DefaultValueHandlingIgnoreAndPopulateProperty = "Default!"; + + string json = JsonConvert.SerializeObject(o, Formatting.Indented); + + Assert.AreEqual(@"{ ""DefaultValueHandlingIncludeProperty"": ""Default!"", ""DefaultValueHandlingPopulateProperty"": ""Default!"", ""NullValueHandlingIncludeProperty"": null, @@ -2620,47 +2635,47 @@ keyword such as type of business."" ""ReferenceLoopHandlingSerializeProperty"": null }", json); - json = JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + json = JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""DefaultValueHandlingIncludeProperty"": ""Default!"", ""DefaultValueHandlingPopulateProperty"": ""Default!"", ""NullValueHandlingIncludeProperty"": null }", json); - } + } - [Test] - public void DeserializeJsonPropertyWithHandlingValues() - { - string json = "{}"; - - JsonPropertyWithHandlingValues o = JsonConvert.DeserializeObject(json); - Assert.AreEqual("Default!", o.DefaultValueHandlingIgnoreAndPopulateProperty); - Assert.AreEqual("Default!", o.DefaultValueHandlingPopulateProperty); - Assert.AreEqual(null, o.DefaultValueHandlingIgnoreProperty); - Assert.AreEqual(null, o.DefaultValueHandlingIncludeProperty); - } - - [Test] - public void JsonPropertyWithHandlingValues_ReferenceLoopError() - { - string classRef = typeof(JsonPropertyWithHandlingValues).FullName; - - ExceptionAssert.Throws( - "Self referencing loop detected for property 'ReferenceLoopHandlingErrorProperty' with type '" + classRef + "'. Path ''.", - () => + [Test] + public void DeserializeJsonPropertyWithHandlingValues() { - JsonPropertyWithHandlingValues o = new JsonPropertyWithHandlingValues(); - o.ReferenceLoopHandlingErrorProperty = o; + string json = "{}"; - JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); - }); - } + JsonPropertyWithHandlingValues o = JsonConvert.DeserializeObject(json); + Assert.AreEqual("Default!", o.DefaultValueHandlingIgnoreAndPopulateProperty); + Assert.AreEqual("Default!", o.DefaultValueHandlingPopulateProperty); + Assert.AreEqual(null, o.DefaultValueHandlingIgnoreProperty); + Assert.AreEqual(null, o.DefaultValueHandlingIncludeProperty); + } - [Test] - public void PartialClassDeserialize() - { - string json = @"{ + [Test] + public void JsonPropertyWithHandlingValues_ReferenceLoopError() + { + string classRef = typeof(JsonPropertyWithHandlingValues).FullName; + + ExceptionAssert.Throws( + "Self referencing loop detected for property 'ReferenceLoopHandlingErrorProperty' with type '" + classRef + "'. Path ''.", + () => + { + JsonPropertyWithHandlingValues o = new JsonPropertyWithHandlingValues(); + o.ReferenceLoopHandlingErrorProperty = o; + + JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); + }); + } + + [Test] + public void PartialClassDeserialize() + { + string json = @"{ ""request"": ""ux.settings.update"", ""sid"": ""14c561bd-32a8-457e-b4e5-4bba0832897f"", ""uid"": ""30c39065-0f31-de11-9442-001e3786a8ec"", @@ -2678,143 +2693,143 @@ keyword such as type of business."" ""setting"": ""entity.field.order"" }"; - RequestOnly r = JsonConvert.DeserializeObject(json); - Assert.AreEqual("ux.settings.update", r.Request); + RequestOnly r = JsonConvert.DeserializeObject(json); + Assert.AreEqual("ux.settings.update", r.Request); - NonRequest n = JsonConvert.DeserializeObject(json); - Assert.AreEqual(new Guid("14c561bd-32a8-457e-b4e5-4bba0832897f"), n.Sid); - Assert.AreEqual(new Guid("30c39065-0f31-de11-9442-001e3786a8ec"), n.Uid); - Assert.AreEqual(8, n.FidOrder.Count); - Assert.AreEqual("id", n.FidOrder[0]); - Assert.AreEqual("titleId", n.FidOrder[n.FidOrder.Count - 1]); - } + NonRequest n = JsonConvert.DeserializeObject(json); + Assert.AreEqual(new Guid("14c561bd-32a8-457e-b4e5-4bba0832897f"), n.Sid); + Assert.AreEqual(new Guid("30c39065-0f31-de11-9442-001e3786a8ec"), n.Uid); + Assert.AreEqual(8, n.FidOrder.Count); + Assert.AreEqual("id", n.FidOrder[0]); + Assert.AreEqual("titleId", n.FidOrder[n.FidOrder.Count - 1]); + } #if !(SILVERLIGHT || NET20 || NETFX_CORE || PORTABLE || PORTABLE40) - [MetadataType(typeof(OptInClassMetadata))] - public class OptInClass - { - [DataContract] - public class OptInClassMetadata - { - [DataMember] - public string Name { get; set; } + [MetadataType(typeof(OptInClassMetadata))] + public class OptInClass + { + [DataContract] + public class OptInClassMetadata + { + [DataMember] + public string Name { get; set; } - [DataMember] - public int Age { get; set; } + [DataMember] + public int Age { get; set; } - public string NotIncluded { get; set; } - } + public string NotIncluded { get; set; } + } - public string Name { get; set; } - public int Age { get; set; } - public string NotIncluded { get; set; } - } + public string Name { get; set; } + public int Age { get; set; } + public string NotIncluded { get; set; } + } - [Test] - public void OptInClassMetadataSerialization() - { - OptInClass optInClass = new OptInClass(); - optInClass.Age = 26; - optInClass.Name = "James NK"; - optInClass.NotIncluded = "Poor me :("; + [Test] + public void OptInClassMetadataSerialization() + { + OptInClass optInClass = new OptInClass(); + optInClass.Age = 26; + optInClass.Name = "James NK"; + optInClass.NotIncluded = "Poor me :("; - string json = JsonConvert.SerializeObject(optInClass, Formatting.Indented); + string json = JsonConvert.SerializeObject(optInClass, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Name"": ""James NK"", ""Age"": 26 }", json); - OptInClass newOptInClass = JsonConvert.DeserializeObject(@"{ + OptInClass newOptInClass = JsonConvert.DeserializeObject(@"{ ""Name"": ""James NK"", ""NotIncluded"": ""Ignore me!"", ""Age"": 26 }"); - Assert.AreEqual(26, newOptInClass.Age); - Assert.AreEqual("James NK", newOptInClass.Name); - Assert.AreEqual(null, newOptInClass.NotIncluded); - } + Assert.AreEqual(26, newOptInClass.Age); + Assert.AreEqual("James NK", newOptInClass.Name); + Assert.AreEqual(null, newOptInClass.NotIncluded); + } #endif #if !NET20 - [DataContract] - public class DataContractPrivateMembers - { - public DataContractPrivateMembers() - { - } + [DataContract] + public class DataContractPrivateMembers + { + public DataContractPrivateMembers() + { + } - public DataContractPrivateMembers(string name, int age, int rank, string title) - { - _name = name; - Age = age; - Rank = rank; - Title = title; - } + public DataContractPrivateMembers(string name, int age, int rank, string title) + { + _name = name; + Age = age; + Rank = rank; + Title = title; + } - [DataMember] - private string _name; + [DataMember] + private string _name; - [DataMember(Name = "_age")] - private int Age { get; set; } + [DataMember(Name = "_age")] + private int Age { get; set; } - [JsonProperty] - private int Rank { get; set; } + [JsonProperty] + private int Rank { get; set; } - [JsonProperty(PropertyName = "JsonTitle")] - [DataMember(Name = "DataTitle")] - private string Title { get; set; } + [JsonProperty(PropertyName = "JsonTitle")] + [DataMember(Name = "DataTitle")] + private string Title { get; set; } - public string NotIncluded { get; set; } + public string NotIncluded { get; set; } - public override string ToString() - { - return "_name: " + _name + ", _age: " + Age + ", Rank: " + Rank + ", JsonTitle: " + Title; - } - } + public override string ToString() + { + return "_name: " + _name + ", _age: " + Age + ", Rank: " + Rank + ", JsonTitle: " + Title; + } + } - [Test] - public void SerializeDataContractPrivateMembers() - { - DataContractPrivateMembers c = new DataContractPrivateMembers("Jeff", 26, 10, "Dr"); - c.NotIncluded = "Hi"; - string json = JsonConvert.SerializeObject(c, Formatting.Indented); + [Test] + public void SerializeDataContractPrivateMembers() + { + DataContractPrivateMembers c = new DataContractPrivateMembers("Jeff", 26, 10, "Dr"); + c.NotIncluded = "Hi"; + string json = JsonConvert.SerializeObject(c, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""_name"": ""Jeff"", ""_age"": 26, ""Rank"": 10, ""JsonTitle"": ""Dr"" }", json); - DataContractPrivateMembers cc = JsonConvert.DeserializeObject(json); - Assert.AreEqual("_name: Jeff, _age: 26, Rank: 10, JsonTitle: Dr", cc.ToString()); - } + DataContractPrivateMembers cc = JsonConvert.DeserializeObject(json); + Assert.AreEqual("_name: Jeff, _age: 26, Rank: 10, JsonTitle: Dr", cc.ToString()); + } #endif - [Test] - public void DeserializeDictionaryInterface() - { - string json = @"{ + [Test] + public void DeserializeDictionaryInterface() + { + string json = @"{ ""Name"": ""Name!"", ""Dictionary"": { ""Item"": 11 } }"; - DictionaryInterfaceClass c = JsonConvert.DeserializeObject( - json, - new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Replace }); + DictionaryInterfaceClass c = JsonConvert.DeserializeObject( + json, + new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Replace }); - Assert.AreEqual("Name!", c.Name); - Assert.AreEqual(1, c.Dictionary.Count); - Assert.AreEqual(11, c.Dictionary["Item"]); - } + Assert.AreEqual("Name!", c.Name); + Assert.AreEqual(1, c.Dictionary.Count); + Assert.AreEqual(11, c.Dictionary["Item"]); + } - [Test] - public void DeserializeDictionaryInterfaceWithExistingValues() - { - string json = @"{ + [Test] + public void DeserializeDictionaryInterfaceWithExistingValues() + { + string json = @"{ ""Random"": { ""blah"": 1 }, @@ -2833,25 +2848,25 @@ keyword such as type of business."" } }"; - DictionaryInterfaceClass c = JsonConvert.DeserializeObject(json, - new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Reuse }); + DictionaryInterfaceClass c = JsonConvert.DeserializeObject(json, + new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Reuse }); - Assert.AreEqual("Name!", c.Name); - Assert.AreEqual(3, c.Dictionary.Count); - Assert.AreEqual(11, c.Dictionary["Item"]); - Assert.AreEqual(1, c.Dictionary["existing"]); - Assert.AreEqual(4, c.Collection.Count); - Assert.AreEqual(1, c.Collection.ElementAt(0)); - Assert.AreEqual(999, c.Collection.ElementAt(3)); - Assert.AreEqual("EmployeeName!", c.Employee.Name); - Assert.AreEqual("ManagerName!", c.Employee.Manager.Name); - Assert.IsNotNull(c.Random); - } + Assert.AreEqual("Name!", c.Name); + Assert.AreEqual(3, c.Dictionary.Count); + Assert.AreEqual(11, c.Dictionary["Item"]); + Assert.AreEqual(1, c.Dictionary["existing"]); + Assert.AreEqual(4, c.Collection.Count); + Assert.AreEqual(1, c.Collection.ElementAt(0)); + Assert.AreEqual(999, c.Collection.ElementAt(3)); + Assert.AreEqual("EmployeeName!", c.Employee.Name); + Assert.AreEqual("ManagerName!", c.Employee.Manager.Name); + Assert.IsNotNull(c.Random); + } - [Test] - public void TypedObjectDeserializationWithComments() - { - string json = @"/*comment*/ { /*comment*/ + [Test] + public void TypedObjectDeserializationWithComments() + { + string json = @"/*comment*/ { /*comment*/ ""Name"": /*comment*/ ""Apple"" /*comment*/, /*comment*/ ""ExpiryDate"": ""\/Date(1230422400000)\/"", ""Price"": 3.99, @@ -2862,20 +2877,20 @@ keyword such as type of business."" /*comment*/ ] /*comment*/ } /*comment*/"; - Product deserializedProduct = (Product)JsonConvert.DeserializeObject(json, typeof(Product)); + Product deserializedProduct = (Product)JsonConvert.DeserializeObject(json, typeof(Product)); - Assert.AreEqual("Apple", deserializedProduct.Name); - Assert.AreEqual(new DateTime(2008, 12, 28, 0, 0, 0, DateTimeKind.Utc), deserializedProduct.ExpiryDate); - Assert.AreEqual(3.99m, deserializedProduct.Price); - Assert.AreEqual("Small", deserializedProduct.Sizes[0]); - Assert.AreEqual("Medium", deserializedProduct.Sizes[1]); - Assert.AreEqual("Large", deserializedProduct.Sizes[2]); - } + Assert.AreEqual("Apple", deserializedProduct.Name); + Assert.AreEqual(new DateTime(2008, 12, 28, 0, 0, 0, DateTimeKind.Utc), deserializedProduct.ExpiryDate); + Assert.AreEqual(3.99m, deserializedProduct.Price); + Assert.AreEqual("Small", deserializedProduct.Sizes[0]); + Assert.AreEqual("Medium", deserializedProduct.Sizes[1]); + Assert.AreEqual("Large", deserializedProduct.Sizes[2]); + } - [Test] - public void NestedInsideOuterObject() - { - string json = @"{ + [Test] + public void NestedInsideOuterObject() + { + string json = @"{ ""short"": { ""original"": ""http://www.contrast.ie/blog/online-marketing-2009/"", ""short"": ""m2sqc6"", @@ -2887,57 +2902,57 @@ keyword such as type of business."" } }"; - JObject o = JObject.Parse(json); + JObject o = JObject.Parse(json); - Shortie s = JsonConvert.DeserializeObject(o["short"].ToString()); - Assert.IsNotNull(s); + Shortie s = JsonConvert.DeserializeObject(o["short"].ToString()); + Assert.IsNotNull(s); - Assert.AreEqual(s.Original, "http://www.contrast.ie/blog/online-marketing-2009/"); - Assert.AreEqual(s.Short, "m2sqc6"); - Assert.AreEqual(s.Shortened, "http://short.ie/m2sqc6"); - } + Assert.AreEqual(s.Original, "http://www.contrast.ie/blog/online-marketing-2009/"); + Assert.AreEqual(s.Short, "m2sqc6"); + Assert.AreEqual(s.Shortened, "http://short.ie/m2sqc6"); + } - [Test] - public void UriSerialization() - { - Uri uri = new Uri("http://codeplex.com"); - string json = JsonConvert.SerializeObject(uri); - - Assert.AreEqual("http://codeplex.com/", uri.ToString()); - - Uri newUri = JsonConvert.DeserializeObject(json); - Assert.AreEqual(uri, newUri); - } - - [Test] - public void AnonymousPlusLinqToSql() - { - var value = new + [Test] + public void UriSerialization() { - bar = new JObject(new JProperty("baz", 13)) - }; + Uri uri = new Uri("http://codeplex.com"); + string json = JsonConvert.SerializeObject(uri); - string json = JsonConvert.SerializeObject(value); + Assert.AreEqual("http://codeplex.com/", uri.ToString()); - Assert.AreEqual(@"{""bar"":{""baz"":13}}", json); - } + Uri newUri = JsonConvert.DeserializeObject(json); + Assert.AreEqual(uri, newUri); + } - [Test] - public void SerializeEnumerableAsObject() - { - Content content = new Content + [Test] + public void AnonymousPlusLinqToSql() { - Text = "Blah, blah, blah", - Children = new List + var value = new { - new Content {Text = "First"}, - new Content {Text = "Second"} - } - }; + bar = new JObject(new JProperty("baz", 13)) + }; - string json = JsonConvert.SerializeObject(content, Formatting.Indented); + string json = JsonConvert.SerializeObject(value); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{""bar"":{""baz"":13}}", json); + } + + [Test] + public void SerializeEnumerableAsObject() + { + Content content = new Content + { + Text = "Blah, blah, blah", + Children = new List + { + new Content { Text = "First" }, + new Content { Text = "Second" } + } + }; + + string json = JsonConvert.SerializeObject(content, Formatting.Indented); + + Assert.AreEqual(@"{ ""Children"": [ { ""Children"": null, @@ -2950,12 +2965,12 @@ keyword such as type of business."" ], ""Text"": ""Blah, blah, blah"" }", json); - } + } - [Test] - public void DeserializeEnumerableAsObject() - { - string json = @"{ + [Test] + public void DeserializeEnumerableAsObject() + { + string json = @"{ ""Children"": [ { ""Children"": null, @@ -2969,113 +2984,113 @@ keyword such as type of business."" ""Text"": ""Blah, blah, blah"" }"; - Content content = JsonConvert.DeserializeObject(json); + Content content = JsonConvert.DeserializeObject(json); - Assert.AreEqual("Blah, blah, blah", content.Text); - Assert.AreEqual(2, content.Children.Count); - Assert.AreEqual("First", content.Children[0].Text); - Assert.AreEqual("Second", content.Children[1].Text); - } + Assert.AreEqual("Blah, blah, blah", content.Text); + Assert.AreEqual(2, content.Children.Count); + Assert.AreEqual("First", content.Children[0].Text); + Assert.AreEqual("Second", content.Children[1].Text); + } - [Test] - public void RoleTransferTest() - { - string json = @"{""Operation"":""1"",""RoleName"":""Admin"",""Direction"":""0""}"; - - RoleTransfer r = JsonConvert.DeserializeObject(json); - - Assert.AreEqual(RoleTransferOperation.Second, r.Operation); - Assert.AreEqual("Admin", r.RoleName); - Assert.AreEqual(RoleTransferDirection.First, r.Direction); - } - - [Test] - public void PrimitiveValuesInObjectArray() - { - string json = @"{""action"":""Router"",""method"":""Navigate"",""data"":[""dashboard"",null],""type"":""rpc"",""tid"":2}"; - - ObjectArrayPropertyTest o = JsonConvert.DeserializeObject(json); - - Assert.AreEqual("Router", o.Action); - Assert.AreEqual("Navigate", o.Method); - Assert.AreEqual(2, o.Data.Length); - Assert.AreEqual("dashboard", o.Data[0]); - Assert.AreEqual(null, o.Data[1]); - } - - [Test] - public void ComplexValuesInObjectArray() - { - string json = @"{""action"":""Router"",""method"":""Navigate"",""data"":[""dashboard"",[""id"", 1, ""teststring"", ""test""],{""one"":1}],""type"":""rpc"",""tid"":2}"; - - ObjectArrayPropertyTest o = JsonConvert.DeserializeObject(json); - - Assert.AreEqual("Router", o.Action); - Assert.AreEqual("Navigate", o.Method); - Assert.AreEqual(3, o.Data.Length); - Assert.AreEqual("dashboard", o.Data[0]); - CustomAssert.IsInstanceOfType(typeof(JArray), o.Data[1]); - Assert.AreEqual(4, ((JArray)o.Data[1]).Count); - CustomAssert.IsInstanceOfType(typeof(JObject), o.Data[2]); - Assert.AreEqual(1, ((JObject)o.Data[2]).Count); - Assert.AreEqual(1, (int)((JObject)o.Data[2])["one"]); - } - - [Test] - public void DeserializeGenericDictionary() - { - string json = @"{""key1"":""value1"",""key2"":""value2""}"; - - Dictionary values = JsonConvert.DeserializeObject>(json); - - Console.WriteLine(values.Count); - // 2 - - Console.WriteLine(values["key1"]); - // value1 - - Assert.AreEqual(2, values.Count); - Assert.AreEqual("value1", values["key1"]); - Assert.AreEqual("value2", values["key2"]); - } - - [Test] - public void SerializeGenericList() - { - Product p1 = new Product + [Test] + public void RoleTransferTest() { - Name = "Product 1", - Price = 99.95m, - ExpiryDate = new DateTime(2000, 12, 29, 0, 0, 0, DateTimeKind.Utc), - }; - Product p2 = new Product + string json = @"{""Operation"":""1"",""RoleName"":""Admin"",""Direction"":""0""}"; + + RoleTransfer r = JsonConvert.DeserializeObject(json); + + Assert.AreEqual(RoleTransferOperation.Second, r.Operation); + Assert.AreEqual("Admin", r.RoleName); + Assert.AreEqual(RoleTransferDirection.First, r.Direction); + } + + [Test] + public void PrimitiveValuesInObjectArray() { - Name = "Product 2", - Price = 12.50m, - ExpiryDate = new DateTime(2009, 7, 31, 0, 0, 0, DateTimeKind.Utc), - }; + string json = @"{""action"":""Router"",""method"":""Navigate"",""data"":[""dashboard"",null],""type"":""rpc"",""tid"":2}"; - List products = new List(); - products.Add(p1); - products.Add(p2); + ObjectArrayPropertyTest o = JsonConvert.DeserializeObject(json); - string json = JsonConvert.SerializeObject(products, Formatting.Indented); - //[ - // { - // "Name": "Product 1", - // "ExpiryDate": "\/Date(978048000000)\/", - // "Price": 99.95, - // "Sizes": null - // }, - // { - // "Name": "Product 2", - // "ExpiryDate": "\/Date(1248998400000)\/", - // "Price": 12.50, - // "Sizes": null - // } - //] + Assert.AreEqual("Router", o.Action); + Assert.AreEqual("Navigate", o.Method); + Assert.AreEqual(2, o.Data.Length); + Assert.AreEqual("dashboard", o.Data[0]); + Assert.AreEqual(null, o.Data[1]); + } - Assert.AreEqual(@"[ + [Test] + public void ComplexValuesInObjectArray() + { + string json = @"{""action"":""Router"",""method"":""Navigate"",""data"":[""dashboard"",[""id"", 1, ""teststring"", ""test""],{""one"":1}],""type"":""rpc"",""tid"":2}"; + + ObjectArrayPropertyTest o = JsonConvert.DeserializeObject(json); + + Assert.AreEqual("Router", o.Action); + Assert.AreEqual("Navigate", o.Method); + Assert.AreEqual(3, o.Data.Length); + Assert.AreEqual("dashboard", o.Data[0]); + CustomAssert.IsInstanceOfType(typeof(JArray), o.Data[1]); + Assert.AreEqual(4, ((JArray)o.Data[1]).Count); + CustomAssert.IsInstanceOfType(typeof(JObject), o.Data[2]); + Assert.AreEqual(1, ((JObject)o.Data[2]).Count); + Assert.AreEqual(1, (int)((JObject)o.Data[2])["one"]); + } + + [Test] + public void DeserializeGenericDictionary() + { + string json = @"{""key1"":""value1"",""key2"":""value2""}"; + + Dictionary values = JsonConvert.DeserializeObject>(json); + + Console.WriteLine(values.Count); + // 2 + + Console.WriteLine(values["key1"]); + // value1 + + Assert.AreEqual(2, values.Count); + Assert.AreEqual("value1", values["key1"]); + Assert.AreEqual("value2", values["key2"]); + } + + [Test] + public void SerializeGenericList() + { + Product p1 = new Product + { + Name = "Product 1", + Price = 99.95m, + ExpiryDate = new DateTime(2000, 12, 29, 0, 0, 0, DateTimeKind.Utc), + }; + Product p2 = new Product + { + Name = "Product 2", + Price = 12.50m, + ExpiryDate = new DateTime(2009, 7, 31, 0, 0, 0, DateTimeKind.Utc), + }; + + List products = new List(); + products.Add(p1); + products.Add(p2); + + string json = JsonConvert.SerializeObject(products, Formatting.Indented); + //[ + // { + // "Name": "Product 1", + // "ExpiryDate": "\/Date(978048000000)\/", + // "Price": 99.95, + // "Sizes": null + // }, + // { + // "Name": "Product 2", + // "ExpiryDate": "\/Date(1248998400000)\/", + // "Price": 12.50, + // "Sizes": null + // } + //] + + Assert.AreEqual(@"[ { ""Name"": ""Product 1"", ""ExpiryDate"": ""2000-12-29T00:00:00Z"", @@ -3089,12 +3104,12 @@ keyword such as type of business."" ""Sizes"": null } ]", json); - } + } - [Test] - public void DeserializeGenericList() - { - string json = @"[ + [Test] + public void DeserializeGenericList() + { + string json = @"[ { ""Name"": ""Product 1"", ""ExpiryDate"": ""\/Date(978048000000)\/"", @@ -3109,384 +3124,348 @@ keyword such as type of business."" } ]"; - List products = JsonConvert.DeserializeObject>(json); + List products = JsonConvert.DeserializeObject>(json); - Console.WriteLine(products.Count); - // 2 + Console.WriteLine(products.Count); + // 2 - Product p1 = products[0]; + Product p1 = products[0]; - Console.WriteLine(p1.Name); - // Product 1 + Console.WriteLine(p1.Name); + // Product 1 - Assert.AreEqual(2, products.Count); - Assert.AreEqual("Product 1", products[0].Name); - } + Assert.AreEqual(2, products.Count); + Assert.AreEqual("Product 1", products[0].Name); + } #if !NET20 - [Test] - public void DeserializeEmptyStringToNullableDateTime() - { - string json = @"{""DateTimeField"":""""}"; + [Test] + public void DeserializeEmptyStringToNullableDateTime() + { + string json = @"{""DateTimeField"":""""}"; - NullableDateTimeTestClass c = JsonConvert.DeserializeObject(json); - Assert.AreEqual(null, c.DateTimeField); - } + NullableDateTimeTestClass c = JsonConvert.DeserializeObject(json); + Assert.AreEqual(null, c.DateTimeField); + } #endif - [Test] - public void FailWhenClassWithNoDefaultConstructorHasMultipleConstructorsWithArguments() - { - string json = @"{""sublocation"":""AlertEmailSender.Program.Main"",""userId"":0,""type"":0,""summary"":""Loading settings variables"",""details"":null,""stackTrace"":"" at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)\r\n at System.Environment.get_StackTrace()\r\n at mr.Logging.Event..ctor(String summary) in C:\\Projects\\MRUtils\\Logging\\Event.vb:line 71\r\n at AlertEmailSender.Program.Main(String[] args) in C:\\Projects\\AlertEmailSender\\AlertEmailSender\\Program.cs:line 25"",""tag"":null,""time"":""\/Date(1249591032026-0400)\/""}"; - - ExceptionAssert.Throws( - @"Unable to find a constructor to use for type Newtonsoft.Json.Tests.TestObjects.Event. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'sublocation', line 1, position 15.", - () => + [Test] + public void FailWhenClassWithNoDefaultConstructorHasMultipleConstructorsWithArguments() { - JsonConvert.DeserializeObject(json); - }); - } + string json = @"{""sublocation"":""AlertEmailSender.Program.Main"",""userId"":0,""type"":0,""summary"":""Loading settings variables"",""details"":null,""stackTrace"":"" at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)\r\n at System.Environment.get_StackTrace()\r\n at mr.Logging.Event..ctor(String summary) in C:\\Projects\\MRUtils\\Logging\\Event.vb:line 71\r\n at AlertEmailSender.Program.Main(String[] args) in C:\\Projects\\AlertEmailSender\\AlertEmailSender\\Program.cs:line 25"",""tag"":null,""time"":""\/Date(1249591032026-0400)\/""}"; - [Test] - public void DeserializeObjectSetOnlyProperty() - { - string json = @"{'SetOnlyProperty':[1,2,3,4,5]}"; + ExceptionAssert.Throws( + @"Unable to find a constructor to use for type Newtonsoft.Json.Tests.TestObjects.Event. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'sublocation', line 1, position 15.", + () => { JsonConvert.DeserializeObject(json); }); + } - SetOnlyPropertyClass2 setOnly = JsonConvert.DeserializeObject(json); - JArray a = (JArray)setOnly.GetValue(); - Assert.AreEqual(5, a.Count); - Assert.AreEqual(1, (int)a[0]); - Assert.AreEqual(5, (int)a[a.Count - 1]); - } + [Test] + public void DeserializeObjectSetOnlyProperty() + { + string json = @"{'SetOnlyProperty':[1,2,3,4,5]}"; - [Test] - public void DeserializeOptInClasses() - { - string json = @"{id: ""12"", name: ""test"", items: [{id: ""112"", name: ""testing""}]}"; + SetOnlyPropertyClass2 setOnly = JsonConvert.DeserializeObject(json); + JArray a = (JArray)setOnly.GetValue(); + Assert.AreEqual(5, a.Count); + Assert.AreEqual(1, (int)a[0]); + Assert.AreEqual(5, (int)a[a.Count - 1]); + } - ListTestClass l = JsonConvert.DeserializeObject(json); - } + [Test] + public void DeserializeOptInClasses() + { + string json = @"{id: ""12"", name: ""test"", items: [{id: ""112"", name: ""testing""}]}"; - [Test] - public void DeserializeNullableListWithNulls() - { - List l = JsonConvert.DeserializeObject>("[ 3.3, null, 1.1 ] "); - Assert.AreEqual(3, l.Count); + ListTestClass l = JsonConvert.DeserializeObject(json); + } - Assert.AreEqual(3.3m, l[0]); - Assert.AreEqual(null, l[1]); - Assert.AreEqual(1.1m, l[2]); - } + [Test] + public void DeserializeNullableListWithNulls() + { + List l = JsonConvert.DeserializeObject>("[ 3.3, null, 1.1 ] "); + Assert.AreEqual(3, l.Count); - [Test] - public void CannotDeserializeArrayIntoObject() - { - string json = @"[]"; + Assert.AreEqual(3.3m, l[0]); + Assert.AreEqual(null, l[1]); + Assert.AreEqual(1.1m, l[2]); + } - ExceptionAssert.Throws( - @"Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Newtonsoft.Json.Tests.TestObjects.Person' because the type requires a JSON object (e.g. {""name"":""value""}) to deserialize correctly. + [Test] + public void CannotDeserializeArrayIntoObject() + { + string json = @"[]"; + + ExceptionAssert.Throws( + @"Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Newtonsoft.Json.Tests.TestObjects.Person' because the type requires a JSON object (e.g. {""name"":""value""}) to deserialize correctly. To fix this error either change the JSON to a JSON object (e.g. {""name"":""value""}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array. Path '', line 1, position 1.", - () => + () => { JsonConvert.DeserializeObject(json); }); + } + + [Test] + public void CannotDeserializeArrayIntoDictionary() { - JsonConvert.DeserializeObject(json); - }); - } + string json = @"[]"; - [Test] - public void CannotDeserializeArrayIntoDictionary() - { - string json = @"[]"; - - ExceptionAssert.Throws( - @"Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'System.Collections.Generic.Dictionary`2[System.String,System.String]' because the type requires a JSON object (e.g. {""name"":""value""}) to deserialize correctly. + ExceptionAssert.Throws( + @"Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'System.Collections.Generic.Dictionary`2[System.String,System.String]' because the type requires a JSON object (e.g. {""name"":""value""}) to deserialize correctly. To fix this error either change the JSON to a JSON object (e.g. {""name"":""value""}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array. Path '', line 1, position 1.", - () => - { - JsonConvert.DeserializeObject>(json); - }); - } + () => { JsonConvert.DeserializeObject>(json); }); + } #if !(SILVERLIGHT || NETFX_CORE || PORTABLE) - [Test] - public void CannotDeserializeArrayIntoSerializable() - { - string json = @"[]"; + [Test] + public void CannotDeserializeArrayIntoSerializable() + { + string json = @"[]"; - ExceptionAssert.Throws( - @"Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'System.Exception' because the type requires a JSON object (e.g. {""name"":""value""}) to deserialize correctly. + ExceptionAssert.Throws( + @"Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'System.Exception' because the type requires a JSON object (e.g. {""name"":""value""}) to deserialize correctly. To fix this error either change the JSON to a JSON object (e.g. {""name"":""value""}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array. Path '', line 1, position 1.", - () => - { - JsonConvert.DeserializeObject(json); - }); - } + () => { JsonConvert.DeserializeObject(json); }); + } #endif - [Test] - public void CannotDeserializeArrayIntoDouble() - { - string json = @"[]"; + [Test] + public void CannotDeserializeArrayIntoDouble() + { + string json = @"[]"; - ExceptionAssert.Throws( - @"Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'System.Double' because the type requires a JSON primitive value (e.g. string, number, boolean, null) to deserialize correctly. + ExceptionAssert.Throws( + @"Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'System.Double' because the type requires a JSON primitive value (e.g. string, number, boolean, null) to deserialize correctly. To fix this error either change the JSON to a JSON primitive value (e.g. string, number, boolean, null) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array. Path '', line 1, position 1.", - () => - { - JsonConvert.DeserializeObject(json); - }); - } + () => { JsonConvert.DeserializeObject(json); }); + } #if !(NET35 || NET20 || PORTABLE40) - [Test] - public void CannotDeserializeArrayIntoDynamic() - { - string json = @"[]"; + [Test] + public void CannotDeserializeArrayIntoDynamic() + { + string json = @"[]"; - ExceptionAssert.Throws( - @"Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Newtonsoft.Json.Tests.Linq.DynamicDictionary' because the type requires a JSON object (e.g. {""name"":""value""}) to deserialize correctly. + ExceptionAssert.Throws( + @"Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Newtonsoft.Json.Tests.Linq.DynamicDictionary' because the type requires a JSON object (e.g. {""name"":""value""}) to deserialize correctly. To fix this error either change the JSON to a JSON object (e.g. {""name"":""value""}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array. Path '', line 1, position 1.", - () => - { - JsonConvert.DeserializeObject(json); - }); - } + () => { JsonConvert.DeserializeObject(json); }); + } #endif - [Test] - public void CannotDeserializeArrayIntoLinqToJson() - { - string json = @"[]"; - - ExceptionAssert.Throws( - @"Unable to cast object of type 'Newtonsoft.Json.Linq.JArray' to type 'Newtonsoft.Json.Linq.JObject'.", - () => + [Test] + public void CannotDeserializeArrayIntoLinqToJson() { - JsonConvert.DeserializeObject(json); - }); - } + string json = @"[]"; - [Test] - public void CannotDeserializeConstructorIntoObject() - { - string json = @"new Constructor(123)"; + ExceptionAssert.Throws( + @"Unable to cast object of type 'Newtonsoft.Json.Linq.JArray' to type 'Newtonsoft.Json.Linq.JObject'.", + () => { JsonConvert.DeserializeObject(json); }); + } - ExceptionAssert.Throws( - @"Error converting value ""Constructor"" to type 'Newtonsoft.Json.Tests.TestObjects.Person'. Path '', line 1, position 16.", - () => + [Test] + public void CannotDeserializeConstructorIntoObject() { - JsonConvert.DeserializeObject(json); - }); - } + string json = @"new Constructor(123)"; - [Test] - public void CannotDeserializeConstructorIntoObjectNested() - { - string json = @"[new Constructor(123)]"; + ExceptionAssert.Throws( + @"Error converting value ""Constructor"" to type 'Newtonsoft.Json.Tests.TestObjects.Person'. Path '', line 1, position 16.", + () => { JsonConvert.DeserializeObject(json); }); + } - ExceptionAssert.Throws( - @"Error converting value ""Constructor"" to type 'Newtonsoft.Json.Tests.TestObjects.Person'. Path '[0]', line 1, position 17.", - () => + [Test] + public void CannotDeserializeConstructorIntoObjectNested() { - JsonConvert.DeserializeObject>(json); - }); - } + string json = @"[new Constructor(123)]"; - [Test] - public void CannotDeserializeObjectIntoArray() - { - string json = @"{}"; + ExceptionAssert.Throws( + @"Error converting value ""Constructor"" to type 'Newtonsoft.Json.Tests.TestObjects.Person'. Path '[0]', line 1, position 17.", + () => { JsonConvert.DeserializeObject>(json); }); + } - ExceptionAssert.Throws( - @"Cannot deserialize the current JSON object (e.g. {""name"":""value""}) into type 'System.Collections.Generic.List`1[Newtonsoft.Json.Tests.TestObjects.Person]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly. + [Test] + public void CannotDeserializeObjectIntoArray() + { + string json = @"{}"; + + ExceptionAssert.Throws( + @"Cannot deserialize the current JSON object (e.g. {""name"":""value""}) into type 'System.Collections.Generic.List`1[Newtonsoft.Json.Tests.TestObjects.Person]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly. To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object. Path '', line 1, position 2.", - () => + () => { JsonConvert.DeserializeObject>(json); }); + } + + [Test] + public void CannotPopulateArrayIntoObject() { - JsonConvert.DeserializeObject>(json); - }); - } + string json = @"[]"; - [Test] - public void CannotPopulateArrayIntoObject() - { - string json = @"[]"; + ExceptionAssert.Throws( + @"Cannot populate JSON array onto type 'Newtonsoft.Json.Tests.TestObjects.Person'. Path '', line 1, position 1.", + () => { JsonConvert.PopulateObject(json, new Person()); }); + } - ExceptionAssert.Throws( - @"Cannot populate JSON array onto type 'Newtonsoft.Json.Tests.TestObjects.Person'. Path '', line 1, position 1.", - () => + [Test] + public void CannotPopulateObjectIntoArray() { - JsonConvert.PopulateObject(json, new Person()); - }); - } + string json = @"{}"; - [Test] - public void CannotPopulateObjectIntoArray() - { - string json = @"{}"; + ExceptionAssert.Throws( + @"Cannot populate JSON object onto type 'System.Collections.Generic.List`1[Newtonsoft.Json.Tests.TestObjects.Person]'. Path '', line 1, position 2.", + () => { JsonConvert.PopulateObject(json, new List()); }); + } - ExceptionAssert.Throws( - @"Cannot populate JSON object onto type 'System.Collections.Generic.List`1[Newtonsoft.Json.Tests.TestObjects.Person]'. Path '', line 1, position 2.", - () => + [Test] + public void DeserializeEmptyString() { - JsonConvert.PopulateObject(json, new List()); - }); - } + string json = @"{""Name"":""""}"; - [Test] - public void DeserializeEmptyString() - { - string json = @"{""Name"":""""}"; + Person p = JsonConvert.DeserializeObject(json); + Assert.AreEqual("", p.Name); + } - Person p = JsonConvert.DeserializeObject(json); - Assert.AreEqual("", p.Name); - } - - [Test] - public void SerializePropertyGetError() - { - ExceptionAssert.Throws( - @"Error getting value from 'ReadTimeout' on 'System.IO.MemoryStream'.", - () => + [Test] + public void SerializePropertyGetError() { - JsonConvert.SerializeObject(new MemoryStream(), new JsonSerializerSettings - { - ContractResolver = new DefaultContractResolver - { + ExceptionAssert.Throws( + @"Error getting value from 'ReadTimeout' on 'System.IO.MemoryStream'.", + () => + { + JsonConvert.SerializeObject(new MemoryStream(), new JsonSerializerSettings + { + ContractResolver = new DefaultContractResolver + { #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - IgnoreSerializableAttribute = true + IgnoreSerializableAttribute = true #endif - } - }); - }); - } + } + }); + }); + } - [Test] - public void DeserializePropertySetError() - { - ExceptionAssert.Throws( - @"Error setting value to 'ReadTimeout' on 'System.IO.MemoryStream'.", - () => + [Test] + public void DeserializePropertySetError() { - JsonConvert.DeserializeObject("{ReadTimeout:0}", new JsonSerializerSettings - { - ContractResolver = new DefaultContractResolver - { + ExceptionAssert.Throws( + @"Error setting value to 'ReadTimeout' on 'System.IO.MemoryStream'.", + () => + { + JsonConvert.DeserializeObject("{ReadTimeout:0}", new JsonSerializerSettings + { + ContractResolver = new DefaultContractResolver + { #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - IgnoreSerializableAttribute = true + IgnoreSerializableAttribute = true #endif - } - }); - }); - } + } + }); + }); + } - [Test] - public void DeserializeEnsureTypeEmptyStringToIntError() - { - ExceptionAssert.Throws( - @"Error converting value {null} to type 'System.Int32'. Path 'ReadTimeout', line 1, position 15.", - () => + [Test] + public void DeserializeEnsureTypeEmptyStringToIntError() { - JsonConvert.DeserializeObject("{ReadTimeout:''}", new JsonSerializerSettings - { - ContractResolver = new DefaultContractResolver - { + ExceptionAssert.Throws( + @"Error converting value {null} to type 'System.Int32'. Path 'ReadTimeout', line 1, position 15.", + () => + { + JsonConvert.DeserializeObject("{ReadTimeout:''}", new JsonSerializerSettings + { + ContractResolver = new DefaultContractResolver + { #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - IgnoreSerializableAttribute = true + IgnoreSerializableAttribute = true #endif - } - }); - }); - } + } + }); + }); + } - [Test] - public void DeserializeEnsureTypeNullToIntError() - { - ExceptionAssert.Throws( - @"Error converting value {null} to type 'System.Int32'. Path 'ReadTimeout', line 1, position 17.", - () => + [Test] + public void DeserializeEnsureTypeNullToIntError() { - JsonConvert.DeserializeObject("{ReadTimeout:null}", new JsonSerializerSettings - { - ContractResolver = new DefaultContractResolver - { + ExceptionAssert.Throws( + @"Error converting value {null} to type 'System.Int32'. Path 'ReadTimeout', line 1, position 17.", + () => + { + JsonConvert.DeserializeObject("{ReadTimeout:null}", new JsonSerializerSettings + { + ContractResolver = new DefaultContractResolver + { #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - IgnoreSerializableAttribute = true + IgnoreSerializableAttribute = true #endif - } - }); - }); - } + } + }); + }); + } - [Test] - public void SerializeGenericListOfStrings() - { - List strings = new List(); + [Test] + public void SerializeGenericListOfStrings() + { + List strings = new List(); - strings.Add("str_1"); - strings.Add("str_2"); - strings.Add("str_3"); + strings.Add("str_1"); + strings.Add("str_2"); + strings.Add("str_3"); - string json = JsonConvert.SerializeObject(strings); - Assert.AreEqual(@"[""str_1"",""str_2"",""str_3""]", json); - } + string json = JsonConvert.SerializeObject(strings); + Assert.AreEqual(@"[""str_1"",""str_2"",""str_3""]", json); + } - [Test] - public void ConstructorReadonlyFieldsTest() - { - ConstructorReadonlyFields c1 = new ConstructorReadonlyFields("String!", int.MaxValue); - string json = JsonConvert.SerializeObject(c1, Formatting.Indented); - Assert.AreEqual(@"{ + [Test] + public void ConstructorReadonlyFieldsTest() + { + ConstructorReadonlyFields c1 = new ConstructorReadonlyFields("String!", int.MaxValue); + string json = JsonConvert.SerializeObject(c1, Formatting.Indented); + Assert.AreEqual(@"{ ""A"": ""String!"", ""B"": 2147483647 }", json); - ConstructorReadonlyFields c2 = JsonConvert.DeserializeObject(json); - Assert.AreEqual("String!", c2.A); - Assert.AreEqual(int.MaxValue, c2.B); - } + ConstructorReadonlyFields c2 = JsonConvert.DeserializeObject(json); + Assert.AreEqual("String!", c2.A); + Assert.AreEqual(int.MaxValue, c2.B); + } - [Test] - public void SerializeStruct() - { - StructTest structTest = new StructTest + [Test] + public void SerializeStruct() { - StringProperty = "StringProperty!", - StringField = "StringField", - IntProperty = 5, - IntField = 10 - }; + StructTest structTest = new StructTest + { + StringProperty = "StringProperty!", + StringField = "StringField", + IntProperty = 5, + IntField = 10 + }; - string json = JsonConvert.SerializeObject(structTest, Formatting.Indented); - Console.WriteLine(json); - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(structTest, Formatting.Indented); + Console.WriteLine(json); + Assert.AreEqual(@"{ ""StringField"": ""StringField"", ""IntField"": 10, ""StringProperty"": ""StringProperty!"", ""IntProperty"": 5 }", json); - StructTest deserialized = JsonConvert.DeserializeObject(json); - Assert.AreEqual(structTest.StringProperty, deserialized.StringProperty); - Assert.AreEqual(structTest.StringField, deserialized.StringField); - Assert.AreEqual(structTest.IntProperty, deserialized.IntProperty); - Assert.AreEqual(structTest.IntField, deserialized.IntField); - } + StructTest deserialized = JsonConvert.DeserializeObject(json); + Assert.AreEqual(structTest.StringProperty, deserialized.StringProperty); + Assert.AreEqual(structTest.StringField, deserialized.StringField); + Assert.AreEqual(structTest.IntProperty, deserialized.IntProperty); + Assert.AreEqual(structTest.IntField, deserialized.IntField); + } - [Test] - public void SerializeListWithJsonConverter() - { - Foo f = new Foo(); - f.Bars.Add(new Bar { Id = 0 }); - f.Bars.Add(new Bar { Id = 1 }); - f.Bars.Add(new Bar { Id = 2 }); + [Test] + public void SerializeListWithJsonConverter() + { + Foo f = new Foo(); + f.Bars.Add(new Bar { Id = 0 }); + f.Bars.Add(new Bar { Id = 1 }); + f.Bars.Add(new Bar { Id = 2 }); - string json = JsonConvert.SerializeObject(f, Formatting.Indented); - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(f, Formatting.Indented); + Assert.AreEqual(@"{ ""Bars"": [ 0, 1, @@ -3494,62 +3473,62 @@ Path '', line 1, position 2.", ] }", json); - Foo newFoo = JsonConvert.DeserializeObject(json); - Assert.AreEqual(3, newFoo.Bars.Count); - Assert.AreEqual(0, newFoo.Bars[0].Id); - Assert.AreEqual(1, newFoo.Bars[1].Id); - Assert.AreEqual(2, newFoo.Bars[2].Id); - } + Foo newFoo = JsonConvert.DeserializeObject(json); + Assert.AreEqual(3, newFoo.Bars.Count); + Assert.AreEqual(0, newFoo.Bars[0].Id); + Assert.AreEqual(1, newFoo.Bars[1].Id); + Assert.AreEqual(2, newFoo.Bars[2].Id); + } - [Test] - public void SerializeGuidKeyedDictionary() - { - Dictionary dictionary = new Dictionary(); - dictionary.Add(new Guid("F60EAEE0-AE47-488E-B330-59527B742D77"), 1); - dictionary.Add(new Guid("C2594C02-EBA1-426A-AA87-8DD8871350B0"), 2); + [Test] + public void SerializeGuidKeyedDictionary() + { + Dictionary dictionary = new Dictionary(); + dictionary.Add(new Guid("F60EAEE0-AE47-488E-B330-59527B742D77"), 1); + dictionary.Add(new Guid("C2594C02-EBA1-426A-AA87-8DD8871350B0"), 2); - string json = JsonConvert.SerializeObject(dictionary, Formatting.Indented); - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(dictionary, Formatting.Indented); + Assert.AreEqual(@"{ ""f60eaee0-ae47-488e-b330-59527b742d77"": 1, ""c2594c02-eba1-426a-aa87-8dd8871350b0"": 2 }", json); - } + } - [Test] - public void SerializePersonKeyedDictionary() - { - Dictionary dictionary = new Dictionary(); - dictionary.Add(new Person { Name = "p1" }, 1); - dictionary.Add(new Person { Name = "p2" }, 2); + [Test] + public void SerializePersonKeyedDictionary() + { + Dictionary dictionary = new Dictionary(); + dictionary.Add(new Person { Name = "p1" }, 1); + dictionary.Add(new Person { Name = "p2" }, 2); - string json = JsonConvert.SerializeObject(dictionary, Formatting.Indented); + string json = JsonConvert.SerializeObject(dictionary, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Newtonsoft.Json.Tests.TestObjects.Person"": 1, ""Newtonsoft.Json.Tests.TestObjects.Person"": 2 }", json); - } + } - [Test] - public void DeserializePersonKeyedDictionary() - { - ExceptionAssert.Throws("Could not convert string 'Newtonsoft.Json.Tests.TestObjects.Person' to dictionary key type 'Newtonsoft.Json.Tests.TestObjects.Person'. Create a TypeConverter to convert from the string to the key type object. Path 'Newtonsoft.Json.Tests.TestObjects.Person', line 2, position 46.", - () => - { - string json = - @"{ + [Test] + public void DeserializePersonKeyedDictionary() + { + ExceptionAssert.Throws("Could not convert string 'Newtonsoft.Json.Tests.TestObjects.Person' to dictionary key type 'Newtonsoft.Json.Tests.TestObjects.Person'. Create a TypeConverter to convert from the string to the key type object. Path 'Newtonsoft.Json.Tests.TestObjects.Person', line 2, position 46.", + () => + { + string json = + @"{ ""Newtonsoft.Json.Tests.TestObjects.Person"": 1, ""Newtonsoft.Json.Tests.TestObjects.Person"": 2 }"; - JsonConvert.DeserializeObject>(json); - }); - } + JsonConvert.DeserializeObject>(json); + }); + } - [Test] - public void SerializeFragment() - { - string googleSearchText = @"{ + [Test] + public void SerializeFragment() + { + string googleSearchText = @"{ ""responseData"": { ""results"": [ { @@ -3601,47 +3580,47 @@ Path '', line 1, position 2.", ""responseStatus"": 200 }"; - JObject googleSearch = JObject.Parse(googleSearchText); + JObject googleSearch = JObject.Parse(googleSearchText); - // get JSON result objects into a list - IList results = googleSearch["responseData"]["results"].Children().ToList(); + // get JSON result objects into a list + IList results = googleSearch["responseData"]["results"].Children().ToList(); - // serialize JSON results into .NET objects - IList searchResults = new List(); - foreach (JToken result in results) - { - SearchResult searchResult = JsonConvert.DeserializeObject(result.ToString()); - searchResults.Add(searchResult); - } + // serialize JSON results into .NET objects + IList searchResults = new List(); + foreach (JToken result in results) + { + SearchResult searchResult = JsonConvert.DeserializeObject(result.ToString()); + searchResults.Add(searchResult); + } - // Title = Paris Hilton - Wikipedia, the free encyclopedia - // Content = [1] In 2006, she released her debut album... - // Url = http://en.wikipedia.org/wiki/Paris_Hilton + // Title = Paris Hilton - Wikipedia, the free encyclopedia + // Content = [1] In 2006, she released her debut album... + // Url = http://en.wikipedia.org/wiki/Paris_Hilton - // Title = Paris Hilton - // Content = Self: Zoolander. Socialite Paris Hilton... - // Url = http://www.imdb.com/name/nm0385296/ + // Title = Paris Hilton + // Content = Self: Zoolander. Socialite Paris Hilton... + // Url = http://www.imdb.com/name/nm0385296/ - Assert.AreEqual(2, searchResults.Count); - Assert.AreEqual("Paris Hilton - Wikipedia, the free encyclopedia", searchResults[0].Title); - Assert.AreEqual("Paris Hilton", searchResults[1].Title); - } + Assert.AreEqual(2, searchResults.Count); + Assert.AreEqual("Paris Hilton - Wikipedia, the free encyclopedia", searchResults[0].Title); + Assert.AreEqual("Paris Hilton", searchResults[1].Title); + } - [Test] - public void DeserializeBaseReferenceWithDerivedValue() - { - PersonPropertyClass personPropertyClass = new PersonPropertyClass(); - WagePerson wagePerson = (WagePerson)personPropertyClass.Person; + [Test] + public void DeserializeBaseReferenceWithDerivedValue() + { + PersonPropertyClass personPropertyClass = new PersonPropertyClass(); + WagePerson wagePerson = (WagePerson)personPropertyClass.Person; - wagePerson.BirthDate = new DateTime(2000, 11, 29, 23, 59, 59, DateTimeKind.Utc); - wagePerson.Department = "McDees"; - wagePerson.HourlyWage = 12.50m; - wagePerson.LastModified = new DateTime(2000, 11, 29, 23, 59, 59, DateTimeKind.Utc); - wagePerson.Name = "Jim Bob"; + wagePerson.BirthDate = new DateTime(2000, 11, 29, 23, 59, 59, DateTimeKind.Utc); + wagePerson.Department = "McDees"; + wagePerson.HourlyWage = 12.50m; + wagePerson.LastModified = new DateTime(2000, 11, 29, 23, 59, 59, DateTimeKind.Utc); + wagePerson.Name = "Jim Bob"; - string json = JsonConvert.SerializeObject(personPropertyClass, Formatting.Indented); - Assert.AreEqual( - @"{ + string json = JsonConvert.SerializeObject(personPropertyClass, Formatting.Indented); + Assert.AreEqual( + @"{ ""Person"": { ""HourlyWage"": 12.50, ""Name"": ""Jim Bob"", @@ -3649,121 +3628,121 @@ Path '', line 1, position 2.", ""LastModified"": ""2000-11-29T23:59:59Z"" } }", - json); + json); - PersonPropertyClass newPersonPropertyClass = JsonConvert.DeserializeObject(json); - Assert.AreEqual(wagePerson.HourlyWage, ((WagePerson)newPersonPropertyClass.Person).HourlyWage); - } - - public class ExistingValueClass - { - public Dictionary Dictionary { get; set; } - public List List { get; set; } - - public ExistingValueClass() - { - Dictionary = new Dictionary - { - {"existing", "yup"} - }; - List = new List - { - "existing" - }; - } - } - - [Test] - public void DeserializePopulateDictionaryAndList() - { - ExistingValueClass d = JsonConvert.DeserializeObject(@"{'Dictionary':{appended:'appended',existing:'new'}}"); - - Assert.IsNotNull(d); - Assert.IsNotNull(d.Dictionary); - Assert.AreEqual(typeof(Dictionary), d.Dictionary.GetType()); - Assert.AreEqual(typeof(List), d.List.GetType()); - Assert.AreEqual(2, d.Dictionary.Count); - Assert.AreEqual("new", d.Dictionary["existing"]); - Assert.AreEqual("appended", d.Dictionary["appended"]); - Assert.AreEqual(1, d.List.Count); - Assert.AreEqual("existing", d.List[0]); - } - - public interface IKeyValueId - { - int Id { get; set; } - string Key { get; set; } - string Value { get; set; } - } - - - public class KeyValueId : IKeyValueId - { - public int Id { get; set; } - public string Key { get; set; } - public string Value { get; set; } - } - - public class ThisGenericTest where T : IKeyValueId - { - private Dictionary _dict1 = new Dictionary(); - - public string MyProperty { get; set; } - - public void Add(T item) - { - this._dict1.Add(item.Key, item); - } - - public T this[string key] - { - get { return this._dict1[key]; } - set { this._dict1[key] = value; } - } - - public T this[int id] - { - get { return this._dict1.Values.FirstOrDefault(x => x.Id == id); } - set - { - var item = this[id]; - - if (item == null) - this.Add(value); - else - this._dict1[item.Key] = value; + PersonPropertyClass newPersonPropertyClass = JsonConvert.DeserializeObject(json); + Assert.AreEqual(wagePerson.HourlyWage, ((WagePerson)newPersonPropertyClass.Person).HourlyWage); } - } - public string ToJson() - { - return JsonConvert.SerializeObject(this, Formatting.Indented); - } - - public T[] TheItems - { - get { return this._dict1.Values.ToArray(); } - set + public class ExistingValueClass { - foreach (var item in value) - this.Add(item); + public Dictionary Dictionary { get; set; } + public List List { get; set; } + + public ExistingValueClass() + { + Dictionary = new Dictionary + { + { "existing", "yup" } + }; + List = new List + { + "existing" + }; + } } - } - } - [Test] - public void IgnoreIndexedProperties() - { - ThisGenericTest g = new ThisGenericTest(); + [Test] + public void DeserializePopulateDictionaryAndList() + { + ExistingValueClass d = JsonConvert.DeserializeObject(@"{'Dictionary':{appended:'appended',existing:'new'}}"); - g.Add(new KeyValueId { Id = 1, Key = "key1", Value = "value1" }); - g.Add(new KeyValueId { Id = 2, Key = "key2", Value = "value2" }); + Assert.IsNotNull(d); + Assert.IsNotNull(d.Dictionary); + Assert.AreEqual(typeof(Dictionary), d.Dictionary.GetType()); + Assert.AreEqual(typeof(List), d.List.GetType()); + Assert.AreEqual(2, d.Dictionary.Count); + Assert.AreEqual("new", d.Dictionary["existing"]); + Assert.AreEqual("appended", d.Dictionary["appended"]); + Assert.AreEqual(1, d.List.Count); + Assert.AreEqual("existing", d.List[0]); + } - g.MyProperty = "some value"; + public interface IKeyValueId + { + int Id { get; set; } + string Key { get; set; } + string Value { get; set; } + } - string json = g.ToJson(); - Assert.AreEqual(@"{ + public class KeyValueId : IKeyValueId + { + public int Id { get; set; } + public string Key { get; set; } + public string Value { get; set; } + } + + public class ThisGenericTest where T : IKeyValueId + { + private Dictionary _dict1 = new Dictionary(); + + public string MyProperty { get; set; } + + public void Add(T item) + { + _dict1.Add(item.Key, item); + } + + public T this[string key] + { + get { return _dict1[key]; } + set { _dict1[key] = value; } + } + + public T this[int id] + { + get { return _dict1.Values.FirstOrDefault(x => x.Id == id); } + set + { + var item = this[id]; + + if (item == null) + Add(value); + else + _dict1[item.Key] = value; + } + } + + public string ToJson() + { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + + public T[] TheItems + { + get { return _dict1.Values.ToArray(); } + set + { + foreach (var item in value) + Add(item); + } + } + } + + [Test] + public void IgnoreIndexedProperties() + { + ThisGenericTest g = new ThisGenericTest(); + + g.Add(new KeyValueId { Id = 1, Key = "key1", Value = "value1" }); + g.Add(new KeyValueId { Id = 2, Key = "key2", Value = "value2" }); + + g.MyProperty = "some value"; + + string json = g.ToJson(); + + Assert.AreEqual(@"{ ""MyProperty"": ""some value"", ""TheItems"": [ { @@ -3779,492 +3758,491 @@ Path '', line 1, position 2.", ] }", json); - ThisGenericTest gen = JsonConvert.DeserializeObject>(json); - Assert.AreEqual("some value", gen.MyProperty); - } - - public class JRawValueTestObject - { - public JRaw Value { get; set; } - } - - [Test] - public void JRawValue() - { - JRawValueTestObject deserialized = JsonConvert.DeserializeObject("{value:3}"); - Assert.AreEqual("3", deserialized.Value.ToString()); - - deserialized = JsonConvert.DeserializeObject("{value:'3'}"); - Assert.AreEqual(@"""3""", deserialized.Value.ToString()); - } - - [Test] - public void DeserializeDictionaryWithNoDefaultConstructor() - { - string json = "{key1:'value1',key2:'value2',key3:'value3'}"; - - var dic = JsonConvert.DeserializeObject(json); - - Assert.AreEqual(3, dic.Count); - Assert.AreEqual("value1", dic["key1"]); - Assert.AreEqual("value2", dic["key2"]); - Assert.AreEqual("value3", dic["key3"]); - } - - [Test] - public void DeserializeDictionaryWithNoDefaultConstructor_PreserveReferences() - { - string json = "{'$id':'1',key1:'value1',key2:'value2',key3:'value3'}"; - - ExceptionAssert.Throws("Cannot preserve reference to readonly dictionary, or dictionary created from a non-default constructor: Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+DictionaryWithNoDefaultConstructor. Path 'key1', line 1, position 16.", - () => JsonConvert.DeserializeObject(json, new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.All })); - } - - public class DictionaryWithNoDefaultConstructor : Dictionary - { - public DictionaryWithNoDefaultConstructor(IEnumerable> initial) - { - foreach (KeyValuePair pair in initial) - { - Add(pair.Key, pair.Value); + ThisGenericTest gen = JsonConvert.DeserializeObject>(json); + Assert.AreEqual("some value", gen.MyProperty); } - } - } - [JsonObject(MemberSerialization.OptIn)] - public class A - { - [JsonProperty("A1")] - private string _A1; + public class JRawValueTestObject + { + public JRaw Value { get; set; } + } - public string A1 - { - get { return _A1; } - set { _A1 = value; } - } + [Test] + public void JRawValue() + { + JRawValueTestObject deserialized = JsonConvert.DeserializeObject("{value:3}"); + Assert.AreEqual("3", deserialized.Value.ToString()); - [JsonProperty("A2")] - private string A2 { get; set; } - } + deserialized = JsonConvert.DeserializeObject("{value:'3'}"); + Assert.AreEqual(@"""3""", deserialized.Value.ToString()); + } - [JsonObject(MemberSerialization.OptIn)] - public class B : A - { - public string B1 { get; set; } + [Test] + public void DeserializeDictionaryWithNoDefaultConstructor() + { + string json = "{key1:'value1',key2:'value2',key3:'value3'}"; - [JsonProperty("B2")] - private string _B2; + var dic = JsonConvert.DeserializeObject(json); - public string B2 - { - get { return _B2; } - set { _B2 = value; } - } + Assert.AreEqual(3, dic.Count); + Assert.AreEqual("value1", dic["key1"]); + Assert.AreEqual("value2", dic["key2"]); + Assert.AreEqual("value3", dic["key3"]); + } - [JsonProperty("B3")] - private string B3 { get; set; } - } + [Test] + public void DeserializeDictionaryWithNoDefaultConstructor_PreserveReferences() + { + string json = "{'$id':'1',key1:'value1',key2:'value2',key3:'value3'}"; - [Test] - public void SerializeNonPublicBaseJsonProperties() - { - B value = new B(); - string json = JsonConvert.SerializeObject(value, Formatting.Indented); + ExceptionAssert.Throws("Cannot preserve reference to readonly dictionary, or dictionary created from a non-default constructor: Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+DictionaryWithNoDefaultConstructor. Path 'key1', line 1, position 16.", + () => JsonConvert.DeserializeObject(json, new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.All })); + } - Assert.AreEqual(@"{ + public class DictionaryWithNoDefaultConstructor : Dictionary + { + public DictionaryWithNoDefaultConstructor(IEnumerable> initial) + { + foreach (KeyValuePair pair in initial) + { + Add(pair.Key, pair.Value); + } + } + } + + [JsonObject(MemberSerialization.OptIn)] + public class A + { + [JsonProperty("A1")] + private string _A1; + + public string A1 + { + get { return _A1; } + set { _A1 = value; } + } + + [JsonProperty("A2")] + private string A2 { get; set; } + } + + [JsonObject(MemberSerialization.OptIn)] + public class B : A + { + public string B1 { get; set; } + + [JsonProperty("B2")] + private string _B2; + + public string B2 + { + get { return _B2; } + set { _B2 = value; } + } + + [JsonProperty("B3")] + private string B3 { get; set; } + } + + [Test] + public void SerializeNonPublicBaseJsonProperties() + { + B value = new B(); + string json = JsonConvert.SerializeObject(value, Formatting.Indented); + + Assert.AreEqual(@"{ ""B2"": null, ""A1"": null, ""B3"": null, ""A2"": null }", json); - } + } - public class TestClass - { - public string Key { get; set; } - public object Value { get; set; } - } + public class TestClass + { + public string Key { get; set; } + public object Value { get; set; } + } - [Test] - public void DeserializeToObjectProperty() - { - var json = "{ Key: 'abc', Value: 123 }"; - var item = JsonConvert.DeserializeObject(json); + [Test] + public void DeserializeToObjectProperty() + { + var json = "{ Key: 'abc', Value: 123 }"; + var item = JsonConvert.DeserializeObject(json); - Assert.AreEqual(123L, item.Value); - } + Assert.AreEqual(123L, item.Value); + } - public abstract class Animal - { - public abstract string Name { get; } - } + public abstract class Animal + { + public abstract string Name { get; } + } - public class Human : Animal - { - public override string Name - { - get { return typeof(Human).Name; } - } + public class Human : Animal + { + public override string Name + { + get { return typeof(Human).Name; } + } - public string Ethnicity { get; set; } - } + public string Ethnicity { get; set; } + } #if !NET20 - public class DataContractJsonSerializerTestClass - { - public TimeSpan TimeSpanProperty { get; set; } - public Guid GuidProperty { get; set; } - public Animal AnimalProperty { get; set; } - public Exception ExceptionProperty { get; set; } - } + public class DataContractJsonSerializerTestClass + { + public TimeSpan TimeSpanProperty { get; set; } + public Guid GuidProperty { get; set; } + public Animal AnimalProperty { get; set; } + public Exception ExceptionProperty { get; set; } + } - [Test] - public void DataContractJsonSerializerTest() - { - Exception ex = new Exception("Blah blah blah"); + [Test] + public void DataContractJsonSerializerTest() + { + Exception ex = new Exception("Blah blah blah"); - DataContractJsonSerializerTestClass c = new DataContractJsonSerializerTestClass(); - c.TimeSpanProperty = new TimeSpan(200, 20, 59, 30, 900); - c.GuidProperty = new Guid("66143115-BE2A-4a59-AF0A-348E1EA15B1E"); - c.AnimalProperty = new Human() { Ethnicity = "European" }; - c.ExceptionProperty = ex; + DataContractJsonSerializerTestClass c = new DataContractJsonSerializerTestClass(); + c.TimeSpanProperty = new TimeSpan(200, 20, 59, 30, 900); + c.GuidProperty = new Guid("66143115-BE2A-4a59-AF0A-348E1EA15B1E"); + c.AnimalProperty = new Human() { Ethnicity = "European" }; + c.ExceptionProperty = ex; - MemoryStream ms = new MemoryStream(); - DataContractJsonSerializer serializer = new DataContractJsonSerializer( - typeof(DataContractJsonSerializerTestClass), - new Type[] { typeof(Human) }); - serializer.WriteObject(ms, c); + MemoryStream ms = new MemoryStream(); + DataContractJsonSerializer serializer = new DataContractJsonSerializer( + typeof(DataContractJsonSerializerTestClass), + new Type[] { typeof(Human) }); + serializer.WriteObject(ms, c); - byte[] jsonBytes = ms.ToArray(); - string json = Encoding.UTF8.GetString(jsonBytes, 0, jsonBytes.Length); + byte[] jsonBytes = ms.ToArray(); + string json = Encoding.UTF8.GetString(jsonBytes, 0, jsonBytes.Length); - //Console.WriteLine(JObject.Parse(json).ToString()); - //Console.WriteLine(); + //Console.WriteLine(JObject.Parse(json).ToString()); + //Console.WriteLine(); - //Console.WriteLine(JsonConvert.SerializeObject(c, Formatting.Indented, new JsonSerializerSettings - // { - // // TypeNameHandling = TypeNameHandling.Objects - // })); - } + //Console.WriteLine(JsonConvert.SerializeObject(c, Formatting.Indented, new JsonSerializerSettings + // { + // // TypeNameHandling = TypeNameHandling.Objects + // })); + } #endif - public class ModelStateDictionary : IDictionary - { - - private readonly Dictionary _innerDictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); - - public ModelStateDictionary() - { - } - - public ModelStateDictionary(ModelStateDictionary dictionary) - { - if (dictionary == null) + public class ModelStateDictionary : IDictionary { - throw new ArgumentNullException("dictionary"); + private readonly Dictionary _innerDictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); + + public ModelStateDictionary() + { + } + + public ModelStateDictionary(ModelStateDictionary dictionary) + { + if (dictionary == null) + { + throw new ArgumentNullException("dictionary"); + } + + foreach (var entry in dictionary) + { + _innerDictionary.Add(entry.Key, entry.Value); + } + } + + public int Count + { + get { return _innerDictionary.Count; } + } + + public bool IsReadOnly + { + get { return ((IDictionary)_innerDictionary).IsReadOnly; } + } + + public ICollection Keys + { + get { return _innerDictionary.Keys; } + } + + public T this[string key] + { + get + { + T value; + _innerDictionary.TryGetValue(key, out value); + return value; + } + set { _innerDictionary[key] = value; } + } + + public ICollection Values + { + get { return _innerDictionary.Values; } + } + + public void Add(KeyValuePair item) + { + ((IDictionary)_innerDictionary).Add(item); + } + + public void Add(string key, T value) + { + _innerDictionary.Add(key, value); + } + + public void Clear() + { + _innerDictionary.Clear(); + } + + public bool Contains(KeyValuePair item) + { + return ((IDictionary)_innerDictionary).Contains(item); + } + + public bool ContainsKey(string key) + { + return _innerDictionary.ContainsKey(key); + } + + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + ((IDictionary)_innerDictionary).CopyTo(array, arrayIndex); + } + + public IEnumerator> GetEnumerator() + { + return _innerDictionary.GetEnumerator(); + } + + public void Merge(ModelStateDictionary dictionary) + { + if (dictionary == null) + { + return; + } + + foreach (var entry in dictionary) + { + this[entry.Key] = entry.Value; + } + } + + public bool Remove(KeyValuePair item) + { + return ((IDictionary)_innerDictionary).Remove(item); + } + + public bool Remove(string key) + { + return _innerDictionary.Remove(key); + } + + public bool TryGetValue(string key, out T value) + { + return _innerDictionary.TryGetValue(key, out value); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return ((IEnumerable)_innerDictionary).GetEnumerator(); + } } - foreach (var entry in dictionary) + [Test] + public void SerializeNonIDictionary() { - _innerDictionary.Add(entry.Key, entry.Value); + ModelStateDictionary modelStateDictionary = new ModelStateDictionary(); + modelStateDictionary.Add("key", "value"); + + string json = JsonConvert.SerializeObject(modelStateDictionary); + + Assert.AreEqual(@"{""key"":""value""}", json); + + ModelStateDictionary newModelStateDictionary = JsonConvert.DeserializeObject>(json); + Assert.AreEqual(1, newModelStateDictionary.Count); + Assert.AreEqual("value", newModelStateDictionary["key"]); } - } - - public int Count - { - get { return _innerDictionary.Count; } - } - - public bool IsReadOnly - { - get { return ((IDictionary)_innerDictionary).IsReadOnly; } - } - - public ICollection Keys - { - get { return _innerDictionary.Keys; } - } - - public T this[string key] - { - get - { - T value; - _innerDictionary.TryGetValue(key, out value); - return value; - } - set { _innerDictionary[key] = value; } - } - - public ICollection Values - { - get { return _innerDictionary.Values; } - } - - public void Add(KeyValuePair item) - { - ((IDictionary)_innerDictionary).Add(item); - } - - public void Add(string key, T value) - { - _innerDictionary.Add(key, value); - } - - public void Clear() - { - _innerDictionary.Clear(); - } - - public bool Contains(KeyValuePair item) - { - return ((IDictionary)_innerDictionary).Contains(item); - } - - public bool ContainsKey(string key) - { - return _innerDictionary.ContainsKey(key); - } - - public void CopyTo(KeyValuePair[] array, int arrayIndex) - { - ((IDictionary)_innerDictionary).CopyTo(array, arrayIndex); - } - - public IEnumerator> GetEnumerator() - { - return _innerDictionary.GetEnumerator(); - } - - public void Merge(ModelStateDictionary dictionary) - { - if (dictionary == null) - { - return; - } - - foreach (var entry in dictionary) - { - this[entry.Key] = entry.Value; - } - } - - public bool Remove(KeyValuePair item) - { - return ((IDictionary)_innerDictionary).Remove(item); - } - - public bool Remove(string key) - { - return _innerDictionary.Remove(key); - } - - public bool TryGetValue(string key, out T value) - { - return _innerDictionary.TryGetValue(key, out value); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return ((IEnumerable)_innerDictionary).GetEnumerator(); - } - } - - [Test] - public void SerializeNonIDictionary() - { - ModelStateDictionary modelStateDictionary = new ModelStateDictionary(); - modelStateDictionary.Add("key", "value"); - - string json = JsonConvert.SerializeObject(modelStateDictionary); - - Assert.AreEqual(@"{""key"":""value""}", json); - - ModelStateDictionary newModelStateDictionary = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(1, newModelStateDictionary.Count); - Assert.AreEqual("value", newModelStateDictionary["key"]); - } #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - public class ISerializableTestObject : ISerializable - { - internal string _stringValue; - internal int _intValue; - internal DateTimeOffset _dateTimeOffsetValue; - internal Person _personValue; - internal Person _nullPersonValue; - internal int? _nullableInt; - internal bool _booleanValue; - internal byte _byteValue; - internal char _charValue; - internal DateTime _dateTimeValue; - internal decimal _decimalValue; - internal short _shortValue; - internal long _longValue; - internal sbyte _sbyteValue; - internal float _floatValue; - internal ushort _ushortValue; - internal uint _uintValue; - internal ulong _ulongValue; + public class ISerializableTestObject : ISerializable + { + internal string _stringValue; + internal int _intValue; + internal DateTimeOffset _dateTimeOffsetValue; + internal Person _personValue; + internal Person _nullPersonValue; + internal int? _nullableInt; + internal bool _booleanValue; + internal byte _byteValue; + internal char _charValue; + internal DateTime _dateTimeValue; + internal decimal _decimalValue; + internal short _shortValue; + internal long _longValue; + internal sbyte _sbyteValue; + internal float _floatValue; + internal ushort _ushortValue; + internal uint _uintValue; + internal ulong _ulongValue; - public ISerializableTestObject(string stringValue, int intValue, DateTimeOffset dateTimeOffset, Person personValue) - { - _stringValue = stringValue; - _intValue = intValue; - _dateTimeOffsetValue = dateTimeOffset; - _personValue = personValue; - _dateTimeValue = new DateTime(0, DateTimeKind.Utc); - } + public ISerializableTestObject(string stringValue, int intValue, DateTimeOffset dateTimeOffset, Person personValue) + { + _stringValue = stringValue; + _intValue = intValue; + _dateTimeOffsetValue = dateTimeOffset; + _personValue = personValue; + _dateTimeValue = new DateTime(0, DateTimeKind.Utc); + } - protected ISerializableTestObject(SerializationInfo info, StreamingContext context) - { - _stringValue = info.GetString("stringValue"); - _intValue = info.GetInt32("intValue"); - _dateTimeOffsetValue = (DateTimeOffset)info.GetValue("dateTimeOffsetValue", typeof(DateTimeOffset)); - _personValue = (Person)info.GetValue("personValue", typeof(Person)); - _nullPersonValue = (Person)info.GetValue("nullPersonValue", typeof(Person)); - _nullableInt = (int?)info.GetValue("nullableInt", typeof(int?)); + protected ISerializableTestObject(SerializationInfo info, StreamingContext context) + { + _stringValue = info.GetString("stringValue"); + _intValue = info.GetInt32("intValue"); + _dateTimeOffsetValue = (DateTimeOffset)info.GetValue("dateTimeOffsetValue", typeof(DateTimeOffset)); + _personValue = (Person)info.GetValue("personValue", typeof(Person)); + _nullPersonValue = (Person)info.GetValue("nullPersonValue", typeof(Person)); + _nullableInt = (int?)info.GetValue("nullableInt", typeof(int?)); - _booleanValue = info.GetBoolean("booleanValue"); - _byteValue = info.GetByte("byteValue"); - _charValue = info.GetChar("charValue"); - _dateTimeValue = info.GetDateTime("dateTimeValue"); - _decimalValue = info.GetDecimal("decimalValue"); - _shortValue = info.GetInt16("shortValue"); - _longValue = info.GetInt64("longValue"); - _sbyteValue = info.GetSByte("sbyteValue"); - _floatValue = info.GetSingle("floatValue"); - _ushortValue = info.GetUInt16("ushortValue"); - _uintValue = info.GetUInt32("uintValue"); - _ulongValue = info.GetUInt64("ulongValue"); - } + _booleanValue = info.GetBoolean("booleanValue"); + _byteValue = info.GetByte("byteValue"); + _charValue = info.GetChar("charValue"); + _dateTimeValue = info.GetDateTime("dateTimeValue"); + _decimalValue = info.GetDecimal("decimalValue"); + _shortValue = info.GetInt16("shortValue"); + _longValue = info.GetInt64("longValue"); + _sbyteValue = info.GetSByte("sbyteValue"); + _floatValue = info.GetSingle("floatValue"); + _ushortValue = info.GetUInt16("ushortValue"); + _uintValue = info.GetUInt32("uintValue"); + _ulongValue = info.GetUInt64("ulongValue"); + } - public void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue("stringValue", _stringValue); - info.AddValue("intValue", _intValue); - info.AddValue("dateTimeOffsetValue", _dateTimeOffsetValue); - info.AddValue("personValue", _personValue); - info.AddValue("nullPersonValue", _nullPersonValue); - info.AddValue("nullableInt", null); + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("stringValue", _stringValue); + info.AddValue("intValue", _intValue); + info.AddValue("dateTimeOffsetValue", _dateTimeOffsetValue); + info.AddValue("personValue", _personValue); + info.AddValue("nullPersonValue", _nullPersonValue); + info.AddValue("nullableInt", null); - info.AddValue("booleanValue", _booleanValue); - info.AddValue("byteValue", _byteValue); - info.AddValue("charValue", _charValue); - info.AddValue("dateTimeValue", _dateTimeValue); - info.AddValue("decimalValue", _decimalValue); - info.AddValue("shortValue", _shortValue); - info.AddValue("longValue", _longValue); - info.AddValue("sbyteValue", _sbyteValue); - info.AddValue("floatValue", _floatValue); - info.AddValue("ushortValue", _ushortValue); - info.AddValue("uintValue", _uintValue); - info.AddValue("ulongValue", _ulongValue); - } - } + info.AddValue("booleanValue", _booleanValue); + info.AddValue("byteValue", _byteValue); + info.AddValue("charValue", _charValue); + info.AddValue("dateTimeValue", _dateTimeValue); + info.AddValue("decimalValue", _decimalValue); + info.AddValue("shortValue", _shortValue); + info.AddValue("longValue", _longValue); + info.AddValue("sbyteValue", _sbyteValue); + info.AddValue("floatValue", _floatValue); + info.AddValue("ushortValue", _ushortValue); + info.AddValue("uintValue", _uintValue); + info.AddValue("ulongValue", _ulongValue); + } + } #if DEBUG - [Test] - public void SerializeISerializableInPartialTrustWithIgnoreInterface() - { - try - { - JsonTypeReflector.SetFullyTrusted(false); - ISerializableTestObject value = new ISerializableTestObject("string!", 0, default(DateTimeOffset), null); + [Test] + public void SerializeISerializableInPartialTrustWithIgnoreInterface() + { + try + { + JsonTypeReflector.SetFullyTrusted(false); + ISerializableTestObject value = new ISerializableTestObject("string!", 0, default(DateTimeOffset), null); - string json = JsonConvert.SerializeObject(value, new JsonSerializerSettings - { - ContractResolver = new DefaultContractResolver(false) - { - IgnoreSerializableInterface = true - } - }); + string json = JsonConvert.SerializeObject(value, new JsonSerializerSettings + { + ContractResolver = new DefaultContractResolver(false) + { + IgnoreSerializableInterface = true + } + }); - Assert.AreEqual("{}", json); + Assert.AreEqual("{}", json); - value = JsonConvert.DeserializeObject("{booleanValue:true}", new JsonSerializerSettings - { - ContractResolver = new DefaultContractResolver(false) - { - IgnoreSerializableInterface = true - } - }); + value = JsonConvert.DeserializeObject("{booleanValue:true}", new JsonSerializerSettings + { + ContractResolver = new DefaultContractResolver(false) + { + IgnoreSerializableInterface = true + } + }); - Assert.IsNotNull(value); - Assert.AreEqual(false, value._booleanValue); - } - finally - { - JsonTypeReflector.SetFullyTrusted(true); - } - } + Assert.IsNotNull(value); + Assert.AreEqual(false, value._booleanValue); + } + finally + { + JsonTypeReflector.SetFullyTrusted(true); + } + } - [Test] - public void SerializeISerializableInPartialTrust() - { - try - { - ExceptionAssert.Throws( - @"Type 'Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+ISerializableTestObject' implements ISerializable but cannot be deserialized using the ISerializable interface because the current application is not fully trusted and ISerializable can expose secure data. + [Test] + public void SerializeISerializableInPartialTrust() + { + try + { + ExceptionAssert.Throws( + @"Type 'Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+ISerializableTestObject' implements ISerializable but cannot be deserialized using the ISerializable interface because the current application is not fully trusted and ISerializable can expose secure data. To fix this error either change the environment to be fully trusted, change the application to not deserialize the type, add JsonObjectAttribute to the type or change the JsonSerializer setting ContractResolver to use a new DefaultContractResolver with IgnoreSerializableInterface set to true. Path 'booleanValue', line 1, position 14.", - () => - { - JsonTypeReflector.SetFullyTrusted(false); + () => + { + JsonTypeReflector.SetFullyTrusted(false); - JsonConvert.DeserializeObject("{booleanValue:true}"); - }); - } - finally - { - JsonTypeReflector.SetFullyTrusted(true); - } - } + JsonConvert.DeserializeObject("{booleanValue:true}"); + }); + } + finally + { + JsonTypeReflector.SetFullyTrusted(true); + } + } - [Test] - public void DeserializeISerializableInPartialTrust() - { - try - { - ExceptionAssert.Throws( - @"Type 'Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+ISerializableTestObject' implements ISerializable but cannot be serialized using the ISerializable interface because the current application is not fully trusted and ISerializable can expose secure data. + [Test] + public void DeserializeISerializableInPartialTrust() + { + try + { + ExceptionAssert.Throws( + @"Type 'Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+ISerializableTestObject' implements ISerializable but cannot be serialized using the ISerializable interface because the current application is not fully trusted and ISerializable can expose secure data. To fix this error either change the environment to be fully trusted, change the application to not deserialize the type, add JsonObjectAttribute to the type or change the JsonSerializer setting ContractResolver to use a new DefaultContractResolver with IgnoreSerializableInterface set to true. Path ''.", - () => - { - JsonTypeReflector.SetFullyTrusted(false); - ISerializableTestObject value = new ISerializableTestObject("string!", 0, default(DateTimeOffset), null); + () => + { + JsonTypeReflector.SetFullyTrusted(false); + ISerializableTestObject value = new ISerializableTestObject("string!", 0, default(DateTimeOffset), null); - JsonConvert.SerializeObject(value); - }); - } - finally - { - JsonTypeReflector.SetFullyTrusted(true); - } - } + JsonConvert.SerializeObject(value); + }); + } + finally + { + JsonTypeReflector.SetFullyTrusted(true); + } + } #endif - [Test] - public void SerializeISerializableTestObject_IsoDate() - { - Person person = new Person(); - person.BirthDate = new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc); - person.LastModified = person.BirthDate; - person.Department = "Department!"; - person.Name = "Name!"; + [Test] + public void SerializeISerializableTestObject_IsoDate() + { + Person person = new Person(); + person.BirthDate = new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc); + person.LastModified = person.BirthDate; + person.Department = "Department!"; + person.Name = "Name!"; - DateTimeOffset dateTimeOffset = new DateTimeOffset(2000, 12, 20, 22, 59, 59, TimeSpan.FromHours(2)); - string dateTimeOffsetText; + DateTimeOffset dateTimeOffset = new DateTimeOffset(2000, 12, 20, 22, 59, 59, TimeSpan.FromHours(2)); + string dateTimeOffsetText; #if !NET20 - dateTimeOffsetText = @"2000-12-20T22:59:59+02:00"; + dateTimeOffsetText = @"2000-12-20T22:59:59+02:00"; #else dateTimeOffsetText = @"12/20/2000 22:59:59 +02:00"; #endif - ISerializableTestObject o = new ISerializableTestObject("String!", int.MinValue, dateTimeOffset, person); + ISerializableTestObject o = new ISerializableTestObject("String!", int.MinValue, dateTimeOffset, person); - string json = JsonConvert.SerializeObject(o, Formatting.Indented); - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(o, Formatting.Indented); + Assert.AreEqual(@"{ ""stringValue"": ""String!"", ""intValue"": -2147483648, ""dateTimeOffsetValue"": """ + dateTimeOffsetText + @""", @@ -4289,39 +4267,39 @@ To fix this error either change the environment to be fully trusted, change the ""ulongValue"": 0 }", json); - ISerializableTestObject o2 = JsonConvert.DeserializeObject(json); - Assert.AreEqual("String!", o2._stringValue); - Assert.AreEqual(int.MinValue, o2._intValue); - Assert.AreEqual(dateTimeOffset, o2._dateTimeOffsetValue); - Assert.AreEqual("Name!", o2._personValue.Name); - Assert.AreEqual(null, o2._nullPersonValue); - Assert.AreEqual(null, o2._nullableInt); - } + ISerializableTestObject o2 = JsonConvert.DeserializeObject(json); + Assert.AreEqual("String!", o2._stringValue); + Assert.AreEqual(int.MinValue, o2._intValue); + Assert.AreEqual(dateTimeOffset, o2._dateTimeOffsetValue); + Assert.AreEqual("Name!", o2._personValue.Name); + Assert.AreEqual(null, o2._nullPersonValue); + Assert.AreEqual(null, o2._nullableInt); + } - [Test] - public void SerializeISerializableTestObject_MsAjax() - { - Person person = new Person(); - person.BirthDate = new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc); - person.LastModified = person.BirthDate; - person.Department = "Department!"; - person.Name = "Name!"; + [Test] + public void SerializeISerializableTestObject_MsAjax() + { + Person person = new Person(); + person.BirthDate = new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc); + person.LastModified = person.BirthDate; + person.Department = "Department!"; + person.Name = "Name!"; - DateTimeOffset dateTimeOffset = new DateTimeOffset(2000, 12, 20, 22, 59, 59, TimeSpan.FromHours(2)); - string dateTimeOffsetText; + DateTimeOffset dateTimeOffset = new DateTimeOffset(2000, 12, 20, 22, 59, 59, TimeSpan.FromHours(2)); + string dateTimeOffsetText; #if !NET20 - dateTimeOffsetText = @"\/Date(977345999000+0200)\/"; + dateTimeOffsetText = @"\/Date(977345999000+0200)\/"; #else dateTimeOffsetText = @"12/20/2000 22:59:59 +02:00"; #endif - ISerializableTestObject o = new ISerializableTestObject("String!", int.MinValue, dateTimeOffset, person); + ISerializableTestObject o = new ISerializableTestObject("String!", int.MinValue, dateTimeOffset, person); - string json = JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings - { - DateFormatHandling = DateFormatHandling.MicrosoftDateFormat - }); - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings + { + DateFormatHandling = DateFormatHandling.MicrosoftDateFormat + }); + Assert.AreEqual(@"{ ""stringValue"": ""String!"", ""intValue"": -2147483648, ""dateTimeOffsetValue"": """ + dateTimeOffsetText + @""", @@ -4346,48 +4324,48 @@ To fix this error either change the environment to be fully trusted, change the ""ulongValue"": 0 }", json); - ISerializableTestObject o2 = JsonConvert.DeserializeObject(json); - Assert.AreEqual("String!", o2._stringValue); - Assert.AreEqual(int.MinValue, o2._intValue); - Assert.AreEqual(dateTimeOffset, o2._dateTimeOffsetValue); - Assert.AreEqual("Name!", o2._personValue.Name); - Assert.AreEqual(null, o2._nullPersonValue); - Assert.AreEqual(null, o2._nullableInt); - } + ISerializableTestObject o2 = JsonConvert.DeserializeObject(json); + Assert.AreEqual("String!", o2._stringValue); + Assert.AreEqual(int.MinValue, o2._intValue); + Assert.AreEqual(dateTimeOffset, o2._dateTimeOffsetValue); + Assert.AreEqual("Name!", o2._personValue.Name); + Assert.AreEqual(null, o2._nullPersonValue); + Assert.AreEqual(null, o2._nullableInt); + } #endif - public class KVPair - { - public TKey Key { get; set; } - public TValue Value { get; set; } + public class KVPair + { + public TKey Key { get; set; } + public TValue Value { get; set; } - public KVPair(TKey k, TValue v) - { - Key = k; - Value = v; - } - } + public KVPair(TKey k, TValue v) + { + Key = k; + Value = v; + } + } - [Test] - public void DeserializeUsingNonDefaultConstructorWithLeftOverValues() - { - List> kvPairs = - JsonConvert.DeserializeObject>>( - "[{\"Key\":\"Two\",\"Value\":\"2\"},{\"Key\":\"One\",\"Value\":\"1\"}]"); + [Test] + public void DeserializeUsingNonDefaultConstructorWithLeftOverValues() + { + List> kvPairs = + JsonConvert.DeserializeObject>>( + "[{\"Key\":\"Two\",\"Value\":\"2\"},{\"Key\":\"One\",\"Value\":\"1\"}]"); - Assert.AreEqual(2, kvPairs.Count); - Assert.AreEqual("Two", kvPairs[0].Key); - Assert.AreEqual("2", kvPairs[0].Value); - Assert.AreEqual("One", kvPairs[1].Key); - Assert.AreEqual("1", kvPairs[1].Value); - } + Assert.AreEqual(2, kvPairs.Count); + Assert.AreEqual("Two", kvPairs[0].Key); + Assert.AreEqual("2", kvPairs[0].Value); + Assert.AreEqual("One", kvPairs[1].Key); + Assert.AreEqual("1", kvPairs[1].Value); + } - [Test] - public void SerializeClassWithInheritedProtectedMember() - { - AA myA = new AA(2); - string json = JsonConvert.SerializeObject(myA, Formatting.Indented); - Assert.AreEqual(@"{ + [Test] + public void SerializeClassWithInheritedProtectedMember() + { + AA myA = new AA(2); + string json = JsonConvert.SerializeObject(myA, Formatting.Indented); + Assert.AreEqual(@"{ ""AA_field1"": 2, ""AA_property1"": 2, ""AA_property2"": 2, @@ -4395,9 +4373,9 @@ To fix this error either change the environment to be fully trusted, change the ""AA_property4"": 2 }", json); - BB myB = new BB(3, 4); - json = JsonConvert.SerializeObject(myB, Formatting.Indented); - Assert.AreEqual(@"{ + BB myB = new BB(3, 4); + json = JsonConvert.SerializeObject(myB, Formatting.Indented); + Assert.AreEqual(@"{ ""BB_field1"": 4, ""BB_field2"": 4, ""AA_field1"": 3, @@ -4412,14 +4390,14 @@ To fix this error either change the environment to be fully trusted, change the ""AA_property3"": 3, ""AA_property4"": 3 }", json); - } + } #if !PORTABLE - [Test] - public void DeserializeClassWithInheritedProtectedMember() - { - AA myA = JsonConvert.DeserializeObject( - @"{ + [Test] + public void DeserializeClassWithInheritedProtectedMember() + { + AA myA = JsonConvert.DeserializeObject( + @"{ ""AA_field1"": 2, ""AA_field2"": 2, ""AA_property1"": 2, @@ -4430,17 +4408,17 @@ To fix this error either change the environment to be fully trusted, change the ""AA_property6"": 2 }"); - Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetField("AA_field1", BindingFlags.Instance | BindingFlags.NonPublic), myA)); - Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetField("AA_field2", BindingFlags.Instance | BindingFlags.NonPublic), myA)); - Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property1", BindingFlags.Instance | BindingFlags.NonPublic), myA)); - Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property2", BindingFlags.Instance | BindingFlags.NonPublic), myA)); - Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property3", BindingFlags.Instance | BindingFlags.NonPublic), myA)); - Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property4", BindingFlags.Instance | BindingFlags.NonPublic), myA)); - Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property5", BindingFlags.Instance | BindingFlags.NonPublic), myA)); - Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property6", BindingFlags.Instance | BindingFlags.NonPublic), myA)); + Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetField("AA_field1", BindingFlags.Instance | BindingFlags.NonPublic), myA)); + Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetField("AA_field2", BindingFlags.Instance | BindingFlags.NonPublic), myA)); + Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property1", BindingFlags.Instance | BindingFlags.NonPublic), myA)); + Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property2", BindingFlags.Instance | BindingFlags.NonPublic), myA)); + Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property3", BindingFlags.Instance | BindingFlags.NonPublic), myA)); + Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property4", BindingFlags.Instance | BindingFlags.NonPublic), myA)); + Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property5", BindingFlags.Instance | BindingFlags.NonPublic), myA)); + Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property6", BindingFlags.Instance | BindingFlags.NonPublic), myA)); - BB myB = JsonConvert.DeserializeObject( - @"{ + BB myB = JsonConvert.DeserializeObject( + @"{ ""BB_field1"": 4, ""BB_field2"": 4, ""AA_field1"": 3, @@ -4461,137 +4439,139 @@ To fix this error either change the environment to be fully trusted, change the ""BB_property8"": 3 }"); - Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(AA).GetField("AA_field1", BindingFlags.Instance | BindingFlags.NonPublic), myB)); - Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetField("AA_field2", BindingFlags.Instance | BindingFlags.NonPublic), myB)); - Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property1", BindingFlags.Instance | BindingFlags.NonPublic), myB)); - Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property2", BindingFlags.Instance | BindingFlags.NonPublic), myB)); - Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property3", BindingFlags.Instance | BindingFlags.NonPublic), myB)); - Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property4", BindingFlags.Instance | BindingFlags.NonPublic), myB)); - Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property5", BindingFlags.Instance | BindingFlags.NonPublic), myB)); - Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property6", BindingFlags.Instance | BindingFlags.NonPublic), myB)); + Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(AA).GetField("AA_field1", BindingFlags.Instance | BindingFlags.NonPublic), myB)); + Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetField("AA_field2", BindingFlags.Instance | BindingFlags.NonPublic), myB)); + Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property1", BindingFlags.Instance | BindingFlags.NonPublic), myB)); + Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property2", BindingFlags.Instance | BindingFlags.NonPublic), myB)); + Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property3", BindingFlags.Instance | BindingFlags.NonPublic), myB)); + Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property4", BindingFlags.Instance | BindingFlags.NonPublic), myB)); + Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property5", BindingFlags.Instance | BindingFlags.NonPublic), myB)); + Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property6", BindingFlags.Instance | BindingFlags.NonPublic), myB)); - Assert.AreEqual(4, myB.BB_field1); - Assert.AreEqual(4, myB.BB_field2); - Assert.AreEqual(3, myB.BB_property1); - Assert.AreEqual(3, myB.BB_property2); - Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(BB).GetProperty("BB_property3", BindingFlags.Instance | BindingFlags.Public), myB)); - Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(BB).GetProperty("BB_property4", BindingFlags.Instance | BindingFlags.NonPublic), myB)); - Assert.AreEqual(0, myB.BB_property5); - Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(BB).GetProperty("BB_property6", BindingFlags.Instance | BindingFlags.Public), myB)); - Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(BB).GetProperty("BB_property7", BindingFlags.Instance | BindingFlags.Public), myB)); - Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(BB).GetProperty("BB_property8", BindingFlags.Instance | BindingFlags.Public), myB)); - } + Assert.AreEqual(4, myB.BB_field1); + Assert.AreEqual(4, myB.BB_field2); + Assert.AreEqual(3, myB.BB_property1); + Assert.AreEqual(3, myB.BB_property2); + Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(BB).GetProperty("BB_property3", BindingFlags.Instance | BindingFlags.Public), myB)); + Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(BB).GetProperty("BB_property4", BindingFlags.Instance | BindingFlags.NonPublic), myB)); + Assert.AreEqual(0, myB.BB_property5); + Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(BB).GetProperty("BB_property6", BindingFlags.Instance | BindingFlags.Public), myB)); + Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(BB).GetProperty("BB_property7", BindingFlags.Instance | BindingFlags.Public), myB)); + Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(BB).GetProperty("BB_property8", BindingFlags.Instance | BindingFlags.Public), myB)); + } #endif - public class AA - { - [JsonProperty] - protected int AA_field1; - protected int AA_field2; + public class AA + { + [JsonProperty] + protected int AA_field1; - [JsonProperty] - protected int AA_property1 { get; set; } + protected int AA_field2; - [JsonProperty] - protected int AA_property2 { get; private set; } + [JsonProperty] + protected int AA_property1 { get; set; } - [JsonProperty] - protected int AA_property3 { private get; set; } + [JsonProperty] + protected int AA_property2 { get; private set; } - [JsonProperty] - private int AA_property4 { get; set; } + [JsonProperty] + protected int AA_property3 { private get; set; } - protected int AA_property5 { get; private set; } - protected int AA_property6 { private get; set; } + [JsonProperty] + private int AA_property4 { get; set; } - public AA() - { - } + protected int AA_property5 { get; private set; } + protected int AA_property6 { private get; set; } - public AA(int f) - { - AA_field1 = f; - AA_field2 = f; - AA_property1 = f; - AA_property2 = f; - AA_property3 = f; - AA_property4 = f; - AA_property5 = f; - AA_property6 = f; - } - } + public AA() + { + } - public class BB : AA - { - [JsonProperty] - public int BB_field1; - public int BB_field2; + public AA(int f) + { + AA_field1 = f; + AA_field2 = f; + AA_property1 = f; + AA_property2 = f; + AA_property3 = f; + AA_property4 = f; + AA_property5 = f; + AA_property6 = f; + } + } - [JsonProperty] - public int BB_property1 { get; set; } + public class BB : AA + { + [JsonProperty] + public int BB_field1; - [JsonProperty] - public int BB_property2 { get; private set; } + public int BB_field2; - [JsonProperty] - public int BB_property3 { private get; set; } + [JsonProperty] + public int BB_property1 { get; set; } - [JsonProperty] - private int BB_property4 { get; set; } + [JsonProperty] + public int BB_property2 { get; private set; } - public int BB_property5 { get; private set; } - public int BB_property6 { private get; set; } + [JsonProperty] + public int BB_property3 { private get; set; } - [JsonProperty] - public int BB_property7 { protected get; set; } + [JsonProperty] + private int BB_property4 { get; set; } - public int BB_property8 { protected get; set; } + public int BB_property5 { get; private set; } + public int BB_property6 { private get; set; } - public BB() - { - } + [JsonProperty] + public int BB_property7 { protected get; set; } - public BB(int f, int g) - : base(f) - { - BB_field1 = g; - BB_field2 = g; - BB_property1 = g; - BB_property2 = g; - BB_property3 = g; - BB_property4 = g; - BB_property5 = g; - BB_property6 = g; - BB_property7 = g; - BB_property8 = g; - } - } + public int BB_property8 { protected get; set; } + + public BB() + { + } + + public BB(int f, int g) + : base(f) + { + BB_field1 = g; + BB_field2 = g; + BB_property1 = g; + BB_property2 = g; + BB_property3 = g; + BB_property4 = g; + BB_property5 = g; + BB_property6 = g; + BB_property7 = g; + BB_property8 = g; + } + } #if !NET20 && !SILVERLIGHT - public class XNodeTestObject - { - public XDocument Document { get; set; } - public XElement Element { get; set; } - } + public class XNodeTestObject + { + public XDocument Document { get; set; } + public XElement Element { get; set; } + } #endif #if !SILVERLIGHT && !NETFX_CORE - public class XmlNodeTestObject - { - public XmlDocument Document { get; set; } - } + public class XmlNodeTestObject + { + public XmlDocument Document { get; set; } + } #endif #if !(NET20 || SILVERLIGHT || PORTABLE40) - [Test] - public void SerializeDeserializeXNodeProperties() - { - XNodeTestObject testObject = new XNodeTestObject(); - testObject.Document = XDocument.Parse("hehe, root"); - testObject.Element = XElement.Parse(@"element"); + [Test] + public void SerializeDeserializeXNodeProperties() + { + XNodeTestObject testObject = new XNodeTestObject(); + testObject.Document = XDocument.Parse("hehe, root"); + testObject.Element = XElement.Parse(@"element"); - string json = JsonConvert.SerializeObject(testObject, Formatting.Indented); - string expected = @"{ + string json = JsonConvert.SerializeObject(testObject, Formatting.Indented); + string expected = @"{ ""Document"": { ""root"": ""hehe, root"" }, @@ -4603,198 +4583,198 @@ To fix this error either change the environment to be fully trusted, change the } } }"; - Assert.AreEqual(expected, json); + Assert.AreEqual(expected, json); - XNodeTestObject newTestObject = JsonConvert.DeserializeObject(json); - Assert.AreEqual(testObject.Document.ToString(), newTestObject.Document.ToString()); - Assert.AreEqual(testObject.Element.ToString(), newTestObject.Element.ToString()); + XNodeTestObject newTestObject = JsonConvert.DeserializeObject(json); + Assert.AreEqual(testObject.Document.ToString(), newTestObject.Document.ToString()); + Assert.AreEqual(testObject.Element.ToString(), newTestObject.Element.ToString()); - Assert.IsNull(newTestObject.Element.Parent); - } + Assert.IsNull(newTestObject.Element.Parent); + } #endif #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - [Test] - public void SerializeDeserializeXmlNodeProperties() - { - XmlNodeTestObject testObject = new XmlNodeTestObject(); - XmlDocument document = new XmlDocument(); - document.LoadXml("hehe, root"); - testObject.Document = document; + [Test] + public void SerializeDeserializeXmlNodeProperties() + { + XmlNodeTestObject testObject = new XmlNodeTestObject(); + XmlDocument document = new XmlDocument(); + document.LoadXml("hehe, root"); + testObject.Document = document; - string json = JsonConvert.SerializeObject(testObject, Formatting.Indented); - string expected = @"{ + string json = JsonConvert.SerializeObject(testObject, Formatting.Indented); + string expected = @"{ ""Document"": { ""root"": ""hehe, root"" } }"; - Assert.AreEqual(expected, json); + Assert.AreEqual(expected, json); - XmlNodeTestObject newTestObject = JsonConvert.DeserializeObject(json); - Assert.AreEqual(testObject.Document.InnerXml, newTestObject.Document.InnerXml); - } + XmlNodeTestObject newTestObject = JsonConvert.DeserializeObject(json); + Assert.AreEqual(testObject.Document.InnerXml, newTestObject.Document.InnerXml); + } #endif - [Test] - public void FullClientMapSerialization() - { - ClientMap source = new ClientMap() + [Test] + public void FullClientMapSerialization() { - position = new Pos() { X = 100, Y = 200 }, - center = new PosDouble() { X = 251.6, Y = 361.3 } - }; + ClientMap source = new ClientMap() + { + position = new Pos() { X = 100, Y = 200 }, + center = new PosDouble() { X = 251.6, Y = 361.3 } + }; - string json = JsonConvert.SerializeObject(source, new PosConverter(), new PosDoubleConverter()); - Assert.AreEqual("{\"position\":new Pos(100,200),\"center\":new PosD(251.6,361.3)}", json); - } + string json = JsonConvert.SerializeObject(source, new PosConverter(), new PosDoubleConverter()); + Assert.AreEqual("{\"position\":new Pos(100,200),\"center\":new PosD(251.6,361.3)}", json); + } - public class ClientMap - { - public Pos position { get; set; } - public PosDouble center { get; set; } - } - - public class Pos - { - public int X { get; set; } - public int Y { get; set; } - } - - public class PosDouble - { - public double X { get; set; } - public double Y { get; set; } - } - - public class PosConverter : JsonConverter - { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - Pos p = (Pos)value; - - if (p != null) - writer.WriteRawValue(String.Format("new Pos({0},{1})", p.X, p.Y)); - else - writer.WriteNull(); - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - throw new NotImplementedException(); - } - - public override bool CanConvert(Type objectType) - { - return objectType.IsAssignableFrom(typeof(Pos)); - } - } - - public class PosDoubleConverter : JsonConverter - { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - PosDouble p = (PosDouble)value; - - if (p != null) - writer.WriteRawValue(String.Format(CultureInfo.InvariantCulture, "new PosD({0},{1})", p.X, p.Y)); - else - writer.WriteNull(); - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - throw new NotImplementedException(); - } - - public override bool CanConvert(Type objectType) - { - return objectType.IsAssignableFrom(typeof(PosDouble)); - } - } - - [Test] - public void TestEscapeDictionaryStrings() - { - const string s = @"host\user"; - string serialized = JsonConvert.SerializeObject(s); - Assert.AreEqual(@"""host\\user""", serialized); - - Dictionary d1 = new Dictionary(); - d1.Add(5, s); - Assert.AreEqual(@"{""5"":""host\\user""}", JsonConvert.SerializeObject(d1)); - - Dictionary d2 = new Dictionary(); - d2.Add(s, 5); - Assert.AreEqual(@"{""host\\user"":5}", JsonConvert.SerializeObject(d2)); - } - - public class GenericListTestClass - { - public List GenericList { get; set; } - - public GenericListTestClass() - { - GenericList = new List(); - } - } - - [Test] - public void DeserializeExistingGenericList() - { - GenericListTestClass c = new GenericListTestClass(); - c.GenericList.Add("1"); - c.GenericList.Add("2"); - - string json = JsonConvert.SerializeObject(c, Formatting.Indented); - - GenericListTestClass newValue = JsonConvert.DeserializeObject(json); - Assert.AreEqual(2, newValue.GenericList.Count); - Assert.AreEqual(typeof(List), newValue.GenericList.GetType()); - } - - [Test] - public void DeserializeSimpleKeyValuePair() - { - List> list = new List>(); - list.Add(new KeyValuePair("key1", "value1")); - list.Add(new KeyValuePair("key2", "value2")); - - string json = JsonConvert.SerializeObject(list); - - Assert.AreEqual(@"[{""Key"":""key1"",""Value"":""value1""},{""Key"":""key2"",""Value"":""value2""}]", json); - - List> result = JsonConvert.DeserializeObject>>(json); - Assert.AreEqual(2, result.Count); - Assert.AreEqual("key1", result[0].Key); - Assert.AreEqual("value1", result[0].Value); - Assert.AreEqual("key2", result[1].Key); - Assert.AreEqual("value2", result[1].Value); - } - - [Test] - public void DeserializeComplexKeyValuePair() - { - DateTime dateTime = new DateTime(2000, 12, 1, 23, 1, 1, DateTimeKind.Utc); - - List> list = new List>(); - list.Add(new KeyValuePair("key1", new WagePerson + public class ClientMap { - BirthDate = dateTime, - Department = "Department1", - LastModified = dateTime, - HourlyWage = 1 - })); - list.Add(new KeyValuePair("key2", new WagePerson + public Pos position { get; set; } + public PosDouble center { get; set; } + } + + public class Pos { - BirthDate = dateTime, - Department = "Department2", - LastModified = dateTime, - HourlyWage = 2 - })); + public int X { get; set; } + public int Y { get; set; } + } - string json = JsonConvert.SerializeObject(list, Formatting.Indented); + public class PosDouble + { + public double X { get; set; } + public double Y { get; set; } + } - Assert.AreEqual(@"[ + public class PosConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + Pos p = (Pos)value; + + if (p != null) + writer.WriteRawValue(String.Format("new Pos({0},{1})", p.X, p.Y)); + else + writer.WriteNull(); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + throw new NotImplementedException(); + } + + public override bool CanConvert(Type objectType) + { + return objectType.IsAssignableFrom(typeof(Pos)); + } + } + + public class PosDoubleConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + PosDouble p = (PosDouble)value; + + if (p != null) + writer.WriteRawValue(String.Format(CultureInfo.InvariantCulture, "new PosD({0},{1})", p.X, p.Y)); + else + writer.WriteNull(); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + throw new NotImplementedException(); + } + + public override bool CanConvert(Type objectType) + { + return objectType.IsAssignableFrom(typeof(PosDouble)); + } + } + + [Test] + public void TestEscapeDictionaryStrings() + { + const string s = @"host\user"; + string serialized = JsonConvert.SerializeObject(s); + Assert.AreEqual(@"""host\\user""", serialized); + + Dictionary d1 = new Dictionary(); + d1.Add(5, s); + Assert.AreEqual(@"{""5"":""host\\user""}", JsonConvert.SerializeObject(d1)); + + Dictionary d2 = new Dictionary(); + d2.Add(s, 5); + Assert.AreEqual(@"{""host\\user"":5}", JsonConvert.SerializeObject(d2)); + } + + public class GenericListTestClass + { + public List GenericList { get; set; } + + public GenericListTestClass() + { + GenericList = new List(); + } + } + + [Test] + public void DeserializeExistingGenericList() + { + GenericListTestClass c = new GenericListTestClass(); + c.GenericList.Add("1"); + c.GenericList.Add("2"); + + string json = JsonConvert.SerializeObject(c, Formatting.Indented); + + GenericListTestClass newValue = JsonConvert.DeserializeObject(json); + Assert.AreEqual(2, newValue.GenericList.Count); + Assert.AreEqual(typeof(List), newValue.GenericList.GetType()); + } + + [Test] + public void DeserializeSimpleKeyValuePair() + { + List> list = new List>(); + list.Add(new KeyValuePair("key1", "value1")); + list.Add(new KeyValuePair("key2", "value2")); + + string json = JsonConvert.SerializeObject(list); + + Assert.AreEqual(@"[{""Key"":""key1"",""Value"":""value1""},{""Key"":""key2"",""Value"":""value2""}]", json); + + List> result = JsonConvert.DeserializeObject>>(json); + Assert.AreEqual(2, result.Count); + Assert.AreEqual("key1", result[0].Key); + Assert.AreEqual("value1", result[0].Value); + Assert.AreEqual("key2", result[1].Key); + Assert.AreEqual("value2", result[1].Value); + } + + [Test] + public void DeserializeComplexKeyValuePair() + { + DateTime dateTime = new DateTime(2000, 12, 1, 23, 1, 1, DateTimeKind.Utc); + + List> list = new List>(); + list.Add(new KeyValuePair("key1", new WagePerson + { + BirthDate = dateTime, + Department = "Department1", + LastModified = dateTime, + HourlyWage = 1 + })); + list.Add(new KeyValuePair("key2", new WagePerson + { + BirthDate = dateTime, + Department = "Department2", + LastModified = dateTime, + HourlyWage = 2 + })); + + string json = JsonConvert.SerializeObject(list, Formatting.Indented); + + Assert.AreEqual(@"[ { ""Key"": ""key1"", ""Value"": { @@ -4815,298 +4795,295 @@ To fix this error either change the environment to be fully trusted, change the } ]", json); - List> result = JsonConvert.DeserializeObject>>(json); - Assert.AreEqual(2, result.Count); - Assert.AreEqual("key1", result[0].Key); - Assert.AreEqual(1, result[0].Value.HourlyWage); - Assert.AreEqual("key2", result[1].Key); - Assert.AreEqual(2, result[1].Value.HourlyWage); - } - - public class StringListAppenderConverter : JsonConverter - { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - writer.WriteValue(value); - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - List existingStrings = (List)existingValue; - List newStrings = new List(existingStrings); - - reader.Read(); - - while (reader.TokenType != JsonToken.EndArray) - { - string s = (string)reader.Value; - newStrings.Add(s); - - reader.Read(); + List> result = JsonConvert.DeserializeObject>>(json); + Assert.AreEqual(2, result.Count); + Assert.AreEqual("key1", result[0].Key); + Assert.AreEqual(1, result[0].Value.HourlyWage); + Assert.AreEqual("key2", result[1].Key); + Assert.AreEqual(2, result[1].Value.HourlyWage); } - return newStrings; - } - - public override bool CanConvert(Type objectType) - { - return (objectType == typeof(List)); - } - } - - [Test] - public void StringListAppenderConverterTest() - { - Movie p = new Movie(); - p.ReleaseCountries = new List { "Existing" }; - - JsonConvert.PopulateObject("{'ReleaseCountries':['Appended']}", p, new JsonSerializerSettings + public class StringListAppenderConverter : JsonConverter { - Converters = new List { new StringListAppenderConverter() } - }); + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + writer.WriteValue(value); + } - Assert.AreEqual(2, p.ReleaseCountries.Count); - Assert.AreEqual("Existing", p.ReleaseCountries[0]); - Assert.AreEqual("Appended", p.ReleaseCountries[1]); - } + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + List existingStrings = (List)existingValue; + List newStrings = new List(existingStrings); - public class StringAppenderConverter : JsonConverter - { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - writer.WriteValue(value); - } + reader.Read(); - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - string existingString = (string)existingValue; - string newString = existingString + (string)reader.Value; - - return newString; - } - - public override bool CanConvert(Type objectType) - { - return (objectType == typeof(string)); - } - } - - [Test] - public void StringAppenderConverterTest() - { - Movie p = new Movie(); - p.Name = "Existing,"; - - JsonConvert.PopulateObject("{'Name':'Appended'}", p, new JsonSerializerSettings - { - Converters = new List { new StringAppenderConverter() } - }); - - Assert.AreEqual("Existing,Appended", p.Name); - } - - [Test] - public void SerializeRefAdditionalContent() - { - //Additional text found in JSON string after finishing deserializing object. - //Test 1 - var reference = new Dictionary(); - reference.Add("$ref", "Persons"); - reference.Add("$id", 1); - - var child = new Dictionary(); - child.Add("_id", 2); - child.Add("Name", "Isabell"); - child.Add("Father", reference); - - var json = JsonConvert.SerializeObject(child, Formatting.Indented); - - ExceptionAssert.Throws( - "Additional content found in JSON reference object. A JSON reference object should only have a $ref property. Path 'Father.$id', line 6, position 11.", - () => - { - JsonConvert.DeserializeObject>(json); - }); - } - - [Test] - public void SerializeRefBadType() - { - ExceptionAssert.Throws( - "JSON reference $ref property must have a string or null value. Path 'Father.$ref', line 5, position 14.", - () => - { - //Additional text found in JSON string after finishing deserializing object. - //Test 1 - var reference = new Dictionary(); - reference.Add("$ref", 1); - reference.Add("$id", 1); - - var child = new Dictionary(); - child.Add("_id", 2); - child.Add("Name", "Isabell"); - child.Add("Father", reference); - - var json = JsonConvert.SerializeObject(child, Formatting.Indented); - JsonConvert.DeserializeObject>(json); - }); - } - - [Test] - public void SerializeRefNull() - { - var reference = new Dictionary(); - reference.Add("$ref", null); - reference.Add("$id", null); - reference.Add("blah", "blah!"); - - var child = new Dictionary(); - child.Add("_id", 2); - child.Add("Name", "Isabell"); - child.Add("Father", reference); - - var json = JsonConvert.SerializeObject(child); - Dictionary result = JsonConvert.DeserializeObject>(json); - - Assert.AreEqual(3, result.Count); - Assert.AreEqual(1, ((JObject)result["Father"]).Count); - Assert.AreEqual("blah!", (string)((JObject)result["Father"])["blah"]); - } - - public class ConstructorCompexIgnoredProperty - { - [JsonIgnore] - public Product Ignored { get; set; } - - public string First { get; set; } - public int Second { get; set; } - - public ConstructorCompexIgnoredProperty(string first, int second) - { - First = first; - Second = second; - } - } - - [Test] - public void DeserializeIgnoredPropertyInConstructor() - { - string json = @"{""First"":""First"",""Second"":2,""Ignored"":{""Name"":""James""},""AdditionalContent"":{""LOL"":true}}"; - - ConstructorCompexIgnoredProperty cc = JsonConvert.DeserializeObject(json); - Assert.AreEqual("First", cc.First); - Assert.AreEqual(2, cc.Second); - Assert.AreEqual(null, cc.Ignored); - } - - [Test] - public void DeserializeFloatAsDecimal() - { - string json = @"{'value':9.9}"; - - var dic = JsonConvert.DeserializeObject>( - json, new JsonSerializerSettings + while (reader.TokenType != JsonToken.EndArray) { - FloatParseHandling = FloatParseHandling.Decimal + string s = (string)reader.Value; + newStrings.Add(s); + + reader.Read(); + } + + return newStrings; + } + + public override bool CanConvert(Type objectType) + { + return (objectType == typeof(List)); + } + } + + [Test] + public void StringListAppenderConverterTest() + { + Movie p = new Movie(); + p.ReleaseCountries = new List { "Existing" }; + + JsonConvert.PopulateObject("{'ReleaseCountries':['Appended']}", p, new JsonSerializerSettings + { + Converters = new List { new StringListAppenderConverter() } + }); + + Assert.AreEqual(2, p.ReleaseCountries.Count); + Assert.AreEqual("Existing", p.ReleaseCountries[0]); + Assert.AreEqual("Appended", p.ReleaseCountries[1]); + } + + public class StringAppenderConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + writer.WriteValue(value); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + string existingString = (string)existingValue; + string newString = existingString + (string)reader.Value; + + return newString; + } + + public override bool CanConvert(Type objectType) + { + return (objectType == typeof(string)); + } + } + + [Test] + public void StringAppenderConverterTest() + { + Movie p = new Movie(); + p.Name = "Existing,"; + + JsonConvert.PopulateObject("{'Name':'Appended'}", p, new JsonSerializerSettings + { + Converters = new List { new StringAppenderConverter() } + }); + + Assert.AreEqual("Existing,Appended", p.Name); + } + + [Test] + public void SerializeRefAdditionalContent() + { + //Additional text found in JSON string after finishing deserializing object. + //Test 1 + var reference = new Dictionary(); + reference.Add("$ref", "Persons"); + reference.Add("$id", 1); + + var child = new Dictionary(); + child.Add("_id", 2); + child.Add("Name", "Isabell"); + child.Add("Father", reference); + + var json = JsonConvert.SerializeObject(child, Formatting.Indented); + + ExceptionAssert.Throws( + "Additional content found in JSON reference object. A JSON reference object should only have a $ref property. Path 'Father.$id', line 6, position 11.", + () => { JsonConvert.DeserializeObject>(json); }); + } + + [Test] + public void SerializeRefBadType() + { + ExceptionAssert.Throws( + "JSON reference $ref property must have a string or null value. Path 'Father.$ref', line 5, position 14.", + () => + { + //Additional text found in JSON string after finishing deserializing object. + //Test 1 + var reference = new Dictionary(); + reference.Add("$ref", 1); + reference.Add("$id", 1); + + var child = new Dictionary(); + child.Add("_id", 2); + child.Add("Name", "Isabell"); + child.Add("Father", reference); + + var json = JsonConvert.SerializeObject(child, Formatting.Indented); + JsonConvert.DeserializeObject>(json); + }); + } + + [Test] + public void SerializeRefNull() + { + var reference = new Dictionary(); + reference.Add("$ref", null); + reference.Add("$id", null); + reference.Add("blah", "blah!"); + + var child = new Dictionary(); + child.Add("_id", 2); + child.Add("Name", "Isabell"); + child.Add("Father", reference); + + var json = JsonConvert.SerializeObject(child); + Dictionary result = JsonConvert.DeserializeObject>(json); + + Assert.AreEqual(3, result.Count); + Assert.AreEqual(1, ((JObject)result["Father"]).Count); + Assert.AreEqual("blah!", (string)((JObject)result["Father"])["blah"]); + } + + public class ConstructorCompexIgnoredProperty + { + [JsonIgnore] + public Product Ignored { get; set; } + + public string First { get; set; } + public int Second { get; set; } + + public ConstructorCompexIgnoredProperty(string first, int second) + { + First = first; + Second = second; + } + } + + [Test] + public void DeserializeIgnoredPropertyInConstructor() + { + string json = @"{""First"":""First"",""Second"":2,""Ignored"":{""Name"":""James""},""AdditionalContent"":{""LOL"":true}}"; + + ConstructorCompexIgnoredProperty cc = JsonConvert.DeserializeObject(json); + Assert.AreEqual("First", cc.First); + Assert.AreEqual(2, cc.Second); + Assert.AreEqual(null, cc.Ignored); + } + + [Test] + public void DeserializeFloatAsDecimal() + { + string json = @"{'value':9.9}"; + + var dic = JsonConvert.DeserializeObject>( + json, new JsonSerializerSettings + { + FloatParseHandling = FloatParseHandling.Decimal }); - Assert.AreEqual(typeof(decimal), dic["value"].GetType()); - Assert.AreEqual(9.9m, dic["value"]); - } + Assert.AreEqual(typeof(decimal), dic["value"].GetType()); + Assert.AreEqual(9.9m, dic["value"]); + } - [Test] - public void ShouldSerializeTest() - { - ShouldSerializeTestClass c = new ShouldSerializeTestClass(); - c.Name = "James"; - c.Age = 27; + [Test] + public void ShouldSerializeTest() + { + ShouldSerializeTestClass c = new ShouldSerializeTestClass(); + c.Name = "James"; + c.Age = 27; - string json = JsonConvert.SerializeObject(c, Formatting.Indented); + string json = JsonConvert.SerializeObject(c, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Age"": 27 }", json); - c._shouldSerializeName = true; - json = JsonConvert.SerializeObject(c, Formatting.Indented); + c._shouldSerializeName = true; + json = JsonConvert.SerializeObject(c, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Name"": ""James"", ""Age"": 27 }", json); - ShouldSerializeTestClass deserialized = JsonConvert.DeserializeObject(json); - Assert.AreEqual("James", deserialized.Name); - Assert.AreEqual(27, deserialized.Age); - } + ShouldSerializeTestClass deserialized = JsonConvert.DeserializeObject(json); + Assert.AreEqual("James", deserialized.Name); + Assert.AreEqual(27, deserialized.Age); + } - public class Employee - { - public string Name { get; set; } - public Employee Manager { get; set; } + public class Employee + { + public string Name { get; set; } + public Employee Manager { get; set; } - public bool ShouldSerializeManager() - { - return (Manager != this); - } - } + public bool ShouldSerializeManager() + { + return (Manager != this); + } + } - [Test] - public void ShouldSerializeExample() - { - Employee joe = new Employee(); - joe.Name = "Joe Employee"; - Employee mike = new Employee(); - mike.Name = "Mike Manager"; + [Test] + public void ShouldSerializeExample() + { + Employee joe = new Employee(); + joe.Name = "Joe Employee"; + Employee mike = new Employee(); + mike.Name = "Mike Manager"; - joe.Manager = mike; - mike.Manager = mike; + joe.Manager = mike; + mike.Manager = mike; - string json = JsonConvert.SerializeObject(new[] { joe, mike }, Formatting.Indented); - // [ - // { - // "Name": "Joe Employee", - // "Manager": { - // "Name": "Mike Manager" - // } - // }, - // { - // "Name": "Mike Manager" - // } - // ] + string json = JsonConvert.SerializeObject(new[] { joe, mike }, Formatting.Indented); + // [ + // { + // "Name": "Joe Employee", + // "Manager": { + // "Name": "Mike Manager" + // } + // }, + // { + // "Name": "Mike Manager" + // } + // ] - Console.WriteLine(json); - } + Console.WriteLine(json); + } - [Test] - public void SpecifiedTest() - { - SpecifiedTestClass c = new SpecifiedTestClass(); - c.Name = "James"; - c.Age = 27; - c.NameSpecified = false; + [Test] + public void SpecifiedTest() + { + SpecifiedTestClass c = new SpecifiedTestClass(); + c.Name = "James"; + c.Age = 27; + c.NameSpecified = false; - string json = JsonConvert.SerializeObject(c, Formatting.Indented); + string json = JsonConvert.SerializeObject(c, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Age"": 27 }", json); - SpecifiedTestClass deserialized = JsonConvert.DeserializeObject(json); - 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); + SpecifiedTestClass deserialized = JsonConvert.DeserializeObject(json); + 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); + c.NameSpecified = true; + c.WeightSpecified = true; + c.HeightSpecified = true; + c.FavoriteNumber = 23; + json = JsonConvert.SerializeObject(c, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Name"": ""James"", ""Age"": 27, ""Weight"": 0, @@ -5114,374 +5091,371 @@ To fix this error either change the environment to be fully trusted, change the ""FavoriteNumber"": 23 }", json); - deserialized = JsonConvert.DeserializeObject(json); - 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); - } + deserialized = JsonConvert.DeserializeObject(json); + 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); + } - // [Test] - // public void XmlSerializerSpecifiedTrueTest() - // { - // XmlSerializer s = new XmlSerializer(typeof(OptionalOrder)); + // [Test] + // public void XmlSerializerSpecifiedTrueTest() + // { + // XmlSerializer s = new XmlSerializer(typeof(OptionalOrder)); - // StringWriter sw = new StringWriter(); - // s.Serialize(sw, new OptionalOrder() { FirstOrder = "First", FirstOrderSpecified = true }); + // StringWriter sw = new StringWriter(); + // s.Serialize(sw, new OptionalOrder() { FirstOrder = "First", FirstOrderSpecified = true }); - // Console.WriteLine(sw.ToString()); + // Console.WriteLine(sw.ToString()); - // string xml = @" - // - // First - //"; + // string xml = @" + // + // First + //"; - // OptionalOrder o = (OptionalOrder)s.Deserialize(new StringReader(xml)); - // Console.WriteLine(o.FirstOrder); - // Console.WriteLine(o.FirstOrderSpecified); - // } + // OptionalOrder o = (OptionalOrder)s.Deserialize(new StringReader(xml)); + // Console.WriteLine(o.FirstOrder); + // Console.WriteLine(o.FirstOrderSpecified); + // } - // [Test] - // public void XmlSerializerSpecifiedFalseTest() - // { - // XmlSerializer s = new XmlSerializer(typeof(OptionalOrder)); + // [Test] + // public void XmlSerializerSpecifiedFalseTest() + // { + // XmlSerializer s = new XmlSerializer(typeof(OptionalOrder)); - // StringWriter sw = new StringWriter(); - // s.Serialize(sw, new OptionalOrder() { FirstOrder = "First", FirstOrderSpecified = false }); + // StringWriter sw = new StringWriter(); + // s.Serialize(sw, new OptionalOrder() { FirstOrder = "First", FirstOrderSpecified = false }); - // Console.WriteLine(sw.ToString()); + // Console.WriteLine(sw.ToString()); - // // string xml = @" - // // - // // First - // //"; + // // string xml = @" + // // + // // First + // //"; - // // OptionalOrder o = (OptionalOrder)s.Deserialize(new StringReader(xml)); - // // Console.WriteLine(o.FirstOrder); - // // Console.WriteLine(o.FirstOrderSpecified); - // } + // // OptionalOrder o = (OptionalOrder)s.Deserialize(new StringReader(xml)); + // // Console.WriteLine(o.FirstOrder); + // // Console.WriteLine(o.FirstOrderSpecified); + // } - public class OptionalOrder - { - // This field shouldn't be serialized - // if it is uninitialized. - public string FirstOrder; - // Use the XmlIgnoreAttribute to ignore the - // special field named "FirstOrderSpecified". - [System.Xml.Serialization.XmlIgnoreAttribute] - public bool FirstOrderSpecified; - } + public class OptionalOrder + { + // This field shouldn't be serialized + // if it is uninitialized. + public string FirstOrder; + // Use the XmlIgnoreAttribute to ignore the + // special field named "FirstOrderSpecified". + [System.Xml.Serialization.XmlIgnoreAttribute] + public bool FirstOrderSpecified; + } - public class FamilyDetails - { - public string Name { get; set; } - public int NumberOfChildren { get; set; } + public class FamilyDetails + { + public string Name { get; set; } + public int NumberOfChildren { get; set; } - [JsonIgnore] - public bool NumberOfChildrenSpecified { get; set; } - } + [JsonIgnore] + public bool NumberOfChildrenSpecified { get; set; } + } - [Test] - public void SpecifiedExample() - { - FamilyDetails joe = new FamilyDetails(); - joe.Name = "Joe Family Details"; - joe.NumberOfChildren = 4; - joe.NumberOfChildrenSpecified = true; + [Test] + public void SpecifiedExample() + { + FamilyDetails joe = new FamilyDetails(); + joe.Name = "Joe Family Details"; + joe.NumberOfChildren = 4; + joe.NumberOfChildrenSpecified = true; - FamilyDetails martha = new FamilyDetails(); - martha.Name = "Martha Family Details"; - martha.NumberOfChildren = 3; - martha.NumberOfChildrenSpecified = false; + FamilyDetails martha = new FamilyDetails(); + martha.Name = "Martha Family Details"; + martha.NumberOfChildren = 3; + martha.NumberOfChildrenSpecified = false; - string json = JsonConvert.SerializeObject(new[] { joe, martha }, Formatting.Indented); - //[ - // { - // "Name": "Joe Family Details", - // "NumberOfChildren": 4 - // }, - // { - // "Name": "Martha Family Details" - // } - //] - Console.WriteLine(json); + string json = JsonConvert.SerializeObject(new[] { joe, martha }, Formatting.Indented); + //[ + // { + // "Name": "Joe Family Details", + // "NumberOfChildren": 4 + // }, + // { + // "Name": "Martha Family Details" + // } + //] + Console.WriteLine(json); - string mikeString = "{\"Name\": \"Mike Person\"}"; - FamilyDetails mike = JsonConvert.DeserializeObject(mikeString); + string mikeString = "{\"Name\": \"Mike Person\"}"; + FamilyDetails mike = JsonConvert.DeserializeObject(mikeString); - Console.WriteLine("mikeString specifies number of children: {0}", mike.NumberOfChildrenSpecified); + Console.WriteLine("mikeString specifies number of children: {0}", mike.NumberOfChildrenSpecified); - string mikeFullDisclosureString = "{\"Name\": \"Mike Person\", \"NumberOfChildren\": \"0\"}"; - mike = JsonConvert.DeserializeObject(mikeFullDisclosureString); + string mikeFullDisclosureString = "{\"Name\": \"Mike Person\", \"NumberOfChildren\": \"0\"}"; + mike = JsonConvert.DeserializeObject(mikeFullDisclosureString); - Console.WriteLine("mikeString specifies number of children: {0}", mike.NumberOfChildrenSpecified); - } + Console.WriteLine("mikeString specifies number of children: {0}", mike.NumberOfChildrenSpecified); + } - public class DictionaryKey - { - public string Value { get; set; } + public class DictionaryKey + { + public string Value { get; set; } - public override string ToString() - { - return Value; - } + public override string ToString() + { + return Value; + } - public static implicit operator DictionaryKey(string value) - { - return new DictionaryKey() { Value = value }; - } - } + public static implicit operator DictionaryKey(string value) + { + return new DictionaryKey() { Value = value }; + } + } - [Test] - public void SerializeDeserializeDictionaryKey() - { - Dictionary dictionary = new Dictionary(); + [Test] + public void SerializeDeserializeDictionaryKey() + { + Dictionary dictionary = new Dictionary(); - dictionary.Add(new DictionaryKey() { Value = "First!" }, "First"); - dictionary.Add(new DictionaryKey() { Value = "Second!" }, "Second"); + dictionary.Add(new DictionaryKey() { Value = "First!" }, "First"); + dictionary.Add(new DictionaryKey() { Value = "Second!" }, "Second"); - string json = JsonConvert.SerializeObject(dictionary, Formatting.Indented); + string json = JsonConvert.SerializeObject(dictionary, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""First!"": ""First"", ""Second!"": ""Second"" }", json); - Dictionary newDictionary = - JsonConvert.DeserializeObject>(json); + Dictionary newDictionary = + JsonConvert.DeserializeObject>(json); - Assert.AreEqual(2, newDictionary.Count); - } + Assert.AreEqual(2, newDictionary.Count); + } - [Test] - public void SerializeNullableArray() - { - string jsonText = JsonConvert.SerializeObject(new double?[] { 2.4, 4.3, null }, Formatting.Indented); + [Test] + public void SerializeNullableArray() + { + string jsonText = JsonConvert.SerializeObject(new double?[] { 2.4, 4.3, null }, Formatting.Indented); - Assert.AreEqual(@"[ + Assert.AreEqual(@"[ 2.4, 4.3, null ]", jsonText); - } + } - [Test] - public void DeserializeNullableArray() - { - double?[] d = (double?[])JsonConvert.DeserializeObject(@"[ + [Test] + public void DeserializeNullableArray() + { + double?[] d = (double?[])JsonConvert.DeserializeObject(@"[ 2.4, 4.3, null ]", typeof(double?[])); - Assert.AreEqual(3, d.Length); - Assert.AreEqual(2.4, d[0]); - Assert.AreEqual(4.3, d[1]); - Assert.AreEqual(null, d[2]); - } + Assert.AreEqual(3, d.Length); + Assert.AreEqual(2.4, d[0]); + Assert.AreEqual(4.3, d[1]); + Assert.AreEqual(null, d[2]); + } #if !SILVERLIGHT && !NET20 - [Test] - public void SerializeHashSet() - { - string jsonText = JsonConvert.SerializeObject(new HashSet() + [Test] + public void SerializeHashSet() { - "One", - "2", - "III" - }, Formatting.Indented); + string jsonText = JsonConvert.SerializeObject(new HashSet() + { + "One", + "2", + "III" + }, Formatting.Indented); - Assert.AreEqual(@"[ + Assert.AreEqual(@"[ ""One"", ""2"", ""III"" ]", jsonText); - HashSet d = JsonConvert.DeserializeObject>(jsonText); + HashSet d = JsonConvert.DeserializeObject>(jsonText); - Assert.AreEqual(3, d.Count); - Assert.IsTrue(d.Contains("One")); - Assert.IsTrue(d.Contains("2")); - Assert.IsTrue(d.Contains("III")); - } + Assert.AreEqual(3, d.Count); + Assert.IsTrue(d.Contains("One")); + Assert.IsTrue(d.Contains("2")); + Assert.IsTrue(d.Contains("III")); + } #endif - private class MyClass - { - public byte[] Prop1 { get; set; } + private class MyClass + { + public byte[] Prop1 { get; set; } - public MyClass() - { - Prop1 = new byte[0]; - } - } + public MyClass() + { + Prop1 = new byte[0]; + } + } - [Test] - public void DeserializeByteArray() - { - JsonSerializer serializer1 = new JsonSerializer(); - serializer1.Converters.Add(new IsoDateTimeConverter()); - serializer1.NullValueHandling = NullValueHandling.Ignore; + [Test] + public void DeserializeByteArray() + { + JsonSerializer serializer1 = new JsonSerializer(); + serializer1.Converters.Add(new IsoDateTimeConverter()); + serializer1.NullValueHandling = NullValueHandling.Ignore; - string json = @"[{""Prop1"":""""},{""Prop1"":""""}]"; + string json = @"[{""Prop1"":""""},{""Prop1"":""""}]"; - JsonTextReader reader = new JsonTextReader(new StringReader(json)); + JsonTextReader reader = new JsonTextReader(new StringReader(json)); - MyClass[] z = (MyClass[])serializer1.Deserialize(reader, typeof(MyClass[])); - Assert.AreEqual(2, z.Length); - Assert.AreEqual(0, z[0].Prop1.Length); - Assert.AreEqual(0, z[1].Prop1.Length); - } + MyClass[] z = (MyClass[])serializer1.Deserialize(reader, typeof(MyClass[])); + Assert.AreEqual(2, z.Length); + Assert.AreEqual(0, z[0].Prop1.Length); + Assert.AreEqual(0, z[1].Prop1.Length); + } #if !NET20 && !SILVERLIGHT && !NETFX_CORE - public class StringDictionaryTestClass - { - public StringDictionary StringDictionaryProperty { get; set; } - } - - [Test] - public void StringDictionaryTest() - { - string classRef = typeof(StringDictionary).FullName; - - StringDictionaryTestClass s1 = new StringDictionaryTestClass() + public class StringDictionaryTestClass { - StringDictionaryProperty = new StringDictionary() + public StringDictionary StringDictionaryProperty { get; set; } + } + + [Test] + public void StringDictionaryTest() + { + string classRef = typeof(StringDictionary).FullName; + + StringDictionaryTestClass s1 = new StringDictionaryTestClass() { - {"1", "One"}, - {"2", "II"}, - {"3", "3"} - } - }; + StringDictionaryProperty = new StringDictionary() + { + { "1", "One" }, + { "2", "II" }, + { "3", "3" } + } + }; - string json = JsonConvert.SerializeObject(s1, Formatting.Indented); + string json = JsonConvert.SerializeObject(s1, Formatting.Indented); - ExceptionAssert.Throws( - "Cannot create and populate list type " + classRef + ". Path 'StringDictionaryProperty', line 2, position 32.", - () => - { - JsonConvert.DeserializeObject(json); - }); - } + ExceptionAssert.Throws( + "Cannot create and populate list type " + classRef + ". Path 'StringDictionaryProperty', line 2, position 32.", + () => { JsonConvert.DeserializeObject(json); }); + } #endif - [JsonObject(MemberSerialization.OptIn)] - public struct StructWithAttribute - { - public string MyString { get; set; } - - [JsonProperty] - public int MyInt { get; set; } - } - - [Test] - public void SerializeStructWithJsonObjectAttribute() - { - StructWithAttribute testStruct = new StructWithAttribute + [JsonObject(MemberSerialization.OptIn)] + public struct StructWithAttribute { - MyInt = int.MaxValue - }; + public string MyString { get; set; } - string json = JsonConvert.SerializeObject(testStruct, Formatting.Indented); + [JsonProperty] + public int MyInt { get; set; } + } - Assert.AreEqual(@"{ + [Test] + public void SerializeStructWithJsonObjectAttribute() + { + StructWithAttribute testStruct = new StructWithAttribute + { + MyInt = int.MaxValue + }; + + string json = JsonConvert.SerializeObject(testStruct, Formatting.Indented); + + Assert.AreEqual(@"{ ""MyInt"": 2147483647 }", json); - StructWithAttribute newStruct = JsonConvert.DeserializeObject(json); + StructWithAttribute newStruct = JsonConvert.DeserializeObject(json); - Assert.AreEqual(int.MaxValue, newStruct.MyInt); - } + Assert.AreEqual(int.MaxValue, newStruct.MyInt); + } - public class TimeZoneOffsetObject - { - public DateTimeOffset Offset { get; set; } - } + public class TimeZoneOffsetObject + { + public DateTimeOffset Offset { get; set; } + } #if !NET20 - [Test] - public void ReadWriteTimeZoneOffsetIso() - { - var serializeObject = JsonConvert.SerializeObject(new TimeZoneOffsetObject + [Test] + public void ReadWriteTimeZoneOffsetIso() { - Offset = new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(6)) - }); + var serializeObject = JsonConvert.SerializeObject(new TimeZoneOffsetObject + { + Offset = new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(6)) + }); - Assert.AreEqual("{\"Offset\":\"2000-01-01T00:00:00+06:00\"}", serializeObject); - var deserializeObject = JsonConvert.DeserializeObject(serializeObject); - Assert.AreEqual(TimeSpan.FromHours(6), deserializeObject.Offset.Offset); - Assert.AreEqual(new DateTime(2000, 1, 1), deserializeObject.Offset.Date); - } + Assert.AreEqual("{\"Offset\":\"2000-01-01T00:00:00+06:00\"}", serializeObject); + var deserializeObject = JsonConvert.DeserializeObject(serializeObject); + Assert.AreEqual(TimeSpan.FromHours(6), deserializeObject.Offset.Offset); + Assert.AreEqual(new DateTime(2000, 1, 1), deserializeObject.Offset.Date); + } - [Test] - public void DeserializePropertyNullableDateTimeOffsetExactIso() - { - NullableDateTimeTestClass d = JsonConvert.DeserializeObject("{\"DateTimeOffsetField\":\"2000-01-01T00:00:00+06:00\"}"); - Assert.AreEqual(new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(6)), d.DateTimeOffsetField); - } + [Test] + public void DeserializePropertyNullableDateTimeOffsetExactIso() + { + NullableDateTimeTestClass d = JsonConvert.DeserializeObject("{\"DateTimeOffsetField\":\"2000-01-01T00:00:00+06:00\"}"); + Assert.AreEqual(new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(6)), d.DateTimeOffsetField); + } - [Test] - public void ReadWriteTimeZoneOffsetMsAjax() - { - var serializeObject = JsonConvert.SerializeObject(new TimeZoneOffsetObject - { - Offset = new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(6)) - }, Formatting.None, new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.MicrosoftDateFormat }); + [Test] + public void ReadWriteTimeZoneOffsetMsAjax() + { + var serializeObject = JsonConvert.SerializeObject(new TimeZoneOffsetObject + { + Offset = new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(6)) + }, Formatting.None, new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.MicrosoftDateFormat }); - Assert.AreEqual("{\"Offset\":\"\\/Date(946663200000+0600)\\/\"}", serializeObject); - var deserializeObject = JsonConvert.DeserializeObject(serializeObject); - Assert.AreEqual(TimeSpan.FromHours(6), deserializeObject.Offset.Offset); - Assert.AreEqual(new DateTime(2000, 1, 1), deserializeObject.Offset.Date); - } + Assert.AreEqual("{\"Offset\":\"\\/Date(946663200000+0600)\\/\"}", serializeObject); + var deserializeObject = JsonConvert.DeserializeObject(serializeObject); + Assert.AreEqual(TimeSpan.FromHours(6), deserializeObject.Offset.Offset); + Assert.AreEqual(new DateTime(2000, 1, 1), deserializeObject.Offset.Date); + } - [Test] - public void DeserializePropertyNullableDateTimeOffsetExactMsAjax() - { - NullableDateTimeTestClass d = JsonConvert.DeserializeObject("{\"DateTimeOffsetField\":\"\\/Date(946663200000+0600)\\/\"}"); - Assert.AreEqual(new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(6)), d.DateTimeOffsetField); - } + [Test] + public void DeserializePropertyNullableDateTimeOffsetExactMsAjax() + { + NullableDateTimeTestClass d = JsonConvert.DeserializeObject("{\"DateTimeOffsetField\":\"\\/Date(946663200000+0600)\\/\"}"); + Assert.AreEqual(new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(6)), d.DateTimeOffsetField); + } #endif - public abstract class LogEvent - { - [JsonProperty("event")] - public abstract string EventName { get; } - } + public abstract class LogEvent + { + [JsonProperty("event")] + public abstract string EventName { get; } + } - public class DerivedEvent : LogEvent - { - public override string EventName - { - get { return "derived"; } - } - } + public class DerivedEvent : LogEvent + { + public override string EventName + { + get { return "derived"; } + } + } - [Test] - public void OverridenPropertyMembers() - { - string json = JsonConvert.SerializeObject(new DerivedEvent(), Formatting.Indented); + [Test] + public void OverridenPropertyMembers() + { + string json = JsonConvert.SerializeObject(new DerivedEvent(), Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""event"": ""derived"" }", json); - } + } #if !(NET35 || NET20 || PORTABLE40) - [Test] - public void SerializeExpandoObject() - { - dynamic expando = new ExpandoObject(); - expando.Int = 1; - expando.Decimal = 99.9d; - expando.Complex = new ExpandoObject(); - expando.Complex.String = "I am a string"; - expando.Complex.DateTime = new DateTime(2000, 12, 20, 18, 55, 0, DateTimeKind.Utc); + [Test] + public void SerializeExpandoObject() + { + dynamic expando = new ExpandoObject(); + expando.Int = 1; + expando.Decimal = 99.9d; + expando.Complex = new ExpandoObject(); + expando.Complex.String = "I am a string"; + expando.Complex.DateTime = new DateTime(2000, 12, 20, 18, 55, 0, DateTimeKind.Utc); - string json = JsonConvert.SerializeObject(expando, Formatting.Indented); - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(expando, Formatting.Indented); + Assert.AreEqual(@"{ ""Int"": 1, ""Decimal"": 99.9, ""Complex"": { @@ -5490,380 +5464,380 @@ To fix this error either change the environment to be fully trusted, change the } }", json); - IDictionary newExpando = JsonConvert.DeserializeObject(json); + IDictionary newExpando = JsonConvert.DeserializeObject(json); - CustomAssert.IsInstanceOfType(typeof(long), newExpando["Int"]); - Assert.AreEqual((long)expando.Int, newExpando["Int"]); + CustomAssert.IsInstanceOfType(typeof(long), newExpando["Int"]); + Assert.AreEqual((long)expando.Int, newExpando["Int"]); - CustomAssert.IsInstanceOfType(typeof(double), newExpando["Decimal"]); - Assert.AreEqual(expando.Decimal, newExpando["Decimal"]); + CustomAssert.IsInstanceOfType(typeof(double), newExpando["Decimal"]); + Assert.AreEqual(expando.Decimal, newExpando["Decimal"]); - CustomAssert.IsInstanceOfType(typeof(ExpandoObject), newExpando["Complex"]); - IDictionary o = (ExpandoObject)newExpando["Complex"]; + CustomAssert.IsInstanceOfType(typeof(ExpandoObject), newExpando["Complex"]); + IDictionary o = (ExpandoObject)newExpando["Complex"]; - CustomAssert.IsInstanceOfType(typeof(string), o["String"]); - Assert.AreEqual(expando.Complex.String, o["String"]); + CustomAssert.IsInstanceOfType(typeof(string), o["String"]); + Assert.AreEqual(expando.Complex.String, o["String"]); - CustomAssert.IsInstanceOfType(typeof(DateTime), o["DateTime"]); - Assert.AreEqual(expando.Complex.DateTime, o["DateTime"]); - } + CustomAssert.IsInstanceOfType(typeof(DateTime), o["DateTime"]); + Assert.AreEqual(expando.Complex.DateTime, o["DateTime"]); + } #endif - [Test] - public void DeserializeDecimalExact() - { - decimal d = JsonConvert.DeserializeObject("123456789876543.21"); - Assert.AreEqual(123456789876543.21m, d); - } - - [Test] - public void DeserializeNullableDecimalExact() - { - decimal? d = JsonConvert.DeserializeObject("123456789876543.21"); - Assert.AreEqual(123456789876543.21m, d); - } - - [Test] - public void DeserializeDecimalPropertyExact() - { - string json = "{Amount:123456789876543.21}"; - Invoice i = JsonConvert.DeserializeObject(json); - Assert.AreEqual(123456789876543.21m, i.Amount); - } - - [Test] - public void DeserializeDecimalArrayExact() - { - string json = "[123456789876543.21]"; - IList a = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(123456789876543.21m, a[0]); - } - - [Test] - public void DeserializeDecimalDictionaryExact() - { - string json = "{'Value':123456789876543.21}"; - IDictionary d = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(123456789876543.21m, d["Value"]); - } - - public struct Vector - { - public float X; - public float Y; - public float Z; - - public override string ToString() - { - return string.Format("({0},{1},{2})", X, Y, Z); - } - } - - public class VectorParent - { - public Vector Position; - } - - [Test] - public void DeserializeStructProperty() - { - VectorParent obj = new VectorParent(); - obj.Position = new Vector { X = 1, Y = 2, Z = 3 }; - - string str = JsonConvert.SerializeObject(obj); - - obj = JsonConvert.DeserializeObject(str); - - Assert.AreEqual(1, obj.Position.X); - Assert.AreEqual(2, obj.Position.Y); - Assert.AreEqual(3, obj.Position.Z); - } - - [JsonObject(MemberSerialization.OptIn)] - public class Derived : Base - { - [JsonProperty] - public string IDoWork { get; private set; } - - private Derived() - { - } - - internal Derived(string dontWork, string doWork) - : base(dontWork) - { - IDoWork = doWork; - } - } - - [JsonObject(MemberSerialization.OptIn)] - public class Base - { - [JsonProperty] - public string IDontWork { get; private set; } - - protected Base() - { - } - - internal Base(string dontWork) - { - IDontWork = dontWork; - } - } - - [Test] - public void PrivateSetterOnBaseClassProperty() - { - var derived = new Derived("meh", "woo"); - - var settings = new JsonSerializerSettings + [Test] + public void DeserializeDecimalExact() { - TypeNameHandling = TypeNameHandling.Objects, - ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor - }; + decimal d = JsonConvert.DeserializeObject("123456789876543.21"); + Assert.AreEqual(123456789876543.21m, d); + } - string json = JsonConvert.SerializeObject(derived, Formatting.Indented, settings); + [Test] + public void DeserializeNullableDecimalExact() + { + decimal? d = JsonConvert.DeserializeObject("123456789876543.21"); + Assert.AreEqual(123456789876543.21m, d); + } - var meh = JsonConvert.DeserializeObject(json, settings); + [Test] + public void DeserializeDecimalPropertyExact() + { + string json = "{Amount:123456789876543.21}"; + Invoice i = JsonConvert.DeserializeObject(json); + Assert.AreEqual(123456789876543.21m, i.Amount); + } - Assert.AreEqual(((Derived)meh).IDoWork, "woo"); - Assert.AreEqual(meh.IDontWork, "meh"); - } + [Test] + public void DeserializeDecimalArrayExact() + { + string json = "[123456789876543.21]"; + IList a = JsonConvert.DeserializeObject>(json); + Assert.AreEqual(123456789876543.21m, a[0]); + } + + [Test] + public void DeserializeDecimalDictionaryExact() + { + string json = "{'Value':123456789876543.21}"; + IDictionary d = JsonConvert.DeserializeObject>(json); + Assert.AreEqual(123456789876543.21m, d["Value"]); + } + + public struct Vector + { + public float X; + public float Y; + public float Z; + + public override string ToString() + { + return string.Format("({0},{1},{2})", X, Y, Z); + } + } + + public class VectorParent + { + public Vector Position; + } + + [Test] + public void DeserializeStructProperty() + { + VectorParent obj = new VectorParent(); + obj.Position = new Vector { X = 1, Y = 2, Z = 3 }; + + string str = JsonConvert.SerializeObject(obj); + + obj = JsonConvert.DeserializeObject(str); + + Assert.AreEqual(1, obj.Position.X); + Assert.AreEqual(2, obj.Position.Y); + Assert.AreEqual(3, obj.Position.Z); + } + + [JsonObject(MemberSerialization.OptIn)] + public class Derived : Base + { + [JsonProperty] + public string IDoWork { get; private set; } + + private Derived() + { + } + + internal Derived(string dontWork, string doWork) + : base(dontWork) + { + IDoWork = doWork; + } + } + + [JsonObject(MemberSerialization.OptIn)] + public class Base + { + [JsonProperty] + public string IDontWork { get; private set; } + + protected Base() + { + } + + internal Base(string dontWork) + { + IDontWork = dontWork; + } + } + + [Test] + public void PrivateSetterOnBaseClassProperty() + { + var derived = new Derived("meh", "woo"); + + var settings = new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Objects, + ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor + }; + + string json = JsonConvert.SerializeObject(derived, Formatting.Indented, settings); + + var meh = JsonConvert.DeserializeObject(json, settings); + + Assert.AreEqual(((Derived)meh).IDoWork, "woo"); + Assert.AreEqual(meh.IDontWork, "meh"); + } #if !(SILVERLIGHT || NET20 || NETFX_CORE) - [DataContract] - public struct StructISerializable : ISerializable - { - private string _name; + [DataContract] + public struct StructISerializable : ISerializable + { + private string _name; - public StructISerializable(SerializationInfo info, StreamingContext context) - { - _name = info.GetString("Name"); - } + public StructISerializable(SerializationInfo info, StreamingContext context) + { + _name = info.GetString("Name"); + } - [DataMember] - public string Name - { - get { return _name; } - set { _name = value; } - } + [DataMember] + public string Name + { + get { return _name; } + set { _name = value; } + } - public void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue("Name", _name); - } - } + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("Name", _name); + } + } - [DataContract] - public class NullableStructPropertyClass - { - private StructISerializable _foo1; - private StructISerializable? _foo2; + [DataContract] + public class NullableStructPropertyClass + { + private StructISerializable _foo1; + private StructISerializable? _foo2; - [DataMember] - public StructISerializable Foo1 - { - get { return _foo1; } - set { _foo1 = value; } - } + [DataMember] + public StructISerializable Foo1 + { + get { return _foo1; } + set { _foo1 = value; } + } - [DataMember] - public StructISerializable? Foo2 - { - get { return _foo2; } - set { _foo2 = value; } - } - } + [DataMember] + public StructISerializable? Foo2 + { + get { return _foo2; } + set { _foo2 = value; } + } + } - [Test] - public void DeserializeNullableStruct() - { - NullableStructPropertyClass nullableStructPropertyClass = new NullableStructPropertyClass(); - nullableStructPropertyClass.Foo1 = new StructISerializable() { Name = "foo 1" }; - nullableStructPropertyClass.Foo2 = new StructISerializable() { Name = "foo 2" }; + [Test] + public void DeserializeNullableStruct() + { + NullableStructPropertyClass nullableStructPropertyClass = new NullableStructPropertyClass(); + nullableStructPropertyClass.Foo1 = new StructISerializable() { Name = "foo 1" }; + nullableStructPropertyClass.Foo2 = new StructISerializable() { Name = "foo 2" }; - NullableStructPropertyClass barWithNull = new NullableStructPropertyClass(); - barWithNull.Foo1 = new StructISerializable() { Name = "foo 1" }; - barWithNull.Foo2 = null; + NullableStructPropertyClass barWithNull = new NullableStructPropertyClass(); + barWithNull.Foo1 = new StructISerializable() { Name = "foo 1" }; + barWithNull.Foo2 = null; - //throws error on deserialization because bar1.Foo2 is of type Foo? - string s = JsonConvert.SerializeObject(nullableStructPropertyClass); - NullableStructPropertyClass deserialized = deserialize(s); - Assert.AreEqual(deserialized.Foo1.Name, "foo 1"); - Assert.AreEqual(deserialized.Foo2.Value.Name, "foo 2"); + //throws error on deserialization because bar1.Foo2 is of type Foo? + string s = JsonConvert.SerializeObject(nullableStructPropertyClass); + NullableStructPropertyClass deserialized = deserialize(s); + Assert.AreEqual(deserialized.Foo1.Name, "foo 1"); + Assert.AreEqual(deserialized.Foo2.Value.Name, "foo 2"); - //no error Foo2 is null - s = JsonConvert.SerializeObject(barWithNull); - deserialized = deserialize(s); - Assert.AreEqual(deserialized.Foo1.Name, "foo 1"); - Assert.AreEqual(deserialized.Foo2, null); - } + //no error Foo2 is null + s = JsonConvert.SerializeObject(barWithNull); + deserialized = deserialize(s); + Assert.AreEqual(deserialized.Foo1.Name, "foo 1"); + Assert.AreEqual(deserialized.Foo2, null); + } - private static NullableStructPropertyClass deserialize(string serStr) - { - return JsonConvert.DeserializeObject( - serStr, - new JsonSerializerSettings - { - NullValueHandling = NullValueHandling.Ignore, - MissingMemberHandling = MissingMemberHandling.Ignore - }); - } + private static NullableStructPropertyClass deserialize(string serStr) + { + return JsonConvert.DeserializeObject( + serStr, + new JsonSerializerSettings + { + NullValueHandling = NullValueHandling.Ignore, + MissingMemberHandling = MissingMemberHandling.Ignore + }); + } #endif - public class Response - { - public string Name { get; set; } - public JToken Data { get; set; } - } - - [Test] - public void DeserializeJToken() - { - Response response = new Response + public class Response { - Name = "Success", - Data = new JObject(new JProperty("First", "Value1"), new JProperty("Second", "Value2")) - }; + public string Name { get; set; } + public JToken Data { get; set; } + } - string json = JsonConvert.SerializeObject(response, Formatting.Indented); - - Response deserializedResponse = JsonConvert.DeserializeObject(json); - - Assert.AreEqual("Success", deserializedResponse.Name); - Assert.IsTrue(deserializedResponse.Data.DeepEquals(response.Data)); - } - - public abstract class Test - { - public abstract T Value { get; set; } - } - - [JsonObject(MemberSerialization.OptIn)] - public class DecimalTest : Test - { - protected DecimalTest() - { - } - - public DecimalTest(decimal val) - { - Value = val; - } - - [JsonProperty] - public override decimal Value { get; set; } - } - - [Test] - public void OnError() - { - var data = new DecimalTest(decimal.MinValue); - var json = JsonConvert.SerializeObject(data); - var obj = JsonConvert.DeserializeObject(json); - - Assert.AreEqual(decimal.MinValue, obj.Value); - } - - public class NonPublicConstructorWithJsonConstructor - { - public string Value { get; private set; } - public string Constructor { get; private set; } - - [JsonConstructor] - private NonPublicConstructorWithJsonConstructor() - { - Constructor = "NonPublic"; - } - - public NonPublicConstructorWithJsonConstructor(string value) - { - Value = value; - Constructor = "Public Paramatized"; - } - } - - [Test] - public void NonPublicConstructorWithJsonConstructorTest() - { - NonPublicConstructorWithJsonConstructor c = JsonConvert.DeserializeObject("{}"); - Assert.AreEqual("NonPublic", c.Constructor); - } - - public class PublicConstructorOverridenByJsonConstructor - { - public string Value { get; private set; } - public string Constructor { get; private set; } - - public PublicConstructorOverridenByJsonConstructor() - { - Constructor = "NonPublic"; - } - - [JsonConstructor] - public PublicConstructorOverridenByJsonConstructor(string value) - { - Value = value; - Constructor = "Public Paramatized"; - } - } - - [Test] - public void PublicConstructorOverridenByJsonConstructorTest() - { - PublicConstructorOverridenByJsonConstructor c = JsonConvert.DeserializeObject("{Value:'value!'}"); - Assert.AreEqual("Public Paramatized", c.Constructor); - Assert.AreEqual("value!", c.Value); - } - - public class MultipleParamatrizedConstructorsJsonConstructor - { - public string Value { get; private set; } - public int Age { get; private set; } - public string Constructor { get; private set; } - - public MultipleParamatrizedConstructorsJsonConstructor(string value) - { - Value = value; - Constructor = "Public Paramatized 1"; - } - - [JsonConstructor] - public MultipleParamatrizedConstructorsJsonConstructor(string value, int age) - { - Value = value; - Age = age; - Constructor = "Public Paramatized 2"; - } - } - - [Test] - public void MultipleParamatrizedConstructorsJsonConstructorTest() - { - MultipleParamatrizedConstructorsJsonConstructor c = JsonConvert.DeserializeObject("{Value:'value!', Age:1}"); - Assert.AreEqual("Public Paramatized 2", c.Constructor); - Assert.AreEqual("value!", c.Value); - Assert.AreEqual(1, c.Age); - } - - public class EnumerableClass - { - public IEnumerable Enumerable { get; set; } - } - - [Test] - public void DeserializeEnumerable() - { - EnumerableClass c = new EnumerableClass + [Test] + public void DeserializeJToken() { - Enumerable = new List { "One", "Two", "Three" } - }; + Response response = new Response + { + Name = "Success", + Data = new JObject(new JProperty("First", "Value1"), new JProperty("Second", "Value2")) + }; - string json = JsonConvert.SerializeObject(c, Formatting.Indented); + string json = JsonConvert.SerializeObject(response, Formatting.Indented); - Assert.AreEqual(@"{ + Response deserializedResponse = JsonConvert.DeserializeObject(json); + + Assert.AreEqual("Success", deserializedResponse.Name); + Assert.IsTrue(deserializedResponse.Data.DeepEquals(response.Data)); + } + + public abstract class Test + { + public abstract T Value { get; set; } + } + + [JsonObject(MemberSerialization.OptIn)] + public class DecimalTest : Test + { + protected DecimalTest() + { + } + + public DecimalTest(decimal val) + { + Value = val; + } + + [JsonProperty] + public override decimal Value { get; set; } + } + + [Test] + public void OnError() + { + var data = new DecimalTest(decimal.MinValue); + var json = JsonConvert.SerializeObject(data); + var obj = JsonConvert.DeserializeObject(json); + + Assert.AreEqual(decimal.MinValue, obj.Value); + } + + public class NonPublicConstructorWithJsonConstructor + { + public string Value { get; private set; } + public string Constructor { get; private set; } + + [JsonConstructor] + private NonPublicConstructorWithJsonConstructor() + { + Constructor = "NonPublic"; + } + + public NonPublicConstructorWithJsonConstructor(string value) + { + Value = value; + Constructor = "Public Paramatized"; + } + } + + [Test] + public void NonPublicConstructorWithJsonConstructorTest() + { + NonPublicConstructorWithJsonConstructor c = JsonConvert.DeserializeObject("{}"); + Assert.AreEqual("NonPublic", c.Constructor); + } + + public class PublicConstructorOverridenByJsonConstructor + { + public string Value { get; private set; } + public string Constructor { get; private set; } + + public PublicConstructorOverridenByJsonConstructor() + { + Constructor = "NonPublic"; + } + + [JsonConstructor] + public PublicConstructorOverridenByJsonConstructor(string value) + { + Value = value; + Constructor = "Public Paramatized"; + } + } + + [Test] + public void PublicConstructorOverridenByJsonConstructorTest() + { + PublicConstructorOverridenByJsonConstructor c = JsonConvert.DeserializeObject("{Value:'value!'}"); + Assert.AreEqual("Public Paramatized", c.Constructor); + Assert.AreEqual("value!", c.Value); + } + + public class MultipleParamatrizedConstructorsJsonConstructor + { + public string Value { get; private set; } + public int Age { get; private set; } + public string Constructor { get; private set; } + + public MultipleParamatrizedConstructorsJsonConstructor(string value) + { + Value = value; + Constructor = "Public Paramatized 1"; + } + + [JsonConstructor] + public MultipleParamatrizedConstructorsJsonConstructor(string value, int age) + { + Value = value; + Age = age; + Constructor = "Public Paramatized 2"; + } + } + + [Test] + public void MultipleParamatrizedConstructorsJsonConstructorTest() + { + MultipleParamatrizedConstructorsJsonConstructor c = JsonConvert.DeserializeObject("{Value:'value!', Age:1}"); + Assert.AreEqual("Public Paramatized 2", c.Constructor); + Assert.AreEqual("value!", c.Value); + Assert.AreEqual(1, c.Age); + } + + public class EnumerableClass + { + public IEnumerable Enumerable { get; set; } + } + + [Test] + public void DeserializeEnumerable() + { + EnumerableClass c = new EnumerableClass + { + Enumerable = new List { "One", "Two", "Three" } + }; + + string json = JsonConvert.SerializeObject(c, Formatting.Indented); + + Assert.AreEqual(@"{ ""Enumerable"": [ ""One"", ""Two"", @@ -5871,121 +5845,117 @@ To fix this error either change the environment to be fully trusted, change the ] }", json); - EnumerableClass c2 = JsonConvert.DeserializeObject(json); + EnumerableClass c2 = JsonConvert.DeserializeObject(json); - Assert.AreEqual("One", c2.Enumerable.ElementAt(0)); - Assert.AreEqual("Two", c2.Enumerable.ElementAt(1)); - Assert.AreEqual("Three", c2.Enumerable.ElementAt(2)); - } + Assert.AreEqual("One", c2.Enumerable.ElementAt(0)); + Assert.AreEqual("Two", c2.Enumerable.ElementAt(1)); + Assert.AreEqual("Three", c2.Enumerable.ElementAt(2)); + } - [JsonObject(MemberSerialization.OptIn)] - public class ItemBase - { - [JsonProperty] - public string Name { get; set; } - } + [JsonObject(MemberSerialization.OptIn)] + public class ItemBase + { + [JsonProperty] + public string Name { get; set; } + } - public class ComplexItem : ItemBase - { - public Stream Source { get; set; } - } + public class ComplexItem : ItemBase + { + public Stream Source { get; set; } + } - [Test] - public void SerializeAttributesOnBase() - { - ComplexItem i = new ComplexItem(); + [Test] + public void SerializeAttributesOnBase() + { + ComplexItem i = new ComplexItem(); - string json = JsonConvert.SerializeObject(i, Formatting.Indented); + string json = JsonConvert.SerializeObject(i, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Name"": null }", json); - } + } - public class DeserializeStringConvert - { - public string Name { get; set; } - public int Age { get; set; } - public double Height { get; set; } - public decimal Price { get; set; } - } + public class DeserializeStringConvert + { + public string Name { get; set; } + public int Age { get; set; } + public double Height { get; set; } + public decimal Price { get; set; } + } - [Test] - public void DeserializeStringEnglish() - { - string json = @"{ + [Test] + public void DeserializeStringEnglish() + { + string json = @"{ 'Name': 'James Hughes', 'Age': '40', 'Height': '44.4', 'Price': '4' }"; - DeserializeStringConvert p = JsonConvert.DeserializeObject(json); - Assert.AreEqual(40, p.Age); - Assert.AreEqual(44.4, p.Height); - Assert.AreEqual(4m, p.Price); - } + DeserializeStringConvert p = JsonConvert.DeserializeObject(json); + Assert.AreEqual(40, p.Age); + Assert.AreEqual(44.4, p.Height); + Assert.AreEqual(4m, p.Price); + } - [Test] - public void DeserializeNullDateTimeValueTest() - { - ExceptionAssert.Throws( - "Error converting value {null} to type 'System.DateTime'. Path '', line 1, position 4.", - () => + [Test] + public void DeserializeNullDateTimeValueTest() { - JsonConvert.DeserializeObject("null", typeof(DateTime)); - }); - } + ExceptionAssert.Throws( + "Error converting value {null} to type 'System.DateTime'. Path '', line 1, position 4.", + () => { JsonConvert.DeserializeObject("null", typeof(DateTime)); }); + } - [Test] - public void DeserializeNullNullableDateTimeValueTest() - { - object dateTime = JsonConvert.DeserializeObject("null", typeof(DateTime?)); + [Test] + public void DeserializeNullNullableDateTimeValueTest() + { + object dateTime = JsonConvert.DeserializeObject("null", typeof(DateTime?)); - Assert.IsNull(dateTime); - } + Assert.IsNull(dateTime); + } - [Test] - public void MultiIndexSuperTest() - { - MultiIndexSuper e = new MultiIndexSuper(); + [Test] + public void MultiIndexSuperTest() + { + MultiIndexSuper e = new MultiIndexSuper(); - string json = JsonConvert.SerializeObject(e, Formatting.Indented); + string json = JsonConvert.SerializeObject(e, Formatting.Indented); - Assert.AreEqual(@"{}", json); - } + Assert.AreEqual(@"{}", json); + } - public class MultiIndexSuper : MultiIndexBase - { + public class MultiIndexSuper : MultiIndexBase + { + } - } + public abstract class MultiIndexBase + { + protected internal object this[string propertyName] + { + get { return null; } + set { } + } - public abstract class MultiIndexBase - { - protected internal object this[string propertyName] - { - get { return null; } - set { } - } + protected internal object this[object property] + { + get { return null; } + set { } + } + } - protected internal object this[object property] - { - get { return null; } - set { } - } - } + public class CommentTestClass + { + public bool Indexed { get; set; } + public int StartYear { get; set; } + public IList Values { get; set; } + } - public class CommentTestClass - { - public bool Indexed { get; set; } - public int StartYear { get; set; } - public IList Values { get; set; } - } - - [Test] - public void CommentTestClassTest() - { - string json = @"{""indexed"":true, ""startYear"":1939, ""values"": + [Test] + public void CommentTestClassTest() + { + string json = @"{""indexed"":true, ""startYear"":1939, ""values"": [ 3000, /* 1940-1949 */ 3000, 3600, 3600, 3600, 3600, 4200, 4200, 4200, 4200, 4800, /* 1950-1959 */ 4800, 4800, 4800, 4800, 4800, 4800, 6600, 6600, 7800, 7800, /* 1960-1969 */ @@ -5996,225 +5966,225 @@ To fix this error either change the environment to be fully trusted, change the 106800, 106800] /* 2010-2011 */ }"; - CommentTestClass commentTestClass = JsonConvert.DeserializeObject(json); + CommentTestClass commentTestClass = JsonConvert.DeserializeObject(json); - Assert.AreEqual(true, commentTestClass.Indexed); - Assert.AreEqual(1939, commentTestClass.StartYear); - Assert.AreEqual(63, commentTestClass.Values.Count); - } - - private class DTOWithParameterisedConstructor - { - public DTOWithParameterisedConstructor(string A) - { - this.A = A; - B = 2; - } - - public string A { get; set; } - public int? B { get; set; } - } - - private class DTOWithoutParameterisedConstructor - { - public DTOWithoutParameterisedConstructor() - { - B = 2; - } - - public string A { get; set; } - public int? B { get; set; } - } - - [Test] - public void PopulationBehaviourForOmittedPropertiesIsTheSameForParameterisedConstructorAsForDefaultConstructor() - { - string json = @"{A:""Test""}"; - - var withoutParameterisedConstructor = JsonConvert.DeserializeObject(json); - var withParameterisedConstructor = JsonConvert.DeserializeObject(json); - Assert.AreEqual(withoutParameterisedConstructor.B, withParameterisedConstructor.B); - } - - public class EnumerableArrayPropertyClass - { - public IEnumerable Numbers - { - get - { - return new[] { 1, 2, 3 }; //fails - //return new List(new[] { 1, 2, 3 }); //works + Assert.AreEqual(true, commentTestClass.Indexed); + Assert.AreEqual(1939, commentTestClass.StartYear); + Assert.AreEqual(63, commentTestClass.Values.Count); } - } - } - [Test] - public void SkipPopulatingArrayPropertyClass() - { - string json = JsonConvert.SerializeObject(new EnumerableArrayPropertyClass()); - JsonConvert.DeserializeObject(json); - } + private class DTOWithParameterisedConstructor + { + public DTOWithParameterisedConstructor(string A) + { + this.A = A; + B = 2; + } + + public string A { get; set; } + public int? B { get; set; } + } + + private class DTOWithoutParameterisedConstructor + { + public DTOWithoutParameterisedConstructor() + { + B = 2; + } + + public string A { get; set; } + public int? B { get; set; } + } + + [Test] + public void PopulationBehaviourForOmittedPropertiesIsTheSameForParameterisedConstructorAsForDefaultConstructor() + { + string json = @"{A:""Test""}"; + + var withoutParameterisedConstructor = JsonConvert.DeserializeObject(json); + var withParameterisedConstructor = JsonConvert.DeserializeObject(json); + Assert.AreEqual(withoutParameterisedConstructor.B, withParameterisedConstructor.B); + } + + public class EnumerableArrayPropertyClass + { + public IEnumerable Numbers + { + get + { + return new[] { 1, 2, 3 }; //fails + //return new List(new[] { 1, 2, 3 }); //works + } + } + } + + [Test] + public void SkipPopulatingArrayPropertyClass() + { + string json = JsonConvert.SerializeObject(new EnumerableArrayPropertyClass()); + JsonConvert.DeserializeObject(json); + } #if !(NET20 || SILVERLIGHT) - [DataContract] - public class BaseDataContract - { - [DataMember(Name = "virtualMember")] - public virtual string VirtualMember { get; set; } - - [DataMember(Name = "nonVirtualMember")] - public string NonVirtualMember { get; set; } - } - - public class ChildDataContract : BaseDataContract - { - public override string VirtualMember { get; set; } - public string NewMember { get; set; } - } - - [Test] - public void ChildDataContractTest() - { - ChildDataContract cc = new ChildDataContract - { - VirtualMember = "VirtualMember!", - NonVirtualMember = "NonVirtualMember!" - }; - - string result = JsonConvert.SerializeObject(cc, Formatting.Indented); -// Assert.AreEqual(@"{ -// ""VirtualMember"": ""VirtualMember!"", -// ""NewMember"": null, -// ""nonVirtualMember"": ""NonVirtualMember!"" -//}", result); - - Console.WriteLine(result); - } - - [Test] - public void ChildDataContractTestWithDataContractSerializer() - { - ChildDataContract cc = new ChildDataContract + [DataContract] + public class BaseDataContract { - VirtualMember = "VirtualMember!", - NonVirtualMember = "NonVirtualMember!" - }; + [DataMember(Name = "virtualMember")] + public virtual string VirtualMember { get; set; } - DataContractSerializer serializer = new DataContractSerializer(typeof(ChildDataContract)); + [DataMember(Name = "nonVirtualMember")] + public string NonVirtualMember { get; set; } + } - MemoryStream ms = new MemoryStream(); - serializer.WriteObject(ms, cc); + public class ChildDataContract : BaseDataContract + { + public override string VirtualMember { get; set; } + public string NewMember { get; set; } + } - string xml = Encoding.UTF8.GetString(ms.ToArray(), 0, Convert.ToInt32(ms.Length)); + [Test] + public void ChildDataContractTest() + { + ChildDataContract cc = new ChildDataContract + { + VirtualMember = "VirtualMember!", + NonVirtualMember = "NonVirtualMember!" + }; - Console.WriteLine(xml); - } + string result = JsonConvert.SerializeObject(cc, Formatting.Indented); + // Assert.AreEqual(@"{ + // ""VirtualMember"": ""VirtualMember!"", + // ""NewMember"": null, + // ""nonVirtualMember"": ""NonVirtualMember!"" + //}", result); + + Console.WriteLine(result); + } + + [Test] + public void ChildDataContractTestWithDataContractSerializer() + { + ChildDataContract cc = new ChildDataContract + { + VirtualMember = "VirtualMember!", + NonVirtualMember = "NonVirtualMember!" + }; + + DataContractSerializer serializer = new DataContractSerializer(typeof(ChildDataContract)); + + MemoryStream ms = new MemoryStream(); + serializer.WriteObject(ms, cc); + + string xml = Encoding.UTF8.GetString(ms.ToArray(), 0, Convert.ToInt32(ms.Length)); + + Console.WriteLine(xml); + } #endif - [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - public class BaseObject - { - [JsonProperty(PropertyName = "virtualMember")] - public virtual string VirtualMember { get; set; } - - [JsonProperty(PropertyName = "nonVirtualMember")] - public string NonVirtualMember { get; set; } - } - - public class ChildObject : BaseObject - { - public override string VirtualMember { get; set; } - public string NewMember { get; set; } - } - - public class ChildWithDifferentOverrideObject : BaseObject - { - [JsonProperty(PropertyName = "differentVirtualMember")] - public override string VirtualMember { get; set; } - } - - [Test] - public void ChildObjectTest() - { - ChildObject cc = new ChildObject + [JsonObject(MemberSerialization = MemberSerialization.OptIn)] + public class BaseObject { - VirtualMember = "VirtualMember!", - NonVirtualMember = "NonVirtualMember!" - }; + [JsonProperty(PropertyName = "virtualMember")] + public virtual string VirtualMember { get; set; } - string result = JsonConvert.SerializeObject(cc); - Assert.AreEqual(@"{""virtualMember"":""VirtualMember!"",""nonVirtualMember"":""NonVirtualMember!""}", result); - } + [JsonProperty(PropertyName = "nonVirtualMember")] + public string NonVirtualMember { get; set; } + } - [Test] - public void ChildWithDifferentOverrideObjectTest() - { - ChildWithDifferentOverrideObject cc = new ChildWithDifferentOverrideObject + public class ChildObject : BaseObject { - VirtualMember = "VirtualMember!", - NonVirtualMember = "NonVirtualMember!" - }; + public override string VirtualMember { get; set; } + public string NewMember { get; set; } + } - string result = JsonConvert.SerializeObject(cc); - Console.WriteLine(result); - Assert.AreEqual(@"{""differentVirtualMember"":""VirtualMember!"",""nonVirtualMember"":""NonVirtualMember!""}", result); - } - - [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - public interface IInterfaceObject - { - [JsonProperty(PropertyName = "virtualMember")] - [JsonConverter(typeof(IsoDateTimeConverter))] - DateTime InterfaceMember { get; set; } - } - - public class ImplementInterfaceObject : IInterfaceObject - { - public DateTime InterfaceMember { get; set; } - public string NewMember { get; set; } - - [JsonProperty(PropertyName = "newMemberWithProperty")] - public string NewMemberWithProperty { get; set; } - } - - [Test] - public void ImplementInterfaceObjectTest() - { - ImplementInterfaceObject cc = new ImplementInterfaceObject + public class ChildWithDifferentOverrideObject : BaseObject { - InterfaceMember = new DateTime(2010, 12, 31, 0, 0, 0, DateTimeKind.Utc), - NewMember = "NewMember!" - }; + [JsonProperty(PropertyName = "differentVirtualMember")] + public override string VirtualMember { get; set; } + } - string result = JsonConvert.SerializeObject(cc, Formatting.Indented); + [Test] + public void ChildObjectTest() + { + ChildObject cc = new ChildObject + { + VirtualMember = "VirtualMember!", + NonVirtualMember = "NonVirtualMember!" + }; - Assert.AreEqual(@"{ + string result = JsonConvert.SerializeObject(cc); + Assert.AreEqual(@"{""virtualMember"":""VirtualMember!"",""nonVirtualMember"":""NonVirtualMember!""}", result); + } + + [Test] + public void ChildWithDifferentOverrideObjectTest() + { + ChildWithDifferentOverrideObject cc = new ChildWithDifferentOverrideObject + { + VirtualMember = "VirtualMember!", + NonVirtualMember = "NonVirtualMember!" + }; + + string result = JsonConvert.SerializeObject(cc); + Console.WriteLine(result); + Assert.AreEqual(@"{""differentVirtualMember"":""VirtualMember!"",""nonVirtualMember"":""NonVirtualMember!""}", result); + } + + [JsonObject(MemberSerialization = MemberSerialization.OptIn)] + public interface IInterfaceObject + { + [JsonProperty(PropertyName = "virtualMember")] + [JsonConverter(typeof(IsoDateTimeConverter))] + DateTime InterfaceMember { get; set; } + } + + public class ImplementInterfaceObject : IInterfaceObject + { + public DateTime InterfaceMember { get; set; } + public string NewMember { get; set; } + + [JsonProperty(PropertyName = "newMemberWithProperty")] + public string NewMemberWithProperty { get; set; } + } + + [Test] + public void ImplementInterfaceObjectTest() + { + ImplementInterfaceObject cc = new ImplementInterfaceObject + { + InterfaceMember = new DateTime(2010, 12, 31, 0, 0, 0, DateTimeKind.Utc), + NewMember = "NewMember!" + }; + + string result = JsonConvert.SerializeObject(cc, Formatting.Indented); + + Assert.AreEqual(@"{ ""virtualMember"": ""2010-12-31T00:00:00Z"", ""newMemberWithProperty"": null }", result); - } + } - public class NonDefaultConstructorWithReadOnlyCollectionProperty - { - public string Title { get; set; } - public IList Categories { get; private set; } + public class NonDefaultConstructorWithReadOnlyCollectionProperty + { + public string Title { get; set; } + public IList Categories { get; private set; } - public NonDefaultConstructorWithReadOnlyCollectionProperty(string title) - { - Title = title; - Categories = new List(); - } - } + public NonDefaultConstructorWithReadOnlyCollectionProperty(string title) + { + Title = title; + Categories = new List(); + } + } - [Test] - public void NonDefaultConstructorWithReadOnlyCollectionPropertyTest() - { - NonDefaultConstructorWithReadOnlyCollectionProperty c1 = new NonDefaultConstructorWithReadOnlyCollectionProperty("blah"); - c1.Categories.Add("one"); - c1.Categories.Add("two"); + [Test] + public void NonDefaultConstructorWithReadOnlyCollectionPropertyTest() + { + NonDefaultConstructorWithReadOnlyCollectionProperty c1 = new NonDefaultConstructorWithReadOnlyCollectionProperty("blah"); + c1.Categories.Add("one"); + c1.Categories.Add("two"); - string json = JsonConvert.SerializeObject(c1, Formatting.Indented); - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(c1, Formatting.Indented); + Assert.AreEqual(@"{ ""Title"": ""blah"", ""Categories"": [ ""one"", @@ -6222,34 +6192,34 @@ To fix this error either change the environment to be fully trusted, change the ] }", json); - NonDefaultConstructorWithReadOnlyCollectionProperty c2 = JsonConvert.DeserializeObject(json); - Assert.AreEqual(c1.Title, c2.Title); - Assert.AreEqual(c1.Categories.Count, c2.Categories.Count); - Assert.AreEqual("one", c2.Categories[0]); - Assert.AreEqual("two", c2.Categories[1]); - } + NonDefaultConstructorWithReadOnlyCollectionProperty c2 = JsonConvert.DeserializeObject(json); + Assert.AreEqual(c1.Title, c2.Title); + Assert.AreEqual(c1.Categories.Count, c2.Categories.Count); + Assert.AreEqual("one", c2.Categories[0]); + Assert.AreEqual("two", c2.Categories[1]); + } - public class NonDefaultConstructorWithReadOnlyDictionaryProperty - { - public string Title { get; set; } - public IDictionary Categories { get; private set; } + public class NonDefaultConstructorWithReadOnlyDictionaryProperty + { + public string Title { get; set; } + public IDictionary Categories { get; private set; } - public NonDefaultConstructorWithReadOnlyDictionaryProperty(string title) - { - Title = title; - Categories = new Dictionary(); - } - } + public NonDefaultConstructorWithReadOnlyDictionaryProperty(string title) + { + Title = title; + Categories = new Dictionary(); + } + } - [Test] - public void NonDefaultConstructorWithReadOnlyDictionaryPropertyTest() - { - NonDefaultConstructorWithReadOnlyDictionaryProperty c1 = new NonDefaultConstructorWithReadOnlyDictionaryProperty("blah"); - c1.Categories.Add("one", 1); - c1.Categories.Add("two", 2); + [Test] + public void NonDefaultConstructorWithReadOnlyDictionaryPropertyTest() + { + NonDefaultConstructorWithReadOnlyDictionaryProperty c1 = new NonDefaultConstructorWithReadOnlyDictionaryProperty("blah"); + c1.Categories.Add("one", 1); + c1.Categories.Add("two", 2); - string json = JsonConvert.SerializeObject(c1, Formatting.Indented); - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(c1, Formatting.Indented); + Assert.AreEqual(@"{ ""Title"": ""blah"", ""Categories"": { ""one"": 1, @@ -6257,202 +6227,209 @@ To fix this error either change the environment to be fully trusted, change the } }", json); - NonDefaultConstructorWithReadOnlyDictionaryProperty c2 = JsonConvert.DeserializeObject(json); - Assert.AreEqual(c1.Title, c2.Title); - Assert.AreEqual(c1.Categories.Count, c2.Categories.Count); - Assert.AreEqual(1, c2.Categories["one"]); - Assert.AreEqual(2, c2.Categories["two"]); - } + NonDefaultConstructorWithReadOnlyDictionaryProperty c2 = JsonConvert.DeserializeObject(json); + Assert.AreEqual(c1.Title, c2.Title); + Assert.AreEqual(c1.Categories.Count, c2.Categories.Count); + Assert.AreEqual(1, c2.Categories["one"]); + Assert.AreEqual(2, c2.Categories["two"]); + } - [JsonObject(MemberSerialization.OptIn)] - public class ClassAttributeBase - { - [JsonProperty] - public string BaseClassValue { get; set; } - } - - public class ClassAttributeDerived : ClassAttributeBase - { - [JsonProperty] - public string DerivedClassValue { get; set; } - - public string NonSerialized { get; set; } - } - - public class CollectionClassAttributeDerived : ClassAttributeBase, ICollection - { - [JsonProperty] - public string CollectionDerivedClassValue { get; set; } - - public void Add(object item) - { - throw new NotImplementedException(); - } - - public void Clear() - { - throw new NotImplementedException(); - } - - public bool Contains(object item) - { - throw new NotImplementedException(); - } - - public void CopyTo(object[] array, int arrayIndex) - { - throw new NotImplementedException(); - } - - public int Count - { - get { throw new NotImplementedException(); } - } - - public bool IsReadOnly - { - get { throw new NotImplementedException(); } - } - - public bool Remove(object item) - { - throw new NotImplementedException(); - } - - public IEnumerator GetEnumerator() - { - throw new NotImplementedException(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - throw new NotImplementedException(); - } - } - - [Test] - public void ClassAttributesInheritance() - { - string json = JsonConvert.SerializeObject(new ClassAttributeDerived + [JsonObject(MemberSerialization.OptIn)] + public class ClassAttributeBase { - BaseClassValue = "BaseClassValue!", - DerivedClassValue = "DerivedClassValue!", - NonSerialized = "NonSerialized!" - }, Formatting.Indented); + [JsonProperty] + public string BaseClassValue { get; set; } + } - Assert.AreEqual(@"{ + public class ClassAttributeDerived : ClassAttributeBase + { + [JsonProperty] + public string DerivedClassValue { get; set; } + + public string NonSerialized { get; set; } + } + + public class CollectionClassAttributeDerived : ClassAttributeBase, ICollection + { + [JsonProperty] + public string CollectionDerivedClassValue { get; set; } + + public void Add(object item) + { + throw new NotImplementedException(); + } + + public void Clear() + { + throw new NotImplementedException(); + } + + public bool Contains(object item) + { + throw new NotImplementedException(); + } + + public void CopyTo(object[] array, int arrayIndex) + { + throw new NotImplementedException(); + } + + public int Count + { + get { throw new NotImplementedException(); } + } + + public bool IsReadOnly + { + get { throw new NotImplementedException(); } + } + + public bool Remove(object item) + { + throw new NotImplementedException(); + } + + public IEnumerator GetEnumerator() + { + throw new NotImplementedException(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + throw new NotImplementedException(); + } + } + + [Test] + public void ClassAttributesInheritance() + { + string json = JsonConvert.SerializeObject(new ClassAttributeDerived + { + BaseClassValue = "BaseClassValue!", + DerivedClassValue = "DerivedClassValue!", + NonSerialized = "NonSerialized!" + }, Formatting.Indented); + + Assert.AreEqual(@"{ ""DerivedClassValue"": ""DerivedClassValue!"", ""BaseClassValue"": ""BaseClassValue!"" }", json); - json = JsonConvert.SerializeObject(new CollectionClassAttributeDerived - { - BaseClassValue = "BaseClassValue!", - CollectionDerivedClassValue = "CollectionDerivedClassValue!" - }, Formatting.Indented); + json = JsonConvert.SerializeObject(new CollectionClassAttributeDerived + { + BaseClassValue = "BaseClassValue!", + CollectionDerivedClassValue = "CollectionDerivedClassValue!" + }, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""CollectionDerivedClassValue"": ""CollectionDerivedClassValue!"", ""BaseClassValue"": ""BaseClassValue!"" }", json); - } + } - public class PrivateMembersClassWithAttributes - { - public PrivateMembersClassWithAttributes(string privateString, string internalString, string readonlyString) - { - _privateString = privateString; - _readonlyString = readonlyString; - _internalString = internalString; - } + public class PrivateMembersClassWithAttributes + { + public PrivateMembersClassWithAttributes(string privateString, string internalString, string readonlyString) + { + _privateString = privateString; + _readonlyString = readonlyString; + _internalString = internalString; + } - public PrivateMembersClassWithAttributes() - { - _readonlyString = "default!"; - } + public PrivateMembersClassWithAttributes() + { + _readonlyString = "default!"; + } - [JsonProperty] - private string _privateString; - [JsonProperty] - private readonly string _readonlyString; - [JsonProperty] - internal string _internalString; + [JsonProperty] + private string _privateString; - public string UseValue() - { - return _readonlyString; - } - } + [JsonProperty] + private readonly string _readonlyString; - [Test] - public void PrivateMembersClassWithAttributesTest() - { - PrivateMembersClassWithAttributes c1 = new PrivateMembersClassWithAttributes("privateString!", "internalString!", "readonlyString!"); + [JsonProperty] + internal string _internalString; - string json = JsonConvert.SerializeObject(c1, Formatting.Indented); - Assert.AreEqual(@"{ + public string UseValue() + { + return _readonlyString; + } + } + + [Test] + public void PrivateMembersClassWithAttributesTest() + { + PrivateMembersClassWithAttributes c1 = new PrivateMembersClassWithAttributes("privateString!", "internalString!", "readonlyString!"); + + string json = JsonConvert.SerializeObject(c1, Formatting.Indented); + Assert.AreEqual(@"{ ""_privateString"": ""privateString!"", ""_readonlyString"": ""readonlyString!"", ""_internalString"": ""internalString!"" }", json); - PrivateMembersClassWithAttributes c2 = JsonConvert.DeserializeObject(json); - Assert.AreEqual("readonlyString!", c2.UseValue()); - } + PrivateMembersClassWithAttributes c2 = JsonConvert.DeserializeObject(json); + Assert.AreEqual("readonlyString!", c2.UseValue()); + } - public partial class BusRun - { - public IEnumerable> Departures { get; set; } - public Boolean WheelchairAccessible { get; set; } - } + public partial class BusRun + { + public IEnumerable> Departures { get; set; } + public Boolean WheelchairAccessible { get; set; } + } - [Test] - public void DeserializeGenericEnumerableProperty() - { - BusRun r = JsonConvert.DeserializeObject("{\"Departures\":[\"\\/Date(1309874148734-0400)\\/\",\"\\/Date(1309874148739-0400)\\/\",null],\"WheelchairAccessible\":true}"); + [Test] + public void DeserializeGenericEnumerableProperty() + { + BusRun r = JsonConvert.DeserializeObject("{\"Departures\":[\"\\/Date(1309874148734-0400)\\/\",\"\\/Date(1309874148739-0400)\\/\",null],\"WheelchairAccessible\":true}"); - Assert.AreEqual(typeof(List), r.Departures.GetType()); - Assert.AreEqual(3, r.Departures.Count()); - Assert.IsNotNull(r.Departures.ElementAt(0)); - Assert.IsNotNull(r.Departures.ElementAt(1)); - Assert.IsNull(r.Departures.ElementAt(2)); - } + Assert.AreEqual(typeof(List), r.Departures.GetType()); + Assert.AreEqual(3, r.Departures.Count()); + Assert.IsNotNull(r.Departures.ElementAt(0)); + Assert.IsNotNull(r.Departures.ElementAt(1)); + Assert.IsNull(r.Departures.ElementAt(2)); + } #if !(NET20) - [DataContract] - public class BaseType - { + [DataContract] + public class BaseType + { + [DataMember] + public string zebra; + } - [DataMember] - public string zebra; - } + [DataContract] + public class DerivedType : BaseType + { + [DataMember(Order = 0)] + public string bird; - [DataContract] - public class DerivedType : BaseType - { - [DataMember(Order = 0)] - public string bird; - [DataMember(Order = 1)] - public string parrot; - [DataMember] - public string dog; - [DataMember(Order = 3)] - public string antelope; - [DataMember] - public string cat; - [JsonProperty(Order = 1)] - public string albatross; - [JsonProperty(Order = -2)] - public string dinosaur; - } + [DataMember(Order = 1)] + public string parrot; - [Test] - public void JsonPropertyDataMemberOrder() - { - DerivedType d = new DerivedType(); - string json = JsonConvert.SerializeObject(d, Formatting.Indented); + [DataMember] + public string dog; - Assert.AreEqual(@"{ + [DataMember(Order = 3)] + public string antelope; + + [DataMember] + public string cat; + + [JsonProperty(Order = 1)] + public string albatross; + + [JsonProperty(Order = -2)] + public string dinosaur; + } + + [Test] + public void JsonPropertyDataMemberOrder() + { + DerivedType d = new DerivedType(); + string json = JsonConvert.SerializeObject(d, Formatting.Indented); + + Assert.AreEqual(@"{ ""dinosaur"": null, ""dog"": null, ""cat"": null, @@ -6462,62 +6439,62 @@ To fix this error either change the environment to be fully trusted, change the ""albatross"": null, ""antelope"": null }", json); - } + } #endif - public class ClassWithException - { - public IList Exceptions { get; set; } + public class ClassWithException + { + public IList Exceptions { get; set; } - public ClassWithException() - { - Exceptions = new List(); - } - } + public ClassWithException() + { + Exceptions = new List(); + } + } #if !(SILVERLIGHT || WINDOWS_PHONE || NETFX_CORE || PORTABLE || PORTABLE40) - [Test] - public void SerializeException1() - { - ClassWithException classWithException = new ClassWithException(); - try - { - throw new Exception("Test Exception"); - } - catch (Exception ex) - { - classWithException.Exceptions.Add(ex); - } - string sex = JsonConvert.SerializeObject(classWithException); - ClassWithException dex = JsonConvert.DeserializeObject(sex); - Assert.AreEqual(dex.Exceptions[0].ToString(), dex.Exceptions[0].ToString()); + [Test] + public void SerializeException1() + { + ClassWithException classWithException = new ClassWithException(); + try + { + throw new Exception("Test Exception"); + } + catch (Exception ex) + { + classWithException.Exceptions.Add(ex); + } + string sex = JsonConvert.SerializeObject(classWithException); + ClassWithException dex = JsonConvert.DeserializeObject(sex); + Assert.AreEqual(dex.Exceptions[0].ToString(), dex.Exceptions[0].ToString()); - sex = JsonConvert.SerializeObject(classWithException, Formatting.Indented); + sex = JsonConvert.SerializeObject(classWithException, Formatting.Indented); - dex = JsonConvert.DeserializeObject(sex); // this fails! - Assert.AreEqual(dex.Exceptions[0].ToString(), dex.Exceptions[0].ToString()); - } + dex = JsonConvert.DeserializeObject(sex); // this fails! + Assert.AreEqual(dex.Exceptions[0].ToString(), dex.Exceptions[0].ToString()); + } #endif - public void DeserializeIDictionary() - { - IDictionary dictionary = JsonConvert.DeserializeObject("{'name':'value!'}"); - Assert.AreEqual(1, dictionary.Count); - Assert.AreEqual("value!", dictionary["name"]); - } + public void DeserializeIDictionary() + { + IDictionary dictionary = JsonConvert.DeserializeObject("{'name':'value!'}"); + Assert.AreEqual(1, dictionary.Count); + Assert.AreEqual("value!", dictionary["name"]); + } - public void DeserializeIList() - { - IList list = JsonConvert.DeserializeObject("['1', 'two', 'III']"); - Assert.AreEqual(3, list.Count); - } + public void DeserializeIList() + { + IList list = JsonConvert.DeserializeObject("['1', 'two', 'III']"); + Assert.AreEqual(3, list.Count); + } - public void UriGuidTimeSpanTestClassEmptyTest() - { - UriGuidTimeSpanTestClass c1 = new UriGuidTimeSpanTestClass(); - string json = JsonConvert.SerializeObject(c1, Formatting.Indented); + public void UriGuidTimeSpanTestClassEmptyTest() + { + UriGuidTimeSpanTestClass c1 = new UriGuidTimeSpanTestClass(); + string json = JsonConvert.SerializeObject(c1, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Guid"": ""00000000-0000-0000-0000-000000000000"", ""NullableGuid"": null, ""TimeSpan"": ""00:00:00"", @@ -6525,27 +6502,27 @@ To fix this error either change the environment to be fully trusted, change the ""Uri"": null }", json); - UriGuidTimeSpanTestClass c2 = JsonConvert.DeserializeObject(json); - Assert.AreEqual(c1.Guid, c2.Guid); - Assert.AreEqual(c1.NullableGuid, c2.NullableGuid); - Assert.AreEqual(c1.TimeSpan, c2.TimeSpan); - Assert.AreEqual(c1.NullableTimeSpan, c2.NullableTimeSpan); - Assert.AreEqual(c1.Uri, c2.Uri); - } + UriGuidTimeSpanTestClass c2 = JsonConvert.DeserializeObject(json); + Assert.AreEqual(c1.Guid, c2.Guid); + Assert.AreEqual(c1.NullableGuid, c2.NullableGuid); + Assert.AreEqual(c1.TimeSpan, c2.TimeSpan); + Assert.AreEqual(c1.NullableTimeSpan, c2.NullableTimeSpan); + Assert.AreEqual(c1.Uri, c2.Uri); + } - public void UriGuidTimeSpanTestClassValuesTest() - { - UriGuidTimeSpanTestClass c1 = new UriGuidTimeSpanTestClass + public void UriGuidTimeSpanTestClassValuesTest() { - Guid = new Guid("1924129C-F7E0-40F3-9607-9939C531395A"), - NullableGuid = new Guid("9E9F3ADF-E017-4F72-91E0-617EBE85967D"), - TimeSpan = TimeSpan.FromDays(1), - NullableTimeSpan = TimeSpan.FromHours(1), - Uri = new Uri("http://testuri.com") - }; - string json = JsonConvert.SerializeObject(c1, Formatting.Indented); + UriGuidTimeSpanTestClass c1 = new UriGuidTimeSpanTestClass + { + Guid = new Guid("1924129C-F7E0-40F3-9607-9939C531395A"), + NullableGuid = new Guid("9E9F3ADF-E017-4F72-91E0-617EBE85967D"), + TimeSpan = TimeSpan.FromDays(1), + NullableTimeSpan = TimeSpan.FromHours(1), + Uri = new Uri("http://testuri.com") + }; + string json = JsonConvert.SerializeObject(c1, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Guid"": ""1924129c-f7e0-40f3-9607-9939c531395a"", ""NullableGuid"": ""9e9f3adf-e017-4f72-91e0-617ebe85967d"", ""TimeSpan"": ""1.00:00:00"", @@ -6553,76 +6530,76 @@ To fix this error either change the environment to be fully trusted, change the ""Uri"": ""http://testuri.com/"" }", json); - UriGuidTimeSpanTestClass c2 = JsonConvert.DeserializeObject(json); - Assert.AreEqual(c1.Guid, c2.Guid); - Assert.AreEqual(c1.NullableGuid, c2.NullableGuid); - Assert.AreEqual(c1.TimeSpan, c2.TimeSpan); - Assert.AreEqual(c1.NullableTimeSpan, c2.NullableTimeSpan); - Assert.AreEqual(c1.Uri, c2.Uri); - } + UriGuidTimeSpanTestClass c2 = JsonConvert.DeserializeObject(json); + Assert.AreEqual(c1.Guid, c2.Guid); + Assert.AreEqual(c1.NullableGuid, c2.NullableGuid); + Assert.AreEqual(c1.TimeSpan, c2.TimeSpan); + Assert.AreEqual(c1.NullableTimeSpan, c2.NullableTimeSpan); + Assert.AreEqual(c1.Uri, c2.Uri); + } - [Test] - public void NullableValueGenericDictionary() - { - IDictionary v1 = new Dictionary + [Test] + public void NullableValueGenericDictionary() { - {"First", 1}, - {"Second", null}, - {"Third", 3} - }; + IDictionary v1 = new Dictionary + { + { "First", 1 }, + { "Second", null }, + { "Third", 3 } + }; - string json = JsonConvert.SerializeObject(v1, Formatting.Indented); + string json = JsonConvert.SerializeObject(v1, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""First"": 1, ""Second"": null, ""Third"": 3 }", json); - IDictionary v2 = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(3, v2.Count); - Assert.AreEqual(1, v2["First"]); - Assert.AreEqual(null, v2["Second"]); - Assert.AreEqual(3, v2["Third"]); - } + IDictionary v2 = JsonConvert.DeserializeObject>(json); + Assert.AreEqual(3, v2.Count); + Assert.AreEqual(1, v2["First"]); + Assert.AreEqual(null, v2["Second"]); + Assert.AreEqual(3, v2["Third"]); + } - [Test] - public void UsingJsonTextWriter() - { - // The property of the object has to be a number for the cast exception to occure - object o = new { p = 1 }; + [Test] + public void UsingJsonTextWriter() + { + // The property of the object has to be a number for the cast exception to occure + object o = new { p = 1 }; - var json = JObject.FromObject(o); + var json = JObject.FromObject(o); - using (var sw = new StringWriter()) - using (var jw = new JsonTextWriter(sw)) - { - jw.WriteToken(json.CreateReader()); - jw.Flush(); + using (var sw = new StringWriter()) + using (var jw = new JsonTextWriter(sw)) + { + jw.WriteToken(json.CreateReader()); + jw.Flush(); - string result = sw.ToString(); - Assert.AreEqual(@"{""p"":1}", result); - } - } + string result = sw.ToString(); + Assert.AreEqual(@"{""p"":1}", result); + } + } #if !(NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE || PORTABLE40) - [Test] - public void DeserializeConcurrentDictionary() - { - IDictionary components = new Dictionary + [Test] + public void DeserializeConcurrentDictionary() { - {"Key!", new Component()} - }; - GameObject go = new GameObject - { - Components = new ConcurrentDictionary(components), - Id = "Id!", - Name = "Name!" - }; + IDictionary components = new Dictionary + { + { "Key!", new Component() } + }; + GameObject go = new GameObject + { + Components = new ConcurrentDictionary(components), + Id = "Id!", + Name = "Name!" + }; - string originalJson = JsonConvert.SerializeObject(go, Formatting.Indented); + string originalJson = JsonConvert.SerializeObject(go, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Components"": { ""Key!"": {} }, @@ -6630,341 +6607,335 @@ To fix this error either change the environment to be fully trusted, change the ""Name"": ""Name!"" }", originalJson); - GameObject newObject = JsonConvert.DeserializeObject(originalJson); + GameObject newObject = JsonConvert.DeserializeObject(originalJson); - Assert.AreEqual(1, newObject.Components.Count); - Assert.AreEqual("Id!", newObject.Id); - Assert.AreEqual("Name!", newObject.Name); - } + Assert.AreEqual(1, newObject.Components.Count); + Assert.AreEqual("Id!", newObject.Id); + Assert.AreEqual("Name!", newObject.Name); + } #endif - [Test] - public void DeserializeKeyValuePairArray() - { - string json = @"[ { ""Value"": [ ""1"", ""2"" ], ""Key"": ""aaa"", ""BadContent"": [ 0 ] }, { ""Value"": [ ""3"", ""4"" ], ""Key"": ""bbb"" } ]"; - - IList>> values = JsonConvert.DeserializeObject>>>(json); - - Assert.AreEqual(2, values.Count); - Assert.AreEqual("aaa", values[0].Key); - Assert.AreEqual(2, values[0].Value.Count); - Assert.AreEqual("1", values[0].Value[0]); - Assert.AreEqual("2", values[0].Value[1]); - Assert.AreEqual("bbb", values[1].Key); - Assert.AreEqual(2, values[1].Value.Count); - Assert.AreEqual("3", values[1].Value[0]); - Assert.AreEqual("4", values[1].Value[1]); - } - - [Test] - public void DeserializeNullableKeyValuePairArray() - { - string json = @"[ { ""Value"": [ ""1"", ""2"" ], ""Key"": ""aaa"", ""BadContent"": [ 0 ] }, null, { ""Value"": [ ""3"", ""4"" ], ""Key"": ""bbb"" } ]"; - - IList>?> values = JsonConvert.DeserializeObject>?>>(json); - - Assert.AreEqual(3, values.Count); - Assert.AreEqual("aaa", values[0].Value.Key); - Assert.AreEqual(2, values[0].Value.Value.Count); - Assert.AreEqual("1", values[0].Value.Value[0]); - Assert.AreEqual("2", values[0].Value.Value[1]); - Assert.AreEqual(null, values[1]); - Assert.AreEqual("bbb", values[2].Value.Key); - Assert.AreEqual(2, values[2].Value.Value.Count); - Assert.AreEqual("3", values[2].Value.Value[0]); - Assert.AreEqual("4", values[2].Value.Value[1]); - } - - [Test] - public void DeserializeNullToNonNullableKeyValuePairArray() - { - string json = @"[ null ]"; - - ExceptionAssert.Throws( - "Cannot convert null value to KeyValuePair. Path '[0]', line 1, position 6.", - () => + [Test] + public void DeserializeKeyValuePairArray() { - JsonConvert.DeserializeObject>>>(json); - }); - } + string json = @"[ { ""Value"": [ ""1"", ""2"" ], ""Key"": ""aaa"", ""BadContent"": [ 0 ] }, { ""Value"": [ ""3"", ""4"" ], ""Key"": ""bbb"" } ]"; - [Test] - public void SerializeUriWithQuotes() - { - string input = "http://test.com/%22foo+bar%22"; - Uri uri = new Uri(input); - string json = JsonConvert.SerializeObject(uri); - Uri output = JsonConvert.DeserializeObject(json); + IList>> values = JsonConvert.DeserializeObject>>>(json); - Assert.AreEqual(uri, output); - } + Assert.AreEqual(2, values.Count); + Assert.AreEqual("aaa", values[0].Key); + Assert.AreEqual(2, values[0].Value.Count); + Assert.AreEqual("1", values[0].Value[0]); + Assert.AreEqual("2", values[0].Value[1]); + Assert.AreEqual("bbb", values[1].Key); + Assert.AreEqual(2, values[1].Value.Count); + Assert.AreEqual("3", values[1].Value[0]); + Assert.AreEqual("4", values[1].Value[1]); + } - [Test] - public void SerializeUriWithSlashes() - { - string input = @"http://tes/?a=b\\c&d=e\"; - Uri uri = new Uri(input); - string json = JsonConvert.SerializeObject(uri); - Uri output = JsonConvert.DeserializeObject(json); + [Test] + public void DeserializeNullableKeyValuePairArray() + { + string json = @"[ { ""Value"": [ ""1"", ""2"" ], ""Key"": ""aaa"", ""BadContent"": [ 0 ] }, null, { ""Value"": [ ""3"", ""4"" ], ""Key"": ""bbb"" } ]"; - Assert.AreEqual(uri, output); - } + IList>?> values = JsonConvert.DeserializeObject>?>>(json); - [Test] - public void DeserializeByteArrayWithTypeNameHandling() - { - TestObject test = new TestObject("Test", new byte[] { 72, 63, 62, 71, 92, 55 }); + Assert.AreEqual(3, values.Count); + Assert.AreEqual("aaa", values[0].Value.Key); + Assert.AreEqual(2, values[0].Value.Value.Count); + Assert.AreEqual("1", values[0].Value.Value[0]); + Assert.AreEqual("2", values[0].Value.Value[1]); + Assert.AreEqual(null, values[1]); + Assert.AreEqual("bbb", values[2].Value.Key); + Assert.AreEqual(2, values[2].Value.Value.Count); + Assert.AreEqual("3", values[2].Value.Value[0]); + Assert.AreEqual("4", values[2].Value.Value[1]); + } - JsonSerializer serializer = new JsonSerializer(); - serializer.TypeNameHandling = TypeNameHandling.All; + [Test] + public void DeserializeNullToNonNullableKeyValuePairArray() + { + string json = @"[ null ]"; - byte[] objectBytes; - using (MemoryStream bsonStream = new MemoryStream()) - using (JsonWriter bsonWriter = new JsonTextWriter(new StreamWriter(bsonStream))) - { - serializer.Serialize(bsonWriter, test); - bsonWriter.Flush(); + ExceptionAssert.Throws( + "Cannot convert null value to KeyValuePair. Path '[0]', line 1, position 6.", + () => { JsonConvert.DeserializeObject>>>(json); }); + } - objectBytes = bsonStream.ToArray(); - } + [Test] + public void SerializeUriWithQuotes() + { + string input = "http://test.com/%22foo+bar%22"; + Uri uri = new Uri(input); + string json = JsonConvert.SerializeObject(uri); + Uri output = JsonConvert.DeserializeObject(json); - using (MemoryStream bsonStream = new MemoryStream(objectBytes)) - using (JsonReader bsonReader = new JsonTextReader(new StreamReader(bsonStream))) - { - // Get exception here - TestObject newObject = (TestObject)serializer.Deserialize(bsonReader); + Assert.AreEqual(uri, output); + } - Assert.AreEqual("Test", newObject.Name); - CollectionAssert.AreEquivalent(new byte[] { 72, 63, 62, 71, 92, 55 }, newObject.Data); - } - } + [Test] + public void SerializeUriWithSlashes() + { + string input = @"http://tes/?a=b\\c&d=e\"; + Uri uri = new Uri(input); + string json = JsonConvert.SerializeObject(uri); + Uri output = JsonConvert.DeserializeObject(json); + + Assert.AreEqual(uri, output); + } + + [Test] + public void DeserializeByteArrayWithTypeNameHandling() + { + TestObject test = new TestObject("Test", new byte[] { 72, 63, 62, 71, 92, 55 }); + + JsonSerializer serializer = new JsonSerializer(); + serializer.TypeNameHandling = TypeNameHandling.All; + + byte[] objectBytes; + using (MemoryStream bsonStream = new MemoryStream()) + using (JsonWriter bsonWriter = new JsonTextWriter(new StreamWriter(bsonStream))) + { + serializer.Serialize(bsonWriter, test); + bsonWriter.Flush(); + + objectBytes = bsonStream.ToArray(); + } + + using (MemoryStream bsonStream = new MemoryStream(objectBytes)) + using (JsonReader bsonReader = new JsonTextReader(new StreamReader(bsonStream))) + { + // Get exception here + TestObject newObject = (TestObject)serializer.Deserialize(bsonReader); + + Assert.AreEqual("Test", newObject.Name); + CollectionAssert.AreEquivalent(new byte[] { 72, 63, 62, 71, 92, 55 }, newObject.Data); + } + } #if !(SILVERLIGHT || WINDOWS_PHONE || NET20 || NETFX_CORE) - [Test] - public void DeserializeDecimalsWithCulture() - { - CultureInfo initialCulture = Thread.CurrentThread.CurrentCulture; + [Test] + public void DeserializeDecimalsWithCulture() + { + CultureInfo initialCulture = Thread.CurrentThread.CurrentCulture; - try - { - CultureInfo testCulture = CultureInfo.CreateSpecificCulture("nb-NO"); + try + { + CultureInfo testCulture = CultureInfo.CreateSpecificCulture("nb-NO"); - Thread.CurrentThread.CurrentCulture = testCulture; - Thread.CurrentThread.CurrentUICulture = testCulture; + Thread.CurrentThread.CurrentCulture = testCulture; + Thread.CurrentThread.CurrentUICulture = testCulture; - string json = @"{ 'Quantity': '1.5', 'OptionalQuantity': '2.2' }"; + string json = @"{ 'Quantity': '1.5', 'OptionalQuantity': '2.2' }"; - DecimalTestClass c = JsonConvert.DeserializeObject(json); + DecimalTestClass c = JsonConvert.DeserializeObject(json); - Assert.AreEqual(1.5m, c.Quantity); - Assert.AreEqual(2.2d, c.OptionalQuantity); - } - finally - { - Thread.CurrentThread.CurrentCulture = initialCulture; - Thread.CurrentThread.CurrentUICulture = initialCulture; - } - } + Assert.AreEqual(1.5m, c.Quantity); + Assert.AreEqual(2.2d, c.OptionalQuantity); + } + finally + { + Thread.CurrentThread.CurrentCulture = initialCulture; + Thread.CurrentThread.CurrentUICulture = initialCulture; + } + } #endif - [Test] - public void ReadForTypeHackFixDecimal() - { - IList d1 = new List { 1.1m }; + [Test] + public void ReadForTypeHackFixDecimal() + { + IList d1 = new List { 1.1m }; - string json = JsonConvert.SerializeObject(d1); + string json = JsonConvert.SerializeObject(d1); - IList d2 = JsonConvert.DeserializeObject>(json); + IList d2 = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(d1.Count, d2.Count); - Assert.AreEqual(d1[0], d2[0]); - } + Assert.AreEqual(d1.Count, d2.Count); + Assert.AreEqual(d1[0], d2[0]); + } - [Test] - public void ReadForTypeHackFixDateTimeOffset() - { - IList d1 = new List { null }; + [Test] + public void ReadForTypeHackFixDateTimeOffset() + { + IList d1 = new List { null }; - string json = JsonConvert.SerializeObject(d1); + string json = JsonConvert.SerializeObject(d1); - IList d2 = JsonConvert.DeserializeObject>(json); + IList d2 = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(d1.Count, d2.Count); - Assert.AreEqual(d1[0], d2[0]); - } + Assert.AreEqual(d1.Count, d2.Count); + Assert.AreEqual(d1[0], d2[0]); + } - [Test] - public void ReadForTypeHackFixByteArray() - { - IList d1 = new List { null }; + [Test] + public void ReadForTypeHackFixByteArray() + { + IList d1 = new List { null }; - string json = JsonConvert.SerializeObject(d1); + string json = JsonConvert.SerializeObject(d1); - IList d2 = JsonConvert.DeserializeObject>(json); + IList d2 = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(d1.Count, d2.Count); - Assert.AreEqual(d1[0], d2[0]); - } + Assert.AreEqual(d1.Count, d2.Count); + Assert.AreEqual(d1[0], d2[0]); + } - [Test] - public void SerializeInheritanceHierarchyWithDuplicateProperty() - { - Bb b = new Bb(); - b.no = true; - Aa a = b; - a.no = int.MaxValue; + [Test] + public void SerializeInheritanceHierarchyWithDuplicateProperty() + { + Bb b = new Bb(); + b.no = true; + Aa a = b; + a.no = int.MaxValue; - string json = JsonConvert.SerializeObject(b); + string json = JsonConvert.SerializeObject(b); - Assert.AreEqual(@"{""no"":true}", json); + Assert.AreEqual(@"{""no"":true}", json); - Bb b2 = JsonConvert.DeserializeObject(json); + Bb b2 = JsonConvert.DeserializeObject(json); - Assert.AreEqual(true, b2.no); - } + Assert.AreEqual(true, b2.no); + } - [Test] - public void DeserializeNullInt() - { - string json = @"[ + [Test] + public void DeserializeNullInt() + { + string json = @"[ 1, 2, 3, null ]"; - ExceptionAssert.Throws( - "Error converting value {null} to type 'System.Int32'. Path '[3]', line 5, position 7.", - () => - { - List numbers = JsonConvert.DeserializeObject>(json); - }); - } + ExceptionAssert.Throws( + "Error converting value {null} to type 'System.Int32'. Path '[3]', line 5, position 7.", + () => { List numbers = JsonConvert.DeserializeObject>(json); }); + } #if !(PORTABLE || NETFX_CORE) - public class ConvertableIntTestClass - { - public ConvertibleInt Integer { get; set; } - public ConvertibleInt? NullableInteger1 { get; set; } - public ConvertibleInt? NullableInteger2 { get; set; } - } + public class ConvertableIntTestClass + { + public ConvertibleInt Integer { get; set; } + public ConvertibleInt? NullableInteger1 { get; set; } + public ConvertibleInt? NullableInteger2 { get; set; } + } - [Test] - public void SerializeIConvertible() - { - ConvertableIntTestClass c = new ConvertableIntTestClass - { - Integer = new ConvertibleInt(1), - NullableInteger1 = new ConvertibleInt(2), - NullableInteger2 = null - }; + [Test] + public void SerializeIConvertible() + { + ConvertableIntTestClass c = new ConvertableIntTestClass + { + Integer = new ConvertibleInt(1), + NullableInteger1 = new ConvertibleInt(2), + NullableInteger2 = null + }; - string json = JsonConvert.SerializeObject(c, Formatting.Indented); + string json = JsonConvert.SerializeObject(c, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Integer"": 1, ""NullableInteger1"": 2, ""NullableInteger2"": null }", json); - } + } - [Test] - public void DeserializeIConvertible() - { - string json = @"{ + [Test] + public void DeserializeIConvertible() + { + string json = @"{ ""Integer"": 1, ""NullableInteger1"": 2, ""NullableInteger2"": null }"; - ExceptionAssert.Throws( - "Error converting value 1 to type 'Newtonsoft.Json.Tests.ConvertibleInt'. Path 'Integer', line 2, position 15.", - () => JsonConvert.DeserializeObject(json)); - } + ExceptionAssert.Throws( + "Error converting value 1 to type 'Newtonsoft.Json.Tests.ConvertibleInt'. Path 'Integer', line 2, position 15.", + () => JsonConvert.DeserializeObject(json)); + } #endif - [Test] - public void SerializeNullableWidgetStruct() - { - Widget widget = new Widget { Id = new WidgetId { Value = "id" } }; - - string json = JsonConvert.SerializeObject(widget); - - Assert.AreEqual(@"{""Id"":{""Value"":""id""}}", json); - } - - [Test] - public void DeserializeNullableWidgetStruct() - { - string json = @"{""Id"":{""Value"":""id""}}"; - - Widget w = JsonConvert.DeserializeObject(json); - - Assert.AreEqual(new WidgetId { Value = "id" }, w.Id); - Assert.AreEqual(new WidgetId { Value = "id" }, w.Id.Value); - Assert.AreEqual("id", w.Id.Value.Value); - } - - [Test] - public void DeserializeBoolInt() - { - ExceptionAssert.Throws( - "Error reading integer. Unexpected token: Boolean. Path 'PreProperty', line 2, position 22.", - () => + [Test] + public void SerializeNullableWidgetStruct() { - string json = @"{ + Widget widget = new Widget { Id = new WidgetId { Value = "id" } }; + + string json = JsonConvert.SerializeObject(widget); + + Assert.AreEqual(@"{""Id"":{""Value"":""id""}}", json); + } + + [Test] + public void DeserializeNullableWidgetStruct() + { + string json = @"{""Id"":{""Value"":""id""}}"; + + Widget w = JsonConvert.DeserializeObject(json); + + Assert.AreEqual(new WidgetId { Value = "id" }, w.Id); + Assert.AreEqual(new WidgetId { Value = "id" }, w.Id.Value); + Assert.AreEqual("id", w.Id.Value.Value); + } + + [Test] + public void DeserializeBoolInt() + { + ExceptionAssert.Throws( + "Error reading integer. Unexpected token: Boolean. Path 'PreProperty', line 2, position 22.", + () => + { + string json = @"{ ""PreProperty"": true, ""PostProperty"": ""-1"" }"; - JsonConvert.DeserializeObject(json); - }); - } + JsonConvert.DeserializeObject(json); + }); + } - [Test] - public void DeserializeUnexpectedEndInt() - { - ExceptionAssert.Throws( - "Unexpected end when setting PreProperty's value. Path 'PreProperty', line 2, position 18.", - () => + [Test] + public void DeserializeUnexpectedEndInt() { - string json = @"{ + ExceptionAssert.Throws( + "Unexpected end when setting PreProperty's value. Path 'PreProperty', line 2, position 18.", + () => + { + string json = @"{ ""PreProperty"": "; - JsonConvert.DeserializeObject(json); - }); - } + JsonConvert.DeserializeObject(json); + }); + } - [Test] - public void DeserializeNullableGuid() - { - string json = @"{""Id"":null}"; - var c = JsonConvert.DeserializeObject(json); - - Assert.AreEqual(null, c.Id); - - json = @"{""Id"":""d8220a4b-75b1-4b7a-8112-b7bdae956a45""}"; - c = JsonConvert.DeserializeObject(json); - - Assert.AreEqual(new Guid("d8220a4b-75b1-4b7a-8112-b7bdae956a45"), c.Id); - } - - [Test] - public void DeserializeGuid() - { - Item expected = new Item() + [Test] + public void DeserializeNullableGuid() { - SourceTypeID = new Guid("d8220a4b-75b1-4b7a-8112-b7bdae956a45"), - BrokerID = new Guid("951663c4-924e-4c86-a57a-7ed737501dbd"), - Latitude = 33.657145, - Longitude = -117.766684, - TimeStamp = new DateTime(2000, 3, 1, 23, 59, 59, DateTimeKind.Utc), - Payload = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } - }; + string json = @"{""Id"":null}"; + var c = JsonConvert.DeserializeObject(json); - string jsonString = JsonConvert.SerializeObject(expected, Formatting.Indented); + Assert.AreEqual(null, c.Id); - Assert.AreEqual(@"{ + json = @"{""Id"":""d8220a4b-75b1-4b7a-8112-b7bdae956a45""}"; + c = JsonConvert.DeserializeObject(json); + + Assert.AreEqual(new Guid("d8220a4b-75b1-4b7a-8112-b7bdae956a45"), c.Id); + } + + [Test] + public void DeserializeGuid() + { + Item expected = new Item() + { + SourceTypeID = new Guid("d8220a4b-75b1-4b7a-8112-b7bdae956a45"), + BrokerID = new Guid("951663c4-924e-4c86-a57a-7ed737501dbd"), + Latitude = 33.657145, + Longitude = -117.766684, + TimeStamp = new DateTime(2000, 3, 1, 23, 59, 59, DateTimeKind.Utc), + Payload = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } + }; + + string jsonString = JsonConvert.SerializeObject(expected, Formatting.Indented); + + Assert.AreEqual(@"{ ""SourceTypeID"": ""d8220a4b-75b1-4b7a-8112-b7bdae956a45"", ""BrokerID"": ""951663c4-924e-4c86-a57a-7ed737501dbd"", ""Latitude"": 33.657145, @@ -6976,277 +6947,261 @@ To fix this error either change the environment to be fully trusted, change the } }", jsonString); - Item actual = JsonConvert.DeserializeObject(jsonString); + Item actual = JsonConvert.DeserializeObject(jsonString); - Assert.AreEqual(new Guid("d8220a4b-75b1-4b7a-8112-b7bdae956a45"), actual.SourceTypeID); - Assert.AreEqual(new Guid("951663c4-924e-4c86-a57a-7ed737501dbd"), actual.BrokerID); - byte[] bytes = (byte[])actual.Payload; - CollectionAssert.AreEquivalent((new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }).ToList(), bytes.ToList()); - } + Assert.AreEqual(new Guid("d8220a4b-75b1-4b7a-8112-b7bdae956a45"), actual.SourceTypeID); + Assert.AreEqual(new Guid("951663c4-924e-4c86-a57a-7ed737501dbd"), actual.BrokerID); + byte[] bytes = (byte[])actual.Payload; + CollectionAssert.AreEquivalent((new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }).ToList(), bytes.ToList()); + } - [Test] - public void DeserializeObjectDictionary() - { - var serializer = JsonSerializer.Create(new JsonSerializerSettings()); - var dict = serializer.Deserialize>(new JsonTextReader(new StringReader("{'k1':'','k2':'v2'}"))); - - Assert.AreEqual("", dict["k1"]); - Assert.AreEqual("v2", dict["k2"]); - } - - [Test] - public void DeserializeNullableEnum() - { - string json = JsonConvert.SerializeObject(new WithEnums + [Test] + public void DeserializeObjectDictionary() { - Id = 7, - NullableEnum = null - }); + var serializer = JsonSerializer.Create(new JsonSerializerSettings()); + var dict = serializer.Deserialize>(new JsonTextReader(new StringReader("{'k1':'','k2':'v2'}"))); - Assert.AreEqual(@"{""Id"":7,""NullableEnum"":null}", json); + Assert.AreEqual("", dict["k1"]); + Assert.AreEqual("v2", dict["k2"]); + } - WithEnums e = JsonConvert.DeserializeObject(json); - - Assert.AreEqual(null, e.NullableEnum); - - json = JsonConvert.SerializeObject(new WithEnums + [Test] + public void DeserializeNullableEnum() { - Id = 7, - NullableEnum = MyEnum.Value2 - }); + string json = JsonConvert.SerializeObject(new WithEnums + { + Id = 7, + NullableEnum = null + }); - Assert.AreEqual(@"{""Id"":7,""NullableEnum"":1}", json); + Assert.AreEqual(@"{""Id"":7,""NullableEnum"":null}", json); - e = JsonConvert.DeserializeObject(json); + WithEnums e = JsonConvert.DeserializeObject(json); - Assert.AreEqual(MyEnum.Value2, e.NullableEnum); - } + Assert.AreEqual(null, e.NullableEnum); - [Test] - public void NullableStructWithConverter() - { - string json = JsonConvert.SerializeObject(new Widget1 { Id = new WidgetId1 { Value = 1234 } }); + json = JsonConvert.SerializeObject(new WithEnums + { + Id = 7, + NullableEnum = MyEnum.Value2 + }); - Assert.AreEqual(@"{""Id"":""1234""}", json); + Assert.AreEqual(@"{""Id"":7,""NullableEnum"":1}", json); - Widget1 w = JsonConvert.DeserializeObject(@"{""Id"":""1234""}"); + e = JsonConvert.DeserializeObject(json); - Assert.AreEqual(new WidgetId1 { Value = 1234 }, w.Id); - } + Assert.AreEqual(MyEnum.Value2, e.NullableEnum); + } - [Test] - public void SerializeDictionaryStringStringAndStringObject() - { - var serializer = JsonSerializer.Create(new JsonSerializerSettings()); - var dict = serializer.Deserialize>(new JsonTextReader(new StringReader("{'k1':'','k2':'v2'}"))); - - var reader = new JsonTextReader(new StringReader("{'k1':'','k2':'v2'}")); - var dict2 = serializer.Deserialize>(reader); - - Assert.AreEqual(dict["k1"], dict2["k1"]); - } - - [Test] - public void DeserializeEmptyStrings() - { - object v = JsonConvert.DeserializeObject(""); - Assert.IsNull(v); - - v = JsonConvert.DeserializeObject(""); - Assert.IsNull(v); - - v = JsonConvert.DeserializeObject(""); - Assert.IsNull(v); - - v = JsonConvert.DeserializeObject(""); - Assert.IsNull(v); - - v = JsonConvert.DeserializeObject(""); - Assert.IsNull(v); - - v = JsonConvert.DeserializeObject(""); - Assert.IsNull(v); - - v = JsonConvert.DeserializeObject(""); - Assert.IsNull(v); - } - - public class Sdfsdf - { - public double Id { get; set; } - } - - [Test] - public void DeserializeDoubleFromEmptyString() - { - ExceptionAssert.Throws( - "No JSON content found and type 'System.Double' is not nullable. Path '', line 0, position 0.", - () => + [Test] + public void NullableStructWithConverter() { - JsonConvert.DeserializeObject(""); - }); - } + string json = JsonConvert.SerializeObject(new Widget1 { Id = new WidgetId1 { Value = 1234 } }); - [Test] - public void DeserializeEnumFromEmptyString() - { - ExceptionAssert.Throws( - "No JSON content found and type 'System.StringComparison' is not nullable. Path '', line 0, position 0.", - () => + Assert.AreEqual(@"{""Id"":""1234""}", json); + + Widget1 w = JsonConvert.DeserializeObject(@"{""Id"":""1234""}"); + + Assert.AreEqual(new WidgetId1 { Value = 1234 }, w.Id); + } + + [Test] + public void SerializeDictionaryStringStringAndStringObject() { - JsonConvert.DeserializeObject(""); - }); - } + var serializer = JsonSerializer.Create(new JsonSerializerSettings()); + var dict = serializer.Deserialize>(new JsonTextReader(new StringReader("{'k1':'','k2':'v2'}"))); - [Test] - public void DeserializeInt32FromEmptyString() - { - ExceptionAssert.Throws( - "No JSON content found and type 'System.Int32' is not nullable. Path '', line 0, position 0.", - () => + var reader = new JsonTextReader(new StringReader("{'k1':'','k2':'v2'}")); + var dict2 = serializer.Deserialize>(reader); + + Assert.AreEqual(dict["k1"], dict2["k1"]); + } + + [Test] + public void DeserializeEmptyStrings() { - JsonConvert.DeserializeObject(""); - }); - } + object v = JsonConvert.DeserializeObject(""); + Assert.IsNull(v); - [Test] - public void DeserializeByteArrayFromEmptyString() - { - byte[] b = JsonConvert.DeserializeObject(""); - Assert.IsNull(b); - } + v = JsonConvert.DeserializeObject(""); + Assert.IsNull(v); - [Test] - public void DeserializeDoubleFromNullString() - { - ExceptionAssert.Throws( - @"Value cannot be null. + v = JsonConvert.DeserializeObject(""); + Assert.IsNull(v); + + v = JsonConvert.DeserializeObject(""); + Assert.IsNull(v); + + v = JsonConvert.DeserializeObject(""); + Assert.IsNull(v); + + v = JsonConvert.DeserializeObject(""); + Assert.IsNull(v); + + v = JsonConvert.DeserializeObject(""); + Assert.IsNull(v); + } + + public class Sdfsdf + { + public double Id { get; set; } + } + + [Test] + public void DeserializeDoubleFromEmptyString() + { + ExceptionAssert.Throws( + "No JSON content found and type 'System.Double' is not nullable. Path '', line 0, position 0.", + () => { JsonConvert.DeserializeObject(""); }); + } + + [Test] + public void DeserializeEnumFromEmptyString() + { + ExceptionAssert.Throws( + "No JSON content found and type 'System.StringComparison' is not nullable. Path '', line 0, position 0.", + () => { JsonConvert.DeserializeObject(""); }); + } + + [Test] + public void DeserializeInt32FromEmptyString() + { + ExceptionAssert.Throws( + "No JSON content found and type 'System.Int32' is not nullable. Path '', line 0, position 0.", + () => { JsonConvert.DeserializeObject(""); }); + } + + [Test] + public void DeserializeByteArrayFromEmptyString() + { + byte[] b = JsonConvert.DeserializeObject(""); + Assert.IsNull(b); + } + + [Test] + public void DeserializeDoubleFromNullString() + { + ExceptionAssert.Throws( + @"Value cannot be null. Parameter name: value", - () => - { - JsonConvert.DeserializeObject(null); - }); - } + () => { JsonConvert.DeserializeObject(null); }); + } - [Test] - public void DeserializeFromNullString() - { - ExceptionAssert.Throws( - @"Value cannot be null. + [Test] + public void DeserializeFromNullString() + { + ExceptionAssert.Throws( + @"Value cannot be null. Parameter name: value", - () => + () => { JsonConvert.DeserializeObject(null); }); + } + + [Test] + public void DeserializeIsoDatesWithIsoConverter() { - JsonConvert.DeserializeObject(null); - }); + string jsonIsoText = + @"{""Value"":""2012-02-25T19:55:50.6095676+13:00""}"; - } - - [Test] - public void DeserializeIsoDatesWithIsoConverter() - { - string jsonIsoText = - @"{""Value"":""2012-02-25T19:55:50.6095676+13:00""}"; - - DateTimeWrapper c = JsonConvert.DeserializeObject(jsonIsoText, new IsoDateTimeConverter()); - Assert.AreEqual(DateTimeKind.Local, c.Value.Kind); - } + DateTimeWrapper c = JsonConvert.DeserializeObject(jsonIsoText, new IsoDateTimeConverter()); + Assert.AreEqual(DateTimeKind.Local, c.Value.Kind); + } #if !NET20 - [Test] - public void DeserializeUTC() - { - DateTimeTestClass c = - JsonConvert.DeserializeObject( - @"{""PreField"":""Pre"",""DateTimeField"":""2008-12-12T12:12:12Z"",""DateTimeOffsetField"":""2008-12-12T12:12:12Z"",""PostField"":""Post""}", - new JsonSerializerSettings - { - DateTimeZoneHandling = DateTimeZoneHandling.Local - }); + [Test] + public void DeserializeUTC() + { + DateTimeTestClass c = + JsonConvert.DeserializeObject( + @"{""PreField"":""Pre"",""DateTimeField"":""2008-12-12T12:12:12Z"",""DateTimeOffsetField"":""2008-12-12T12:12:12Z"",""PostField"":""Post""}", + new JsonSerializerSettings + { + DateTimeZoneHandling = DateTimeZoneHandling.Local + }); - Assert.AreEqual(new DateTime(2008, 12, 12, 12, 12, 12, 0, DateTimeKind.Utc).ToLocalTime(), c.DateTimeField); - Assert.AreEqual(new DateTimeOffset(2008, 12, 12, 12, 12, 12, 0, TimeSpan.Zero), c.DateTimeOffsetField); - Assert.AreEqual("Pre", c.PreField); - Assert.AreEqual("Post", c.PostField); + Assert.AreEqual(new DateTime(2008, 12, 12, 12, 12, 12, 0, DateTimeKind.Utc).ToLocalTime(), c.DateTimeField); + Assert.AreEqual(new DateTimeOffset(2008, 12, 12, 12, 12, 12, 0, TimeSpan.Zero), c.DateTimeOffsetField); + Assert.AreEqual("Pre", c.PreField); + Assert.AreEqual("Post", c.PostField); - DateTimeTestClass c2 = - JsonConvert.DeserializeObject( - @"{""PreField"":""Pre"",""DateTimeField"":""2008-01-01T01:01:01Z"",""DateTimeOffsetField"":""2008-01-01T01:01:01Z"",""PostField"":""Post""}", - new JsonSerializerSettings - { - DateTimeZoneHandling = DateTimeZoneHandling.Local - }); + DateTimeTestClass c2 = + JsonConvert.DeserializeObject( + @"{""PreField"":""Pre"",""DateTimeField"":""2008-01-01T01:01:01Z"",""DateTimeOffsetField"":""2008-01-01T01:01:01Z"",""PostField"":""Post""}", + new JsonSerializerSettings + { + DateTimeZoneHandling = DateTimeZoneHandling.Local + }); - Assert.AreEqual(new DateTime(2008, 1, 1, 1, 1, 1, 0, DateTimeKind.Utc).ToLocalTime(), c2.DateTimeField); - Assert.AreEqual(new DateTimeOffset(2008, 1, 1, 1, 1, 1, 0, TimeSpan.Zero), c2.DateTimeOffsetField); - Assert.AreEqual("Pre", c2.PreField); - Assert.AreEqual("Post", c2.PostField); - } + Assert.AreEqual(new DateTime(2008, 1, 1, 1, 1, 1, 0, DateTimeKind.Utc).ToLocalTime(), c2.DateTimeField); + Assert.AreEqual(new DateTimeOffset(2008, 1, 1, 1, 1, 1, 0, TimeSpan.Zero), c2.DateTimeOffsetField); + Assert.AreEqual("Pre", c2.PreField); + Assert.AreEqual("Post", c2.PostField); + } - [Test] - public void NullableDeserializeUTC() - { - NullableDateTimeTestClass c = - JsonConvert.DeserializeObject( - @"{""PreField"":""Pre"",""DateTimeField"":""2008-12-12T12:12:12Z"",""DateTimeOffsetField"":""2008-12-12T12:12:12Z"",""PostField"":""Post""}", - new JsonSerializerSettings - { - DateTimeZoneHandling = DateTimeZoneHandling.Local - }); + [Test] + public void NullableDeserializeUTC() + { + NullableDateTimeTestClass c = + JsonConvert.DeserializeObject( + @"{""PreField"":""Pre"",""DateTimeField"":""2008-12-12T12:12:12Z"",""DateTimeOffsetField"":""2008-12-12T12:12:12Z"",""PostField"":""Post""}", + new JsonSerializerSettings + { + DateTimeZoneHandling = DateTimeZoneHandling.Local + }); - Assert.AreEqual(new DateTime(2008, 12, 12, 12, 12, 12, 0, DateTimeKind.Utc).ToLocalTime(), c.DateTimeField); - Assert.AreEqual(new DateTimeOffset(2008, 12, 12, 12, 12, 12, 0, TimeSpan.Zero), c.DateTimeOffsetField); - Assert.AreEqual("Pre", c.PreField); - Assert.AreEqual("Post", c.PostField); + Assert.AreEqual(new DateTime(2008, 12, 12, 12, 12, 12, 0, DateTimeKind.Utc).ToLocalTime(), c.DateTimeField); + Assert.AreEqual(new DateTimeOffset(2008, 12, 12, 12, 12, 12, 0, TimeSpan.Zero), c.DateTimeOffsetField); + Assert.AreEqual("Pre", c.PreField); + Assert.AreEqual("Post", c.PostField); - NullableDateTimeTestClass c2 = - JsonConvert.DeserializeObject( - @"{""PreField"":""Pre"",""DateTimeField"":null,""DateTimeOffsetField"":null,""PostField"":""Post""}"); + NullableDateTimeTestClass c2 = + JsonConvert.DeserializeObject( + @"{""PreField"":""Pre"",""DateTimeField"":null,""DateTimeOffsetField"":null,""PostField"":""Post""}"); - Assert.AreEqual(null, c2.DateTimeField); - Assert.AreEqual(null, c2.DateTimeOffsetField); - Assert.AreEqual("Pre", c2.PreField); - Assert.AreEqual("Post", c2.PostField); - } + Assert.AreEqual(null, c2.DateTimeField); + Assert.AreEqual(null, c2.DateTimeOffsetField); + Assert.AreEqual("Pre", c2.PreField); + Assert.AreEqual("Post", c2.PostField); + } - [Test] - public void PrivateConstructor() - { - var person = PersonWithPrivateConstructor.CreatePerson(); - person.Name = "John Doe"; - person.Age = 25; + [Test] + public void PrivateConstructor() + { + var person = PersonWithPrivateConstructor.CreatePerson(); + person.Name = "John Doe"; + person.Age = 25; - var serializedPerson = JsonConvert.SerializeObject(person); - var roundtrippedPerson = JsonConvert.DeserializeObject(serializedPerson); + var serializedPerson = JsonConvert.SerializeObject(person); + var roundtrippedPerson = JsonConvert.DeserializeObject(serializedPerson); - Assert.AreEqual(person.Name, roundtrippedPerson.Name); - } + Assert.AreEqual(person.Name, roundtrippedPerson.Name); + } #endif #if !(SILVERLIGHT || NETFX_CORE) - [Test] - public void MetroBlogPost() - { - Product product = new Product(); - product.Name = "Apple"; - product.ExpiryDate = new DateTime(2012, 4, 1); - product.Price = 3.99M; - product.Sizes = new[] { "Small", "Medium", "Large" }; - - string json = JsonConvert.SerializeObject(product); - //{ - // "Name": "Apple", - // "ExpiryDate": "2012-04-01T00:00:00", - // "Price": 3.99, - // "Sizes": [ "Small", "Medium", "Large" ] - //} - - string metroJson = JsonConvert.SerializeObject(product, new JsonSerializerSettings + [Test] + public void MetroBlogPost() { - ContractResolver = new MetroPropertyNameResolver(), - Converters = { new MetroStringConverter() }, - Formatting = Formatting.Indented - }); - Assert.AreEqual(@"{ + Product product = new Product(); + product.Name = "Apple"; + product.ExpiryDate = new DateTime(2012, 4, 1); + product.Price = 3.99M; + product.Sizes = new[] { "Small", "Medium", "Large" }; + + string json = JsonConvert.SerializeObject(product); + //{ + // "Name": "Apple", + // "ExpiryDate": "2012-04-01T00:00:00", + // "Price": 3.99, + // "Sizes": [ "Small", "Medium", "Large" ] + //} + + string metroJson = JsonConvert.SerializeObject(product, new JsonSerializerSettings + { + ContractResolver = new MetroPropertyNameResolver(), + Converters = { new MetroStringConverter() }, + Formatting = Formatting.Indented + }); + Assert.AreEqual(@"{ "":::NAME:::"": "":::APPLE:::"", "":::EXPIRYDATE:::"": ""2012-04-01T00:00:00"", "":::PRICE:::"": 3.99, @@ -7256,23 +7211,23 @@ Parameter name: value", "":::LARGE:::"" ] }", metroJson); - //{ - // ":::NAME:::": ":::APPLE:::", - // ":::EXPIRYDATE:::": "2012-04-01T00:00:00", - // ":::PRICE:::": 3.99, - // ":::SIZES:::": [ ":::SMALL:::", ":::MEDIUM:::", ":::LARGE:::" ] - //} + //{ + // ":::NAME:::": ":::APPLE:::", + // ":::EXPIRYDATE:::": "2012-04-01T00:00:00", + // ":::PRICE:::": 3.99, + // ":::SIZES:::": [ ":::SMALL:::", ":::MEDIUM:::", ":::LARGE:::" ] + //} - Color[] colors = new[] { Color.Blue, Color.Red, Color.Yellow, Color.Green, Color.Black, Color.Brown }; + Color[] colors = new[] { Color.Blue, Color.Red, Color.Yellow, Color.Green, Color.Black, Color.Brown }; - string json2 = JsonConvert.SerializeObject(colors, new JsonSerializerSettings - { - ContractResolver = new MetroPropertyNameResolver(), - Converters = { new MetroStringConverter(), new MetroColorConverter() }, - Formatting = Formatting.Indented - }); + string json2 = JsonConvert.SerializeObject(colors, new JsonSerializerSettings + { + ContractResolver = new MetroPropertyNameResolver(), + Converters = { new MetroStringConverter(), new MetroColorConverter() }, + Formatting = Formatting.Indented + }); - Assert.AreEqual(@"[ + Assert.AreEqual(@"[ "":::GRAY:::"", "":::GRAY:::"", "":::GRAY:::"", @@ -7280,352 +7235,353 @@ Parameter name: value", "":::BLACK:::"", "":::GRAY:::"" ]", json2); - } + } - public class MetroColorConverter : JsonConverter - { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - Color color = (Color)value; - Color fixedColor = (color == Color.White || color == Color.Black) ? color : Color.Gray; + public class MetroColorConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + Color color = (Color)value; + Color fixedColor = (color == Color.White || color == Color.Black) ? color : Color.Gray; - writer.WriteValue(":::" + fixedColor.ToKnownColor().ToString().ToUpper() + ":::"); - } + writer.WriteValue(":::" + fixedColor.ToKnownColor().ToString().ToUpper() + ":::"); + } - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - return Enum.Parse(typeof(Color), reader.Value.ToString()); - } + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + return Enum.Parse(typeof(Color), reader.Value.ToString()); + } - public override bool CanConvert(Type objectType) - { - return objectType == typeof(Color); - } - } + public override bool CanConvert(Type objectType) + { + return objectType == typeof(Color); + } + } #endif - private class FooBar - { - public DateTimeOffset Foo { get; set; } - } - - [Test] - public void TokenFromBson() - { - MemoryStream ms = new MemoryStream(); - BsonWriter writer = new BsonWriter(ms); - writer.WriteStartArray(); - writer.WriteValue("2000-01-02T03:04:05+06:00"); - writer.WriteEndArray(); - - byte[] data = ms.ToArray(); - BsonReader reader = new BsonReader(new MemoryStream(data)) + private class FooBar { - ReadRootValueAsArray = true - }; + public DateTimeOffset Foo { get; set; } + } - JArray a = (JArray)JArray.ReadFrom(reader); - JValue v = (JValue)a[0]; - Console.WriteLine(v.Value.GetType()); - Console.WriteLine(a.ToString()); - } - - [Test] - public void ObjectRequiredDeserializeMissing() - { - string json = "{}"; - IList errors = new List(); - - EventHandler error = (s, e) => + [Test] + public void TokenFromBson() { - errors.Add(e.ErrorContext.Error.Message); - e.ErrorContext.Handled = true; - }; + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); + writer.WriteStartArray(); + writer.WriteValue("2000-01-02T03:04:05+06:00"); + writer.WriteEndArray(); - var o = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + byte[] data = ms.ToArray(); + BsonReader reader = new BsonReader(new MemoryStream(data)) + { + ReadRootValueAsArray = true + }; + + JArray a = (JArray)JArray.ReadFrom(reader); + JValue v = (JValue)a[0]; + Console.WriteLine(v.Value.GetType()); + Console.WriteLine(a.ToString()); + } + + [Test] + public void ObjectRequiredDeserializeMissing() { - Error = error - }); + string json = "{}"; + IList errors = new List(); - Assert.IsNotNull(o); - Assert.AreEqual(4, errors.Count); - Assert.AreEqual("Required property 'NonAttributeProperty' not found in JSON. Path '', line 1, position 2.", errors[0]); - Assert.AreEqual("Required property 'UnsetProperty' not found in JSON. Path '', line 1, position 2.", errors[1]); - Assert.AreEqual("Required property 'AllowNullProperty' not found in JSON. Path '', line 1, position 2.", errors[2]); - Assert.AreEqual("Required property 'AlwaysProperty' not found in JSON. Path '', line 1, position 2.", errors[3]); - } + EventHandler error = (s, e) => + { + errors.Add(e.ErrorContext.Error.Message); + e.ErrorContext.Handled = true; + }; - [Test] - public void ObjectRequiredDeserializeNull() - { - string json = "{'NonAttributeProperty':null,'UnsetProperty':null,'AllowNullProperty':null,'AlwaysProperty':null}"; - IList errors = new List(); + var o = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + Error = error + }); - EventHandler error = (s, e) => - { - errors.Add(e.ErrorContext.Error.Message); - e.ErrorContext.Handled = true; - }; + Assert.IsNotNull(o); + Assert.AreEqual(4, errors.Count); + Assert.AreEqual("Required property 'NonAttributeProperty' not found in JSON. Path '', line 1, position 2.", errors[0]); + Assert.AreEqual("Required property 'UnsetProperty' not found in JSON. Path '', line 1, position 2.", errors[1]); + Assert.AreEqual("Required property 'AllowNullProperty' not found in JSON. Path '', line 1, position 2.", errors[2]); + Assert.AreEqual("Required property 'AlwaysProperty' not found in JSON. Path '', line 1, position 2.", errors[3]); + } - var o = JsonConvert.DeserializeObject(json, new JsonSerializerSettings - { - Error = error - }); + [Test] + public void ObjectRequiredDeserializeNull() + { + string json = "{'NonAttributeProperty':null,'UnsetProperty':null,'AllowNullProperty':null,'AlwaysProperty':null}"; + IList errors = new List(); - Assert.IsNotNull(o); - Assert.AreEqual(3, errors.Count); - Assert.AreEqual("Required property 'NonAttributeProperty' expects a value but got null. Path '', line 1, position 97.", errors[0]); - Assert.AreEqual("Required property 'UnsetProperty' expects a value but got null. Path '', line 1, position 97.", errors[1]); - Assert.AreEqual("Required property 'AlwaysProperty' expects a value but got null. Path '', line 1, position 97.", errors[2]); - } + EventHandler error = (s, e) => + { + errors.Add(e.ErrorContext.Error.Message); + e.ErrorContext.Handled = true; + }; - [Test] - public void ObjectRequiredSerialize() - { - IList errors = new List(); + var o = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + Error = error + }); - EventHandler error = (s, e) => - { - errors.Add(e.ErrorContext.Error.Message); - e.ErrorContext.Handled = true; - }; + Assert.IsNotNull(o); + Assert.AreEqual(3, errors.Count); + Assert.AreEqual("Required property 'NonAttributeProperty' expects a value but got null. Path '', line 1, position 97.", errors[0]); + Assert.AreEqual("Required property 'UnsetProperty' expects a value but got null. Path '', line 1, position 97.", errors[1]); + Assert.AreEqual("Required property 'AlwaysProperty' expects a value but got null. Path '', line 1, position 97.", errors[2]); + } - string json = JsonConvert.SerializeObject(new RequiredObject(), new JsonSerializerSettings - { - Error = error, - Formatting = Formatting.Indented - }); + [Test] + public void ObjectRequiredSerialize() + { + IList errors = new List(); - Assert.AreEqual(@"{ + EventHandler error = (s, e) => + { + errors.Add(e.ErrorContext.Error.Message); + e.ErrorContext.Handled = true; + }; + + string json = JsonConvert.SerializeObject(new RequiredObject(), new JsonSerializerSettings + { + Error = error, + Formatting = Formatting.Indented + }); + + Assert.AreEqual(@"{ ""DefaultProperty"": null, ""AllowNullProperty"": null }", json); - Assert.AreEqual(3, errors.Count); - Assert.AreEqual("Cannot write a null value for property 'NonAttributeProperty'. Property requires a value. Path ''.", errors[0]); - Assert.AreEqual("Cannot write a null value for property 'UnsetProperty'. Property requires a value. Path ''.", errors[1]); - Assert.AreEqual("Cannot write a null value for property 'AlwaysProperty'. Property requires a value. Path ''.", errors[2]); - } + Assert.AreEqual(3, errors.Count); + Assert.AreEqual("Cannot write a null value for property 'NonAttributeProperty'. Property requires a value. Path ''.", errors[0]); + Assert.AreEqual("Cannot write a null value for property 'UnsetProperty'. Property requires a value. Path ''.", errors[1]); + Assert.AreEqual("Cannot write a null value for property 'AlwaysProperty'. Property requires a value. Path ''.", errors[2]); + } - [Test] - public void DeserializeCollectionItemConverter() - { - PropertyItemConverter c = new PropertyItemConverter + [Test] + public void DeserializeCollectionItemConverter() { - Data = - new[]{ - "one", - "two", - "three" - } - }; - - var c2 = JsonConvert.DeserializeObject("{'Data':['::ONE::','::TWO::']}"); - - Assert.IsNotNull(c2); - Assert.AreEqual(2, c2.Data.Count); - Assert.AreEqual("one", c2.Data[0]); - Assert.AreEqual("two", c2.Data[1]); - } - - [Test] - public void SerializeCollectionItemConverter() - { - PropertyItemConverter c = new PropertyItemConverter - { - Data = new[] + PropertyItemConverter c = new PropertyItemConverter { - "one", - "two", - "three" - } - }; + Data = + new[] + { + "one", + "two", + "three" + } + }; - string json = JsonConvert.SerializeObject(c); + var c2 = JsonConvert.DeserializeObject("{'Data':['::ONE::','::TWO::']}"); - Assert.AreEqual(@"{""Data"":["":::ONE:::"","":::TWO:::"","":::THREE:::""]}", json); - } + Assert.IsNotNull(c2); + Assert.AreEqual(2, c2.Data.Count); + Assert.AreEqual("one", c2.Data[0]); + Assert.AreEqual("two", c2.Data[1]); + } + + [Test] + public void SerializeCollectionItemConverter() + { + PropertyItemConverter c = new PropertyItemConverter + { + Data = new[] + { + "one", + "two", + "three" + } + }; + + string json = JsonConvert.SerializeObject(c); + + Assert.AreEqual(@"{""Data"":["":::ONE:::"","":::TWO:::"","":::THREE:::""]}", json); + } #if !NET20 - [Test] - public void DateTimeDictionaryKey_DateTimeOffset_Iso() - { - IDictionary dic1 = new Dictionary + [Test] + public void DateTimeDictionaryKey_DateTimeOffset_Iso() { - {new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.Zero), 1}, - {new DateTimeOffset(2013, 12, 12, 12, 12, 12, TimeSpan.Zero), 2} - }; + IDictionary dic1 = new Dictionary + { + { new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.Zero), 1 }, + { new DateTimeOffset(2013, 12, 12, 12, 12, 12, TimeSpan.Zero), 2 } + }; - string json = JsonConvert.SerializeObject(dic1, Formatting.Indented); + string json = JsonConvert.SerializeObject(dic1, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""2000-12-12T12:12:12+00:00"": 1, ""2013-12-12T12:12:12+00:00"": 2 }", json); - IDictionary dic2 = JsonConvert.DeserializeObject>(json); + IDictionary dic2 = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(2, dic2.Count); - Assert.AreEqual(1, dic2[new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.Zero)]); - Assert.AreEqual(2, dic2[new DateTimeOffset(2013, 12, 12, 12, 12, 12, TimeSpan.Zero)]); - } + Assert.AreEqual(2, dic2.Count); + Assert.AreEqual(1, dic2[new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.Zero)]); + Assert.AreEqual(2, dic2[new DateTimeOffset(2013, 12, 12, 12, 12, 12, TimeSpan.Zero)]); + } - [Test] - public void DateTimeDictionaryKey_DateTimeOffset_MS() - { - IDictionary dic1 = new Dictionary + [Test] + public void DateTimeDictionaryKey_DateTimeOffset_MS() { - {new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.Zero), 1}, - {new DateTimeOffset(2013, 12, 12, 12, 12, 12, TimeSpan.Zero), 2} - }; + IDictionary dic1 = new Dictionary + { + { new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.Zero), 1 }, + { new DateTimeOffset(2013, 12, 12, 12, 12, 12, TimeSpan.Zero), 2 } + }; - string json = JsonConvert.SerializeObject(dic1, Formatting.Indented, new JsonSerializerSettings - { - DateFormatHandling = DateFormatHandling.MicrosoftDateFormat - }); + string json = JsonConvert.SerializeObject(dic1, Formatting.Indented, new JsonSerializerSettings + { + DateFormatHandling = DateFormatHandling.MicrosoftDateFormat + }); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""\/Date(976623132000+0000)\/"": 1, ""\/Date(1386850332000+0000)\/"": 2 }", json); - IDictionary dic2 = JsonConvert.DeserializeObject>(json); + IDictionary dic2 = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(2, dic2.Count); - Assert.AreEqual(1, dic2[new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.Zero)]); - Assert.AreEqual(2, dic2[new DateTimeOffset(2013, 12, 12, 12, 12, 12, TimeSpan.Zero)]); - } + Assert.AreEqual(2, dic2.Count); + Assert.AreEqual(1, dic2[new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.Zero)]); + Assert.AreEqual(2, dic2[new DateTimeOffset(2013, 12, 12, 12, 12, 12, TimeSpan.Zero)]); + } #endif - [Test] - public void DateTimeDictionaryKey_DateTime_Iso() - { - IDictionary dic1 = new Dictionary + [Test] + public void DateTimeDictionaryKey_DateTime_Iso() { - {new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc), 1}, - {new DateTime(2013, 12, 12, 12, 12, 12, DateTimeKind.Utc), 2} - }; + IDictionary dic1 = new Dictionary + { + { new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc), 1 }, + { new DateTime(2013, 12, 12, 12, 12, 12, DateTimeKind.Utc), 2 } + }; - string json = JsonConvert.SerializeObject(dic1, Formatting.Indented); + string json = JsonConvert.SerializeObject(dic1, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""2000-12-12T12:12:12Z"": 1, ""2013-12-12T12:12:12Z"": 2 }", json); - IDictionary dic2 = JsonConvert.DeserializeObject>(json); + IDictionary dic2 = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(2, dic2.Count); - Assert.AreEqual(1, dic2[new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc)]); - Assert.AreEqual(2, dic2[new DateTime(2013, 12, 12, 12, 12, 12, DateTimeKind.Utc)]); - } + Assert.AreEqual(2, dic2.Count); + Assert.AreEqual(1, dic2[new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc)]); + Assert.AreEqual(2, dic2[new DateTime(2013, 12, 12, 12, 12, 12, DateTimeKind.Utc)]); + } - [Test] - public void DateTimeDictionaryKey_DateTime_MS() - { - IDictionary dic1 = new Dictionary + [Test] + public void DateTimeDictionaryKey_DateTime_MS() { - {new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc), 1}, - {new DateTime(2013, 12, 12, 12, 12, 12, DateTimeKind.Utc), 2} - }; + IDictionary dic1 = new Dictionary + { + { new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc), 1 }, + { new DateTime(2013, 12, 12, 12, 12, 12, DateTimeKind.Utc), 2 } + }; - string json = JsonConvert.SerializeObject(dic1, Formatting.Indented, new JsonSerializerSettings - { - DateFormatHandling = DateFormatHandling.MicrosoftDateFormat - }); + string json = JsonConvert.SerializeObject(dic1, Formatting.Indented, new JsonSerializerSettings + { + DateFormatHandling = DateFormatHandling.MicrosoftDateFormat + }); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""\/Date(976623132000)\/"": 1, ""\/Date(1386850332000)\/"": 2 }", json); - IDictionary dic2 = JsonConvert.DeserializeObject>(json); + IDictionary dic2 = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(2, dic2.Count); - Assert.AreEqual(1, dic2[new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc)]); - Assert.AreEqual(2, dic2[new DateTime(2013, 12, 12, 12, 12, 12, DateTimeKind.Utc)]); - } + Assert.AreEqual(2, dic2.Count); + Assert.AreEqual(1, dic2[new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc)]); + Assert.AreEqual(2, dic2[new DateTime(2013, 12, 12, 12, 12, 12, DateTimeKind.Utc)]); + } - [Test] - public void DeserializeEmptyJsonString() - { - string s = (string) new JsonSerializer().Deserialize(new JsonTextReader(new StringReader("''"))); - Assert.AreEqual("", s); - } + [Test] + public void DeserializeEmptyJsonString() + { + string s = (string)new JsonSerializer().Deserialize(new JsonTextReader(new StringReader("''"))); + Assert.AreEqual("", s); + } #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - [Test] - public void SerializeAndDeserializeWithAttributes() - { - var testObj = new PersonSerializable() { Name = "John Doe", Age = 28 }; - var objDeserialized = this.SerializeAndDeserialize(testObj); - - Assert.AreEqual(testObj.Name, objDeserialized.Name); - Assert.AreEqual(0, objDeserialized.Age); - } - - private T SerializeAndDeserialize(T obj) - where T : class - { - var json = Serialize(obj); - return Deserialize(json); - } - - private string Serialize(T obj) - where T : class - { - var stringWriter = new StringWriter(); - var serializer = new Newtonsoft.Json.JsonSerializer(); - serializer.ContractResolver = new DefaultContractResolver(false) + [Test] + public void SerializeAndDeserializeWithAttributes() { - IgnoreSerializableAttribute = false - }; - serializer.Serialize(stringWriter, obj); + var testObj = new PersonSerializable() { Name = "John Doe", Age = 28 }; + var objDeserialized = SerializeAndDeserialize(testObj); - return stringWriter.ToString(); - } + Assert.AreEqual(testObj.Name, objDeserialized.Name); + Assert.AreEqual(0, objDeserialized.Age); + } - private T Deserialize(string json) - where T : class - { - var jsonReader = new Newtonsoft.Json.JsonTextReader(new StringReader(json)); - var serializer = new Newtonsoft.Json.JsonSerializer(); - serializer.ContractResolver = new DefaultContractResolver(false) - { - IgnoreSerializableAttribute = false - }; + private T SerializeAndDeserialize(T obj) + where T : class + { + var json = Serialize(obj); + return Deserialize(json); + } - return serializer.Deserialize(jsonReader, typeof(T)) as T; - } + private string Serialize(T obj) + where T : class + { + var stringWriter = new StringWriter(); + var serializer = new Newtonsoft.Json.JsonSerializer(); + serializer.ContractResolver = new DefaultContractResolver(false) + { + IgnoreSerializableAttribute = false + }; + serializer.Serialize(stringWriter, obj); + + return stringWriter.ToString(); + } + + private T Deserialize(string json) + where T : class + { + var jsonReader = new Newtonsoft.Json.JsonTextReader(new StringReader(json)); + var serializer = new Newtonsoft.Json.JsonSerializer(); + serializer.ContractResolver = new DefaultContractResolver(false) + { + IgnoreSerializableAttribute = false + }; + + return serializer.Deserialize(jsonReader, typeof(T)) as T; + } #endif - [Test] - public void PropertyItemConverter() - { - Event e = new Event + [Test] + public void PropertyItemConverter() { - EventName = "Blackadder III", - Venue = "Gryphon Theatre", - Performances = new List + Event e = new Event { - DateTimeUtils.ConvertJavaScriptTicksToDateTime(1336458600000), - DateTimeUtils.ConvertJavaScriptTicksToDateTime(1336545000000), - DateTimeUtils.ConvertJavaScriptTicksToDateTime(1336636800000) - } - }; + EventName = "Blackadder III", + Venue = "Gryphon Theatre", + Performances = new List + { + DateTimeUtils.ConvertJavaScriptTicksToDateTime(1336458600000), + DateTimeUtils.ConvertJavaScriptTicksToDateTime(1336545000000), + DateTimeUtils.ConvertJavaScriptTicksToDateTime(1336636800000) + } + }; - string json = JsonConvert.SerializeObject(e, Formatting.Indented); - //{ - // "EventName": "Blackadder III", - // "Venue": "Gryphon Theatre", - // "Performances": [ - // new Date(1336458600000), - // new Date(1336545000000), - // new Date(1336636800000) - // ] - //} + string json = JsonConvert.SerializeObject(e, Formatting.Indented); + //{ + // "EventName": "Blackadder III", + // "Venue": "Gryphon Theatre", + // "Performances": [ + // new Date(1336458600000), + // new Date(1336545000000), + // new Date(1336636800000) + // ] + //} - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""EventName"": ""Blackadder III"", ""Venue"": ""Gryphon Theatre"", ""Performances"": [ @@ -7640,90 +7596,87 @@ Parameter name: value", ) ] }", json); - } + } #if !(NET20 || NET35) - public class IgnoreDataMemberTestClass - { - [IgnoreDataMember] - public int Ignored { get; set; } - } + public class IgnoreDataMemberTestClass + { + [IgnoreDataMember] + public int Ignored { get; set; } + } - [Test] - public void IgnoreDataMemberTest() - { - string json = JsonConvert.SerializeObject(new IgnoreDataMemberTestClass() { Ignored = int.MaxValue }, Formatting.Indented); - Assert.AreEqual(@"{}", json); - } + [Test] + public void IgnoreDataMemberTest() + { + string json = JsonConvert.SerializeObject(new IgnoreDataMemberTestClass() { Ignored = int.MaxValue }, Formatting.Indented); + Assert.AreEqual(@"{}", json); + } #endif #if !(NET20 || NET35) - [Test] - public void SerializeDataContractSerializationAttributes() - { - DataContractSerializationAttributesClass dataContract = new DataContractSerializationAttributesClass + [Test] + public void SerializeDataContractSerializationAttributes() { - NoAttribute = "Value!", - IgnoreDataMemberAttribute = "Value!", - DataMemberAttribute = "Value!", - IgnoreDataMemberAndDataMemberAttribute = "Value!" - }; + DataContractSerializationAttributesClass dataContract = new DataContractSerializationAttributesClass + { + NoAttribute = "Value!", + IgnoreDataMemberAttribute = "Value!", + DataMemberAttribute = "Value!", + IgnoreDataMemberAndDataMemberAttribute = "Value!" + }; - //MemoryStream ms = new MemoryStream(); - //DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(DataContractSerializationAttributesClass)); - //serializer.WriteObject(ms, dataContract); + //MemoryStream ms = new MemoryStream(); + //DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(DataContractSerializationAttributesClass)); + //serializer.WriteObject(ms, dataContract); - //Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray())); + //Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray())); - string json = JsonConvert.SerializeObject(dataContract, Formatting.Indented); - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(dataContract, Formatting.Indented); + Assert.AreEqual(@"{ ""DataMemberAttribute"": ""Value!"", ""IgnoreDataMemberAndDataMemberAttribute"": ""Value!"" }", json); - PocoDataContractSerializationAttributesClass poco = new PocoDataContractSerializationAttributesClass - { - NoAttribute = "Value!", - IgnoreDataMemberAttribute = "Value!", - DataMemberAttribute = "Value!", - IgnoreDataMemberAndDataMemberAttribute = "Value!" - }; + PocoDataContractSerializationAttributesClass poco = new PocoDataContractSerializationAttributesClass + { + NoAttribute = "Value!", + IgnoreDataMemberAttribute = "Value!", + DataMemberAttribute = "Value!", + IgnoreDataMemberAndDataMemberAttribute = "Value!" + }; - json = JsonConvert.SerializeObject(poco, Formatting.Indented); - Assert.AreEqual(@"{ + json = JsonConvert.SerializeObject(poco, Formatting.Indented); + Assert.AreEqual(@"{ ""NoAttribute"": ""Value!"", ""DataMemberAttribute"": ""Value!"" }", json); - } + } #endif - [Test] - public void CheckAdditionalContent() - { - string json = "{one:1}{}"; + [Test] + public void CheckAdditionalContent() + { + string json = "{one:1}{}"; - JsonSerializerSettings settings = new JsonSerializerSettings(); - JsonSerializer s = JsonSerializer.Create(settings); - IDictionary o = s.Deserialize>(new JsonTextReader(new StringReader(json))); + JsonSerializerSettings settings = new JsonSerializerSettings(); + JsonSerializer s = JsonSerializer.Create(settings); + IDictionary o = s.Deserialize>(new JsonTextReader(new StringReader(json))); - Assert.IsNotNull(o); - Assert.AreEqual(1, o["one"]); + Assert.IsNotNull(o); + Assert.AreEqual(1, o["one"]); - settings.CheckAdditionalContent = true; - s = JsonSerializer.Create(settings); - ExceptionAssert.Throws( - "Additional text encountered after finished reading JSON content: {. Path '', line 1, position 7.", - () => - { - s.Deserialize>(new JsonTextReader(new StringReader(json))); - }); - } + settings.CheckAdditionalContent = true; + s = JsonSerializer.Create(settings); + ExceptionAssert.Throws( + "Additional text encountered after finished reading JSON content: {. Path '', line 1, position 7.", + () => { s.Deserialize>(new JsonTextReader(new StringReader(json))); }); + } #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - [Test] - public void DeserializeException() - { - string json = @"{ ""ClassName"" : ""System.InvalidOperationException"", + [Test] + public void DeserializeException() + { + string json = @"{ ""ClassName"" : ""System.InvalidOperationException"", ""Data"" : null, ""ExceptionMethod"" : ""8\nLogin\nAppBiz, Version=4.0.0.0, Culture=neutral, PublicKeyToken=null\nMyApp.LoginBiz\nMyApp.User Login()"", ""HResult"" : -2146233079, @@ -7749,399 +7702,396 @@ Parameter name: value", ""WatsonBuckets"" : null }"; - InvalidOperationException exception = JsonConvert.DeserializeObject(json); - Assert.IsNotNull(exception); - CustomAssert.IsInstanceOfType(typeof(InvalidOperationException), exception); + InvalidOperationException exception = JsonConvert.DeserializeObject(json); + Assert.IsNotNull(exception); + CustomAssert.IsInstanceOfType(typeof(InvalidOperationException), exception); - Assert.AreEqual("Outter exception...", exception.Message); - } + Assert.AreEqual("Outter exception...", exception.Message); + } #endif - [Test] - public void AdditionalContentAfterFinish() - { - ExceptionAssert.Throws( - "Additional text found in JSON string after finishing deserializing object.", - () => - { - string json = "[{},1]"; + [Test] + public void AdditionalContentAfterFinish() + { + ExceptionAssert.Throws( + "Additional text found in JSON string after finishing deserializing object.", + () => + { + string json = "[{},1]"; - JsonSerializer serializer = new JsonSerializer(); - serializer.CheckAdditionalContent = true; + JsonSerializer serializer = new JsonSerializer(); + serializer.CheckAdditionalContent = true; - var reader = new JsonTextReader(new StringReader(json)); - reader.Read(); - reader.Read(); + var reader = new JsonTextReader(new StringReader(json)); + reader.Read(); + reader.Read(); - serializer.Deserialize(reader, typeof (MyType)); - }); - } + serializer.Deserialize(reader, typeof(MyType)); + }); + } - [Test] - public void DeserializeRelativeUri() - { - IList uris = JsonConvert.DeserializeObject>(@"[""http://localhost/path?query#hash""]"); - Assert.AreEqual(1, uris.Count); - Assert.AreEqual(new Uri("http://localhost/path?query#hash"), uris[0]); + [Test] + public void DeserializeRelativeUri() + { + IList uris = JsonConvert.DeserializeObject>(@"[""http://localhost/path?query#hash""]"); + Assert.AreEqual(1, uris.Count); + Assert.AreEqual(new Uri("http://localhost/path?query#hash"), uris[0]); - Uri uri = JsonConvert.DeserializeObject(@"""http://localhost/path?query#hash"""); - Assert.IsNotNull(uri); + Uri uri = JsonConvert.DeserializeObject(@"""http://localhost/path?query#hash"""); + Assert.IsNotNull(uri); - Uri i1 = new Uri("http://localhost/path?query#hash", UriKind.RelativeOrAbsolute); - Uri i2 = new Uri("http://localhost/path?query#hash"); - Assert.AreEqual(i1, i2); + Uri i1 = new Uri("http://localhost/path?query#hash", UriKind.RelativeOrAbsolute); + Uri i2 = new Uri("http://localhost/path?query#hash"); + Assert.AreEqual(i1, i2); - uri = JsonConvert.DeserializeObject(@"""/path?query#hash"""); - Assert.IsNotNull(uri); - Assert.AreEqual(new Uri("/path?query#hash", UriKind.RelativeOrAbsolute), uri); - } + uri = JsonConvert.DeserializeObject(@"""/path?query#hash"""); + Assert.IsNotNull(uri); + Assert.AreEqual(new Uri("/path?query#hash", UriKind.RelativeOrAbsolute), uri); + } - public class MyConverter : JsonConverter - { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - writer.WriteValue("X"); - } + public class MyConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + writer.WriteValue("X"); + } - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - return "X"; - } + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + return "X"; + } - public override bool CanConvert(Type objectType) - { - return true; - } - } + public override bool CanConvert(Type objectType) + { + return true; + } + } - public class MyType - { - [JsonProperty(ItemConverterType = typeof(MyConverter))] - public Dictionary MyProperty { get; set; } - } + public class MyType + { + [JsonProperty(ItemConverterType = typeof(MyConverter))] + public Dictionary MyProperty { get; set; } + } - [Test] - public void DeserializeDictionaryItemConverter() - { - var actual = JsonConvert.DeserializeObject(@"{ ""MyProperty"":{""Key"":""Y""}}"); - Assert.AreEqual("X", actual.MyProperty["Key"]); - } + [Test] + public void DeserializeDictionaryItemConverter() + { + var actual = JsonConvert.DeserializeObject(@"{ ""MyProperty"":{""Key"":""Y""}}"); + Assert.AreEqual("X", actual.MyProperty["Key"]); + } - [Test] - public void DeserializeCaseInsensitiveKeyValuePairConverter() - { - KeyValuePair result = - JsonConvert.DeserializeObject>( - "{key: 123, \"VALUE\": \"test value\"}" - ); + [Test] + public void DeserializeCaseInsensitiveKeyValuePairConverter() + { + KeyValuePair result = + JsonConvert.DeserializeObject>( + "{key: 123, \"VALUE\": \"test value\"}" + ); - Assert.AreEqual(123, result.Key); - Assert.AreEqual("test value", result.Value); - } + Assert.AreEqual(123, result.Key); + Assert.AreEqual("test value", result.Value); + } - [Test] - public void SerializeKeyValuePairConverterWithCamelCase() - { - string json = - JsonConvert.SerializeObject(new KeyValuePair(123, "test value"), Formatting.Indented, new JsonSerializerSettings - { - ContractResolver = new CamelCasePropertyNamesContractResolver() - }); + [Test] + public void SerializeKeyValuePairConverterWithCamelCase() + { + string json = + JsonConvert.SerializeObject(new KeyValuePair(123, "test value"), Formatting.Indented, new JsonSerializerSettings + { + ContractResolver = new CamelCasePropertyNamesContractResolver() + }); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""key"": 123, ""value"": ""test value"" }", json); - } + } - public class EnumerableClass : IEnumerable - { - private readonly IList _values; - - public EnumerableClass(IEnumerable values) - { - _values = new List(values); - } + public class EnumerableClass : IEnumerable + { + private readonly IList _values; - public IEnumerator GetEnumerator() - { - return _values.GetEnumerator(); - } + public EnumerableClass(IEnumerable values) + { + _values = new List(values); + } - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } + public IEnumerator GetEnumerator() + { + return _values.GetEnumerator(); + } - [Test] - public void DeserializeIEnumerableFromConstructor() - { - string json = @"[ + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } + + [Test] + public void DeserializeIEnumerableFromConstructor() + { + string json = @"[ 1, 2, null ]"; - var result = JsonConvert.DeserializeObject>(json); + var result = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(3, result.Count()); - Assert.AreEqual(1, result.ElementAt(0)); - Assert.AreEqual(2, result.ElementAt(1)); - Assert.AreEqual(null, result.ElementAt(2)); - } + Assert.AreEqual(3, result.Count()); + Assert.AreEqual(1, result.ElementAt(0)); + Assert.AreEqual(2, result.ElementAt(1)); + Assert.AreEqual(null, result.ElementAt(2)); + } - public class EnumerableClassFailure : IEnumerable - { - private readonly IList _values; + public class EnumerableClassFailure : IEnumerable + { + private readonly IList _values; - public EnumerableClassFailure() - { - _values = new List(); - } + public EnumerableClassFailure() + { + _values = new List(); + } - public IEnumerator GetEnumerator() - { - return _values.GetEnumerator(); - } + public IEnumerator GetEnumerator() + { + return _values.GetEnumerator(); + } - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } - [Test] - public void DeserializeIEnumerableFromConstructor_Failure() - { - string json = @"[ + [Test] + public void DeserializeIEnumerableFromConstructor_Failure() + { + string json = @"[ ""One"", ""II"", ""3"" ]"; - ExceptionAssert.Throws( - "Cannot create and populate list type Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+EnumerableClassFailure`1[System.String]. Path '', line 1, position 1.", - () => JsonConvert.DeserializeObject>(json)); - } + ExceptionAssert.Throws( + "Cannot create and populate list type Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+EnumerableClassFailure`1[System.String]. Path '', line 1, position 1.", + () => JsonConvert.DeserializeObject>(json)); + } - [JsonObject(MemberSerialization.Fields)] - public class MyTuple - { - private readonly T1 m_Item1; + [JsonObject(MemberSerialization.Fields)] + public class MyTuple + { + private readonly T1 m_Item1; - public MyTuple(T1 item1) - { - m_Item1 = item1; - } + public MyTuple(T1 item1) + { + m_Item1 = item1; + } - public T1 Item1 - { - get { return m_Item1; } - } - } + public T1 Item1 + { + get { return m_Item1; } + } + } - [JsonObject(MemberSerialization.Fields)] - public class MyTuplePartial - { - private readonly T1 m_Item1; + [JsonObject(MemberSerialization.Fields)] + public class MyTuplePartial + { + private readonly T1 m_Item1; - public MyTuplePartial(T1 item1) - { - m_Item1 = item1; - } + public MyTuplePartial(T1 item1) + { + m_Item1 = item1; + } - public T1 Item1 - { - get { return m_Item1; } - } - } + public T1 Item1 + { + get { return m_Item1; } + } + } - [Test] - public void SerializeFloatingPointHandling() - { - string json; - IList d = new List {1.1, double.NaN, double.PositiveInfinity}; + [Test] + public void SerializeFloatingPointHandling() + { + string json; + IList d = new List { 1.1, double.NaN, double.PositiveInfinity }; - json = JsonConvert.SerializeObject(d); - // [1.1,"NaN","Infinity"] + json = JsonConvert.SerializeObject(d); + // [1.1,"NaN","Infinity"] - json = JsonConvert.SerializeObject(d, new JsonSerializerSettings { FloatFormatHandling = FloatFormatHandling.Symbol }); - // [1.1,NaN,Infinity] + json = JsonConvert.SerializeObject(d, new JsonSerializerSettings { FloatFormatHandling = FloatFormatHandling.Symbol }); + // [1.1,NaN,Infinity] - json = JsonConvert.SerializeObject(d, new JsonSerializerSettings {FloatFormatHandling = FloatFormatHandling.DefaultValue}); - // [1.1,0.0,0.0] + json = JsonConvert.SerializeObject(d, new JsonSerializerSettings { FloatFormatHandling = FloatFormatHandling.DefaultValue }); + // [1.1,0.0,0.0] - Assert.AreEqual("[1.1,0.0,0.0]", json); - } + Assert.AreEqual("[1.1,0.0,0.0]", json); + } #if !(NET20 || NET35 || NET40 || SILVERLIGHT || PORTABLE40) #if !PORTABLE - [Test] - public void DeserializeReadOnlyListWithBigInteger() - { - string json = @"[ + [Test] + public void DeserializeReadOnlyListWithBigInteger() + { + string json = @"[ 9000000000000000000000000000000000000000000000000 ]"; - var l = JsonConvert.DeserializeObject>(json); + var l = JsonConvert.DeserializeObject>(json); - BigInteger nineQuindecillion = l[0]; - // 9000000000000000000000000000000000000000000000000 + BigInteger nineQuindecillion = l[0]; + // 9000000000000000000000000000000000000000000000000 - Assert.AreEqual(BigInteger.Parse("9000000000000000000000000000000000000000000000000"), nineQuindecillion); - } + Assert.AreEqual(BigInteger.Parse("9000000000000000000000000000000000000000000000000"), nineQuindecillion); + } #endif - [Test] - public void DeserializeReadOnlyListWithInt() - { - string json = @"[ + [Test] + public void DeserializeReadOnlyListWithInt() + { + string json = @"[ 900 ]"; - var l = JsonConvert.DeserializeObject>(json); + var l = JsonConvert.DeserializeObject>(json); - int i = l[0]; - // 900 + int i = l[0]; + // 900 - Assert.AreEqual(900, i); - } + Assert.AreEqual(900, i); + } - [Test] - public void DeserializeReadOnlyListWithNullableType() - { - string json = @"[ + [Test] + public void DeserializeReadOnlyListWithNullableType() + { + string json = @"[ 1, null ]"; - var l = JsonConvert.DeserializeObject>(json); + var l = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(1, l[0]); - Assert.AreEqual(null, l[1]); - } + Assert.AreEqual(1, l[0]); + Assert.AreEqual(null, l[1]); + } #endif - [Test] - public void SerializeCustomTupleWithSerializableAttribute() - { - var tuple = new MyTuple(500); - var json = JsonConvert.SerializeObject(tuple); - Assert.AreEqual(@"{""m_Item1"":500}", json); + [Test] + public void SerializeCustomTupleWithSerializableAttribute() + { + var tuple = new MyTuple(500); + var json = JsonConvert.SerializeObject(tuple); + Assert.AreEqual(@"{""m_Item1"":500}", json); - MyTuple obj = null; + MyTuple obj = null; - Action doStuff = () => - { - obj = JsonConvert.DeserializeObject>(json); - }; + Action doStuff = () => { obj = JsonConvert.DeserializeObject>(json); }; #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - doStuff(); - Assert.AreEqual(500, obj.Item1); + doStuff(); + Assert.AreEqual(500, obj.Item1); #else - ExceptionAssert.Throws( - "Unable to find a constructor to use for type Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+MyTuple`1[System.Int32]. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'm_Item1', line 1, position 11.", - doStuff); + ExceptionAssert.Throws( + "Unable to find a constructor to use for type Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+MyTuple`1[System.Int32]. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'm_Item1', line 1, position 11.", + doStuff); #endif - } + } #if DEBUG - [Test] - public void SerializeCustomTupleWithSerializableAttributeInPartialTrust() - { - try - { - JsonTypeReflector.SetFullyTrusted(false); + [Test] + public void SerializeCustomTupleWithSerializableAttributeInPartialTrust() + { + try + { + JsonTypeReflector.SetFullyTrusted(false); - var tuple = new MyTuplePartial(500); - var json = JsonConvert.SerializeObject(tuple); - Assert.AreEqual(@"{""m_Item1"":500}", json); + var tuple = new MyTuplePartial(500); + var json = JsonConvert.SerializeObject(tuple); + Assert.AreEqual(@"{""m_Item1"":500}", json); - ExceptionAssert.Throws( - "Unable to find a constructor to use for type Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+MyTuplePartial`1[System.Int32]. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'm_Item1', line 1, position 11.", - () => JsonConvert.DeserializeObject>(json)); - } - finally - { - JsonTypeReflector.SetFullyTrusted(true); - } - } + ExceptionAssert.Throws( + "Unable to find a constructor to use for type Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+MyTuplePartial`1[System.Int32]. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'm_Item1', line 1, position 11.", + () => JsonConvert.DeserializeObject>(json)); + } + finally + { + JsonTypeReflector.SetFullyTrusted(true); + } + } #endif #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || NET35 || NET20 || PORTABLE40) - [Test] - public void SerializeTupleWithSerializableAttribute() - { - var tuple = Tuple.Create(500); - var json = JsonConvert.SerializeObject(tuple, new JsonSerializerSettings - { - ContractResolver = new SerializableContractResolver() - }); - Assert.AreEqual(@"{""m_Item1"":500}", json); + [Test] + public void SerializeTupleWithSerializableAttribute() + { + var tuple = Tuple.Create(500); + var json = JsonConvert.SerializeObject(tuple, new JsonSerializerSettings + { + ContractResolver = new SerializableContractResolver() + }); + Assert.AreEqual(@"{""m_Item1"":500}", json); - var obj = JsonConvert.DeserializeObject>(json, new JsonSerializerSettings - { - ContractResolver = new SerializableContractResolver() - }); - Assert.AreEqual(500, obj.Item1); - } + var obj = JsonConvert.DeserializeObject>(json, new JsonSerializerSettings + { + ContractResolver = new SerializableContractResolver() + }); + Assert.AreEqual(500, obj.Item1); + } - public class SerializableContractResolver : DefaultContractResolver - { - public SerializableContractResolver() - { - IgnoreSerializableAttribute = false; - } - } + public class SerializableContractResolver : DefaultContractResolver + { + public SerializableContractResolver() + { + IgnoreSerializableAttribute = false; + } + } #endif #if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - public class PopulateReadOnlyTestClass - { - public IList NonReadOnlyList { get; set; } - public IDictionary NonReadOnlyDictionary { get; set; } + public class PopulateReadOnlyTestClass + { + public IList NonReadOnlyList { get; set; } + public IDictionary NonReadOnlyDictionary { get; set; } - public IList Array { get; set; } + public IList Array { get; set; } - public IList List { get; set; } - public IDictionary Dictionary { get; set; } + public IList List { get; set; } + public IDictionary Dictionary { get; set; } - public IReadOnlyCollection IReadOnlyCollection { get; set; } - public ReadOnlyCollection ReadOnlyCollection { get; set; } - public IReadOnlyList IReadOnlyList { get; set; } + public IReadOnlyCollection IReadOnlyCollection { get; set; } + public ReadOnlyCollection ReadOnlyCollection { get; set; } + public IReadOnlyList IReadOnlyList { get; set; } - public IReadOnlyDictionary IReadOnlyDictionary { get; set; } - public ReadOnlyDictionary ReadOnlyDictionary { get; set; } + public IReadOnlyDictionary IReadOnlyDictionary { get; set; } + public ReadOnlyDictionary ReadOnlyDictionary { get; set; } - public PopulateReadOnlyTestClass() - { - NonReadOnlyList = new List { 1 }; - NonReadOnlyDictionary = new Dictionary { { "first", 2 } }; + public PopulateReadOnlyTestClass() + { + NonReadOnlyList = new List { 1 }; + NonReadOnlyDictionary = new Dictionary { { "first", 2 } }; - Array = new[] {3}; + Array = new[] { 3 }; - List = new ReadOnlyCollection(new[] { 4 }); - Dictionary = new ReadOnlyDictionary(new Dictionary { { "first", 5 } }); + List = new ReadOnlyCollection(new[] { 4 }); + Dictionary = new ReadOnlyDictionary(new Dictionary { { "first", 5 } }); - IReadOnlyCollection = new ReadOnlyCollection(new[] { 6 }); - ReadOnlyCollection = new ReadOnlyCollection(new[] { 7 }); - IReadOnlyList = new ReadOnlyCollection(new[] { 8 }); + IReadOnlyCollection = new ReadOnlyCollection(new[] { 6 }); + ReadOnlyCollection = new ReadOnlyCollection(new[] { 7 }); + IReadOnlyList = new ReadOnlyCollection(new[] { 8 }); - IReadOnlyDictionary = new ReadOnlyDictionary(new Dictionary { { "first", 9 } }); - ReadOnlyDictionary = new ReadOnlyDictionary(new Dictionary { { "first", 10 } }); - } - } + IReadOnlyDictionary = new ReadOnlyDictionary(new Dictionary { { "first", 9 } }); + ReadOnlyDictionary = new ReadOnlyDictionary(new Dictionary { { "first", 10 } }); + } + } - [Test] - public void SerializeReadOnlyCollections() - { - PopulateReadOnlyTestClass c1 = new PopulateReadOnlyTestClass(); + [Test] + public void SerializeReadOnlyCollections() + { + PopulateReadOnlyTestClass c1 = new PopulateReadOnlyTestClass(); - string json = JsonConvert.SerializeObject(c1, Formatting.Indented); + string json = JsonConvert.SerializeObject(c1, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""NonReadOnlyList"": [ 1 ], @@ -8173,12 +8123,12 @@ Parameter name: value", ""first"": 10 } }", json); - } + } - [Test] - public void PopulateReadOnlyCollections() - { - string json = @"{ + [Test] + public void PopulateReadOnlyCollections() + { + string json = @"{ ""NonReadOnlyList"": [ 11 ], @@ -8211,57 +8161,57 @@ Parameter name: value", } }"; - var c2 = JsonConvert.DeserializeObject(json); + var c2 = JsonConvert.DeserializeObject(json); - Assert.AreEqual(1, c2.NonReadOnlyDictionary.Count); - Assert.AreEqual(12, c2.NonReadOnlyDictionary["first"]); + Assert.AreEqual(1, c2.NonReadOnlyDictionary.Count); + Assert.AreEqual(12, c2.NonReadOnlyDictionary["first"]); - Assert.AreEqual(2, c2.NonReadOnlyList.Count); - Assert.AreEqual(1, c2.NonReadOnlyList[0]); - Assert.AreEqual(11, c2.NonReadOnlyList[1]); + Assert.AreEqual(2, c2.NonReadOnlyList.Count); + Assert.AreEqual(1, c2.NonReadOnlyList[0]); + Assert.AreEqual(11, c2.NonReadOnlyList[1]); - Assert.AreEqual(1, c2.Array.Count); - Assert.AreEqual(13, c2.Array[0]); - } + Assert.AreEqual(1, c2.Array.Count); + Assert.AreEqual(13, c2.Array[0]); + } #endif - [Test] - public void SerializeArray2D() - { - Array2D aa = new Array2D(); - aa.Before = "Before!"; - aa.After = "After!"; - aa.Coordinates = new[,] { { 1, 1 }, { 1, 2 }, { 2, 1 }, { 2, 2 } }; + [Test] + public void SerializeArray2D() + { + Array2D aa = new Array2D(); + aa.Before = "Before!"; + aa.After = "After!"; + aa.Coordinates = new[,] { { 1, 1 }, { 1, 2 }, { 2, 1 }, { 2, 2 } }; - string json = JsonConvert.SerializeObject(aa); + string json = JsonConvert.SerializeObject(aa); - Assert.AreEqual(@"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2],[2,1],[2,2]],""After"":""After!""}", json); - } + Assert.AreEqual(@"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2],[2,1],[2,2]],""After"":""After!""}", json); + } - [Test] - public void SerializeArray3D() - { - Array3D aa = new Array3D(); - aa.Before = "Before!"; - aa.After = "After!"; - aa.Coordinates = new[, ,] { { { 1, 1, 1 }, { 1, 1, 2 } }, { { 1, 2, 1 }, { 1, 2, 2 } }, { { 2, 1, 1 }, { 2, 1, 2 } }, { { 2, 2, 1 }, { 2, 2, 2 } } }; + [Test] + public void SerializeArray3D() + { + Array3D aa = new Array3D(); + aa.Before = "Before!"; + aa.After = "After!"; + aa.Coordinates = new[,,] { { { 1, 1, 1 }, { 1, 1, 2 } }, { { 1, 2, 1 }, { 1, 2, 2 } }, { { 2, 1, 1 }, { 2, 1, 2 } }, { { 2, 2, 1 }, { 2, 2, 2 } } }; - string json = JsonConvert.SerializeObject(aa); + string json = JsonConvert.SerializeObject(aa); - Assert.AreEqual(@"{""Before"":""Before!"",""Coordinates"":[[[1,1,1],[1,1,2]],[[1,2,1],[1,2,2]],[[2,1,1],[2,1,2]],[[2,2,1],[2,2,2]]],""After"":""After!""}", json); - } + Assert.AreEqual(@"{""Before"":""Before!"",""Coordinates"":[[[1,1,1],[1,1,2]],[[1,2,1],[1,2,2]],[[2,1,1],[2,1,2]],[[2,2,1],[2,2,2]]],""After"":""After!""}", json); + } - [Test] - public void SerializeArray3DWithConverter() - { - Array3DWithConverter aa = new Array3DWithConverter(); - aa.Before = "Before!"; - aa.After = "After!"; - aa.Coordinates = new[, ,] { { { 1, 1, 1 }, { 1, 1, 2 } }, { { 1, 2, 1 }, { 1, 2, 2 } }, { { 2, 1, 1 }, { 2, 1, 2 } }, { { 2, 2, 1 }, { 2, 2, 2 } } }; + [Test] + public void SerializeArray3DWithConverter() + { + Array3DWithConverter aa = new Array3DWithConverter(); + aa.Before = "Before!"; + aa.After = "After!"; + aa.Coordinates = new[,,] { { { 1, 1, 1 }, { 1, 1, 2 } }, { { 1, 2, 1 }, { 1, 2, 2 } }, { { 2, 1, 1 }, { 2, 1, 2 } }, { { 2, 2, 1 }, { 2, 2, 2 } } }; - string json = JsonConvert.SerializeObject(aa, Formatting.Indented); + string json = JsonConvert.SerializeObject(aa, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Before"": ""Before!"", ""Coordinates"": [ [ @@ -8315,12 +8265,12 @@ Parameter name: value", ], ""After"": ""After!"" }", json); - } + } - [Test] - public void DeserializeArray3DWithConverter() - { - string json = @"{ + [Test] + public void DeserializeArray3DWithConverter() + { + string json = @"{ ""Before"": ""Before!"", ""Coordinates"": [ [ @@ -8375,212 +8325,212 @@ Parameter name: value", ""After"": ""After!"" }"; - Array3DWithConverter aa = JsonConvert.DeserializeObject(json); + Array3DWithConverter aa = JsonConvert.DeserializeObject(json); - Assert.AreEqual("Before!", aa.Before); - Assert.AreEqual("After!", aa.After); - Assert.AreEqual(4, aa.Coordinates.GetLength(0)); - Assert.AreEqual(2, aa.Coordinates.GetLength(1)); - Assert.AreEqual(3, aa.Coordinates.GetLength(2)); - Assert.AreEqual(1, aa.Coordinates[0, 0, 0]); - Assert.AreEqual(2, aa.Coordinates[1, 1, 1]); - } + Assert.AreEqual("Before!", aa.Before); + Assert.AreEqual("After!", aa.After); + Assert.AreEqual(4, aa.Coordinates.GetLength(0)); + Assert.AreEqual(2, aa.Coordinates.GetLength(1)); + Assert.AreEqual(3, aa.Coordinates.GetLength(2)); + Assert.AreEqual(1, aa.Coordinates[0, 0, 0]); + Assert.AreEqual(2, aa.Coordinates[1, 1, 1]); + } - [Test] - public void DeserializeArray2D() - { - string json = @"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2],[2,1],[2,2]],""After"":""After!""}"; - - Array2D aa = JsonConvert.DeserializeObject(json); - - Assert.AreEqual("Before!", aa.Before); - Assert.AreEqual("After!", aa.After); - Assert.AreEqual(4, aa.Coordinates.GetLength(0)); - Assert.AreEqual(2, aa.Coordinates.GetLength(1)); - Assert.AreEqual(1, aa.Coordinates[0, 0]); - Assert.AreEqual(2, aa.Coordinates[1, 1]); - - string after = JsonConvert.SerializeObject(aa); - - Assert.AreEqual(json, after); - } - - [Test] - public void DeserializeArray2D_WithTooManyItems() - { - string json = @"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2,3],[2,1],[2,2]],""After"":""After!""}"; - - ExceptionAssert.Throws( - "Cannot deserialize non-cubical array as multidimensional array.", - () => JsonConvert.DeserializeObject(json)); - } - - [Test] - public void DeserializeArray2D_WithTooFewItems() - { - string json = @"{""Before"":""Before!"",""Coordinates"":[[1,1],[1],[2,1],[2,2]],""After"":""After!""}"; - - ExceptionAssert.Throws( - "Cannot deserialize non-cubical array as multidimensional array.", - () => JsonConvert.DeserializeObject(json)); - } - - [Test] - public void DeserializeArray3D() - { - string json = @"{""Before"":""Before!"",""Coordinates"":[[[1,1,1],[1,1,2]],[[1,2,1],[1,2,2]],[[2,1,1],[2,1,2]],[[2,2,1],[2,2,2]]],""After"":""After!""}"; - - Array3D aa = JsonConvert.DeserializeObject(json); - - Assert.AreEqual("Before!", aa.Before); - Assert.AreEqual("After!", aa.After); - Assert.AreEqual(4, aa.Coordinates.GetLength(0)); - Assert.AreEqual(2, aa.Coordinates.GetLength(1)); - Assert.AreEqual(3, aa.Coordinates.GetLength(2)); - Assert.AreEqual(1, aa.Coordinates[0, 0, 0]); - Assert.AreEqual(2, aa.Coordinates[1, 1, 1]); - - string after = JsonConvert.SerializeObject(aa); - - Assert.AreEqual(json, after); - } - - [Test] - public void DeserializeArray3D_WithTooManyItems() - { - string json = @"{""Before"":""Before!"",""Coordinates"":[[[1,1,1],[1,1,2,1]],[[1,2,1],[1,2,2]],[[2,1,1],[2,1,2]],[[2,2,1],[2,2,2]]],""After"":""After!""}"; - - ExceptionAssert.Throws( - "Cannot deserialize non-cubical array as multidimensional array.", - () => JsonConvert.DeserializeObject(json)); - } - - [Test] - public void DeserializeArray3D_WithBadItems() - { - string json = @"{""Before"":""Before!"",""Coordinates"":[[[1,1,1],[1,1,2]],[[1,2,1],[1,2,2]],[[2,1,1],[2,1,2]],[[2,2,1],{}]],""After"":""After!""}"; - - ExceptionAssert.Throws( - "Unexpected token when deserializing multidimensional array: StartObject. Path 'Coordinates[3][1]', line 1, position 99.", - () => JsonConvert.DeserializeObject(json)); - } - - [Test] - public void DeserializeArray3D_WithTooFewItems() - { - string json = @"{""Before"":""Before!"",""Coordinates"":[[[1,1,1],[1,1]],[[1,2,1],[1,2,2]],[[2,1,1],[2,1,2]],[[2,2,1],[2,2,2]]],""After"":""After!""}"; - - ExceptionAssert.Throws( - "Cannot deserialize non-cubical array as multidimensional array.", - () => JsonConvert.DeserializeObject(json)); - } - - [Test] - public void SerializeEmpty3DArray() - { - Array3D aa = new Array3D(); - aa.Before = "Before!"; - aa.After = "After!"; - aa.Coordinates = new int[0, 0, 0]; - - string json = JsonConvert.SerializeObject(aa); - - Assert.AreEqual(@"{""Before"":""Before!"",""Coordinates"":[],""After"":""After!""}", json); - } - - [Test] - public void DeserializeEmpty3DArray() - { - string json = @"{""Before"":""Before!"",""Coordinates"":[],""After"":""After!""}"; - - Array3D aa = JsonConvert.DeserializeObject(json); - - Assert.AreEqual("Before!", aa.Before); - Assert.AreEqual("After!", aa.After); - Assert.AreEqual(0, aa.Coordinates.GetLength(0)); - Assert.AreEqual(0, aa.Coordinates.GetLength(1)); - Assert.AreEqual(0, aa.Coordinates.GetLength(2)); - - string after = JsonConvert.SerializeObject(aa); - - Assert.AreEqual(json, after); - } - - [Test] - public void DeserializeIncomplete3DArray() - { - string json = @"{""Before"":""Before!"",""Coordinates"":[/*hi*/[/*hi*/[1/*hi*/,/*hi*/1/*hi*/,1]/*hi*/,/*hi*/[1,1"; - - ExceptionAssert.Throws( - "Unexpected end when deserializing array. Path 'Coordinates[0][1][1]', line 1, position 90.", - () => JsonConvert.DeserializeObject(json)); - } - - [Test] - public void DeserializeIncompleteNotTopLevel3DArray() - { - string json = @"{""Before"":""Before!"",""Coordinates"":[/*hi*/[/*hi*/"; - - ExceptionAssert.Throws( - "Unexpected end when deserializing array. Path 'Coordinates[0]', line 1, position 48.", - () => JsonConvert.DeserializeObject(json)); - } - - [Test] - public void DeserializeNull3DArray() - { - string json = @"{""Before"":""Before!"",""Coordinates"":null,""After"":""After!""}"; - - Array3D aa = JsonConvert.DeserializeObject(json); - - Assert.AreEqual("Before!", aa.Before); - Assert.AreEqual("After!", aa.After); - Assert.AreEqual(null, aa.Coordinates); - - string after = JsonConvert.SerializeObject(aa); - - Assert.AreEqual(json, after); - } - - [Test] - public void DeserializeSemiEmpty3DArray() - { - string json = @"{""Before"":""Before!"",""Coordinates"":[[]],""After"":""After!""}"; - - Array3D aa = JsonConvert.DeserializeObject(json); - - Assert.AreEqual("Before!", aa.Before); - Assert.AreEqual("After!", aa.After); - Assert.AreEqual(1, aa.Coordinates.GetLength(0)); - Assert.AreEqual(0, aa.Coordinates.GetLength(1)); - Assert.AreEqual(0, aa.Coordinates.GetLength(2)); - - string after = JsonConvert.SerializeObject(aa); - - Assert.AreEqual(json, after); - } - - [Test] - public void SerializeReferenceTracked3DArray() - { - Event e1 = new Event + [Test] + public void DeserializeArray2D() { - EventName = "EventName!" - }; - Event[,] array1 = new [,] { { e1, e1 }, { e1, e1 } }; - IList values1 = new List - { - array1, - array1 - }; + string json = @"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2],[2,1],[2,2]],""After"":""After!""}"; - string json = JsonConvert.SerializeObject(values1, new JsonSerializerSettings - { - PreserveReferencesHandling = PreserveReferencesHandling.All, - Formatting = Formatting.Indented - }); + Array2D aa = JsonConvert.DeserializeObject(json); - Assert.AreEqual(@"{ + Assert.AreEqual("Before!", aa.Before); + Assert.AreEqual("After!", aa.After); + Assert.AreEqual(4, aa.Coordinates.GetLength(0)); + Assert.AreEqual(2, aa.Coordinates.GetLength(1)); + Assert.AreEqual(1, aa.Coordinates[0, 0]); + Assert.AreEqual(2, aa.Coordinates[1, 1]); + + string after = JsonConvert.SerializeObject(aa); + + Assert.AreEqual(json, after); + } + + [Test] + public void DeserializeArray2D_WithTooManyItems() + { + string json = @"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2,3],[2,1],[2,2]],""After"":""After!""}"; + + ExceptionAssert.Throws( + "Cannot deserialize non-cubical array as multidimensional array.", + () => JsonConvert.DeserializeObject(json)); + } + + [Test] + public void DeserializeArray2D_WithTooFewItems() + { + string json = @"{""Before"":""Before!"",""Coordinates"":[[1,1],[1],[2,1],[2,2]],""After"":""After!""}"; + + ExceptionAssert.Throws( + "Cannot deserialize non-cubical array as multidimensional array.", + () => JsonConvert.DeserializeObject(json)); + } + + [Test] + public void DeserializeArray3D() + { + string json = @"{""Before"":""Before!"",""Coordinates"":[[[1,1,1],[1,1,2]],[[1,2,1],[1,2,2]],[[2,1,1],[2,1,2]],[[2,2,1],[2,2,2]]],""After"":""After!""}"; + + Array3D aa = JsonConvert.DeserializeObject(json); + + Assert.AreEqual("Before!", aa.Before); + Assert.AreEqual("After!", aa.After); + Assert.AreEqual(4, aa.Coordinates.GetLength(0)); + Assert.AreEqual(2, aa.Coordinates.GetLength(1)); + Assert.AreEqual(3, aa.Coordinates.GetLength(2)); + Assert.AreEqual(1, aa.Coordinates[0, 0, 0]); + Assert.AreEqual(2, aa.Coordinates[1, 1, 1]); + + string after = JsonConvert.SerializeObject(aa); + + Assert.AreEqual(json, after); + } + + [Test] + public void DeserializeArray3D_WithTooManyItems() + { + string json = @"{""Before"":""Before!"",""Coordinates"":[[[1,1,1],[1,1,2,1]],[[1,2,1],[1,2,2]],[[2,1,1],[2,1,2]],[[2,2,1],[2,2,2]]],""After"":""After!""}"; + + ExceptionAssert.Throws( + "Cannot deserialize non-cubical array as multidimensional array.", + () => JsonConvert.DeserializeObject(json)); + } + + [Test] + public void DeserializeArray3D_WithBadItems() + { + string json = @"{""Before"":""Before!"",""Coordinates"":[[[1,1,1],[1,1,2]],[[1,2,1],[1,2,2]],[[2,1,1],[2,1,2]],[[2,2,1],{}]],""After"":""After!""}"; + + ExceptionAssert.Throws( + "Unexpected token when deserializing multidimensional array: StartObject. Path 'Coordinates[3][1]', line 1, position 99.", + () => JsonConvert.DeserializeObject(json)); + } + + [Test] + public void DeserializeArray3D_WithTooFewItems() + { + string json = @"{""Before"":""Before!"",""Coordinates"":[[[1,1,1],[1,1]],[[1,2,1],[1,2,2]],[[2,1,1],[2,1,2]],[[2,2,1],[2,2,2]]],""After"":""After!""}"; + + ExceptionAssert.Throws( + "Cannot deserialize non-cubical array as multidimensional array.", + () => JsonConvert.DeserializeObject(json)); + } + + [Test] + public void SerializeEmpty3DArray() + { + Array3D aa = new Array3D(); + aa.Before = "Before!"; + aa.After = "After!"; + aa.Coordinates = new int[0, 0, 0]; + + string json = JsonConvert.SerializeObject(aa); + + Assert.AreEqual(@"{""Before"":""Before!"",""Coordinates"":[],""After"":""After!""}", json); + } + + [Test] + public void DeserializeEmpty3DArray() + { + string json = @"{""Before"":""Before!"",""Coordinates"":[],""After"":""After!""}"; + + Array3D aa = JsonConvert.DeserializeObject(json); + + Assert.AreEqual("Before!", aa.Before); + Assert.AreEqual("After!", aa.After); + Assert.AreEqual(0, aa.Coordinates.GetLength(0)); + Assert.AreEqual(0, aa.Coordinates.GetLength(1)); + Assert.AreEqual(0, aa.Coordinates.GetLength(2)); + + string after = JsonConvert.SerializeObject(aa); + + Assert.AreEqual(json, after); + } + + [Test] + public void DeserializeIncomplete3DArray() + { + string json = @"{""Before"":""Before!"",""Coordinates"":[/*hi*/[/*hi*/[1/*hi*/,/*hi*/1/*hi*/,1]/*hi*/,/*hi*/[1,1"; + + ExceptionAssert.Throws( + "Unexpected end when deserializing array. Path 'Coordinates[0][1][1]', line 1, position 90.", + () => JsonConvert.DeserializeObject(json)); + } + + [Test] + public void DeserializeIncompleteNotTopLevel3DArray() + { + string json = @"{""Before"":""Before!"",""Coordinates"":[/*hi*/[/*hi*/"; + + ExceptionAssert.Throws( + "Unexpected end when deserializing array. Path 'Coordinates[0]', line 1, position 48.", + () => JsonConvert.DeserializeObject(json)); + } + + [Test] + public void DeserializeNull3DArray() + { + string json = @"{""Before"":""Before!"",""Coordinates"":null,""After"":""After!""}"; + + Array3D aa = JsonConvert.DeserializeObject(json); + + Assert.AreEqual("Before!", aa.Before); + Assert.AreEqual("After!", aa.After); + Assert.AreEqual(null, aa.Coordinates); + + string after = JsonConvert.SerializeObject(aa); + + Assert.AreEqual(json, after); + } + + [Test] + public void DeserializeSemiEmpty3DArray() + { + string json = @"{""Before"":""Before!"",""Coordinates"":[[]],""After"":""After!""}"; + + Array3D aa = JsonConvert.DeserializeObject(json); + + Assert.AreEqual("Before!", aa.Before); + Assert.AreEqual("After!", aa.After); + Assert.AreEqual(1, aa.Coordinates.GetLength(0)); + Assert.AreEqual(0, aa.Coordinates.GetLength(1)); + Assert.AreEqual(0, aa.Coordinates.GetLength(2)); + + string after = JsonConvert.SerializeObject(aa); + + Assert.AreEqual(json, after); + } + + [Test] + public void SerializeReferenceTracked3DArray() + { + Event e1 = new Event + { + EventName = "EventName!" + }; + Event[,] array1 = new[,] { { e1, e1 }, { e1, e1 } }; + IList values1 = new List + { + array1, + array1 + }; + + string json = JsonConvert.SerializeObject(values1, new JsonSerializerSettings + { + PreserveReferencesHandling = PreserveReferencesHandling.All, + Formatting = Formatting.Indented + }); + + Assert.AreEqual(@"{ ""$id"": ""1"", ""$values"": [ { @@ -8612,29 +8562,29 @@ Parameter name: value", } ] }", json); - } + } - [Test] - public void SerializeTypeName3DArray() - { - Event e1 = new Event - { - EventName = "EventName!" - }; - Event[,] array1 = new[,] { { e1, e1 }, { e1, e1 } }; - IList values1 = new List + [Test] + public void SerializeTypeName3DArray() { - array1, - array1 - }; + Event e1 = new Event + { + EventName = "EventName!" + }; + Event[,] array1 = new[,] { { e1, e1 }, { e1, e1 } }; + IList values1 = new List + { + array1, + array1 + }; - string json = JsonConvert.SerializeObject(values1, new JsonSerializerSettings - { - TypeNameHandling = TypeNameHandling.All, - Formatting = Formatting.Indented - }); + string json = JsonConvert.SerializeObject(values1, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.All, + Formatting = Formatting.Indented + }); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""$type"": ""System.Collections.Generic.List`1[[Newtonsoft.Json.Tests.Serialization.Event[,], Newtonsoft.Json.Tests]], mscorlib"", ""$values"": [ { @@ -8706,14 +8656,14 @@ Parameter name: value", ] }", json); - IList values2 = (IList)JsonConvert.DeserializeObject(json, new JsonSerializerSettings - { - TypeNameHandling = TypeNameHandling.All - }); + IList values2 = (IList)JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.All + }); - Assert.AreEqual(2, values2.Count); - Assert.AreEqual("EventName!", values2[0][0, 0].EventName); - } + Assert.AreEqual(2, values2.Count); + Assert.AreEqual("EventName!", values2[0][0, 0].EventName); + } #if NETFX_CORE [Test] @@ -8739,49 +8689,49 @@ Parameter name: value", #endif #if !NET20 - [Test] - public void RoundtripOfDateTimeOffset() - { - var content = @"{""startDateTime"":""2012-07-19T14:30:00+09:30""}"; - - var jsonSerializerSettings = new JsonSerializerSettings() {DateFormatHandling = DateFormatHandling.IsoDateFormat, DateParseHandling = DateParseHandling.DateTimeOffset, DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind}; - - var obj = (JObject)JsonConvert.DeserializeObject(content, jsonSerializerSettings); - - var dateTimeOffset = (DateTimeOffset)((JValue) obj["startDateTime"]).Value; - - Assert.AreEqual(TimeSpan.FromHours(9.5), dateTimeOffset.Offset); - Assert.AreEqual("07/19/2012 14:30:00 +09:30", dateTimeOffset.ToString(CultureInfo.InvariantCulture)); - } - - public class NullableFloats - { - public object Object { get; set; } - public float Float { get; set; } - public double Double { get; set; } - public float? NullableFloat { get; set; } - public double? NullableDouble { get; set; } - public object ObjectNull { get; set; } - } - - [Test] - public void NullableFloatingPoint() - { - NullableFloats floats = new NullableFloats + [Test] + public void RoundtripOfDateTimeOffset() { - Object = double.NaN, - ObjectNull = null, - Float = float.NaN, - NullableDouble = double.NaN, - NullableFloat = null - }; + var content = @"{""startDateTime"":""2012-07-19T14:30:00+09:30""}"; - string json = JsonConvert.SerializeObject(floats, Formatting.Indented, new JsonSerializerSettings + var jsonSerializerSettings = new JsonSerializerSettings() { DateFormatHandling = DateFormatHandling.IsoDateFormat, DateParseHandling = DateParseHandling.DateTimeOffset, DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind }; + + var obj = (JObject)JsonConvert.DeserializeObject(content, jsonSerializerSettings); + + var dateTimeOffset = (DateTimeOffset)((JValue)obj["startDateTime"]).Value; + + Assert.AreEqual(TimeSpan.FromHours(9.5), dateTimeOffset.Offset); + Assert.AreEqual("07/19/2012 14:30:00 +09:30", dateTimeOffset.ToString(CultureInfo.InvariantCulture)); + } + + public class NullableFloats { - FloatFormatHandling = FloatFormatHandling.DefaultValue - }); + public object Object { get; set; } + public float Float { get; set; } + public double Double { get; set; } + public float? NullableFloat { get; set; } + public double? NullableDouble { get; set; } + public object ObjectNull { get; set; } + } - Assert.AreEqual(@"{ + [Test] + public void NullableFloatingPoint() + { + NullableFloats floats = new NullableFloats + { + Object = double.NaN, + ObjectNull = null, + Float = float.NaN, + NullableDouble = double.NaN, + NullableFloat = null + }; + + string json = JsonConvert.SerializeObject(floats, Formatting.Indented, new JsonSerializerSettings + { + FloatFormatHandling = FloatFormatHandling.DefaultValue + }); + + Assert.AreEqual(@"{ ""Object"": 0.0, ""Float"": 0.0, ""Double"": 0.0, @@ -8789,233 +8739,233 @@ Parameter name: value", ""NullableDouble"": null, ""ObjectNull"": null }", json); - } + } - [Test] - public void DateFormatString() - { - IList dates = new List + [Test] + public void DateFormatString() { - new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc), - new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.FromHours(1)) - }; + IList dates = new List + { + new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc), + new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.FromHours(1)) + }; - string json = JsonConvert.SerializeObject(dates, Formatting.Indented, new JsonSerializerSettings - { - DateFormatString = "yyyy tt", - Culture = new CultureInfo("en-NZ") - }); + string json = JsonConvert.SerializeObject(dates, Formatting.Indented, new JsonSerializerSettings + { + DateFormatString = "yyyy tt", + Culture = new CultureInfo("en-NZ") + }); - Assert.AreEqual(@"[ + Assert.AreEqual(@"[ ""2000 p.m."", ""2000 p.m."" ]", json); - } + } - [Test] - public void DateFormatStringForInternetExplorer() - { - IList dates = new List + [Test] + public void DateFormatStringForInternetExplorer() { - new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc), - new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.FromHours(1)) - }; + IList dates = new List + { + new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc), + new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.FromHours(1)) + }; - string json = JsonConvert.SerializeObject(dates, Formatting.Indented, new JsonSerializerSettings - { - DateFormatString = @"yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffK" - }); + string json = JsonConvert.SerializeObject(dates, Formatting.Indented, new JsonSerializerSettings + { + DateFormatString = @"yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffK" + }); - Assert.AreEqual(@"[ + Assert.AreEqual(@"[ ""2000-12-12T12:12:12.000Z"", ""2000-12-12T12:12:12.000+01:00"" ]", json); - } + } - [Test] - public void JsonSerializerDateFormatString() - { - IList dates = new List + [Test] + public void JsonSerializerDateFormatString() { - new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc), - new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.FromHours(1)) - }; + IList dates = new List + { + new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc), + new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.FromHours(1)) + }; - StringWriter sw = new StringWriter(); - JsonTextWriter jsonWriter = new JsonTextWriter(sw); + StringWriter sw = new StringWriter(); + JsonTextWriter jsonWriter = new JsonTextWriter(sw); - JsonSerializer serializer = JsonSerializer.Create(new JsonSerializerSettings - { - DateFormatString = "yyyy tt", - Culture = new CultureInfo("en-NZ"), - Formatting = Formatting.Indented - }); - serializer.Serialize(jsonWriter, dates); + JsonSerializer serializer = JsonSerializer.Create(new JsonSerializerSettings + { + DateFormatString = "yyyy tt", + Culture = new CultureInfo("en-NZ"), + Formatting = Formatting.Indented + }); + serializer.Serialize(jsonWriter, dates); - Assert.IsNull(jsonWriter.DateFormatString); - Assert.AreEqual(CultureInfo.InvariantCulture, jsonWriter.Culture); - Assert.AreEqual(Formatting.None, jsonWriter.Formatting); + Assert.IsNull(jsonWriter.DateFormatString); + Assert.AreEqual(CultureInfo.InvariantCulture, jsonWriter.Culture); + Assert.AreEqual(Formatting.None, jsonWriter.Formatting); - string json = sw.ToString(); + string json = sw.ToString(); - Assert.AreEqual(@"[ + Assert.AreEqual(@"[ ""2000 p.m."", ""2000 p.m."" ]", json); - } + } #if !(NET20 || NET35) - [Test] - public void SerializeDeserializeTuple() - { - Tuple tuple = Tuple.Create(500, 20); - string json = JsonConvert.SerializeObject(tuple); - Assert.AreEqual(@"{""Item1"":500,""Item2"":20}", json); + [Test] + public void SerializeDeserializeTuple() + { + Tuple tuple = Tuple.Create(500, 20); + string json = JsonConvert.SerializeObject(tuple); + Assert.AreEqual(@"{""Item1"":500,""Item2"":20}", json); - Tuple tuple2 = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(500, tuple2.Item1); - Assert.AreEqual(20, tuple2.Item2); - } + Tuple tuple2 = JsonConvert.DeserializeObject>(json); + Assert.AreEqual(500, tuple2.Item1); + Assert.AreEqual(20, tuple2.Item2); + } #endif - public class MessageWithIsoDate - { - public String IsoDate { get; set; } - } + public class MessageWithIsoDate + { + public String IsoDate { get; set; } + } - [Test] - public void JsonSerializerStringEscapeHandling() - { - StringWriter sw = new StringWriter(); - JsonTextWriter jsonWriter = new JsonTextWriter(sw); + [Test] + public void JsonSerializerStringEscapeHandling() + { + StringWriter sw = new StringWriter(); + JsonTextWriter jsonWriter = new JsonTextWriter(sw); - JsonSerializer serializer = JsonSerializer.Create(new JsonSerializerSettings - { - StringEscapeHandling = StringEscapeHandling.EscapeHtml, - Formatting = Formatting.Indented - }); - serializer.Serialize(jsonWriter, new { html = "" }); + JsonSerializer serializer = JsonSerializer.Create(new JsonSerializerSettings + { + StringEscapeHandling = StringEscapeHandling.EscapeHtml, + Formatting = Formatting.Indented + }); + serializer.Serialize(jsonWriter, new { html = "" }); - Assert.AreEqual(StringEscapeHandling.Default, jsonWriter.StringEscapeHandling); + Assert.AreEqual(StringEscapeHandling.Default, jsonWriter.StringEscapeHandling); - string json = sw.ToString(); + string json = sw.ToString(); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""html"": ""\u003chtml\u003e\u003c/html\u003e"" }", json); - } + } - public class NoConstructorReadOnlyCollection : ReadOnlyCollection - { - public NoConstructorReadOnlyCollection() : base(new List()) - { - } - } + public class NoConstructorReadOnlyCollection : ReadOnlyCollection + { + public NoConstructorReadOnlyCollection() : base(new List()) + { + } + } - [Test] - public void NoConstructorReadOnlyCollectionTest() - { - ExceptionAssert.Throws( - "Cannot deserialize readonly or fixed size list: Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+NoConstructorReadOnlyCollection`1[System.Int32]. Path '', line 1, position 1.", - () => JsonConvert.DeserializeObject>("[1]")); - } + [Test] + public void NoConstructorReadOnlyCollectionTest() + { + ExceptionAssert.Throws( + "Cannot deserialize readonly or fixed size list: Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+NoConstructorReadOnlyCollection`1[System.Int32]. Path '', line 1, position 1.", + () => JsonConvert.DeserializeObject>("[1]")); + } #if !(NET40 || NET35 || NET20 || PORTABLE40) - public class NoConstructorReadOnlyDictionary : ReadOnlyDictionary - { - public NoConstructorReadOnlyDictionary() - : base(new Dictionary()) - { - } - } + public class NoConstructorReadOnlyDictionary : ReadOnlyDictionary + { + public NoConstructorReadOnlyDictionary() + : base(new Dictionary()) + { + } + } - [Test] - public void NoConstructorReadOnlyDictionaryTest() - { - ExceptionAssert.Throws( - "Cannot deserialize readonly or fixed size dictionary: Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+NoConstructorReadOnlyDictionary`2[System.Int32,System.Int32]. Path '1', line 1, position 5.", - () => JsonConvert.DeserializeObject>("{'1':1}")); - } + [Test] + public void NoConstructorReadOnlyDictionaryTest() + { + ExceptionAssert.Throws( + "Cannot deserialize readonly or fixed size dictionary: Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+NoConstructorReadOnlyDictionary`2[System.Int32,System.Int32]. Path '1', line 1, position 5.", + () => JsonConvert.DeserializeObject>("{'1':1}")); + } #endif #if !(PORTABLE || NET35 || NET20 || SILVERLIGHT || PORTABLE40) - [Test] - public void ReadTooLargeInteger() - { - string json = @"[999999999999999999999999999999999999999999999999]"; + [Test] + public void ReadTooLargeInteger() + { + string json = @"[999999999999999999999999999999999999999999999999]"; - IList l = JsonConvert.DeserializeObject>(json); + IList l = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(BigInteger.Parse("999999999999999999999999999999999999999999999999"), l[0]); + Assert.AreEqual(BigInteger.Parse("999999999999999999999999999999999999999999999999"), l[0]); - ExceptionAssert.Throws( - "Error converting value 999999999999999999999999999999999999999999999999 to type 'System.Int64'. Path '[0]', line 1, position 49.", - () => JsonConvert.DeserializeObject>(json)); - } + ExceptionAssert.Throws( + "Error converting value 999999999999999999999999999999999999999999999999 to type 'System.Int64'. Path '[0]', line 1, position 49.", + () => JsonConvert.DeserializeObject>(json)); + } #endif - [Test] - public void ReadStringFloatingPointSymbols() - { - string json = @"[ + [Test] + public void ReadStringFloatingPointSymbols() + { + string json = @"[ ""NaN"", ""Infinity"", ""-Infinity"" ]"; - IList floats = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(float.NaN, floats[0]); - Assert.AreEqual(float.PositiveInfinity, floats[1]); - Assert.AreEqual(float.NegativeInfinity, floats[2]); + IList floats = JsonConvert.DeserializeObject>(json); + Assert.AreEqual(float.NaN, floats[0]); + Assert.AreEqual(float.PositiveInfinity, floats[1]); + Assert.AreEqual(float.NegativeInfinity, floats[2]); - IList doubles = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(float.NaN, doubles[0]); - Assert.AreEqual(float.PositiveInfinity, doubles[1]); - Assert.AreEqual(float.NegativeInfinity, doubles[2]); - } + IList doubles = JsonConvert.DeserializeObject>(json); + Assert.AreEqual(float.NaN, doubles[0]); + Assert.AreEqual(float.PositiveInfinity, doubles[1]); + Assert.AreEqual(float.NegativeInfinity, doubles[2]); + } - [Test] - public void DefaultDateStringFormatVsUnsetDateStringFormat() - { - IDictionary dates = new Dictionary + [Test] + public void DefaultDateStringFormatVsUnsetDateStringFormat() { - {"DateTime-Unspecified", new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Unspecified)}, - {"DateTime-Utc", new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc)}, - {"DateTime-Local", new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Local)}, - {"DateTimeOffset-Zero", new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.Zero)}, - {"DateTimeOffset-Plus1", new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.FromHours(1))}, - {"DateTimeOffset-Plus15", new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.FromHours(1.5))} - }; + IDictionary dates = new Dictionary + { + { "DateTime-Unspecified", new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Unspecified) }, + { "DateTime-Utc", new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc) }, + { "DateTime-Local", new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Local) }, + { "DateTimeOffset-Zero", new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.Zero) }, + { "DateTimeOffset-Plus1", new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.FromHours(1)) }, + { "DateTimeOffset-Plus15", new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.FromHours(1.5)) } + }; - string expected = JsonConvert.SerializeObject(dates, Formatting.Indented); + string expected = JsonConvert.SerializeObject(dates, Formatting.Indented); - Console.WriteLine(expected); + Console.WriteLine(expected); - string actual = JsonConvert.SerializeObject(dates, Formatting.Indented, new JsonSerializerSettings - { - DateFormatString = JsonSerializerSettings.DefaultDateFormatString - }); + string actual = JsonConvert.SerializeObject(dates, Formatting.Indented, new JsonSerializerSettings + { + DateFormatString = JsonSerializerSettings.DefaultDateFormatString + }); - Console.WriteLine(expected); + Console.WriteLine(expected); - Assert.AreEqual(expected, actual); - } + Assert.AreEqual(expected, actual); + } #endif #if !NET20 - public class NullableTestClass - { - public bool? MyNullableBool { get; set; } - public int? MyNullableInteger { get; set; } - public DateTime? MyNullableDateTime { get; set; } - public DateTimeOffset? MyNullableDateTimeOffset { get; set; } - public Decimal? MyNullableDecimal { get; set; } - } + public class NullableTestClass + { + public bool? MyNullableBool { get; set; } + public int? MyNullableInteger { get; set; } + public DateTime? MyNullableDateTime { get; set; } + public DateTimeOffset? MyNullableDateTimeOffset { get; set; } + public Decimal? MyNullableDecimal { get; set; } + } - [Test] - public void TestStringToNullableDeserialization() - { - string json = @"{ + [Test] + public void TestStringToNullableDeserialization() + { + string json = @"{ ""MyNullableBool"": """", ""MyNullableInteger"": """", ""MyNullableDateTime"": """", @@ -9023,102 +8973,102 @@ Parameter name: value", ""MyNullableDecimal"": """" }"; - NullableTestClass c2 = JsonConvert.DeserializeObject(json); - Assert.IsNull(c2.MyNullableBool); - Assert.IsNull(c2.MyNullableInteger); - Assert.IsNull(c2.MyNullableDateTime); - Assert.IsNull(c2.MyNullableDateTimeOffset); - Assert.IsNull(c2.MyNullableDecimal); - } + NullableTestClass c2 = JsonConvert.DeserializeObject(json); + Assert.IsNull(c2.MyNullableBool); + Assert.IsNull(c2.MyNullableInteger); + Assert.IsNull(c2.MyNullableDateTime); + Assert.IsNull(c2.MyNullableDateTimeOffset); + Assert.IsNull(c2.MyNullableDecimal); + } #endif #if !(NET20 || NET35 || PORTABLE40) - [Test] - public void HashSetInterface() - { - ISet s1 = new HashSet(new[] {"1", "two", "III"}); + [Test] + public void HashSetInterface() + { + ISet s1 = new HashSet(new[] { "1", "two", "III" }); - string json = JsonConvert.SerializeObject(s1); + string json = JsonConvert.SerializeObject(s1); - ISet s2 = JsonConvert.DeserializeObject>(json); + ISet s2 = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(s1.Count, s2.Count); - foreach (string s in s1) - { - Assert.IsTrue(s2.Contains(s)); - } - } + Assert.AreEqual(s1.Count, s2.Count); + foreach (string s in s1) + { + Assert.IsTrue(s2.Contains(s)); + } + } #endif - public class NewEmployee : Employee - { - public int Age { get; set; } - - public bool ShouldSerializeName() + public class NewEmployee : Employee { - return false; + public int Age { get; set; } + + public bool ShouldSerializeName() + { + return false; + } } - } - [Test] - public void ShouldSerializeInheritedClassTest() - { - NewEmployee joe = new NewEmployee(); - joe.Name = "Joe Employee"; - joe.Age = 100; + [Test] + public void ShouldSerializeInheritedClassTest() + { + NewEmployee joe = new NewEmployee(); + joe.Name = "Joe Employee"; + joe.Age = 100; - Employee mike = new Employee(); - mike.Name = "Mike Manager"; - mike.Manager = mike; + Employee mike = new Employee(); + mike.Name = "Mike Manager"; + mike.Manager = mike; - joe.Manager = mike; + joe.Manager = mike; - //StringWriter sw = new StringWriter(); + //StringWriter sw = new StringWriter(); - //XmlSerializer x = new XmlSerializer(typeof(NewEmployee)); - //x.Serialize(sw, joe); + //XmlSerializer x = new XmlSerializer(typeof(NewEmployee)); + //x.Serialize(sw, joe); - //Console.WriteLine(sw); + //Console.WriteLine(sw); - //JavaScriptSerializer s = new JavaScriptSerializer(); - //Console.WriteLine(s.Serialize(new {html = @"; & ! ^ * ( ) ! @ # $ % ^ ' "" - , . / ; : [ { } ] ; ' - _ = + ? ` ~ \ |"})); + //JavaScriptSerializer s = new JavaScriptSerializer(); + //Console.WriteLine(s.Serialize(new {html = @"; & ! ^ * ( ) ! @ # $ % ^ ' "" - , . / ; : [ { } ] ; ' - _ = + ? ` ~ \ |"})); - string json = JsonConvert.SerializeObject(joe, Formatting.Indented); + string json = JsonConvert.SerializeObject(joe, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Age"": 100, ""Name"": ""Joe Employee"", ""Manager"": { ""Name"": ""Mike Manager"" } }", json); - } + } - [Test] - public void DeserializeDecimal() - { - JsonTextReader reader = new JsonTextReader(new StringReader("1234567890.123456")); - var settings = new JsonSerializerSettings(); - var serialiser = JsonSerializer.Create(settings); - decimal? d = serialiser.Deserialize(reader); + [Test] + public void DeserializeDecimal() + { + JsonTextReader reader = new JsonTextReader(new StringReader("1234567890.123456")); + var settings = new JsonSerializerSettings(); + var serialiser = JsonSerializer.Create(settings); + decimal? d = serialiser.Deserialize(reader); - Assert.AreEqual(1234567890.123456m, d); - } + Assert.AreEqual(1234567890.123456m, d); + } #if !(PORTABLE || SILVERLIGHT || NETFX_CORE || WINDOWS_PHONE || PORTABLE40) - [Test] - public void DontSerializeStaticFields() - { - string json = - JsonConvert.SerializeObject(new AnswerFilterModel(), Formatting.Indented, new JsonSerializerSettings - { - ContractResolver = new DefaultContractResolver - { - IgnoreSerializableAttribute = false - } - }); + [Test] + public void DontSerializeStaticFields() + { + string json = + JsonConvert.SerializeObject(new AnswerFilterModel(), Formatting.Indented, new JsonSerializerSettings + { + ContractResolver = new DefaultContractResolver + { + IgnoreSerializableAttribute = false + } + }); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""k__BackingField"": false, ""k__BackingField"": false, ""k__BackingField"": false, @@ -9126,334 +9076,334 @@ Parameter name: value", ""k__BackingField"": false, ""k__BackingField"": false }", json); - } + } #endif - [Test] - public void DeserializeNonGenericList() - { - IList l = JsonConvert.DeserializeObject("['string!']"); + [Test] + public void DeserializeNonGenericList() + { + IList l = JsonConvert.DeserializeObject("['string!']"); - Assert.AreEqual(typeof(List), l.GetType()); - Assert.AreEqual(1, l.Count); - Assert.AreEqual("string!", l[0]); - } + Assert.AreEqual(typeof(List), l.GetType()); + Assert.AreEqual(1, l.Count); + Assert.AreEqual("string!", l[0]); + } #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE || PORTABLE40) - [Test] - public void SerializeBigInteger() - { - BigInteger i = BigInteger.Parse("123456789999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999990"); + [Test] + public void SerializeBigInteger() + { + BigInteger i = BigInteger.Parse("123456789999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999990"); - string json = JsonConvert.SerializeObject(new [] {i}, Formatting.Indented); + string json = JsonConvert.SerializeObject(new[] { i }, Formatting.Indented); - Assert.AreEqual(@"[ + Assert.AreEqual(@"[ 123456789999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999990 ]", json); - } + } #endif #if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - [Test] - public void DeserializeReadOnlyListInterface() - { - IReadOnlyList list = JsonConvert.DeserializeObject>("[1,2,3]"); + [Test] + public void DeserializeReadOnlyListInterface() + { + IReadOnlyList list = JsonConvert.DeserializeObject>("[1,2,3]"); - Assert.AreEqual(3, list.Count); - Assert.AreEqual(1, list[0]); - Assert.AreEqual(2, list[1]); - Assert.AreEqual(3, list[2]); - } + Assert.AreEqual(3, list.Count); + Assert.AreEqual(1, list[0]); + Assert.AreEqual(2, list[1]); + Assert.AreEqual(3, list[2]); + } - [Test] - public void DeserializeReadOnlyCollectionInterface() - { - IReadOnlyCollection list = JsonConvert.DeserializeObject>("[1,2,3]"); + [Test] + public void DeserializeReadOnlyCollectionInterface() + { + IReadOnlyCollection list = JsonConvert.DeserializeObject>("[1,2,3]"); - Assert.AreEqual(3, list.Count); + Assert.AreEqual(3, list.Count); - Assert.AreEqual(1, list.ElementAt(0)); - Assert.AreEqual(2, list.ElementAt(1)); - Assert.AreEqual(3, list.ElementAt(2)); - } + Assert.AreEqual(1, list.ElementAt(0)); + Assert.AreEqual(2, list.ElementAt(1)); + Assert.AreEqual(3, list.ElementAt(2)); + } - [Test] - public void DeserializeReadOnlyCollection() - { - ReadOnlyCollection list = JsonConvert.DeserializeObject>("[1,2,3]"); + [Test] + public void DeserializeReadOnlyCollection() + { + ReadOnlyCollection list = JsonConvert.DeserializeObject>("[1,2,3]"); - Assert.AreEqual(3, list.Count); + Assert.AreEqual(3, list.Count); - Assert.AreEqual(1, list[0]); - Assert.AreEqual(2, list[1]); - Assert.AreEqual(3, list[2]); - } + Assert.AreEqual(1, list[0]); + Assert.AreEqual(2, list[1]); + Assert.AreEqual(3, list[2]); + } - [Test] - public void DeserializeReadOnlyDictionaryInterface() - { - IReadOnlyDictionary dic = JsonConvert.DeserializeObject>("{'one':1,'two':2}"); + [Test] + public void DeserializeReadOnlyDictionaryInterface() + { + IReadOnlyDictionary dic = JsonConvert.DeserializeObject>("{'one':1,'two':2}"); - Assert.AreEqual(2, dic.Count); + Assert.AreEqual(2, dic.Count); - Assert.AreEqual(1, dic["one"]); - Assert.AreEqual(2, dic["two"]); + Assert.AreEqual(1, dic["one"]); + Assert.AreEqual(2, dic["two"]); - CustomAssert.IsInstanceOfType(typeof(ReadOnlyDictionary), dic); - } + CustomAssert.IsInstanceOfType(typeof(ReadOnlyDictionary), dic); + } - [Test] - public void DeserializeReadOnlyDictionary() - { - ReadOnlyDictionary dic = JsonConvert.DeserializeObject>("{'one':1,'two':2}"); + [Test] + public void DeserializeReadOnlyDictionary() + { + ReadOnlyDictionary dic = JsonConvert.DeserializeObject>("{'one':1,'two':2}"); - Assert.AreEqual(2, dic.Count); + Assert.AreEqual(2, dic.Count); - Assert.AreEqual(1, dic["one"]); - Assert.AreEqual(2, dic["two"]); - } + Assert.AreEqual(1, dic["one"]); + Assert.AreEqual(2, dic["two"]); + } - public class CustomReadOnlyDictionary : IReadOnlyDictionary - { - private readonly IDictionary _dictionary; + public class CustomReadOnlyDictionary : IReadOnlyDictionary + { + private readonly IDictionary _dictionary; - public CustomReadOnlyDictionary(IDictionary dictionary) - { - _dictionary = dictionary; - } - - public bool ContainsKey(TKey key) - { - return _dictionary.ContainsKey(key); - } + public CustomReadOnlyDictionary(IDictionary dictionary) + { + _dictionary = dictionary; + } - public IEnumerable Keys - { - get { return _dictionary.Keys; } - } + public bool ContainsKey(TKey key) + { + return _dictionary.ContainsKey(key); + } - public bool TryGetValue(TKey key, out TValue value) - { - return _dictionary.TryGetValue(key, out value); - } + public IEnumerable Keys + { + get { return _dictionary.Keys; } + } - public IEnumerable Values - { - get { return _dictionary.Values; } - } + public bool TryGetValue(TKey key, out TValue value) + { + return _dictionary.TryGetValue(key, out value); + } - public TValue this[TKey key] - { - get { return _dictionary[key]; } - } + public IEnumerable Values + { + get { return _dictionary.Values; } + } - public int Count - { - get { return _dictionary.Count; } - } + public TValue this[TKey key] + { + get { return _dictionary[key]; } + } - public IEnumerator> GetEnumerator() - { - return _dictionary.GetEnumerator(); - } + public int Count + { + get { return _dictionary.Count; } + } - IEnumerator IEnumerable.GetEnumerator() - { - return _dictionary.GetEnumerator(); - } - } + public IEnumerator> GetEnumerator() + { + return _dictionary.GetEnumerator(); + } - [Test] - public void SerializeCustomReadOnlyDictionary() - { - IDictionary d = new Dictionary - { - {"one", 1}, - {"two", 2} - }; + IEnumerator IEnumerable.GetEnumerator() + { + return _dictionary.GetEnumerator(); + } + } - CustomReadOnlyDictionary dic = new CustomReadOnlyDictionary(d); + [Test] + public void SerializeCustomReadOnlyDictionary() + { + IDictionary d = new Dictionary + { + { "one", 1 }, + { "two", 2 } + }; - string json = JsonConvert.SerializeObject(dic, Formatting.Indented); - Assert.AreEqual(@"{ + CustomReadOnlyDictionary dic = new CustomReadOnlyDictionary(d); + + string json = JsonConvert.SerializeObject(dic, Formatting.Indented); + Assert.AreEqual(@"{ ""one"": 1, ""two"": 2 }", json); - } + } - public class CustomReadOnlyCollection : IReadOnlyCollection - { - private readonly IList _values; + public class CustomReadOnlyCollection : IReadOnlyCollection + { + private readonly IList _values; - public CustomReadOnlyCollection (IList values) - { - _values = values; - } + public CustomReadOnlyCollection(IList values) + { + _values = values; + } - public int Count - { - get { return _values.Count; } - } + public int Count + { + get { return _values.Count; } + } - public IEnumerator GetEnumerator() - { - return _values.GetEnumerator(); - } + public IEnumerator GetEnumerator() + { + return _values.GetEnumerator(); + } - IEnumerator IEnumerable.GetEnumerator() - { - return _values.GetEnumerator(); - } - } + IEnumerator IEnumerable.GetEnumerator() + { + return _values.GetEnumerator(); + } + } - [Test] - public void SerializeCustomReadOnlyCollection() - { - IList l = new List - { - 1, - 2, - 3 - }; + [Test] + public void SerializeCustomReadOnlyCollection() + { + IList l = new List + { + 1, + 2, + 3 + }; - CustomReadOnlyCollection list = new CustomReadOnlyCollection(l); + CustomReadOnlyCollection list = new CustomReadOnlyCollection(l); - string json = JsonConvert.SerializeObject(list, Formatting.Indented); - Assert.AreEqual(@"[ + string json = JsonConvert.SerializeObject(list, Formatting.Indented); + Assert.AreEqual(@"[ 1, 2, 3 ]", json); - } + } #endif - public class PrivateDefaultCtorList : List - { - private PrivateDefaultCtorList() - { - } - } - - [Test] - public void DeserializePrivateListCtor() - { - ExceptionAssert.Throws( - "Unable to find a constructor to use for type Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+PrivateDefaultCtorList`1[System.Int32]. Path '', line 1, position 1.", - () => JsonConvert.DeserializeObject>("[1,2]") - ); - - var list = JsonConvert.DeserializeObject>("[1,2]", new JsonSerializerSettings + public class PrivateDefaultCtorList : List { - ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor - }); + private PrivateDefaultCtorList() + { + } + } - Assert.AreEqual(2, list.Count); - } - - public class PrivateDefaultCtorWithIEnumerableCtorList : List - { - private PrivateDefaultCtorWithIEnumerableCtorList() - { - } - - public PrivateDefaultCtorWithIEnumerableCtorList(IEnumerable values) - : base(values) - { - Add(default(T)); - } - } - - [Test] - public void DeserializePrivateListConstructor() - { - var list = JsonConvert.DeserializeObject>("[1,2]"); - - Assert.AreEqual(3, list.Count); - Assert.AreEqual(1, list[0]); - Assert.AreEqual(2, list[1]); - Assert.AreEqual(0, list[2]); - } - - [Test] - public void DeserializeNonIsoDateDictionaryKey() - { - Dictionary d = JsonConvert.DeserializeObject>(@"{""04/28/2013 00:00:00"":""test""}"); - - Assert.AreEqual(1, d.Count); - - DateTime key = DateTime.Parse("04/28/2013 00:00:00", CultureInfo.InvariantCulture); - Assert.AreEqual("test", d[key]); - } - - public class IdReferenceResolver : IReferenceResolver - { - private readonly IDictionary _people = new Dictionary(); - - public object ResolveReference(object context, string reference) - { - Guid id = new Guid(reference); - - PersonReference p; - _people.TryGetValue(id, out p); - - return p; - } - - public string GetReference(object context, object value) - { - PersonReference p = (PersonReference)value; - _people[p.Id] = p; - - return p.Id.ToString(); - } - - public bool IsReferenced(object context, object value) - { - PersonReference p = (PersonReference)value; - - return _people.ContainsKey(p.Id); - } - - public void AddReference(object context, string reference, object value) - { - Guid id = new Guid(reference); - - _people[id] = (PersonReference)value; - } - } - - [Test] - public void SerializeCustomReferenceResolver() - { - PersonReference john = new PersonReference + [Test] + public void DeserializePrivateListCtor() { - Id = new Guid("0B64FFDF-D155-44AD-9689-58D9ADB137F3"), - Name = "John Smith" - }; + ExceptionAssert.Throws( + "Unable to find a constructor to use for type Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+PrivateDefaultCtorList`1[System.Int32]. Path '', line 1, position 1.", + () => JsonConvert.DeserializeObject>("[1,2]") + ); - PersonReference jane = new PersonReference + var list = JsonConvert.DeserializeObject>("[1,2]", new JsonSerializerSettings + { + ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor + }); + + Assert.AreEqual(2, list.Count); + } + + public class PrivateDefaultCtorWithIEnumerableCtorList : List { - Id = new Guid("AE3C399C-058D-431D-91B0-A36C266441B9"), - Name = "Jane Smith" - }; + private PrivateDefaultCtorWithIEnumerableCtorList() + { + } - john.Spouse = jane; - jane.Spouse = john; + public PrivateDefaultCtorWithIEnumerableCtorList(IEnumerable values) + : base(values) + { + Add(default(T)); + } + } - IList people = new List + [Test] + public void DeserializePrivateListConstructor() { - john, - jane - }; + var list = JsonConvert.DeserializeObject>("[1,2]"); - string json = JsonConvert.SerializeObject(people, new JsonSerializerSettings + Assert.AreEqual(3, list.Count); + Assert.AreEqual(1, list[0]); + Assert.AreEqual(2, list[1]); + Assert.AreEqual(0, list[2]); + } + + [Test] + public void DeserializeNonIsoDateDictionaryKey() { - ReferenceResolver = new IdReferenceResolver(), - PreserveReferencesHandling = PreserveReferencesHandling.Objects, - Formatting = Formatting.Indented - }); + Dictionary d = JsonConvert.DeserializeObject>(@"{""04/28/2013 00:00:00"":""test""}"); - Assert.AreEqual(@"[ + Assert.AreEqual(1, d.Count); + + DateTime key = DateTime.Parse("04/28/2013 00:00:00", CultureInfo.InvariantCulture); + Assert.AreEqual("test", d[key]); + } + + public class IdReferenceResolver : IReferenceResolver + { + private readonly IDictionary _people = new Dictionary(); + + public object ResolveReference(object context, string reference) + { + Guid id = new Guid(reference); + + PersonReference p; + _people.TryGetValue(id, out p); + + return p; + } + + public string GetReference(object context, object value) + { + PersonReference p = (PersonReference)value; + _people[p.Id] = p; + + return p.Id.ToString(); + } + + public bool IsReferenced(object context, object value) + { + PersonReference p = (PersonReference)value; + + return _people.ContainsKey(p.Id); + } + + public void AddReference(object context, string reference, object value) + { + Guid id = new Guid(reference); + + _people[id] = (PersonReference)value; + } + } + + [Test] + public void SerializeCustomReferenceResolver() + { + PersonReference john = new PersonReference + { + Id = new Guid("0B64FFDF-D155-44AD-9689-58D9ADB137F3"), + Name = "John Smith" + }; + + PersonReference jane = new PersonReference + { + Id = new Guid("AE3C399C-058D-431D-91B0-A36C266441B9"), + Name = "Jane Smith" + }; + + john.Spouse = jane; + jane.Spouse = john; + + IList people = new List + { + john, + jane + }; + + string json = JsonConvert.SerializeObject(people, new JsonSerializerSettings + { + ReferenceResolver = new IdReferenceResolver(), + PreserveReferencesHandling = PreserveReferencesHandling.Objects, + Formatting = Formatting.Indented + }); + + Assert.AreEqual(@"[ { ""$id"": ""0b64ffdf-d155-44ad-9689-58d9adb137f3"", ""Name"": ""John Smith"", @@ -9469,51 +9419,51 @@ Parameter name: value", ""$ref"": ""ae3c399c-058d-431d-91b0-a36c266441b9"" } ]", json); - } + } - public class Foo2 - { - public string Name { get; set; } - } + public class Foo2 + { + public string Name { get; set; } + } - [Test] - [Ignore] - public void SerializeMultipleObjectsFromStream() - { - StringReader sr = new StringReader(@"{ ""name"": ""bar"" }{ ""name"": ""baz"" }"); + [Test] + [Ignore] + public void SerializeMultipleObjectsFromStream() + { + StringReader sr = new StringReader(@"{ ""name"": ""bar"" }{ ""name"": ""baz"" }"); - var reader1 = new JsonTextReader(sr); - var serializer1 = new JsonSerializer { }; - var foo1 = serializer1.Deserialize(reader1); - Assert.AreEqual("bar", foo1.Name); + var reader1 = new JsonTextReader(sr); + var serializer1 = new JsonSerializer { }; + var foo1 = serializer1.Deserialize(reader1); + Assert.AreEqual("bar", foo1.Name); - var reader2 = new JsonTextReader(sr); - var serializer2 = new JsonSerializer { }; - var foo2 = serializer2.Deserialize(reader2); - Assert.AreEqual("baz", foo2.Name); - } + var reader2 = new JsonTextReader(sr); + var serializer2 = new JsonSerializer { }; + var foo2 = serializer2.Deserialize(reader2); + Assert.AreEqual("baz", foo2.Name); + } #if !(PORTABLE || PORTABLE40 || NETFX_CORE) - [Test] - public void SerializeDictionaryWithStructKey() - { - string json = JsonConvert.SerializeObject( - new Dictionary { { new Size(1, 2), new Size(3, 4) } } - ); + [Test] + public void SerializeDictionaryWithStructKey() + { + string json = JsonConvert.SerializeObject( + new Dictionary { { new Size(1, 2), new Size(3, 4) } } + ); - Assert.AreEqual(@"{""1, 2"":""3, 4""}", json); + Assert.AreEqual(@"{""1, 2"":""3, 4""}", json); - Dictionary d = JsonConvert.DeserializeObject>(json); + Dictionary d = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(new Size(1, 2), d.Keys.First()); - Assert.AreEqual(new Size(3, 4), d.Values.First()); - } + Assert.AreEqual(new Size(1, 2), d.Keys.First()); + Assert.AreEqual(new Size(3, 4), d.Values.First()); + } #endif - [Test] - public void DeserializeCustomReferenceResolver() - { - string json = @"[ + [Test] + public void DeserializeCustomReferenceResolver() + { + string json = @"[ { ""$id"": ""0b64ffdf-d155-44ad-9689-58d9adb137f3"", ""Name"": ""John Smith"", @@ -9530,1003 +9480,1085 @@ Parameter name: value", } ]"; - IList people = JsonConvert.DeserializeObject>(json, new JsonSerializerSettings - { - ReferenceResolver = new IdReferenceResolver(), - PreserveReferencesHandling = PreserveReferencesHandling.Objects, - Formatting = Formatting.Indented - }); + IList people = JsonConvert.DeserializeObject>(json, new JsonSerializerSettings + { + ReferenceResolver = new IdReferenceResolver(), + PreserveReferencesHandling = PreserveReferencesHandling.Objects, + Formatting = Formatting.Indented + }); - Assert.AreEqual(2, people.Count); + Assert.AreEqual(2, people.Count); - PersonReference john = people[0]; - PersonReference jane = people[1]; + PersonReference john = people[0]; + PersonReference jane = people[1]; - Assert.AreEqual(john, jane.Spouse); - Assert.AreEqual(jane, john.Spouse); - } + Assert.AreEqual(john, jane.Spouse); + Assert.AreEqual(jane, john.Spouse); + } #if !(NETFX_CORE || NET35 || NET20 || PORTABLE || PORTABLE40) - [TypeConverter(typeof(MyInterfaceConverter))] - internal interface IMyInterface - { - string Name { get; } + [TypeConverter(typeof(MyInterfaceConverter))] + internal interface IMyInterface + { + string Name { get; } - string PrintTest(); - } + string PrintTest(); + } - internal class MyInterfaceConverter : TypeConverter - { - private readonly List _writers = new List - { - new ConsoleWriter(), - new TraceWriter() - }; + internal class MyInterfaceConverter : TypeConverter + { + private readonly List _writers = new List + { + new ConsoleWriter(), + new TraceWriter() + }; - public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) - { - return destinationType == typeof(string); - } + public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) + { + return destinationType == typeof(string); + } - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) - { - return sourceType == typeof(string); - } + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + return sourceType == typeof(string); + } - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) - { - if (value == null) - return null; + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + if (value == null) + return null; - return (from w in _writers where w.Name == value.ToString() select w).FirstOrDefault(); - } + return (from w in _writers where w.Name == value.ToString() select w).FirstOrDefault(); + } - public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, - Type destinationType) - { - if (value == null) - return null; - return ((IMyInterface)value).Name; - } - } + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, + Type destinationType) + { + if (value == null) + return null; + return ((IMyInterface)value).Name; + } + } - [TypeConverter(typeof(MyInterfaceConverter))] - internal class ConsoleWriter : IMyInterface - { - public string Name - { - get { return "Console Writer"; } - } + [TypeConverter(typeof(MyInterfaceConverter))] + internal class ConsoleWriter : IMyInterface + { + public string Name + { + get { return "Console Writer"; } + } - public string PrintTest() - { - return "ConsoleWriter"; - } + public string PrintTest() + { + return "ConsoleWriter"; + } - public override string ToString() - { - return Name; - } - } + public override string ToString() + { + return Name; + } + } - internal class TraceWriter : IMyInterface - { - public string Name - { - get { return "Trace Writer"; } - } + internal class TraceWriter : IMyInterface + { + public string Name + { + get { return "Trace Writer"; } + } - public override string ToString() - { - return Name; - } + public override string ToString() + { + return Name; + } - public string PrintTest() - { - return "TraceWriter"; - } - } + public string PrintTest() + { + return "TraceWriter"; + } + } - internal class TypeConverterJsonConverter : JsonConverter - { - private TypeConverter GetConverter(Type type) - { - var converters = type.GetCustomAttributes(typeof(TypeConverterAttribute), true).Union( - from t in type.GetInterfaces() - from c in t.GetCustomAttributes(typeof(TypeConverterAttribute), true) - select c).Distinct(); + internal class TypeConverterJsonConverter : JsonConverter + { + private TypeConverter GetConverter(Type type) + { + var converters = type.GetCustomAttributes(typeof(TypeConverterAttribute), true).Union( + from t in type.GetInterfaces() + from c in t.GetCustomAttributes(typeof(TypeConverterAttribute), true) + select c).Distinct(); - return - (from c in converters - let converter = - (TypeConverter)Activator.CreateInstance(Type.GetType(((TypeConverterAttribute)c).ConverterTypeName)) - where converter.CanConvertFrom(typeof(string)) - && converter.CanConvertTo(typeof(string)) - select converter) - .FirstOrDefault(); - } + return + (from c in converters + let converter = + (TypeConverter)Activator.CreateInstance(Type.GetType(((TypeConverterAttribute)c).ConverterTypeName)) + where converter.CanConvertFrom(typeof(string)) + && converter.CanConvertTo(typeof(string)) + select converter) + .FirstOrDefault(); + } - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - var converter = GetConverter(value.GetType()); - var text = converter.ConvertToInvariantString(value); + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + var converter = GetConverter(value.GetType()); + var text = converter.ConvertToInvariantString(value); - writer.WriteValue(text); - } + writer.WriteValue(text); + } - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - var converter = GetConverter(objectType); - return converter.ConvertFromInvariantString(reader.Value.ToString()); - } + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + var converter = GetConverter(objectType); + return converter.ConvertFromInvariantString(reader.Value.ToString()); + } - public override bool CanConvert(Type objectType) - { - return GetConverter(objectType) != null; - } - } + public override bool CanConvert(Type objectType) + { + return GetConverter(objectType) != null; + } + } - [Test] - public void TypeConverterOnInterface() - { - var consoleWriter = new ConsoleWriter(); + [Test] + public void TypeConverterOnInterface() + { + var consoleWriter = new ConsoleWriter(); - // If dynamic type handling is enabled, case 1 and 3 work fine - var options = new JsonSerializerSettings - { - Converters = new JsonConverterCollection {new TypeConverterJsonConverter()}, - //TypeNameHandling = TypeNameHandling.All - }; + // If dynamic type handling is enabled, case 1 and 3 work fine + var options = new JsonSerializerSettings + { + Converters = new JsonConverterCollection { new TypeConverterJsonConverter() }, + //TypeNameHandling = TypeNameHandling.All + }; - // - // Case 1: Serialize the concrete value and restore it from the interface - // Therefore we need dynamic handling of type information if the type is not serialized with the type converter directly - // - var text1 = JsonConvert.SerializeObject(consoleWriter, Formatting.Indented, options); - Assert.AreEqual(@"""Console Writer""", text1); + // + // Case 1: Serialize the concrete value and restore it from the interface + // Therefore we need dynamic handling of type information if the type is not serialized with the type converter directly + // + var text1 = JsonConvert.SerializeObject(consoleWriter, Formatting.Indented, options); + Assert.AreEqual(@"""Console Writer""", text1); - var restoredWriter = JsonConvert.DeserializeObject(text1, options); - Assert.AreEqual("ConsoleWriter", restoredWriter.PrintTest()); + var restoredWriter = JsonConvert.DeserializeObject(text1, options); + Assert.AreEqual("ConsoleWriter", restoredWriter.PrintTest()); - // - // Case 2: Serialize a dictionary where the interface is the key - // The key is always serialized with its ToString() method and therefore needs a mechanism to be restored from that (using the type converter) - // - var dict2 = new Dictionary(); - dict2.Add(consoleWriter, "Console"); + // + // Case 2: Serialize a dictionary where the interface is the key + // The key is always serialized with its ToString() method and therefore needs a mechanism to be restored from that (using the type converter) + // + var dict2 = new Dictionary(); + dict2.Add(consoleWriter, "Console"); - var text2 = JsonConvert.SerializeObject(dict2, Formatting.Indented, options); - Assert.AreEqual(@"{ + var text2 = JsonConvert.SerializeObject(dict2, Formatting.Indented, options); + Assert.AreEqual(@"{ ""Console Writer"": ""Console"" }", text2); - var restoredObject = JsonConvert.DeserializeObject>(text2, options); - Assert.AreEqual("ConsoleWriter", restoredObject.First().Key.PrintTest()); + var restoredObject = JsonConvert.DeserializeObject>(text2, options); + Assert.AreEqual("ConsoleWriter", restoredObject.First().Key.PrintTest()); - // - // Case 3 Serialize a dictionary where the interface is the value - // The key is always serialized with its ToString() method and therefore needs a mechanism to be restored from that (using the type converter) - // - var dict3 = new Dictionary(); - dict3.Add("Console", consoleWriter); + // + // Case 3 Serialize a dictionary where the interface is the value + // The key is always serialized with its ToString() method and therefore needs a mechanism to be restored from that (using the type converter) + // + var dict3 = new Dictionary(); + dict3.Add("Console", consoleWriter); - var text3 = JsonConvert.SerializeObject(dict3, Formatting.Indented, options); - Assert.AreEqual(@"{ + var text3 = JsonConvert.SerializeObject(dict3, Formatting.Indented, options); + Assert.AreEqual(@"{ ""Console"": ""Console Writer"" }", text3); - var restoredDict2 = JsonConvert.DeserializeObject>(text3, options); - Assert.AreEqual("ConsoleWriter", restoredDict2.First().Value.PrintTest()); - } + var restoredDict2 = JsonConvert.DeserializeObject>(text3, options); + Assert.AreEqual("ConsoleWriter", restoredDict2.First().Value.PrintTest()); + } #endif - [Test] - public void Main() - { - ParticipantEntity product = new ParticipantEntity(); - product.Properties = new Dictionary { { "s", "d" } }; - string json = JsonConvert.SerializeObject(product); - Console.WriteLine(json); - ParticipantEntity deserializedProduct = JsonConvert.DeserializeObject(json); - } + [Test] + public void Main() + { + ParticipantEntity product = new ParticipantEntity(); + product.Properties = new Dictionary { { "s", "d" } }; + string json = JsonConvert.SerializeObject(product); + Console.WriteLine(json); + ParticipantEntity deserializedProduct = JsonConvert.DeserializeObject(json); + } - internal class ParticipantEntity - { - private Dictionary _properties; + internal class ParticipantEntity + { + private Dictionary _properties; - [JsonConstructor] - public ParticipantEntity() - { - } + [JsonConstructor] + public ParticipantEntity() + { + } - /// - /// Gets or sets the date and time that the participant was created in the CU. - /// - [JsonProperty(PropertyName = "pa_created", DefaultValueHandling = DefaultValueHandling.Ignore, NullValueHandling = NullValueHandling.Ignore)] - public DateTimeOffset CreationDate { get; internal set; } + /// + /// Gets or sets the date and time that the participant was created in the CU. + /// + [JsonProperty(PropertyName = "pa_created", DefaultValueHandling = DefaultValueHandling.Ignore, NullValueHandling = NullValueHandling.Ignore)] + public DateTimeOffset CreationDate { get; internal set; } - /// - /// Gets the properties of the participant. - /// - [JsonProperty(PropertyName = "pa_info")] - public Dictionary Properties - { - get { return _properties ?? (_properties = new Dictionary()); } - set { _properties = value; } - } - } + /// + /// Gets the properties of the participant. + /// + [JsonProperty(PropertyName = "pa_info")] + public Dictionary Properties + { + get { return _properties ?? (_properties = new Dictionary()); } + set { _properties = value; } + } + } #if !(PORTABLE || NETFX_CORE) - public class ConvertibleId : IConvertible - { - public int Value; + public class ConvertibleId : IConvertible + { + public int Value; - TypeCode IConvertible.GetTypeCode() { return TypeCode.Object; } + TypeCode IConvertible.GetTypeCode() + { + return TypeCode.Object; + } - object IConvertible.ToType(Type conversionType, IFormatProvider provider) - { - if (conversionType == typeof(object)) { return this; } - if (conversionType == typeof(int)) { return (int)Value; } - if (conversionType == typeof(long)) { return (long)Value; } - if (conversionType == typeof(string)) { return Value.ToString(CultureInfo.InvariantCulture); } - throw new InvalidCastException(); - } + object IConvertible.ToType(Type conversionType, IFormatProvider provider) + { + if (conversionType == typeof(object)) + { + return this; + } + if (conversionType == typeof(int)) + { + return (int)Value; + } + if (conversionType == typeof(long)) + { + return (long)Value; + } + if (conversionType == typeof(string)) + { + return Value.ToString(CultureInfo.InvariantCulture); + } + throw new InvalidCastException(); + } - bool IConvertible.ToBoolean(IFormatProvider provider) { throw new InvalidCastException(); } - byte IConvertible.ToByte(IFormatProvider provider) { throw new InvalidCastException(); } - char IConvertible.ToChar(IFormatProvider provider) { throw new InvalidCastException(); } - DateTime IConvertible.ToDateTime(IFormatProvider provider) { throw new InvalidCastException(); } - decimal IConvertible.ToDecimal(IFormatProvider provider) { throw new InvalidCastException(); } - double IConvertible.ToDouble(IFormatProvider provider) { throw new InvalidCastException(); } - short IConvertible.ToInt16(IFormatProvider provider) { return (short)Value; } - int IConvertible.ToInt32(IFormatProvider provider) { return Value; } - long IConvertible.ToInt64(IFormatProvider provider) { return (long)Value; } - sbyte IConvertible.ToSByte(IFormatProvider provider) { throw new InvalidCastException(); } - float IConvertible.ToSingle(IFormatProvider provider) { throw new InvalidCastException(); } - string IConvertible.ToString(IFormatProvider provider) { throw new InvalidCastException(); } - ushort IConvertible.ToUInt16(IFormatProvider provider) { throw new InvalidCastException(); } - uint IConvertible.ToUInt32(IFormatProvider provider) { throw new InvalidCastException(); } - ulong IConvertible.ToUInt64(IFormatProvider provider) { throw new InvalidCastException(); } - } + bool IConvertible.ToBoolean(IFormatProvider provider) + { + throw new InvalidCastException(); + } - public class TestClassConvertable - { - public ConvertibleId Id; - public int X; - } + byte IConvertible.ToByte(IFormatProvider provider) + { + throw new InvalidCastException(); + } - [Test] - public void ConvertibleIdTest() - { - var c = new TestClassConvertable { Id = new ConvertibleId { Value = 1 }, X = 2 }; - var s = JsonConvert.SerializeObject(c, Formatting.Indented); - Assert.AreEqual(@"{ + char IConvertible.ToChar(IFormatProvider provider) + { + throw new InvalidCastException(); + } + + DateTime IConvertible.ToDateTime(IFormatProvider provider) + { + throw new InvalidCastException(); + } + + decimal IConvertible.ToDecimal(IFormatProvider provider) + { + throw new InvalidCastException(); + } + + double IConvertible.ToDouble(IFormatProvider provider) + { + throw new InvalidCastException(); + } + + short IConvertible.ToInt16(IFormatProvider provider) + { + return (short)Value; + } + + int IConvertible.ToInt32(IFormatProvider provider) + { + return Value; + } + + long IConvertible.ToInt64(IFormatProvider provider) + { + return (long)Value; + } + + sbyte IConvertible.ToSByte(IFormatProvider provider) + { + throw new InvalidCastException(); + } + + float IConvertible.ToSingle(IFormatProvider provider) + { + throw new InvalidCastException(); + } + + string IConvertible.ToString(IFormatProvider provider) + { + throw new InvalidCastException(); + } + + ushort IConvertible.ToUInt16(IFormatProvider provider) + { + throw new InvalidCastException(); + } + + uint IConvertible.ToUInt32(IFormatProvider provider) + { + throw new InvalidCastException(); + } + + ulong IConvertible.ToUInt64(IFormatProvider provider) + { + throw new InvalidCastException(); + } + } + + public class TestClassConvertable + { + public ConvertibleId Id; + public int X; + } + + [Test] + public void ConvertibleIdTest() + { + var c = new TestClassConvertable { Id = new ConvertibleId { Value = 1 }, X = 2 }; + var s = JsonConvert.SerializeObject(c, Formatting.Indented); + Assert.AreEqual(@"{ ""Id"": ""1"", ""X"": 2 }", s); - } + } #endif - } + } - public class PersonReference - { - internal Guid Id { get; set; } - public string Name { get; set; } - public PersonReference Spouse { get; set; } - } + public class PersonReference + { + internal Guid Id { get; set; } + public string Name { get; set; } + public PersonReference Spouse { get; set; } + } - public enum Antworten - { - First, - Second - } + public enum Antworten + { + First, + Second + } - public class SelectListItem - { - public string Text { get; set; } - public string Value { get; set; } - public bool Selected { get; set; } - } + public class SelectListItem + { + public string Text { get; set; } + public string Value { get; set; } + public bool Selected { get; set; } + } #if !(SILVERLIGHT || NETFX_CORE || PORTABLE) - [Serializable] - public class AnswerFilterModel - { - [NonSerialized] - private readonly IList answerValues; - - /// - /// Initializes a new instance of the class. - /// - public AnswerFilterModel() + [Serializable] + public class AnswerFilterModel { - this.answerValues = (from answer in Enum.GetNames(typeof(Antworten)) - select new SelectListItem { Text = answer, Value = answer, Selected = false }) - .ToList(); + [NonSerialized] + private readonly IList answerValues; + + /// + /// Initializes a new instance of the class. + /// + public AnswerFilterModel() + { + answerValues = (from answer in Enum.GetNames(typeof(Antworten)) + select new SelectListItem { Text = answer, Value = answer, Selected = false }) + .ToList(); + } + + /// + /// Gets or sets a value indicating whether active. + /// + public bool Active { get; set; } + + /// + /// Gets or sets a value indicating whether ja. + /// nach bisherigen Antworten. + /// + public bool Ja { get; set; } + + /// + /// Gets or sets a value indicating whether handlungsbedarf. + /// + public bool Handlungsbedarf { get; set; } + + /// + /// Gets or sets a value indicating whether beratungsbedarf. + /// + public bool Beratungsbedarf { get; set; } + + /// + /// Gets or sets a value indicating whether unzutreffend. + /// + public bool Unzutreffend { get; set; } + + /// + /// Gets or sets a value indicating whether unbeantwortet. + /// + public bool Unbeantwortet { get; set; } + + /// + /// Gets the answer values. + /// + public IEnumerable AnswerValues + { + get { return answerValues; } + } } - /// - /// Gets or sets a value indicating whether active. - /// - public bool Active { get; set; } - - /// - /// Gets or sets a value indicating whether ja. - /// nach bisherigen Antworten. - /// - public bool Ja { get; set; } - - /// - /// Gets or sets a value indicating whether handlungsbedarf. - /// - public bool Handlungsbedarf { get; set; } - - /// - /// Gets or sets a value indicating whether beratungsbedarf. - /// - public bool Beratungsbedarf { get; set; } - - /// - /// Gets or sets a value indicating whether unzutreffend. - /// - public bool Unzutreffend { get; set; } - - /// - /// Gets or sets a value indicating whether unbeantwortet. - /// - public bool Unbeantwortet { get; set; } - - /// - /// Gets the answer values. - /// - public IEnumerable AnswerValues + [Serializable] + public class PersonSerializable { - get { return this.answerValues; } - } - } + public PersonSerializable() + { + } - [Serializable] - public class PersonSerializable - { - public PersonSerializable() - { } + private string _name = ""; - private string _name = ""; - public string Name - { - get { return _name; } - set { _name = value; } - } + public string Name + { + get { return _name; } + set { _name = value; } + } - [NonSerialized] - private int _age = 0; - public int Age - { - get { return _age; } - set { _age = value; } + [NonSerialized] + private int _age = 0; + + public int Age + { + get { return _age; } + set { _age = value; } + } } - } #endif - public class Event - { - public string EventName { get; set; } - public string Venue { get; set; } - - [JsonProperty(ItemConverterType = typeof(JavaScriptDateTimeConverter))] - public IList Performances { get; set; } - } - - public class PropertyItemConverter - { - [JsonProperty(ItemConverterType = typeof(MetroStringConverter))] - public IList Data { get; set; } - } - - public class PersonWithPrivateConstructor - { - private PersonWithPrivateConstructor() - { } - - public static PersonWithPrivateConstructor CreatePerson() + public class Event { - return new PersonWithPrivateConstructor(); + public string EventName { get; set; } + public string Venue { get; set; } + + [JsonProperty(ItemConverterType = typeof(JavaScriptDateTimeConverter))] + public IList Performances { get; set; } } - public string Name { get; set; } - - public int Age { get; set; } - } - - public class DateTimeWrapper - { - public DateTime Value { get; set; } - } - - public class Widget1 - { - public WidgetId1? Id { get; set; } - } - - [JsonConverter(typeof(WidgetIdJsonConverter))] - public struct WidgetId1 - { - public long Value { get; set; } - } - - public class WidgetIdJsonConverter : JsonConverter - { - public override bool CanConvert(Type objectType) + public class PropertyItemConverter { - return objectType == typeof(WidgetId1) || objectType == typeof(WidgetId1?); + [JsonProperty(ItemConverterType = typeof(MetroStringConverter))] + public IList Data { get; set; } } - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + public class PersonWithPrivateConstructor { - WidgetId1 id = (WidgetId1)value; - writer.WriteValue(id.Value.ToString()); + private PersonWithPrivateConstructor() + { + } + + public static PersonWithPrivateConstructor CreatePerson() + { + return new PersonWithPrivateConstructor(); + } + + public string Name { get; set; } + + public int Age { get; set; } } - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + public class DateTimeWrapper { - if (reader.TokenType == JsonToken.Null) - return null; - return new WidgetId1 { Value = int.Parse(reader.Value.ToString()) }; - } - } - - - public enum MyEnum - { - Value1, - Value2, - Value3 - } - - public class WithEnums - { - public int Id { get; set; } - public MyEnum? NullableEnum { get; set; } - } - - public class Item - { - public Guid SourceTypeID { get; set; } - public Guid BrokerID { get; set; } - public double Latitude { get; set; } - public double Longitude { get; set; } - public DateTime TimeStamp { get; set; } - [JsonProperty(TypeNameHandling = TypeNameHandling.All)] - public object Payload { get; set; } - } - - public class NullableGuid - { - public Guid? Id { get; set; } - } - - public class Widget - { - public WidgetId? Id { get; set; } - } - - public struct WidgetId - { - public string Value { get; set; } - } - - public class DecimalTestClass - { - public decimal Quantity { get; set; } - public double OptionalQuantity { get; set; } - } - - public class TestObject - { - public TestObject() - { - + public DateTime Value { get; set; } } - public TestObject(string name, byte[] data) + public class Widget1 { - Name = name; - Data = data; + public WidgetId1? Id { get; set; } } - public string Name { get; set; } - public byte[] Data { get; set; } - } + [JsonConverter(typeof(WidgetIdJsonConverter))] + public struct WidgetId1 + { + public long Value { get; set; } + } - public class UriGuidTimeSpanTestClass - { - public Guid Guid { get; set; } - public Guid? NullableGuid { get; set; } - public TimeSpan TimeSpan { get; set; } - public TimeSpan? NullableTimeSpan { get; set; } - public Uri Uri { get; set; } - } + public class WidgetIdJsonConverter : JsonConverter + { + public override bool CanConvert(Type objectType) + { + return objectType == typeof(WidgetId1) || objectType == typeof(WidgetId1?); + } - internal class Aa - { - public int no; - } + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + WidgetId1 id = (WidgetId1)value; + writer.WriteValue(id.Value.ToString()); + } - internal class Bb : Aa - { - public new bool no; - } + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) + return null; + return new WidgetId1 { Value = int.Parse(reader.Value.ToString()) }; + } + } + + + public enum MyEnum + { + Value1, + Value2, + Value3 + } + + public class WithEnums + { + public int Id { get; set; } + public MyEnum? NullableEnum { get; set; } + } + + public class Item + { + public Guid SourceTypeID { get; set; } + public Guid BrokerID { get; set; } + public double Latitude { get; set; } + public double Longitude { get; set; } + public DateTime TimeStamp { get; set; } + + [JsonProperty(TypeNameHandling = TypeNameHandling.All)] + public object Payload { get; set; } + } + + public class NullableGuid + { + public Guid? Id { get; set; } + } + + public class Widget + { + public WidgetId? Id { get; set; } + } + + public struct WidgetId + { + public string Value { get; set; } + } + + public class DecimalTestClass + { + public decimal Quantity { get; set; } + public double OptionalQuantity { get; set; } + } + + public class TestObject + { + public TestObject() + { + } + + public TestObject(string name, byte[] data) + { + Name = name; + Data = data; + } + + public string Name { get; set; } + public byte[] Data { get; set; } + } + + public class UriGuidTimeSpanTestClass + { + public Guid Guid { get; set; } + public Guid? NullableGuid { get; set; } + public TimeSpan TimeSpan { get; set; } + public TimeSpan? NullableTimeSpan { get; set; } + public Uri Uri { get; set; } + } + + internal class Aa + { + public int no; + } + + internal class Bb : Aa + { + public new bool no; + } #if !(NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE) - [JsonObject(MemberSerialization.OptIn)] - public class GameObject - { - [JsonProperty] - public string Id { get; set; } - - [JsonProperty] - public string Name { get; set; } - - [JsonProperty] public ConcurrentDictionary Components; - - public GameObject() + [JsonObject(MemberSerialization.OptIn)] + public class GameObject { - Components = new ConcurrentDictionary(); + [JsonProperty] + public string Id { get; set; } + + [JsonProperty] + public string Name { get; set; } + + [JsonProperty] + public ConcurrentDictionary Components; + + public GameObject() + { + Components = new ConcurrentDictionary(); + } } - } - - [JsonObject(MemberSerialization.OptIn)] - public class Component - { - [JsonIgnore] // Ignore circular reference - public GameObject GameObject { get; set; } - - public Component() + [JsonObject(MemberSerialization.OptIn)] + public class Component { + [JsonIgnore] // Ignore circular reference + public GameObject GameObject { get; set; } + + public Component() + { + } } - } - [JsonObject(MemberSerialization.OptIn)] - public class TestComponent : Component - { - [JsonProperty] - public int MyProperty { get; set; } - - public TestComponent() + [JsonObject(MemberSerialization.OptIn)] + public class TestComponent : Component { + [JsonProperty] + public int MyProperty { get; set; } + + public TestComponent() + { + } } - } #endif - [JsonObject(MemberSerialization.OptIn)] - public class TestComponentSimple - { - [JsonProperty] - public int MyProperty { get; set; } - - public TestComponentSimple() + [JsonObject(MemberSerialization.OptIn)] + public class TestComponentSimple { + [JsonProperty] + public int MyProperty { get; set; } + + public TestComponentSimple() + { + } } - } - [JsonObject(ItemRequired = Required.Always)] - public class RequiredObject - { - public int? NonAttributeProperty { get; set; } - [JsonProperty] - public int? UnsetProperty { get; set; } - [JsonProperty(Required = Required.Default)] - public int? DefaultProperty { get; set; } - [JsonProperty(Required = Required.AllowNull)] - public int? AllowNullProperty { get; set; } - [JsonProperty(Required = Required.Always)] - public int? AlwaysProperty { get; set; } - } - - public class MetroStringConverter : JsonConverter - { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + [JsonObject(ItemRequired = Required.Always)] + public class RequiredObject { + public int? NonAttributeProperty { get; set; } + + [JsonProperty] + public int? UnsetProperty { get; set; } + + [JsonProperty(Required = Required.Default)] + public int? DefaultProperty { get; set; } + + [JsonProperty(Required = Required.AllowNull)] + public int? AllowNullProperty { get; set; } + + [JsonProperty(Required = Required.Always)] + public int? AlwaysProperty { get; set; } + } + + public class MetroStringConverter : JsonConverter + { + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { #if !(SILVERLIGHT || NETFX_CORE) - writer.WriteValue(":::" + value.ToString().ToUpper(CultureInfo.InvariantCulture) + ":::"); + writer.WriteValue(":::" + value.ToString().ToUpper(CultureInfo.InvariantCulture) + ":::"); #else writer.WriteValue(":::" + value.ToString().ToUpper() + ":::"); #endif - } + } - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - string s = (string)reader.Value; - if (s == null) - return null; + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + string s = (string)reader.Value; + if (s == null) + return null; #if !(SILVERLIGHT || NETFX_CORE) - return s.ToLower(CultureInfo.InvariantCulture).Trim(new[] { ':' }); + return s.ToLower(CultureInfo.InvariantCulture).Trim(new[] { ':' }); #else return s.ToLower().Trim(new[] { ':' }); #endif + } + + public override bool CanConvert(Type objectType) + { + return objectType == typeof(string); + } } - public override bool CanConvert(Type objectType) - { - return objectType == typeof(string); - } - } - - public class MetroPropertyNameResolver : DefaultContractResolver - { - protected internal override string ResolvePropertyName(string propertyName) + public class MetroPropertyNameResolver : DefaultContractResolver { + protected internal override string ResolvePropertyName(string propertyName) + { #if !(SILVERLIGHT || NETFX_CORE) - return ":::" + propertyName.ToUpper(CultureInfo.InvariantCulture) + ":::"; + return ":::" + propertyName.ToUpper(CultureInfo.InvariantCulture) + ":::"; #else return ":::" + propertyName.ToUpper() + ":::"; #endif + } } - } #if !(NET20 || NET35) - [DataContract] - public class DataContractSerializationAttributesClass - { - public string NoAttribute { get; set; } - [IgnoreDataMember] - public string IgnoreDataMemberAttribute { get; set; } - [DataMember] - public string DataMemberAttribute { get; set; } - [IgnoreDataMember] - [DataMember] - public string IgnoreDataMemberAndDataMemberAttribute { get; set; } - } + [DataContract] + public class DataContractSerializationAttributesClass + { + public string NoAttribute { get; set; } - public class PocoDataContractSerializationAttributesClass - { - public string NoAttribute { get; set; } - [IgnoreDataMember] - public string IgnoreDataMemberAttribute { get; set; } - [DataMember] - public string DataMemberAttribute { get; set; } - [IgnoreDataMember] - [DataMember] - public string IgnoreDataMemberAndDataMemberAttribute { get; set; } - } + [IgnoreDataMember] + public string IgnoreDataMemberAttribute { get; set; } + + [DataMember] + public string DataMemberAttribute { get; set; } + + [IgnoreDataMember] + [DataMember] + public string IgnoreDataMemberAndDataMemberAttribute { get; set; } + } + + public class PocoDataContractSerializationAttributesClass + { + public string NoAttribute { get; set; } + + [IgnoreDataMember] + public string IgnoreDataMemberAttribute { get; set; } + + [DataMember] + public string DataMemberAttribute { get; set; } + + [IgnoreDataMember] + [DataMember] + public string IgnoreDataMemberAndDataMemberAttribute { get; set; } + } #endif - public class Array2D - { - public string Before { get; set; } - public int[,] Coordinates { get; set; } - public string After { get; set; } - } - - public class Array3D - { - public string Before { get; set; } - public int[,,] Coordinates { get; set; } - public string After { get; set; } - } - - public class Array3DWithConverter - { - public string Before { get; set; } - [JsonProperty(ItemConverterType = typeof(IntToFloatConverter))] - public int[, ,] Coordinates { get; set; } - public string After { get; set; } - } - - public class IntToFloatConverter : JsonConverter - { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + public class Array2D { - writer.WriteValue(Convert.ToDouble(value)); + public string Before { get; set; } + public int[,] Coordinates { get; set; } + public string After { get; set; } } - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + public class Array3D { - return Convert.ToInt32(reader.Value); + public string Before { get; set; } + public int[,,] Coordinates { get; set; } + public string After { get; set; } } - public override bool CanConvert(Type objectType) + public class Array3DWithConverter { - return objectType == typeof (int); - } - } + public string Before { get; set; } - public class ShouldSerializeTestClass - { - internal bool _shouldSerializeName; + [JsonProperty(ItemConverterType = typeof(IntToFloatConverter))] + public int[,,] Coordinates { get; set; } - 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 string After { get; set; } } - public bool ShouldSerializeName() + public class IntToFloatConverter : JsonConverter { - return _shouldSerializeName; - } - } + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + writer.WriteValue(Convert.ToDouble(value)); + } - public class SpecifiedTestClass - { - private bool _nameSpecified; + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + return Convert.ToInt32(reader.Value); + } - 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; } + public override bool CanConvert(Type objectType) + { + return objectType == typeof(int); + } } - [JsonIgnore] - public bool WeightSpecified; - - [JsonIgnore] - [System.Xml.Serialization.XmlIgnoreAttribute] - public bool HeightSpecified; - - [JsonIgnore] - public bool FavoriteNumberSpecified + public class ShouldSerializeTestClass { - // get only example - get { return FavoriteNumber != 0; } - } - } + internal bool _shouldSerializeName; - public class DirectoryAccount - { - // normal deserialization - public string DisplayName { get; set; } + public string Name { get; set; } + public int Age { get; set; } - // these properties are set in OnDeserialized - public string UserName { get; set; } - public string Domain { get; set; } + public void ShouldSerializeAge() + { + // dummy. should never be used because it doesn't return bool + } - [JsonExtensionData] - private IDictionary _additionalData; - - [OnDeserialized] - private void OnDeserialized(StreamingContext context) - { - // SAMAccountName is not deserialized to any property - // and so it is added to the extension data dictionary - string samAccountName = (string)_additionalData["SAMAccountName"]; - - Domain = samAccountName.Split('\\')[0]; - UserName = samAccountName.Split('\\')[1]; + public bool ShouldSerializeName() + { + return _shouldSerializeName; + } } - public DirectoryAccount() + public class SpecifiedTestClass { - _additionalData = new Dictionary(); + 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; } + } + } + + public class DirectoryAccount + { + // normal deserialization + public string DisplayName { get; set; } + + // these properties are set in OnDeserialized + public string UserName { get; set; } + public string Domain { get; set; } + + [JsonExtensionData] + private IDictionary _additionalData; + + [OnDeserialized] + private void OnDeserialized(StreamingContext context) + { + // SAMAccountName is not deserialized to any property + // and so it is added to the extension data dictionary + string samAccountName = (string)_additionalData["SAMAccountName"]; + + Domain = samAccountName.Split('\\')[0]; + UserName = samAccountName.Split('\\')[1]; + } + + public DirectoryAccount() + { + _additionalData = new Dictionary(); + } } - } #if !NETFX_CORE - public struct Ratio : IConvertible, IFormattable, ISerializable - { - private readonly int _numerator; - private readonly int _denominator; - - public Ratio(int numerator, int denominator) + public struct Ratio : IConvertible, IFormattable, ISerializable { - _numerator = numerator; - _denominator = denominator; - } + private readonly int _numerator; + private readonly int _denominator; - #region Properties - - public int Numerator - { - get { return _numerator; } - } - - public int Denominator - { - get { return _denominator; } - } - - public bool IsNan - { - get { return _denominator == 0; } - } - - #endregion - - #region Serialization operations - - public Ratio(SerializationInfo info, StreamingContext context) - { - _numerator = info.GetInt32("n"); - _denominator = info.GetInt32("d"); - } - - public void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue("n", _numerator); - info.AddValue("d", _denominator); - } - - #endregion - - #region IConvertible Members - - public TypeCode GetTypeCode() - { - return TypeCode.Object; - } - - public bool ToBoolean(IFormatProvider provider) - { - return this._numerator == 0; - } - - public byte ToByte(IFormatProvider provider) - { - return (byte)(this._numerator / this._denominator); - } - - public char ToChar(IFormatProvider provider) - { - return Convert.ToChar(this._numerator / this._denominator); - } - - public DateTime ToDateTime(IFormatProvider provider) - { - return Convert.ToDateTime(this._numerator / this._denominator); - } - - public decimal ToDecimal(IFormatProvider provider) - { - return (decimal)this._numerator / this._denominator; - } - - public double ToDouble(IFormatProvider provider) - { - return this._denominator == 0 - ? double.NaN - : (double)this._numerator / this._denominator; - } - - public short ToInt16(IFormatProvider provider) - { - return (short)(this._numerator / this._denominator); - } - - public int ToInt32(IFormatProvider provider) - { - return this._numerator / this._denominator; - } - - public long ToInt64(IFormatProvider provider) - { - return this._numerator / this._denominator; - } - - public sbyte ToSByte(IFormatProvider provider) - { - return (sbyte)(this._numerator / this._denominator); - } - - public float ToSingle(IFormatProvider provider) - { - return this._denominator == 0 - ? float.NaN - : (float)this._numerator / this._denominator; - } - - public string ToString(IFormatProvider provider) - { - return this._denominator == 1 - ? this._numerator.ToString(provider) - : this._numerator.ToString(provider) + "/" + this._denominator.ToString(provider); - } - - public object ToType(Type conversionType, IFormatProvider provider) - { - return Convert.ChangeType(ToDouble(provider), conversionType, provider); - } - - public ushort ToUInt16(IFormatProvider provider) - { - return (ushort)(this._numerator / this._denominator); - } - - public uint ToUInt32(IFormatProvider provider) - { - return (uint)(this._numerator / this._denominator); - } - - public ulong ToUInt64(IFormatProvider provider) - { - return (ulong)(this._numerator / this._denominator); - } - - #endregion - - #region String operations - - public override string ToString() - { - return ToString(CultureInfo.InvariantCulture); - } - - public string ToString(string format, IFormatProvider formatProvider) - { - return ToString(CultureInfo.InvariantCulture); - } - - public static Ratio Parse(string input) - { - return Parse(input, CultureInfo.InvariantCulture); - } - - public static Ratio Parse(string input, IFormatProvider formatProvider) - { - Ratio result; - if (!TryParse(input, formatProvider, out result)) - { - throw new FormatException( - string.Format( - CultureInfo.InvariantCulture, - "Text '{0}' is invalid text representation of ratio", - input)); - } - return result; - } - - public static bool TryParse(string input, out Ratio result) - { - return TryParse(input, CultureInfo.InvariantCulture, out result); - } - - public static bool TryParse(string input, IFormatProvider formatProvider, out Ratio result) - { - if (input != null) - { - var fractionIndex = input.IndexOf('/'); - - int numerator; - if (fractionIndex < 0) + public Ratio(int numerator, int denominator) { - if (int.TryParse(input, NumberStyles.Integer, formatProvider, out numerator)) - { - result = new Ratio(numerator, 1); - return true; - } + _numerator = numerator; + _denominator = denominator; } - else + + #region Properties + public int Numerator { - int denominator; - if (int.TryParse(input.Substring(0, fractionIndex), NumberStyles.Integer, formatProvider, out numerator) && - int.TryParse(input.Substring(fractionIndex + 1), NumberStyles.Integer, formatProvider, out denominator)) - { - result = new Ratio(numerator, denominator); - return true; - } + get { return _numerator; } } - } - result = default(Ratio); - return false; + public int Denominator + { + get { return _denominator; } + } + + public bool IsNan + { + get { return _denominator == 0; } + } + #endregion + + #region Serialization operations + public Ratio(SerializationInfo info, StreamingContext context) + { + _numerator = info.GetInt32("n"); + _denominator = info.GetInt32("d"); + } + + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("n", _numerator); + info.AddValue("d", _denominator); + } + #endregion + + #region IConvertible Members + public TypeCode GetTypeCode() + { + return TypeCode.Object; + } + + public bool ToBoolean(IFormatProvider provider) + { + return _numerator == 0; + } + + public byte ToByte(IFormatProvider provider) + { + return (byte)(_numerator / _denominator); + } + + public char ToChar(IFormatProvider provider) + { + return Convert.ToChar(_numerator / _denominator); + } + + public DateTime ToDateTime(IFormatProvider provider) + { + return Convert.ToDateTime(_numerator / _denominator); + } + + public decimal ToDecimal(IFormatProvider provider) + { + return (decimal)_numerator / _denominator; + } + + public double ToDouble(IFormatProvider provider) + { + return _denominator == 0 + ? double.NaN + : (double)_numerator / _denominator; + } + + public short ToInt16(IFormatProvider provider) + { + return (short)(_numerator / _denominator); + } + + public int ToInt32(IFormatProvider provider) + { + return _numerator / _denominator; + } + + public long ToInt64(IFormatProvider provider) + { + return _numerator / _denominator; + } + + public sbyte ToSByte(IFormatProvider provider) + { + return (sbyte)(_numerator / _denominator); + } + + public float ToSingle(IFormatProvider provider) + { + return _denominator == 0 + ? float.NaN + : (float)_numerator / _denominator; + } + + public string ToString(IFormatProvider provider) + { + return _denominator == 1 + ? _numerator.ToString(provider) + : _numerator.ToString(provider) + "/" + _denominator.ToString(provider); + } + + public object ToType(Type conversionType, IFormatProvider provider) + { + return Convert.ChangeType(ToDouble(provider), conversionType, provider); + } + + public ushort ToUInt16(IFormatProvider provider) + { + return (ushort)(_numerator / _denominator); + } + + public uint ToUInt32(IFormatProvider provider) + { + return (uint)(_numerator / _denominator); + } + + public ulong ToUInt64(IFormatProvider provider) + { + return (ulong)(_numerator / _denominator); + } + #endregion + + #region String operations + public override string ToString() + { + return ToString(CultureInfo.InvariantCulture); + } + + public string ToString(string format, IFormatProvider formatProvider) + { + return ToString(CultureInfo.InvariantCulture); + } + + public static Ratio Parse(string input) + { + return Parse(input, CultureInfo.InvariantCulture); + } + + public static Ratio Parse(string input, IFormatProvider formatProvider) + { + Ratio result; + if (!TryParse(input, formatProvider, out result)) + { + throw new FormatException( + string.Format( + CultureInfo.InvariantCulture, + "Text '{0}' is invalid text representation of ratio", + input)); + } + return result; + } + + public static bool TryParse(string input, out Ratio result) + { + return TryParse(input, CultureInfo.InvariantCulture, out result); + } + + public static bool TryParse(string input, IFormatProvider formatProvider, out Ratio result) + { + if (input != null) + { + var fractionIndex = input.IndexOf('/'); + + int numerator; + if (fractionIndex < 0) + { + if (int.TryParse(input, NumberStyles.Integer, formatProvider, out numerator)) + { + result = new Ratio(numerator, 1); + return true; + } + } + else + { + int denominator; + if (int.TryParse(input.Substring(0, fractionIndex), NumberStyles.Integer, formatProvider, out numerator) && + int.TryParse(input.Substring(fractionIndex + 1), NumberStyles.Integer, formatProvider, out denominator)) + { + result = new Ratio(numerator, denominator); + return true; + } + } + } + + result = default(Ratio); + return false; + } + #endregion } - - #endregion - } #endif } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Serialization/MissingMemberHandlingTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/MissingMemberHandlingTests.cs index d101539b..28897a21 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/MissingMemberHandlingTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/MissingMemberHandlingTests.cs @@ -29,6 +29,7 @@ using Newtonsoft.Json.Converters; using Newtonsoft.Json.Tests.TestObjects; #if !NETFX_CORE using NUnit.Framework; + #else using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; @@ -37,116 +38,110 @@ using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAtt namespace Newtonsoft.Json.Tests.Serialization { - [TestFixture] - public class MissingMemberHandlingTests : TestFixtureBase - { - [Test] - public void MissingMemberDeserialize() + [TestFixture] + public class MissingMemberHandlingTests : TestFixtureBase { - Product product = new Product(); - - product.Name = "Apple"; - product.ExpiryDate = new DateTime(2008, 12, 28); - product.Price = 3.99M; - product.Sizes = new string[] { "Small", "Medium", "Large" }; - - string output = JsonConvert.SerializeObject(product, Formatting.Indented); - //{ - // "Name": "Apple", - // "ExpiryDate": new Date(1230422400000), - // "Price": 3.99, - // "Sizes": [ - // "Small", - // "Medium", - // "Large" - // ] - //} - - ExceptionAssert.Throws( - @"Could not find member 'Price' on object of type 'ProductShort'. Path 'Price', line 4, position 11.", - () => - { - ProductShort deserializedProductShort = (ProductShort)JsonConvert.DeserializeObject(output, typeof(ProductShort), new JsonSerializerSettings { MissingMemberHandling = MissingMemberHandling.Error }); - }); - } - - [Test] - public void MissingMemberDeserializeOkay() - { - Product product = new Product(); - - product.Name = "Apple"; - product.ExpiryDate = new DateTime(2008, 12, 28); - product.Price = 3.99M; - product.Sizes = new string[] { "Small", "Medium", "Large" }; - - string output = JsonConvert.SerializeObject(product); - //{ - // "Name": "Apple", - // "ExpiryDate": new Date(1230422400000), - // "Price": 3.99, - // "Sizes": [ - // "Small", - // "Medium", - // "Large" - // ] - //} - - JsonSerializer jsonSerializer = new JsonSerializer(); - jsonSerializer.MissingMemberHandling = MissingMemberHandling.Ignore; - - object deserializedValue; - - using (JsonReader jsonReader = new JsonTextReader(new StringReader(output))) - { - deserializedValue = jsonSerializer.Deserialize(jsonReader, typeof(ProductShort)); - } - - ProductShort deserializedProductShort = (ProductShort)deserializedValue; - - Assert.AreEqual("Apple", deserializedProductShort.Name); - Assert.AreEqual(new DateTime(2008, 12, 28), deserializedProductShort.ExpiryDate); - Assert.AreEqual("Small", deserializedProductShort.Sizes[0]); - Assert.AreEqual("Medium", deserializedProductShort.Sizes[1]); - Assert.AreEqual("Large", deserializedProductShort.Sizes[2]); - } - - [Test] - public void MissingMemberIgnoreComplexValue() - { - JsonSerializer serializer = new JsonSerializer { MissingMemberHandling = MissingMemberHandling.Ignore }; - serializer.Converters.Add(new JavaScriptDateTimeConverter()); - - string response = @"{""PreProperty"":1,""DateProperty"":new Date(1225962698973),""PostProperty"":2}"; - - MyClass myClass = (MyClass)serializer.Deserialize(new StringReader(response), typeof(MyClass)); - - Assert.AreEqual(1, myClass.PreProperty); - Assert.AreEqual(2, myClass.PostProperty); - } - - [Test] - public void MissingMemeber() - { - string json = @"{""Missing"":1}"; - - ExceptionAssert.Throws( - "Could not find member 'Missing' on object of type 'DoubleClass'. Path 'Missing', line 1, position 11.", - () => - { - JsonConvert.DeserializeObject(json, new JsonSerializerSettings { MissingMemberHandling = MissingMemberHandling.Error }); - }); - } - - [Test] - public void MissingJson() - { - string json = @"{}"; - - JsonConvert.DeserializeObject(json, new JsonSerializerSettings + [Test] + public void MissingMemberDeserialize() { - MissingMemberHandling = MissingMemberHandling.Error - }); + Product product = new Product(); + + product.Name = "Apple"; + product.ExpiryDate = new DateTime(2008, 12, 28); + product.Price = 3.99M; + product.Sizes = new string[] { "Small", "Medium", "Large" }; + + string output = JsonConvert.SerializeObject(product, Formatting.Indented); + //{ + // "Name": "Apple", + // "ExpiryDate": new Date(1230422400000), + // "Price": 3.99, + // "Sizes": [ + // "Small", + // "Medium", + // "Large" + // ] + //} + + ExceptionAssert.Throws( + @"Could not find member 'Price' on object of type 'ProductShort'. Path 'Price', line 4, position 11.", + () => { ProductShort deserializedProductShort = (ProductShort)JsonConvert.DeserializeObject(output, typeof(ProductShort), new JsonSerializerSettings { MissingMemberHandling = MissingMemberHandling.Error }); }); + } + + [Test] + public void MissingMemberDeserializeOkay() + { + Product product = new Product(); + + product.Name = "Apple"; + product.ExpiryDate = new DateTime(2008, 12, 28); + product.Price = 3.99M; + product.Sizes = new string[] { "Small", "Medium", "Large" }; + + string output = JsonConvert.SerializeObject(product); + //{ + // "Name": "Apple", + // "ExpiryDate": new Date(1230422400000), + // "Price": 3.99, + // "Sizes": [ + // "Small", + // "Medium", + // "Large" + // ] + //} + + JsonSerializer jsonSerializer = new JsonSerializer(); + jsonSerializer.MissingMemberHandling = MissingMemberHandling.Ignore; + + object deserializedValue; + + using (JsonReader jsonReader = new JsonTextReader(new StringReader(output))) + { + deserializedValue = jsonSerializer.Deserialize(jsonReader, typeof(ProductShort)); + } + + ProductShort deserializedProductShort = (ProductShort)deserializedValue; + + Assert.AreEqual("Apple", deserializedProductShort.Name); + Assert.AreEqual(new DateTime(2008, 12, 28), deserializedProductShort.ExpiryDate); + Assert.AreEqual("Small", deserializedProductShort.Sizes[0]); + Assert.AreEqual("Medium", deserializedProductShort.Sizes[1]); + Assert.AreEqual("Large", deserializedProductShort.Sizes[2]); + } + + [Test] + public void MissingMemberIgnoreComplexValue() + { + JsonSerializer serializer = new JsonSerializer { MissingMemberHandling = MissingMemberHandling.Ignore }; + serializer.Converters.Add(new JavaScriptDateTimeConverter()); + + string response = @"{""PreProperty"":1,""DateProperty"":new Date(1225962698973),""PostProperty"":2}"; + + MyClass myClass = (MyClass)serializer.Deserialize(new StringReader(response), typeof(MyClass)); + + Assert.AreEqual(1, myClass.PreProperty); + Assert.AreEqual(2, myClass.PostProperty); + } + + [Test] + public void MissingMemeber() + { + string json = @"{""Missing"":1}"; + + ExceptionAssert.Throws( + "Could not find member 'Missing' on object of type 'DoubleClass'. Path 'Missing', line 1, position 11.", + () => { JsonConvert.DeserializeObject(json, new JsonSerializerSettings { MissingMemberHandling = MissingMemberHandling.Error }); }); + } + + [Test] + public void MissingJson() + { + string json = @"{}"; + + JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + MissingMemberHandling = MissingMemberHandling.Error + }); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Serialization/NullValueHandlingTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/NullValueHandlingTests.cs index 48facbb2..f4e27a11 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/NullValueHandlingTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/NullValueHandlingTests.cs @@ -28,6 +28,7 @@ using System.IO; using Newtonsoft.Json.Tests.TestObjects; #if !NETFX_CORE using NUnit.Framework; + #else using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; @@ -36,80 +37,80 @@ using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAtt namespace Newtonsoft.Json.Tests.Serialization { - [TestFixture] - public class NullValueHandlingTests : TestFixtureBase - { + [TestFixture] + public class NullValueHandlingTests : TestFixtureBase + { #if !NET20 - [Test] - public void DeserializeNullIntoDateTime() - { - DateTimeTestClass c = JsonConvert.DeserializeObject(@"{DateTimeField:null}", new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); - Assert.AreEqual(c.DateTimeField, default(DateTime)); - } + [Test] + public void DeserializeNullIntoDateTime() + { + DateTimeTestClass c = JsonConvert.DeserializeObject(@"{DateTimeField:null}", new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + Assert.AreEqual(c.DateTimeField, default(DateTime)); + } - [Test] - public void DeserializeEmptyStringIntoDateTimeWithEmptyStringDefaultValue() - { - DateTimeTestClass c = JsonConvert.DeserializeObject(@"{DateTimeField:""""}", new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); - Assert.AreEqual(c.DateTimeField, default(DateTime)); - } + [Test] + public void DeserializeEmptyStringIntoDateTimeWithEmptyStringDefaultValue() + { + DateTimeTestClass c = JsonConvert.DeserializeObject(@"{DateTimeField:""""}", new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + Assert.AreEqual(c.DateTimeField, default(DateTime)); + } #endif - [Test] - public void NullValueHandlingSerialization() - { - Store s1 = new Store(); + [Test] + public void NullValueHandlingSerialization() + { + Store s1 = new Store(); - JsonSerializer jsonSerializer = new JsonSerializer(); - jsonSerializer.NullValueHandling = NullValueHandling.Ignore; + JsonSerializer jsonSerializer = new JsonSerializer(); + jsonSerializer.NullValueHandling = NullValueHandling.Ignore; - StringWriter sw = new StringWriter(); - jsonSerializer.Serialize(sw, s1); + StringWriter sw = new StringWriter(); + jsonSerializer.Serialize(sw, s1); - //JsonConvert.ConvertDateTimeToJavaScriptTicks(s1.Establised.DateTime) + //JsonConvert.ConvertDateTimeToJavaScriptTicks(s1.Establised.DateTime) - Assert.AreEqual(@"{""Color"":4,""Establised"":""2010-01-22T01:01:01Z"",""Width"":1.1,""Employees"":999,""RoomsPerFloor"":[1,2,3,4,5,6,7,8,9],""Open"":false,""Symbol"":""@"",""Mottos"":[""Hello World"",""öäüÖÄÜ\\'{new Date(12345);}[222]_µ@²³~"",null,"" ""],""Cost"":100980.1,""Escape"":""\r\n\t\f\b?{\\r\\n\""'"",""product"":[{""Name"":""Rocket"",""ExpiryDate"":""2000-02-02T23:01:30Z"",""Price"":0.0},{""Name"":""Alien"",""ExpiryDate"":""2000-01-01T00:00:00Z"",""Price"":0.0}]}", sw.GetStringBuilder().ToString()); + Assert.AreEqual(@"{""Color"":4,""Establised"":""2010-01-22T01:01:01Z"",""Width"":1.1,""Employees"":999,""RoomsPerFloor"":[1,2,3,4,5,6,7,8,9],""Open"":false,""Symbol"":""@"",""Mottos"":[""Hello World"",""öäüÖÄÜ\\'{new Date(12345);}[222]_µ@²³~"",null,"" ""],""Cost"":100980.1,""Escape"":""\r\n\t\f\b?{\\r\\n\""'"",""product"":[{""Name"":""Rocket"",""ExpiryDate"":""2000-02-02T23:01:30Z"",""Price"":0.0},{""Name"":""Alien"",""ExpiryDate"":""2000-01-01T00:00:00Z"",""Price"":0.0}]}", sw.GetStringBuilder().ToString()); - Store s2 = (Store)jsonSerializer.Deserialize(new JsonTextReader(new StringReader("{}")), typeof(Store)); - Assert.AreEqual("\r\n\t\f\b?{\\r\\n\"\'", s2.Escape); + Store s2 = (Store)jsonSerializer.Deserialize(new JsonTextReader(new StringReader("{}")), typeof(Store)); + Assert.AreEqual("\r\n\t\f\b?{\\r\\n\"\'", s2.Escape); - Store s3 = (Store)jsonSerializer.Deserialize(new JsonTextReader(new StringReader(@"{""Escape"":null}")), typeof(Store)); - Assert.AreEqual("\r\n\t\f\b?{\\r\\n\"\'", s3.Escape); + Store s3 = (Store)jsonSerializer.Deserialize(new JsonTextReader(new StringReader(@"{""Escape"":null}")), typeof(Store)); + Assert.AreEqual("\r\n\t\f\b?{\\r\\n\"\'", s3.Escape); - Store s4 = (Store)jsonSerializer.Deserialize(new JsonTextReader(new StringReader(@"{""Color"":2,""Establised"":""\/Date(1264071600000+1300)\/"",""Width"":1.1,""Employees"":999,""RoomsPerFloor"":[1,2,3,4,5,6,7,8,9],""Open"":false,""Symbol"":""@"",""Mottos"":[""Hello World"",""öäüÖÄÜ\\'{new Date(12345);}[222]_µ@²³~"",null,"" ""],""Cost"":100980.1,""Escape"":""\r\n\t\f\b?{\\r\\n\""'"",""product"":[{""Name"":""Rocket"",""ExpiryDate"":""\/Date(949485690000+1300)\/"",""Price"":0},{""Name"":""Alien"",""ExpiryDate"":""\/Date(946638000000)\/"",""Price"":0.0}]}")), typeof(Store)); - Assert.AreEqual(s1.Establised, s3.Establised); - } + Store s4 = (Store)jsonSerializer.Deserialize(new JsonTextReader(new StringReader(@"{""Color"":2,""Establised"":""\/Date(1264071600000+1300)\/"",""Width"":1.1,""Employees"":999,""RoomsPerFloor"":[1,2,3,4,5,6,7,8,9],""Open"":false,""Symbol"":""@"",""Mottos"":[""Hello World"",""öäüÖÄÜ\\'{new Date(12345);}[222]_µ@²³~"",null,"" ""],""Cost"":100980.1,""Escape"":""\r\n\t\f\b?{\\r\\n\""'"",""product"":[{""Name"":""Rocket"",""ExpiryDate"":""\/Date(949485690000+1300)\/"",""Price"":0},{""Name"":""Alien"",""ExpiryDate"":""\/Date(946638000000)\/"",""Price"":0.0}]}")), typeof(Store)); + Assert.AreEqual(s1.Establised, s3.Establised); + } - [Test] - public void NullValueHandlingBlogPost() - { - Movie movie = new Movie(); - movie.Name = "Bad Boys III"; - movie.Description = "It's no Bad Boys"; + [Test] + public void NullValueHandlingBlogPost() + { + Movie movie = new Movie(); + movie.Name = "Bad Boys III"; + movie.Description = "It's no Bad Boys"; - string included = JsonConvert.SerializeObject(movie, - Formatting.Indented, - new JsonSerializerSettings { }); + string included = JsonConvert.SerializeObject(movie, + Formatting.Indented, + new JsonSerializerSettings { }); - // { - // "Name": "Bad Boys III", - // "Description": "It's no Bad Boys", - // "Classification": null, - // "Studio": null, - // "ReleaseDate": null, - // "ReleaseCountries": null - // } + // { + // "Name": "Bad Boys III", + // "Description": "It's no Bad Boys", + // "Classification": null, + // "Studio": null, + // "ReleaseDate": null, + // "ReleaseCountries": null + // } - string ignored = JsonConvert.SerializeObject(movie, - Formatting.Indented, - new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + string ignored = JsonConvert.SerializeObject(movie, + Formatting.Indented, + new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); - // { - // "Name": "Bad Boys III", - // "Description": "It's no Bad Boys" - // } + // { + // "Name": "Bad Boys III", + // "Description": "It's no Bad Boys" + // } - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Name"": ""Bad Boys III"", ""Description"": ""It's no Bad Boys"", ""Classification"": null, @@ -118,10 +119,10 @@ namespace Newtonsoft.Json.Tests.Serialization ""ReleaseCountries"": null }", included); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Name"": ""Bad Boys III"", ""Description"": ""It's no Bad Boys"" }", ignored); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Serialization/PopulateTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/PopulateTests.cs index 2f0b9722..d9c586f1 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/PopulateTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/PopulateTests.cs @@ -29,6 +29,7 @@ using System.IO; using Newtonsoft.Json.Tests.TestObjects; #if !NETFX_CORE using NUnit.Framework; + #else using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; @@ -37,53 +38,53 @@ using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAtt namespace Newtonsoft.Json.Tests.Serialization { - [TestFixture] - public class PopulateTests : TestFixtureBase - { - [Test] - public void PopulatePerson() + [TestFixture] + public class PopulateTests : TestFixtureBase { - Person p = new Person(); - - JsonConvert.PopulateObject(@"{""Name"":""James""}", p); - - Assert.AreEqual("James", p.Name); - } - - [Test] - public void PopulateArray() - { - IList people = new List + [Test] + public void PopulatePerson() { - new Person { Name = "Initial" } - }; + Person p = new Person(); - JsonConvert.PopulateObject(@"[{""Name"":""James""}, null]", people); + JsonConvert.PopulateObject(@"{""Name"":""James""}", p); - Assert.AreEqual(3, people.Count); - Assert.AreEqual("Initial", people[0].Name); - Assert.AreEqual("James", people[1].Name); - Assert.AreEqual(null, people[2]); - } + Assert.AreEqual("James", p.Name); + } - [Test] - public void PopulateStore() - { - Store s = new Store(); - s.Color = StoreColor.Red; - s.product = new List + [Test] + public void PopulateArray() { - new Product + IList people = new List { - ExpiryDate = new DateTime(2000, 12, 3, 0, 0, 0, DateTimeKind.Utc), - Name = "ProductName!", - Price = 9.9m - } - }; - s.Width = 99.99d; - s.Mottos = new List { "Can do!", "We deliver!" }; + new Person { Name = "Initial" } + }; - string json = @"{ + JsonConvert.PopulateObject(@"[{""Name"":""James""}, null]", people); + + Assert.AreEqual(3, people.Count); + Assert.AreEqual("Initial", people[0].Name); + Assert.AreEqual("James", people[1].Name); + Assert.AreEqual(null, people[2]); + } + + [Test] + public void PopulateStore() + { + Store s = new Store(); + s.Color = StoreColor.Red; + s.product = new List + { + new Product + { + ExpiryDate = new DateTime(2000, 12, 3, 0, 0, 0, DateTimeKind.Utc), + Name = "ProductName!", + Price = 9.9m + } + }; + s.Width = 99.99d; + s.Mottos = new List { "Can do!", "We deliver!" }; + + string json = @"{ ""Color"": 2, ""Establised"": ""\/Date(1264122061000+0000)\/"", ""Width"": 99.99, @@ -116,51 +117,48 @@ namespace Newtonsoft.Json.Tests.Serialization ] }"; - JsonConvert.PopulateObject(json, s, new JsonSerializerSettings + JsonConvert.PopulateObject(json, s, new JsonSerializerSettings + { + ObjectCreationHandling = ObjectCreationHandling.Replace + }); + + Assert.AreEqual(1, s.Mottos.Count); + Assert.AreEqual("Fail whale", s.Mottos[0]); + Assert.AreEqual(1, s.product.Count); + + //Assert.AreEqual("James", p.Name); + } + + [Test] + public void PopulateListOfPeople() { - ObjectCreationHandling = ObjectCreationHandling.Replace - }); + List p = new List(); - Assert.AreEqual(1, s.Mottos.Count); - Assert.AreEqual("Fail whale", s.Mottos[0]); - Assert.AreEqual(1, s.product.Count); + JsonSerializer serializer = new JsonSerializer(); + serializer.Populate(new StringReader(@"[{""Name"":""James""},{""Name"":""Jim""}]"), p); - //Assert.AreEqual("James", p.Name); - } + Assert.AreEqual(2, p.Count); + Assert.AreEqual("James", p[0].Name); + Assert.AreEqual("Jim", p[1].Name); + } - [Test] - public void PopulateListOfPeople() - { - List p = new List(); - - JsonSerializer serializer = new JsonSerializer(); - serializer.Populate(new StringReader(@"[{""Name"":""James""},{""Name"":""Jim""}]"), p); - - Assert.AreEqual(2, p.Count); - Assert.AreEqual("James", p[0].Name); - Assert.AreEqual("Jim", p[1].Name); - } - - [Test] - public void PopulateDictionary() - { - Dictionary p = new Dictionary(); - - JsonSerializer serializer = new JsonSerializer(); - serializer.Populate(new StringReader(@"{""Name"":""James""}"), p); - - Assert.AreEqual(1, p.Count); - Assert.AreEqual("James", p["Name"]); - } - - [Test] - public void PopulateWithBadJson() - { - ExceptionAssert.Throws("Unexpected initial token 'Integer' when populating object. Expected JSON object or array. Path '', line 1, position 1.", - () => + [Test] + public void PopulateDictionary() { - JsonConvert.PopulateObject("1", new Person()); - }); + Dictionary p = new Dictionary(); + + JsonSerializer serializer = new JsonSerializer(); + serializer.Populate(new StringReader(@"{""Name"":""James""}"), p); + + Assert.AreEqual(1, p.Count); + Assert.AreEqual("James", p["Name"]); + } + + [Test] + public void PopulateWithBadJson() + { + ExceptionAssert.Throws("Unexpected initial token 'Integer' when populating object. Expected JSON object or array. Path '', line 1, position 1.", + () => { JsonConvert.PopulateObject("1", new Person()); }); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Serialization/PreserveReferencesHandlingTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/PreserveReferencesHandlingTests.cs index 48f2f862..d618d945 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/PreserveReferencesHandlingTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/PreserveReferencesHandlingTests.cs @@ -32,6 +32,7 @@ using Newtonsoft.Json.Linq; using Newtonsoft.Json.Tests.TestObjects; #if !NETFX_CORE using NUnit.Framework; + #else using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; @@ -40,20 +41,20 @@ using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAtt namespace Newtonsoft.Json.Tests.Serialization { - [TestFixture] - public class PreserveReferencesHandlingTests : TestFixtureBase - { - [Test] - public void SerializeDictionarysWithPreserveObjectReferences() + [TestFixture] + public class PreserveReferencesHandlingTests : TestFixtureBase { - CircularDictionary circularDictionary = new CircularDictionary(); - circularDictionary.Add("other", new CircularDictionary { { "blah", null } }); - circularDictionary.Add("self", circularDictionary); + [Test] + public void SerializeDictionarysWithPreserveObjectReferences() + { + CircularDictionary circularDictionary = new CircularDictionary(); + circularDictionary.Add("other", new CircularDictionary { { "blah", null } }); + circularDictionary.Add("self", circularDictionary); - string json = JsonConvert.SerializeObject(circularDictionary, Formatting.Indented, - new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.All }); + string json = JsonConvert.SerializeObject(circularDictionary, Formatting.Indented, + new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.All }); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""$id"": ""1"", ""other"": { ""$id"": ""2"", @@ -63,12 +64,12 @@ namespace Newtonsoft.Json.Tests.Serialization ""$ref"": ""1"" } }", json); - } + } - [Test] - public void DeserializeDictionarysWithPreserveObjectReferences() - { - string json = @"{ + [Test] + public void DeserializeDictionarysWithPreserveObjectReferences() + { + string json = @"{ ""$id"": ""1"", ""other"": { ""$id"": ""2"", @@ -79,52 +80,49 @@ namespace Newtonsoft.Json.Tests.Serialization } }"; - CircularDictionary circularDictionary = JsonConvert.DeserializeObject(json, - new JsonSerializerSettings + CircularDictionary circularDictionary = JsonConvert.DeserializeObject(json, + new JsonSerializerSettings + { + PreserveReferencesHandling = PreserveReferencesHandling.All + }); + + Assert.AreEqual(2, circularDictionary.Count); + Assert.AreEqual(1, circularDictionary["other"].Count); + Assert.AreEqual(circularDictionary, circularDictionary["self"]); + } + + public class CircularList : List { - PreserveReferencesHandling = PreserveReferencesHandling.All - }); + } - Assert.AreEqual(2, circularDictionary.Count); - Assert.AreEqual(1, circularDictionary["other"].Count); - Assert.AreEqual(circularDictionary, circularDictionary["self"]); - } - - public class CircularList : List - { - } - - [Test] - public void SerializeCircularListsError() - { - string classRef = typeof(CircularList).FullName; - - CircularList circularList = new CircularList(); - circularList.Add(null); - circularList.Add(new CircularList { null }); - circularList.Add(new CircularList { new CircularList { circularList } }); - - ExceptionAssert.Throws( - "Self referencing loop detected with type '" + classRef + "'. Path '[2][0]'.", - () => + [Test] + public void SerializeCircularListsError() { - JsonConvert.SerializeObject(circularList, Formatting.Indented); - }); - } + string classRef = typeof(CircularList).FullName; - [Test] - public void SerializeCircularListsIgnore() - { - CircularList circularList = new CircularList(); - circularList.Add(null); - circularList.Add(new CircularList { null }); - circularList.Add(new CircularList { new CircularList { circularList } }); + CircularList circularList = new CircularList(); + circularList.Add(null); + circularList.Add(new CircularList { null }); + circularList.Add(new CircularList { new CircularList { circularList } }); - string json = JsonConvert.SerializeObject(circularList, - Formatting.Indented, - new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); + ExceptionAssert.Throws( + "Self referencing loop detected with type '" + classRef + "'. Path '[2][0]'.", + () => { JsonConvert.SerializeObject(circularList, Formatting.Indented); }); + } - Assert.AreEqual(@"[ + [Test] + public void SerializeCircularListsIgnore() + { + CircularList circularList = new CircularList(); + circularList.Add(null); + circularList.Add(new CircularList { null }); + circularList.Add(new CircularList { new CircularList { circularList } }); + + string json = JsonConvert.SerializeObject(circularList, + Formatting.Indented, + new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); + + Assert.AreEqual(@"[ null, [ null @@ -133,20 +131,20 @@ namespace Newtonsoft.Json.Tests.Serialization [] ] ]", json); - } + } - [Test] - public void SerializeListsWithPreserveObjectReferences() - { - CircularList circularList = new CircularList(); - circularList.Add(null); - circularList.Add(new CircularList { null }); - circularList.Add(new CircularList { new CircularList { circularList } }); + [Test] + public void SerializeListsWithPreserveObjectReferences() + { + CircularList circularList = new CircularList(); + circularList.Add(null); + circularList.Add(new CircularList { null }); + circularList.Add(new CircularList { new CircularList { circularList } }); - string json = JsonConvert.SerializeObject(circularList, Formatting.Indented, - new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.All }); + string json = JsonConvert.SerializeObject(circularList, Formatting.Indented, + new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.All }); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""$id"": ""1"", ""$values"": [ null, @@ -171,12 +169,12 @@ namespace Newtonsoft.Json.Tests.Serialization } ] }", json); - } + } - [Test] - public void DeserializeListsWithPreserveObjectReferences() - { - string json = @"{ + [Test] + public void DeserializeListsWithPreserveObjectReferences() + { + string json = @"{ ""$id"": ""1"", ""$values"": [ null, @@ -202,21 +200,21 @@ namespace Newtonsoft.Json.Tests.Serialization ] }"; - CircularList circularList = JsonConvert.DeserializeObject(json, - new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.All }); + CircularList circularList = JsonConvert.DeserializeObject(json, + new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.All }); - Assert.AreEqual(3, circularList.Count); - Assert.AreEqual(null, circularList[0]); - Assert.AreEqual(1, circularList[1].Count); - Assert.AreEqual(1, circularList[2].Count); - Assert.AreEqual(1, circularList[2][0].Count); - Assert.IsTrue(ReferenceEquals(circularList, circularList[2][0][0])); - } + Assert.AreEqual(3, circularList.Count); + Assert.AreEqual(null, circularList[0]); + Assert.AreEqual(1, circularList[1].Count); + Assert.AreEqual(1, circularList[2].Count); + Assert.AreEqual(1, circularList[2][0].Count); + Assert.IsTrue(ReferenceEquals(circularList, circularList[2][0][0])); + } - [Test] - public void DeserializeArraysWithPreserveObjectReferences() - { - string json = @"{ + [Test] + public void DeserializeArraysWithPreserveObjectReferences() + { + string json = @"{ ""$id"": ""1"", ""$values"": [ null, @@ -242,128 +240,125 @@ namespace Newtonsoft.Json.Tests.Serialization ] }"; - ExceptionAssert.Throws( - @"Cannot preserve reference to array or readonly list, or list created from a non-default constructor: System.String[][]. Path '$values', line 3, position 15.", - () => - { - JsonConvert.DeserializeObject(json, - new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.All }); - }); - } + ExceptionAssert.Throws( + @"Cannot preserve reference to array or readonly list, or list created from a non-default constructor: System.String[][]. Path '$values', line 3, position 15.", + () => + { + JsonConvert.DeserializeObject(json, + new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.All }); + }); + } - public class CircularDictionary : Dictionary - { - } + public class CircularDictionary : Dictionary + { + } - [Test] - public void SerializeCircularDictionarysError() - { - string classRef = typeof(CircularDictionary).FullName; + [Test] + public void SerializeCircularDictionarysError() + { + string classRef = typeof(CircularDictionary).FullName; - CircularDictionary circularDictionary = new CircularDictionary(); - circularDictionary.Add("other", new CircularDictionary {{"blah", null}}); - circularDictionary.Add("self", circularDictionary); + CircularDictionary circularDictionary = new CircularDictionary(); + circularDictionary.Add("other", new CircularDictionary { { "blah", null } }); + circularDictionary.Add("self", circularDictionary); - ExceptionAssert.Throws( - @"Self referencing loop detected with type '" + classRef + "'. Path ''.", - () => - { - JsonConvert.SerializeObject(circularDictionary, Formatting.Indented); - }); - } + ExceptionAssert.Throws( + @"Self referencing loop detected with type '" + classRef + "'. Path ''.", + () => { JsonConvert.SerializeObject(circularDictionary, Formatting.Indented); }); + } - [Test] - public void SerializeCircularDictionarysIgnore() - { - CircularDictionary circularDictionary = new CircularDictionary(); - circularDictionary.Add("other", new CircularDictionary { { "blah", null } }); - circularDictionary.Add("self", circularDictionary); + [Test] + public void SerializeCircularDictionarysIgnore() + { + CircularDictionary circularDictionary = new CircularDictionary(); + circularDictionary.Add("other", new CircularDictionary { { "blah", null } }); + circularDictionary.Add("self", circularDictionary); - string json = JsonConvert.SerializeObject(circularDictionary, Formatting.Indented, - new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); + string json = JsonConvert.SerializeObject(circularDictionary, Formatting.Indented, + new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""other"": { ""blah"": null } }", json); - } + } - [Test] - public void UnexpectedEnd() - { - string json = @"{ + [Test] + public void UnexpectedEnd() + { + string json = @"{ ""$id"":"; - ExceptionAssert.Throws( - @"Unexpected end when deserializing object. Path '$id', line 2, position 9.", - () => - { - JsonConvert.DeserializeObject(json, - new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.All }); - }); - } - - public class CircularReferenceClassConverter : JsonConverter - { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - CircularReferenceClass circularReferenceClass = (CircularReferenceClass)value; - - string reference = serializer.ReferenceResolver.GetReference(serializer, circularReferenceClass); - - JObject me = new JObject(); - me["$id"] = new JValue(reference); - me["$type"] = new JValue(value.GetType().Name); - me["Name"] = new JValue(circularReferenceClass.Name); - - JObject o = JObject.FromObject(circularReferenceClass.Child, serializer); - me["Child"] = o; - - me.WriteTo(writer); - } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - JObject o = JObject.Load(reader); - string id = (string)o["$id"]; - if (id != null) - { - CircularReferenceClass circularReferenceClass = new CircularReferenceClass(); - serializer.Populate(o.CreateReader(), circularReferenceClass); - return circularReferenceClass; + ExceptionAssert.Throws( + @"Unexpected end when deserializing object. Path '$id', line 2, position 9.", + () => + { + JsonConvert.DeserializeObject(json, + new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.All }); + }); } - else + + public class CircularReferenceClassConverter : JsonConverter { - string reference = (string)o["$ref"]; - return serializer.ReferenceResolver.ResolveReference(serializer, reference); + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + CircularReferenceClass circularReferenceClass = (CircularReferenceClass)value; + + string reference = serializer.ReferenceResolver.GetReference(serializer, circularReferenceClass); + + JObject me = new JObject(); + me["$id"] = new JValue(reference); + me["$type"] = new JValue(value.GetType().Name); + me["Name"] = new JValue(circularReferenceClass.Name); + + JObject o = JObject.FromObject(circularReferenceClass.Child, serializer); + me["Child"] = o; + + me.WriteTo(writer); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + JObject o = JObject.Load(reader); + string id = (string)o["$id"]; + if (id != null) + { + CircularReferenceClass circularReferenceClass = new CircularReferenceClass(); + serializer.Populate(o.CreateReader(), circularReferenceClass); + return circularReferenceClass; + } + else + { + string reference = (string)o["$ref"]; + return serializer.ReferenceResolver.ResolveReference(serializer, reference); + } + } + + public override bool CanConvert(Type objectType) + { + return (objectType == typeof(CircularReferenceClass)); + } } - } - public override bool CanConvert(Type objectType) - { - return (objectType == typeof(CircularReferenceClass)); - } - } + [Test] + public void SerializeCircularReferencesWithConverter() + { + CircularReferenceClass c1 = new CircularReferenceClass { Name = "c1" }; + CircularReferenceClass c2 = new CircularReferenceClass { Name = "c2" }; + CircularReferenceClass c3 = new CircularReferenceClass { Name = "c3" }; - [Test] - public void SerializeCircularReferencesWithConverter() - { - CircularReferenceClass c1 = new CircularReferenceClass { Name = "c1" }; - CircularReferenceClass c2 = new CircularReferenceClass { Name = "c2" }; - CircularReferenceClass c3 = new CircularReferenceClass { Name = "c3" }; + c1.Child = c2; + c2.Child = c3; + c3.Child = c1; - c1.Child = c2; - c2.Child = c3; - c3.Child = c1; + string json = JsonConvert.SerializeObject(c1, Formatting.Indented, new JsonSerializerSettings + { + PreserveReferencesHandling = PreserveReferencesHandling.Objects, + Converters = new List { new CircularReferenceClassConverter() } + }); - string json = JsonConvert.SerializeObject(c1, Formatting.Indented, new JsonSerializerSettings - { - PreserveReferencesHandling = PreserveReferencesHandling.Objects, - Converters = new List { new CircularReferenceClassConverter() } - }); - - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""$id"": ""1"", ""$type"": ""CircularReferenceClass"", ""Name"": ""c1"", @@ -381,12 +376,12 @@ namespace Newtonsoft.Json.Tests.Serialization } } }", json); - } + } - [Test] - public void DeserializeCircularReferencesWithConverter() - { - string json = @"{ + [Test] + public void DeserializeCircularReferencesWithConverter() + { + string json = @"{ ""$id"": ""1"", ""$type"": ""CircularReferenceClass"", ""Name"": ""c1"", @@ -405,39 +400,39 @@ namespace Newtonsoft.Json.Tests.Serialization } }"; - CircularReferenceClass c1 = JsonConvert.DeserializeObject(json, new JsonSerializerSettings - { - PreserveReferencesHandling = PreserveReferencesHandling.Objects, - Converters = new List { new CircularReferenceClassConverter() } - }); + CircularReferenceClass c1 = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + PreserveReferencesHandling = PreserveReferencesHandling.Objects, + Converters = new List { new CircularReferenceClassConverter() } + }); - Assert.AreEqual("c1", c1.Name); - Assert.AreEqual("c2", c1.Child.Name); - Assert.AreEqual("c3", c1.Child.Child.Name); - Assert.AreEqual("c1", c1.Child.Child.Child.Name); - } + Assert.AreEqual("c1", c1.Name); + Assert.AreEqual("c2", c1.Child.Name); + Assert.AreEqual("c3", c1.Child.Child.Name); + Assert.AreEqual("c1", c1.Child.Child.Child.Name); + } - [Test] - public void SerializeEmployeeReference() - { - EmployeeReference mikeManager = new EmployeeReference - { - Name = "Mike Manager" - }; - EmployeeReference joeUser = new EmployeeReference - { - Name = "Joe User", - Manager = mikeManager - }; - - List employees = new List + [Test] + public void SerializeEmployeeReference() { - mikeManager, - joeUser - }; + EmployeeReference mikeManager = new EmployeeReference + { + Name = "Mike Manager" + }; + EmployeeReference joeUser = new EmployeeReference + { + Name = "Joe User", + Manager = mikeManager + }; - string json = JsonConvert.SerializeObject(employees, Formatting.Indented); - Assert.AreEqual(@"[ + List employees = new List + { + mikeManager, + joeUser + }; + + string json = JsonConvert.SerializeObject(employees, Formatting.Indented); + Assert.AreEqual(@"[ { ""$id"": ""1"", ""Name"": ""Mike Manager"", @@ -451,12 +446,12 @@ namespace Newtonsoft.Json.Tests.Serialization } } ]", json); - } + } - [Test] - public void DeserializeEmployeeReference() - { - string json = @"[ + [Test] + public void DeserializeEmployeeReference() + { + string json = @"[ { ""$id"": ""1"", ""Name"": ""Mike Manager"", @@ -471,31 +466,31 @@ namespace Newtonsoft.Json.Tests.Serialization } ]"; - List employees = JsonConvert.DeserializeObject>(json); + List employees = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(2, employees.Count); - Assert.AreEqual("Mike Manager", employees[0].Name); - Assert.AreEqual("Joe User", employees[1].Name); - Assert.AreEqual(employees[0], employees[1].Manager); - } + Assert.AreEqual(2, employees.Count); + Assert.AreEqual("Mike Manager", employees[0].Name); + Assert.AreEqual("Joe User", employees[1].Name); + Assert.AreEqual(employees[0], employees[1].Manager); + } - [Test] - public void SerializeCircularReference() - { - CircularReferenceClass c1 = new CircularReferenceClass { Name = "c1" }; - CircularReferenceClass c2 = new CircularReferenceClass { Name = "c2" }; - CircularReferenceClass c3 = new CircularReferenceClass { Name = "c3" }; + [Test] + public void SerializeCircularReference() + { + CircularReferenceClass c1 = new CircularReferenceClass { Name = "c1" }; + CircularReferenceClass c2 = new CircularReferenceClass { Name = "c2" }; + CircularReferenceClass c3 = new CircularReferenceClass { Name = "c3" }; - c1.Child = c2; - c2.Child = c3; - c3.Child = c1; + c1.Child = c2; + c2.Child = c3; + c3.Child = c1; - string json = JsonConvert.SerializeObject(c1, Formatting.Indented, new JsonSerializerSettings - { - PreserveReferencesHandling = PreserveReferencesHandling.Objects - }); + string json = JsonConvert.SerializeObject(c1, Formatting.Indented, new JsonSerializerSettings + { + PreserveReferencesHandling = PreserveReferencesHandling.Objects + }); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""$id"": ""1"", ""Name"": ""c1"", ""Child"": { @@ -510,12 +505,12 @@ namespace Newtonsoft.Json.Tests.Serialization } } }", json); - } + } - [Test] - public void DeserializeCircularReference() - { - string json = @"{ + [Test] + public void DeserializeCircularReference() + { + string json = @"{ ""$id"": ""1"", ""Name"": ""c1"", ""Child"": { @@ -531,29 +526,29 @@ namespace Newtonsoft.Json.Tests.Serialization } }"; - CircularReferenceClass c1 = - JsonConvert.DeserializeObject(json, new JsonSerializerSettings + CircularReferenceClass c1 = + JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + PreserveReferencesHandling = PreserveReferencesHandling.Objects + }); + + Assert.AreEqual("c1", c1.Name); + Assert.AreEqual("c2", c1.Child.Name); + Assert.AreEqual("c3", c1.Child.Child.Name); + Assert.AreEqual("c1", c1.Child.Child.Child.Name); + } + + [Test] + public void SerializeReferenceInList() { - PreserveReferencesHandling = PreserveReferencesHandling.Objects - }); + EmployeeReference e1 = new EmployeeReference { Name = "e1" }; + EmployeeReference e2 = new EmployeeReference { Name = "e2" }; - Assert.AreEqual("c1", c1.Name); - Assert.AreEqual("c2", c1.Child.Name); - Assert.AreEqual("c3", c1.Child.Child.Name); - Assert.AreEqual("c1", c1.Child.Child.Child.Name); - } + List employees = new List { e1, e2, e1, e2 }; - [Test] - public void SerializeReferenceInList() - { - EmployeeReference e1 = new EmployeeReference { Name = "e1" }; - EmployeeReference e2 = new EmployeeReference { Name = "e2" }; + string json = JsonConvert.SerializeObject(employees, Formatting.Indented); - List employees = new List { e1, e2, e1, e2 }; - - string json = JsonConvert.SerializeObject(employees, Formatting.Indented); - - Assert.AreEqual(@"[ + Assert.AreEqual(@"[ { ""$id"": ""1"", ""Name"": ""e1"", @@ -571,12 +566,12 @@ namespace Newtonsoft.Json.Tests.Serialization ""$ref"": ""2"" } ]", json); - } + } - [Test] - public void DeserializeReferenceInList() - { - string json = @"[ + [Test] + public void DeserializeReferenceInList() + { + string json = @"[ { ""$id"": ""1"", ""Name"": ""e1"", @@ -595,35 +590,35 @@ namespace Newtonsoft.Json.Tests.Serialization } ]"; - List employees = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(4, employees.Count); + List employees = JsonConvert.DeserializeObject>(json); + Assert.AreEqual(4, employees.Count); - Assert.AreEqual("e1", employees[0].Name); - Assert.AreEqual("e2", employees[1].Name); - Assert.AreEqual("e1", employees[2].Name); - Assert.AreEqual("e2", employees[3].Name); + Assert.AreEqual("e1", employees[0].Name); + Assert.AreEqual("e2", employees[1].Name); + Assert.AreEqual("e1", employees[2].Name); + Assert.AreEqual("e2", employees[3].Name); - Assert.AreEqual(employees[0], employees[2]); - Assert.AreEqual(employees[1], employees[3]); - } + Assert.AreEqual(employees[0], employees[2]); + Assert.AreEqual(employees[1], employees[3]); + } - [Test] - public void SerializeReferenceInDictionary() - { - EmployeeReference e1 = new EmployeeReference { Name = "e1" }; - EmployeeReference e2 = new EmployeeReference { Name = "e2" }; - - Dictionary employees = new Dictionary + [Test] + public void SerializeReferenceInDictionary() { - {"One", e1}, - {"Two", e2}, - {"Three", e1}, - {"Four", e2} - }; + EmployeeReference e1 = new EmployeeReference { Name = "e1" }; + EmployeeReference e2 = new EmployeeReference { Name = "e2" }; - string json = JsonConvert.SerializeObject(employees, Formatting.Indented); + Dictionary employees = new Dictionary + { + { "One", e1 }, + { "Two", e2 }, + { "Three", e1 }, + { "Four", e2 } + }; - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(employees, Formatting.Indented); + + Assert.AreEqual(@"{ ""One"": { ""$id"": ""1"", ""Name"": ""e1"", @@ -641,12 +636,12 @@ namespace Newtonsoft.Json.Tests.Serialization ""$ref"": ""2"" } }", json); - } + } - [Test] - public void DeserializeReferenceInDictionary() - { - string json = @"{ + [Test] + public void DeserializeReferenceInDictionary() + { + string json = @"{ ""One"": { ""$id"": ""1"", ""Name"": ""e1"", @@ -665,199 +660,192 @@ namespace Newtonsoft.Json.Tests.Serialization } }"; - Dictionary employees = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(4, employees.Count); + Dictionary employees = JsonConvert.DeserializeObject>(json); + Assert.AreEqual(4, employees.Count); - EmployeeReference e1 = employees["One"]; - EmployeeReference e2 = employees["Two"]; + EmployeeReference e1 = employees["One"]; + EmployeeReference e2 = employees["Two"]; - Assert.AreEqual("e1", e1.Name); - Assert.AreEqual("e2", e2.Name); + Assert.AreEqual("e1", e1.Name); + Assert.AreEqual("e2", e2.Name); - Assert.AreEqual(e1, employees["Three"]); - Assert.AreEqual(e2, employees["Four"]); - } + Assert.AreEqual(e1, employees["Three"]); + Assert.AreEqual(e2, employees["Four"]); + } - [Test] - public void ExampleWithout() - { - Person p = new Person + [Test] + public void ExampleWithout() { - BirthDate = new DateTime(1980, 12, 23, 0, 0, 0, DateTimeKind.Utc), - LastModified = new DateTime(2009, 2, 20, 12, 59, 21, DateTimeKind.Utc), - Department = "IT", - Name = "James" - }; + Person p = new Person + { + BirthDate = new DateTime(1980, 12, 23, 0, 0, 0, DateTimeKind.Utc), + LastModified = new DateTime(2009, 2, 20, 12, 59, 21, DateTimeKind.Utc), + Department = "IT", + Name = "James" + }; - List people = new List(); - people.Add(p); - people.Add(p); + List people = new List(); + people.Add(p); + people.Add(p); - string json = JsonConvert.SerializeObject(people, Formatting.Indented); - //[ - // { - // "Name": "James", - // "BirthDate": "\/Date(346377600000)\/", - // "LastModified": "\/Date(1235134761000)\/" - // }, - // { - // "Name": "James", - // "BirthDate": "\/Date(346377600000)\/", - // "LastModified": "\/Date(1235134761000)\/" - // } - //] - } + string json = JsonConvert.SerializeObject(people, Formatting.Indented); + //[ + // { + // "Name": "James", + // "BirthDate": "\/Date(346377600000)\/", + // "LastModified": "\/Date(1235134761000)\/" + // }, + // { + // "Name": "James", + // "BirthDate": "\/Date(346377600000)\/", + // "LastModified": "\/Date(1235134761000)\/" + // } + //] + } - [Test] - public void ExampleWith() - { - Person p = new Person - { - BirthDate = new DateTime(1980, 12, 23, 0, 0, 0, DateTimeKind.Utc), - LastModified = new DateTime(2009, 2, 20, 12, 59, 21, DateTimeKind.Utc), - Department = "IT", - Name = "James" - }; - - List people = new List(); - people.Add(p); - people.Add(p); - - string json = JsonConvert.SerializeObject(people, Formatting.Indented, - new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects }); - //[ - // { - // "$id": "1", - // "Name": "James", - // "BirthDate": "\/Date(346377600000)\/", - // "LastModified": "\/Date(1235134761000)\/" - // }, - // { - // "$ref": "1" - // } - //] - - List deserializedPeople = JsonConvert.DeserializeObject>(json, - new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects }); - - Console.WriteLine(deserializedPeople.Count); - // 2 - - Person p1 = deserializedPeople[0]; - Person p2 = deserializedPeople[1]; - - Console.WriteLine(p1.Name); - // James - Console.WriteLine(p2.Name); - // James - - bool equal = Object.ReferenceEquals(p1, p2); - // true - } - - [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - public class User - { - #region properties - - [JsonProperty(Required = Required.Always, PropertyName = "SecretType")] - private string secretType; - - [JsonProperty(Required = Required.Always)] - public string Login { get; set; } - - public Type SecretType - { - get { return Type.GetType(secretType); } - set { secretType = value.AssemblyQualifiedName; } - } - - [JsonProperty] - public User Friend { get; set; } - - #endregion - - #region constructors - - public User() - { - - } - - public User(string login, Type secretType) - : this() - { - this.Login = login; - this.SecretType = secretType; - } - - #endregion - - #region methods - - public override int GetHashCode() - { - return SecretType.GetHashCode(); - } - - public override string ToString() - { - return string.Format("SecretType: {0}, Login: {1}", secretType, Login); - } - - #endregion - } - - [Test] - public void DeserializeTypeWithDubiousGetHashcode() - { - User user1 = new User("Peter", typeof(Version)); - User user2 = new User("Michael", typeof(Version)); - - user1.Friend = user2; - - JsonSerializerSettings serializerSettings = new JsonSerializerSettings - { - TypeNameHandling = TypeNameHandling.All, - ReferenceLoopHandling = ReferenceLoopHandling.Ignore, - ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor, - PreserveReferencesHandling = PreserveReferencesHandling.Objects - }; - - string json = JsonConvert.SerializeObject(user1, Formatting.Indented, serializerSettings); - - User deserializedUser = JsonConvert.DeserializeObject(json, serializerSettings); - Assert.IsNotNull(deserializedUser); - } - - [Test] - public void PreserveReferencesHandlingWithReusedJsonSerializer() - { - MyClass c = new MyClass(); - - IList myClasses1 = new List + [Test] + public void ExampleWith() { - c, - c - }; + Person p = new Person + { + BirthDate = new DateTime(1980, 12, 23, 0, 0, 0, DateTimeKind.Utc), + LastModified = new DateTime(2009, 2, 20, 12, 59, 21, DateTimeKind.Utc), + Department = "IT", + Name = "James" + }; - var ser = new JsonSerializer() - { - PreserveReferencesHandling = PreserveReferencesHandling.All - }; + List people = new List(); + people.Add(p); + people.Add(p); - MemoryStream ms = new MemoryStream(); + string json = JsonConvert.SerializeObject(people, Formatting.Indented, + new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects }); + //[ + // { + // "$id": "1", + // "Name": "James", + // "BirthDate": "\/Date(346377600000)\/", + // "LastModified": "\/Date(1235134761000)\/" + // }, + // { + // "$ref": "1" + // } + //] - using (var sw = new StreamWriter(ms)) - using (var writer = new JsonTextWriter(sw) { Formatting = Formatting.Indented }) - { - ser.Serialize(writer, myClasses1); - } + List deserializedPeople = JsonConvert.DeserializeObject>(json, + new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects }); - byte[] data = ms.ToArray(); - string json = Encoding.UTF8.GetString(data, 0, data.Length); + Console.WriteLine(deserializedPeople.Count); + // 2 - Assert.AreEqual(@"{ + Person p1 = deserializedPeople[0]; + Person p2 = deserializedPeople[1]; + + Console.WriteLine(p1.Name); + // James + Console.WriteLine(p2.Name); + // James + + bool equal = Object.ReferenceEquals(p1, p2); + // true + } + + [JsonObject(MemberSerialization = MemberSerialization.OptIn)] + public class User + { + #region properties + [JsonProperty(Required = Required.Always, PropertyName = "SecretType")] + private string secretType; + + [JsonProperty(Required = Required.Always)] + public string Login { get; set; } + + public Type SecretType + { + get { return Type.GetType(secretType); } + set { secretType = value.AssemblyQualifiedName; } + } + + [JsonProperty] + public User Friend { get; set; } + #endregion + + #region constructors + public User() + { + } + + public User(string login, Type secretType) + : this() + { + Login = login; + SecretType = secretType; + } + #endregion + + #region methods + public override int GetHashCode() + { + return SecretType.GetHashCode(); + } + + public override string ToString() + { + return string.Format("SecretType: {0}, Login: {1}", secretType, Login); + } + #endregion + } + + [Test] + public void DeserializeTypeWithDubiousGetHashcode() + { + User user1 = new User("Peter", typeof(Version)); + User user2 = new User("Michael", typeof(Version)); + + user1.Friend = user2; + + JsonSerializerSettings serializerSettings = new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.All, + ReferenceLoopHandling = ReferenceLoopHandling.Ignore, + ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor, + PreserveReferencesHandling = PreserveReferencesHandling.Objects + }; + + string json = JsonConvert.SerializeObject(user1, Formatting.Indented, serializerSettings); + + User deserializedUser = JsonConvert.DeserializeObject(json, serializerSettings); + Assert.IsNotNull(deserializedUser); + } + + [Test] + public void PreserveReferencesHandlingWithReusedJsonSerializer() + { + MyClass c = new MyClass(); + + IList myClasses1 = new List + { + c, + c + }; + + var ser = new JsonSerializer() + { + PreserveReferencesHandling = PreserveReferencesHandling.All + }; + + MemoryStream ms = new MemoryStream(); + + using (var sw = new StreamWriter(ms)) + using (var writer = new JsonTextWriter(sw) { Formatting = Formatting.Indented }) + { + ser.Serialize(writer, myClasses1); + } + + byte[] data = ms.ToArray(); + string json = Encoding.UTF8.GetString(data, 0, data.Length); + + Assert.AreEqual(@"{ ""$id"": ""1"", ""$values"": [ { @@ -871,49 +859,49 @@ namespace Newtonsoft.Json.Tests.Serialization ] }", json); - ms = new MemoryStream(data); - IList myClasses2; + ms = new MemoryStream(data); + IList myClasses2; - using (var sr = new StreamReader(ms)) - using (var reader = new JsonTextReader(sr)) - { - myClasses2 = ser.Deserialize>(reader); - } + using (var sr = new StreamReader(ms)) + using (var reader = new JsonTextReader(sr)) + { + myClasses2 = ser.Deserialize>(reader); + } - Assert.AreEqual(2, myClasses2.Count); - Assert.AreEqual(myClasses2[0], myClasses2[1]); + Assert.AreEqual(2, myClasses2.Count); + Assert.AreEqual(myClasses2[0], myClasses2[1]); - Assert.AreNotEqual(myClasses1[0], myClasses2[0]); - } + Assert.AreNotEqual(myClasses1[0], myClasses2[0]); + } - [Test] - public void ReferencedIntList() - { - ReferencedList l = new ReferencedList(); - l.Add(1); - l.Add(2); - l.Add(3); + [Test] + public void ReferencedIntList() + { + ReferencedList l = new ReferencedList(); + l.Add(1); + l.Add(2); + l.Add(3); - string json = JsonConvert.SerializeObject(l, Formatting.Indented); - Assert.AreEqual(@"[ + string json = JsonConvert.SerializeObject(l, Formatting.Indented); + Assert.AreEqual(@"[ 1, 2, 3 ]", json); - } + } - [Test] - public void ReferencedComponentList() - { - var c1 = new TestComponentSimple(); + [Test] + public void ReferencedComponentList() + { + var c1 = new TestComponentSimple(); - ReferencedList l = new ReferencedList(); - l.Add(c1); - l.Add(new TestComponentSimple()); - l.Add(c1); + ReferencedList l = new ReferencedList(); + l.Add(c1); + l.Add(new TestComponentSimple()); + l.Add(c1); - string json = JsonConvert.SerializeObject(l, Formatting.Indented); - Assert.AreEqual(@"[ + string json = JsonConvert.SerializeObject(l, Formatting.Indented); + Assert.AreEqual(@"[ { ""$id"": ""1"", ""MyProperty"": 0 @@ -926,36 +914,36 @@ namespace Newtonsoft.Json.Tests.Serialization ""$ref"": ""1"" } ]", json); - } + } - [Test] - public void ReferencedIntDictionary() - { - ReferencedDictionary l = new ReferencedDictionary(); - l.Add("First", 1); - l.Add("Second", 2); - l.Add("Third", 3); + [Test] + public void ReferencedIntDictionary() + { + ReferencedDictionary l = new ReferencedDictionary(); + l.Add("First", 1); + l.Add("Second", 2); + l.Add("Third", 3); - string json = JsonConvert.SerializeObject(l, Formatting.Indented); - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(l, Formatting.Indented); + Assert.AreEqual(@"{ ""First"": 1, ""Second"": 2, ""Third"": 3 }", json); - } + } - [Test] - public void ReferencedComponentDictionary() - { - var c1 = new TestComponentSimple(); + [Test] + public void ReferencedComponentDictionary() + { + var c1 = new TestComponentSimple(); - ReferencedDictionary l = new ReferencedDictionary(); - l.Add("First", c1); - l.Add("Second", new TestComponentSimple()); - l.Add("Third", c1); + ReferencedDictionary l = new ReferencedDictionary(); + l.Add("First", c1); + l.Add("Second", new TestComponentSimple()); + l.Add("Third", c1); - string json = JsonConvert.SerializeObject(l, Formatting.Indented); - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(l, Formatting.Indented); + Assert.AreEqual(@"{ ""First"": { ""$id"": ""1"", ""MyProperty"": 0 @@ -969,24 +957,24 @@ namespace Newtonsoft.Json.Tests.Serialization } }", json); - ReferencedDictionary d = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(3, d.Count); - Assert.IsTrue(ReferenceEquals(d["First"], d["Third"])); - } + ReferencedDictionary d = JsonConvert.DeserializeObject>(json); + Assert.AreEqual(3, d.Count); + Assert.IsTrue(ReferenceEquals(d["First"], d["Third"])); + } - [Test] - public void ReferencedObjectItems() - { - ReferenceObject o1 = new ReferenceObject(); + [Test] + public void ReferencedObjectItems() + { + ReferenceObject o1 = new ReferenceObject(); - o1.Component1 = new TestComponentSimple { MyProperty = 1 }; - o1.Component2 = o1.Component1; - o1.ComponentNotReference = new TestComponentSimple(); - o1.String = "String!"; - o1.Integer = int.MaxValue; + o1.Component1 = new TestComponentSimple { MyProperty = 1 }; + o1.Component2 = o1.Component1; + o1.ComponentNotReference = new TestComponentSimple(); + o1.String = "String!"; + o1.Integer = int.MaxValue; - string json = JsonConvert.SerializeObject(o1, Formatting.Indented); - string expected = @"{ + string json = JsonConvert.SerializeObject(o1, Formatting.Indented); + string expected = @"{ ""Component1"": { ""$id"": ""1"", ""MyProperty"": 1 @@ -1000,34 +988,34 @@ namespace Newtonsoft.Json.Tests.Serialization ""String"": ""String!"", ""Integer"": 2147483647 }"; - Assert.AreEqual(expected, json); + Assert.AreEqual(expected, json); - ReferenceObject referenceObject = JsonConvert.DeserializeObject(json); - Assert.IsNotNull(referenceObject); + ReferenceObject referenceObject = JsonConvert.DeserializeObject(json); + Assert.IsNotNull(referenceObject); - Assert.IsTrue(ReferenceEquals(referenceObject.Component1, referenceObject.Component2)); - } + Assert.IsTrue(ReferenceEquals(referenceObject.Component1, referenceObject.Component2)); + } - [Test] - public void PropertyItemIsReferenceObject() - { - TestComponentSimple c1 = new TestComponentSimple(); - - PropertyItemIsReferenceObject o1 = new PropertyItemIsReferenceObject + [Test] + public void PropertyItemIsReferenceObject() { - Data = new PropertyItemIsReferenceBody - { - Prop1 = c1, - Prop2 = c1, - Data = new List - { - c1 - } - } - }; + TestComponentSimple c1 = new TestComponentSimple(); - string json = JsonConvert.SerializeObject(o1, Formatting.Indented); - Assert.AreEqual(@"{ + PropertyItemIsReferenceObject o1 = new PropertyItemIsReferenceObject + { + Data = new PropertyItemIsReferenceBody + { + Prop1 = c1, + Prop2 = c1, + Data = new List + { + c1 + } + } + }; + + string json = JsonConvert.SerializeObject(o1, Formatting.Indented); + Assert.AreEqual(@"{ ""Data"": { ""Prop1"": { ""$id"": ""1"", @@ -1047,20 +1035,20 @@ namespace Newtonsoft.Json.Tests.Serialization } }", json); - PropertyItemIsReferenceObject o2 = JsonConvert.DeserializeObject(json); + PropertyItemIsReferenceObject o2 = JsonConvert.DeserializeObject(json); - TestComponentSimple c2 = o2.Data.Prop1; - TestComponentSimple c3 = o2.Data.Prop2; - TestComponentSimple c4 = o2.Data.Data[0]; + TestComponentSimple c2 = o2.Data.Prop1; + TestComponentSimple c3 = o2.Data.Prop2; + TestComponentSimple c4 = o2.Data.Data[0]; - Assert.IsTrue(ReferenceEquals(c2, c3)); - Assert.IsFalse(ReferenceEquals(c2, c4)); - } + Assert.IsTrue(ReferenceEquals(c2, c3)); + Assert.IsFalse(ReferenceEquals(c2, c4)); + } - [Test] - public void DuplicateId() - { - string json = @"{ + [Test] + public void DuplicateId() + { + string json = @"{ ""Data"": { ""Prop1"": { ""$id"": ""1"", @@ -1073,49 +1061,51 @@ namespace Newtonsoft.Json.Tests.Serialization } }"; - ExceptionAssert.Throws( - "Error reading object reference '1'. Path 'Data.Prop2.MyProperty', line 9, position 20.", - () => JsonConvert.DeserializeObject(json)); + ExceptionAssert.Throws( + "Error reading object reference '1'. Path 'Data.Prop2.MyProperty', line 9, position 20.", + () => JsonConvert.DeserializeObject(json)); + } } - } - public class PropertyItemIsReferenceBody - { - public TestComponentSimple Prop1 { get; set; } - public TestComponentSimple Prop2 { get; set; } - public IList Data { get; set; } - } + public class PropertyItemIsReferenceBody + { + public TestComponentSimple Prop1 { get; set; } + public TestComponentSimple Prop2 { get; set; } + public IList Data { get; set; } + } - public class PropertyItemIsReferenceObject - { - [JsonProperty(ItemIsReference = true)] - public PropertyItemIsReferenceBody Data { get; set; } - } + public class PropertyItemIsReferenceObject + { + [JsonProperty(ItemIsReference = true)] + public PropertyItemIsReferenceBody Data { get; set; } + } - public class PropertyItemIsReferenceList - { - [JsonProperty(ItemIsReference = true)] - public IList> Data { get; set; } - } + public class PropertyItemIsReferenceList + { + [JsonProperty(ItemIsReference = true)] + public IList> Data { get; set; } + } - [JsonArray(ItemIsReference = true)] - public class ReferencedList : List - { - } + [JsonArray(ItemIsReference = true)] + public class ReferencedList : List + { + } - [JsonDictionary(ItemIsReference = true)] - public class ReferencedDictionary : Dictionary - { - } + [JsonDictionary(ItemIsReference = true)] + public class ReferencedDictionary : Dictionary + { + } - [JsonObject(ItemIsReference = true)] - public class ReferenceObject - { - public TestComponentSimple Component1 { get; set; } - public TestComponentSimple Component2 { get; set; } - [JsonProperty(IsReference = false)] - public TestComponentSimple ComponentNotReference { get; set; } - public string String { get; set; } - public int Integer { get; set; } - } -} + [JsonObject(ItemIsReference = true)] + public class ReferenceObject + { + public TestComponentSimple Component1 { get; set; } + public TestComponentSimple Component2 { get; set; } + + [JsonProperty(IsReference = false)] + public TestComponentSimple ComponentNotReference { get; set; } + + public string String { get; set; } + public int Integer { get; set; } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Serialization/ReferenceLoopHandlingTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/ReferenceLoopHandlingTests.cs index 0a4f3557..4c5640df 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/ReferenceLoopHandlingTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/ReferenceLoopHandlingTests.cs @@ -40,45 +40,45 @@ using Newtonsoft.Json.Tests.Linq; namespace Newtonsoft.Json.Tests.Serialization { - [TestFixture] - public class ReferenceLoopHandlingTests : TestFixtureBase - { - [Test] - public void ReferenceLoopHandlingTest() + [TestFixture] + public class ReferenceLoopHandlingTests : TestFixtureBase { - JsonPropertyAttribute attribute = new JsonPropertyAttribute(); - Assert.AreEqual(null, attribute._defaultValueHandling); - Assert.AreEqual(ReferenceLoopHandling.Error, attribute.ReferenceLoopHandling); - - attribute.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; - Assert.AreEqual(ReferenceLoopHandling.Ignore, attribute._referenceLoopHandling); - Assert.AreEqual(ReferenceLoopHandling.Ignore, attribute.ReferenceLoopHandling); - } - - [Test] - public void IgnoreObjectReferenceLoop() - { - ReferenceLoopHandlingObjectContainerAttribute o = new ReferenceLoopHandlingObjectContainerAttribute(); - o.Value = o; - - string json = JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings + [Test] + public void ReferenceLoopHandlingTest() { - ReferenceLoopHandling = ReferenceLoopHandling.Serialize - }); - Assert.AreEqual("{}", json); - } + JsonPropertyAttribute attribute = new JsonPropertyAttribute(); + Assert.AreEqual(null, attribute._defaultValueHandling); + Assert.AreEqual(ReferenceLoopHandling.Error, attribute.ReferenceLoopHandling); - [Test] - public void IgnoreObjectReferenceLoopWithPropertyOverride() - { - ReferenceLoopHandlingObjectContainerAttributeWithPropertyOverride o = new ReferenceLoopHandlingObjectContainerAttributeWithPropertyOverride(); - o.Value = o; + attribute.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; + Assert.AreEqual(ReferenceLoopHandling.Ignore, attribute._referenceLoopHandling); + Assert.AreEqual(ReferenceLoopHandling.Ignore, attribute.ReferenceLoopHandling); + } - string json = JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings - { - ReferenceLoopHandling = ReferenceLoopHandling.Serialize - }); - Assert.AreEqual(@"{ + [Test] + public void IgnoreObjectReferenceLoop() + { + ReferenceLoopHandlingObjectContainerAttribute o = new ReferenceLoopHandlingObjectContainerAttribute(); + o.Value = o; + + string json = JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings + { + ReferenceLoopHandling = ReferenceLoopHandling.Serialize + }); + Assert.AreEqual("{}", json); + } + + [Test] + public void IgnoreObjectReferenceLoopWithPropertyOverride() + { + ReferenceLoopHandlingObjectContainerAttributeWithPropertyOverride o = new ReferenceLoopHandlingObjectContainerAttributeWithPropertyOverride(); + o.Value = o; + + string json = JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings + { + ReferenceLoopHandling = ReferenceLoopHandling.Serialize + }); + Assert.AreEqual(@"{ ""Value"": { ""Value"": { ""Value"": { @@ -91,44 +91,44 @@ namespace Newtonsoft.Json.Tests.Serialization } } }", json); - } + } - [Test] - public void IgnoreArrayReferenceLoop() - { - ReferenceLoopHandlingList a = new ReferenceLoopHandlingList(); - a.Add(a); + [Test] + public void IgnoreArrayReferenceLoop() + { + ReferenceLoopHandlingList a = new ReferenceLoopHandlingList(); + a.Add(a); - string json = JsonConvert.SerializeObject(a, Formatting.Indented, new JsonSerializerSettings - { - ReferenceLoopHandling = ReferenceLoopHandling.Serialize - }); - Assert.AreEqual("[]", json); - } + string json = JsonConvert.SerializeObject(a, Formatting.Indented, new JsonSerializerSettings + { + ReferenceLoopHandling = ReferenceLoopHandling.Serialize + }); + Assert.AreEqual("[]", json); + } - [Test] - public void IgnoreDictionaryReferenceLoop() - { - ReferenceLoopHandlingDictionary d = new ReferenceLoopHandlingDictionary(); - d.Add("First", d); + [Test] + public void IgnoreDictionaryReferenceLoop() + { + ReferenceLoopHandlingDictionary d = new ReferenceLoopHandlingDictionary(); + d.Add("First", d); - string json = JsonConvert.SerializeObject(d, Formatting.Indented, new JsonSerializerSettings - { - ReferenceLoopHandling = ReferenceLoopHandling.Serialize - }); - Assert.AreEqual("{}", json); - } + string json = JsonConvert.SerializeObject(d, Formatting.Indented, new JsonSerializerSettings + { + ReferenceLoopHandling = ReferenceLoopHandling.Serialize + }); + Assert.AreEqual("{}", json); + } - [Test] - public void SerializePropertyItemReferenceLoopHandling() - { - PropertyItemReferenceLoopHandling c = new PropertyItemReferenceLoopHandling(); - c.Text = "Text!"; - c.SetData(new List { c }); + [Test] + public void SerializePropertyItemReferenceLoopHandling() + { + PropertyItemReferenceLoopHandling c = new PropertyItemReferenceLoopHandling(); + c.Text = "Text!"; + c.SetData(new List { c }); - string json = JsonConvert.SerializeObject(c, Formatting.Indented); + string json = JsonConvert.SerializeObject(c, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Text"": ""Text!"", ""Data"": [ { @@ -147,190 +147,190 @@ namespace Newtonsoft.Json.Tests.Serialization } ] }", json); - } + } #if !(PORTABLE || SILVERLIGHT || NETFX_CORE || PORTABLE40) - public class MainClass : ISerializable - { - public ChildClass Child { get; set; } + public class MainClass : ISerializable + { + public ChildClass Child { get; set; } - public void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue("Child", Child); - } - } + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("Child", Child); + } + } - public class ChildClass : ISerializable - { - public string Name { get; set; } - public MainClass Parent { get; set; } + public class ChildClass : ISerializable + { + public string Name { get; set; } + public MainClass Parent { get; set; } - public void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue("Parent", Parent); - info.AddValue("Name", Name); - } - } + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("Parent", Parent); + info.AddValue("Name", Name); + } + } - [Test] - public void ErrorISerializableCyclicReferenceLoop() - { - var main = new MainClass(); - var child = new ChildClass(); + [Test] + public void ErrorISerializableCyclicReferenceLoop() + { + var main = new MainClass(); + var child = new ChildClass(); - child.Name = "Child1"; - child.Parent = main; // Obvious Circular Reference + child.Name = "Child1"; + child.Parent = main; // Obvious Circular Reference - main.Child = child; + main.Child = child; - var settings = - new JsonSerializerSettings(); + var settings = + new JsonSerializerSettings(); - ExceptionAssert.Throws( - "Self referencing loop detected with type 'Newtonsoft.Json.Tests.Serialization.ReferenceLoopHandlingTests+MainClass'. Path 'Child'.", - () => JsonConvert.SerializeObject(main, settings)); - } + ExceptionAssert.Throws( + "Self referencing loop detected with type 'Newtonsoft.Json.Tests.Serialization.ReferenceLoopHandlingTests+MainClass'. Path 'Child'.", + () => JsonConvert.SerializeObject(main, settings)); + } - [Test] - public void IgnoreISerializableCyclicReferenceLoop() - { - var main = new MainClass(); - var child = new ChildClass(); + [Test] + public void IgnoreISerializableCyclicReferenceLoop() + { + var main = new MainClass(); + var child = new ChildClass(); - child.Name = "Child1"; - child.Parent = main; // Obvious Circular Reference + child.Name = "Child1"; + child.Parent = main; // Obvious Circular Reference - main.Child = child; + main.Child = child; - var settings = - new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }; + var settings = + new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }; - var c = JsonConvert.SerializeObject(main, settings); - Assert.AreEqual(@"{""Child"":{""Name"":""Child1""}}", c); - } + var c = JsonConvert.SerializeObject(main, settings); + Assert.AreEqual(@"{""Child"":{""Name"":""Child1""}}", c); + } #endif #if !(NET20 || NET35 || PORTABLE40) - public class DictionaryDynamicObject : DynamicObject - { - public IDictionary Values { get; private set; } - - public DictionaryDynamicObject() - { - Values = new Dictionary(); - } - - public override bool TrySetMember(SetMemberBinder binder, object value) - { - Values[binder.Name] = value; - return true; - } - - public override bool TryGetMember(GetMemberBinder binder, out object result) - { - return Values.TryGetValue(binder.Name, out result); - } - - public override IEnumerable GetDynamicMemberNames() - { - return Values.Keys; - } - } - - [Test] - public void ErrorDynamicCyclicReferenceLoop() - { - dynamic parent = new DictionaryDynamicObject(); - dynamic child = new DictionaryDynamicObject(); - parent.child = child; - child.parent = parent; - - var settings = new JsonSerializerSettings(); - - ExceptionAssert.Throws( - "Self referencing loop detected with type 'Newtonsoft.Json.Tests.Serialization.ReferenceLoopHandlingTests+DictionaryDynamicObject'. Path 'child'.", - () => JsonConvert.SerializeObject(parent, settings)); - } - - [Test] - public void IgnoreDynamicCyclicReferenceLoop() - { - dynamic parent = new DictionaryDynamicObject(); - dynamic child = new DictionaryDynamicObject(); - parent.child = child; - parent.name = "parent"; - child.parent = parent; - child.name = "child"; - - var settings = new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }; - - var c = JsonConvert.SerializeObject(parent, settings); - Assert.AreEqual(@"{""child"":{""name"":""child""},""name"":""parent""}", c); - } -#endif - } - - public class PropertyItemReferenceLoopHandling - { - private IList _data; - private int _accessCount; - - public string Text { get; set; } - - [JsonProperty(ItemReferenceLoopHandling = ReferenceLoopHandling.Serialize)] - public IList Data - { - get - { - if (_accessCount >= 3) - return null; - - _accessCount++; - return new List(_data); - } - } - - public void SetData(IList data) - { - _data = data; - } - } - - [JsonArray(ItemReferenceLoopHandling = ReferenceLoopHandling.Ignore)] - public class ReferenceLoopHandlingList : List - { - } - - [JsonDictionary(ItemReferenceLoopHandling = ReferenceLoopHandling.Ignore)] - public class ReferenceLoopHandlingDictionary : Dictionary - { - } - - [JsonObject(ItemReferenceLoopHandling = ReferenceLoopHandling.Ignore)] - public class ReferenceLoopHandlingObjectContainerAttribute - { - public ReferenceLoopHandlingObjectContainerAttribute Value { get; set; } - } - - [JsonObject(ItemReferenceLoopHandling = ReferenceLoopHandling.Ignore)] - public class ReferenceLoopHandlingObjectContainerAttributeWithPropertyOverride - { - private ReferenceLoopHandlingObjectContainerAttributeWithPropertyOverride _value; - private int _getCount; - - [JsonProperty(ReferenceLoopHandling = ReferenceLoopHandling.Serialize)] - public ReferenceLoopHandlingObjectContainerAttributeWithPropertyOverride Value - { - get - { - if (_getCount < 5) + public class DictionaryDynamicObject : DynamicObject { - _getCount++; - return _value; + public IDictionary Values { get; private set; } + + public DictionaryDynamicObject() + { + Values = new Dictionary(); + } + + public override bool TrySetMember(SetMemberBinder binder, object value) + { + Values[binder.Name] = value; + return true; + } + + public override bool TryGetMember(GetMemberBinder binder, out object result) + { + return Values.TryGetValue(binder.Name, out result); + } + + public override IEnumerable GetDynamicMemberNames() + { + return Values.Keys; + } } - return null; - } - set { _value = value; } + + [Test] + public void ErrorDynamicCyclicReferenceLoop() + { + dynamic parent = new DictionaryDynamicObject(); + dynamic child = new DictionaryDynamicObject(); + parent.child = child; + child.parent = parent; + + var settings = new JsonSerializerSettings(); + + ExceptionAssert.Throws( + "Self referencing loop detected with type 'Newtonsoft.Json.Tests.Serialization.ReferenceLoopHandlingTests+DictionaryDynamicObject'. Path 'child'.", + () => JsonConvert.SerializeObject(parent, settings)); + } + + [Test] + public void IgnoreDynamicCyclicReferenceLoop() + { + dynamic parent = new DictionaryDynamicObject(); + dynamic child = new DictionaryDynamicObject(); + parent.child = child; + parent.name = "parent"; + child.parent = parent; + child.name = "child"; + + var settings = new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }; + + var c = JsonConvert.SerializeObject(parent, settings); + Assert.AreEqual(@"{""child"":{""name"":""child""},""name"":""parent""}", c); + } +#endif } - } -} + + public class PropertyItemReferenceLoopHandling + { + private IList _data; + private int _accessCount; + + public string Text { get; set; } + + [JsonProperty(ItemReferenceLoopHandling = ReferenceLoopHandling.Serialize)] + public IList Data + { + get + { + if (_accessCount >= 3) + return null; + + _accessCount++; + return new List(_data); + } + } + + public void SetData(IList data) + { + _data = data; + } + } + + [JsonArray(ItemReferenceLoopHandling = ReferenceLoopHandling.Ignore)] + public class ReferenceLoopHandlingList : List + { + } + + [JsonDictionary(ItemReferenceLoopHandling = ReferenceLoopHandling.Ignore)] + public class ReferenceLoopHandlingDictionary : Dictionary + { + } + + [JsonObject(ItemReferenceLoopHandling = ReferenceLoopHandling.Ignore)] + public class ReferenceLoopHandlingObjectContainerAttribute + { + public ReferenceLoopHandlingObjectContainerAttribute Value { get; set; } + } + + [JsonObject(ItemReferenceLoopHandling = ReferenceLoopHandling.Ignore)] + public class ReferenceLoopHandlingObjectContainerAttributeWithPropertyOverride + { + private ReferenceLoopHandlingObjectContainerAttributeWithPropertyOverride _value; + private int _getCount; + + [JsonProperty(ReferenceLoopHandling = ReferenceLoopHandling.Serialize)] + public ReferenceLoopHandlingObjectContainerAttributeWithPropertyOverride Value + { + get + { + if (_getCount < 5) + { + _getCount++; + return _value; + } + return null; + } + set { _value = value; } + } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Serialization/SerializationErrorHandlingTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/SerializationErrorHandlingTests.cs index ab007af4..17bb9756 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/SerializationErrorHandlingTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/SerializationErrorHandlingTests.cs @@ -43,17 +43,17 @@ using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestCl using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; #endif using System.IO; -using ErrorEventArgs=Newtonsoft.Json.Serialization.ErrorEventArgs; +using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs; namespace Newtonsoft.Json.Tests.Serialization { - [TestFixture] - public class SerializationErrorHandlingTests : TestFixtureBase - { - [Test] - public void ErrorDeserializingListHandled() + [TestFixture] + public class SerializationErrorHandlingTests : TestFixtureBase { - string json = @"[ + [Test] + public void ErrorDeserializingListHandled() + { + string json = @"[ { ""Name"": ""Jim"", ""BirthDate"": ""\/Date(978048000000)\/"", @@ -66,16 +66,16 @@ namespace Newtonsoft.Json.Tests.Serialization } ]"; - VersionKeyedCollection c = JsonConvert.DeserializeObject(json); - Assert.AreEqual(1, c.Count); - Assert.AreEqual(1, c.Messages.Count); - Assert.AreEqual("[1] - Error message for member 1 = An item with the same key has already been added.", c.Messages[0]); - } + VersionKeyedCollection c = JsonConvert.DeserializeObject(json); + Assert.AreEqual(1, c.Count); + Assert.AreEqual(1, c.Messages.Count); + Assert.AreEqual("[1] - Error message for member 1 = An item with the same key has already been added.", c.Messages[0]); + } - [Test] - public void DeserializingErrorInChildObject() - { - ListErrorObjectCollection c = JsonConvert.DeserializeObject(@"[ + [Test] + public void DeserializingErrorInChildObject() + { + ListErrorObjectCollection c = JsonConvert.DeserializeObject(@"[ { ""Member"": ""Value1"", ""Member2"": null @@ -98,71 +98,71 @@ namespace Newtonsoft.Json.Tests.Serialization } ]"); - Assert.AreEqual(3, c.Count); - Assert.AreEqual("Value1", c[0].Member); - Assert.AreEqual("Value2", c[1].Member); - Assert.AreEqual("Value3", c[2].Member); - Assert.AreEqual("Handle this!", c[2].ThrowError); - } + Assert.AreEqual(3, c.Count); + Assert.AreEqual("Value1", c[0].Member); + Assert.AreEqual("Value2", c[1].Member); + Assert.AreEqual("Value3", c[2].Member); + Assert.AreEqual("Handle this!", c[2].ThrowError); + } - [Test] - public void SerializingErrorIn3DArray() - { - ListErrorObject[,,] c = new ListErrorObject[,,] + [Test] + public void SerializingErrorIn3DArray() { - { + ListErrorObject[,,] c = new ListErrorObject[,,] { - new ListErrorObject { - Member = "Value1", - ThrowError = "Handle this!", - Member2 = "Member1" - }, - new ListErrorObject - { - Member = "Value2", - Member2 = "Member2" - }, - new ListErrorObject - { - Member = "Value3", - ThrowError = "Handle that!", - Member2 = "Member3" + { + new ListErrorObject + { + Member = "Value1", + ThrowError = "Handle this!", + Member2 = "Member1" + }, + new ListErrorObject + { + Member = "Value2", + Member2 = "Member2" + }, + new ListErrorObject + { + Member = "Value3", + ThrowError = "Handle that!", + Member2 = "Member3" + } + }, + { + new ListErrorObject + { + Member = "Value1", + ThrowError = "Handle this!", + Member2 = "Member1" + }, + new ListErrorObject + { + Member = "Value2", + Member2 = "Member2" + }, + new ListErrorObject + { + Member = "Value3", + ThrowError = "Handle that!", + Member2 = "Member3" + } + } } - }, + }; + + string json = JsonConvert.SerializeObject(c, new JsonSerializerSettings { - new ListErrorObject + Formatting = Formatting.Indented, + Error = (s, e) => { - Member = "Value1", - ThrowError = "Handle this!", - Member2 = "Member1" - }, - new ListErrorObject - { - Member = "Value2", - Member2 = "Member2" - }, - new ListErrorObject - { - Member = "Value3", - ThrowError = "Handle that!", - Member2 = "Member3" + if (e.CurrentObject.GetType().IsArray) + e.ErrorContext.Handled = true; } - } - } - }; + }); - string json = JsonConvert.SerializeObject(c, new JsonSerializerSettings - { - Formatting = Formatting.Indented, - Error = (s, e) => - { - if (e.CurrentObject.GetType().IsArray) - e.ErrorContext.Handled = true; - } - }); - - Assert.AreEqual(@"[ + Assert.AreEqual(@"[ [ [ { @@ -196,35 +196,35 @@ namespace Newtonsoft.Json.Tests.Serialization ] ] ]", json); - } + } - [Test] - public void SerializingErrorInChildObject() - { - ListErrorObjectCollection c = new ListErrorObjectCollection + [Test] + public void SerializingErrorInChildObject() { - new ListErrorObject + ListErrorObjectCollection c = new ListErrorObjectCollection { - Member = "Value1", - ThrowError = "Handle this!", - Member2 = "Member1" - }, - new ListErrorObject - { - Member = "Value2", - Member2 = "Member2" - }, - new ListErrorObject - { - Member = "Value3", - ThrowError = "Handle that!", - Member2 = "Member3" - } - }; + new ListErrorObject + { + Member = "Value1", + ThrowError = "Handle this!", + Member2 = "Member1" + }, + new ListErrorObject + { + Member = "Value2", + Member2 = "Member2" + }, + new ListErrorObject + { + Member = "Value3", + ThrowError = "Handle that!", + Member2 = "Member3" + } + }; - string json = JsonConvert.SerializeObject(c, Formatting.Indented); + string json = JsonConvert.SerializeObject(c, Formatting.Indented); - Assert.AreEqual(@"[ + Assert.AreEqual(@"[ { ""Member"": ""Value1"", ""ThrowError"": ""Handle this!"", @@ -239,12 +239,12 @@ namespace Newtonsoft.Json.Tests.Serialization ""Member2"": ""Member3"" } ]", json); - } + } - [Test] - public void DeserializingErrorInDateTimeCollection() - { - DateTimeErrorObjectCollection c = JsonConvert.DeserializeObject(@"[ + [Test] + public void DeserializingErrorInDateTimeCollection() + { + DateTimeErrorObjectCollection c = JsonConvert.DeserializeObject(@"[ ""2009-09-09T00:00:00Z"", ""kjhkjhkjhkjh"", [ @@ -255,27 +255,27 @@ namespace Newtonsoft.Json.Tests.Serialization ""2000-12-01T00:00:00Z"" ]", new IsoDateTimeConverter()); - Assert.AreEqual(3, c.Count); - Assert.AreEqual(new DateTime(2009, 9, 9, 0, 0, 0, DateTimeKind.Utc), c[0]); - Assert.AreEqual(new DateTime(1977, 2, 20, 0, 0, 0, DateTimeKind.Utc), c[1]); - Assert.AreEqual(new DateTime(2000, 12, 1, 0, 0, 0, DateTimeKind.Utc), c[2]); - } + Assert.AreEqual(3, c.Count); + Assert.AreEqual(new DateTime(2009, 9, 9, 0, 0, 0, DateTimeKind.Utc), c[0]); + Assert.AreEqual(new DateTime(1977, 2, 20, 0, 0, 0, DateTimeKind.Utc), c[1]); + Assert.AreEqual(new DateTime(2000, 12, 1, 0, 0, 0, DateTimeKind.Utc), c[2]); + } - [Test] - public void DeserializingErrorHandlingUsingEvent() - { - List errors = new List(); - - JsonSerializer serializer = JsonSerializer.Create(new JsonSerializerSettings + [Test] + public void DeserializingErrorHandlingUsingEvent() { - Error = delegate(object sender, ErrorEventArgs args) + List errors = new List(); + + JsonSerializer serializer = JsonSerializer.Create(new JsonSerializerSettings { - errors.Add(args.ErrorContext.Path + " - " + args.ErrorContext.Member + " - " + args.ErrorContext.Error.Message); - args.ErrorContext.Handled = true; - }, - Converters = {new IsoDateTimeConverter()} - }); - var c = serializer.Deserialize>(new JsonTextReader(new StringReader(@"[ + Error = delegate(object sender, ErrorEventArgs args) + { + errors.Add(args.ErrorContext.Path + " - " + args.ErrorContext.Member + " - " + args.ErrorContext.Error.Message); + args.ErrorContext.Handled = true; + }, + Converters = { new IsoDateTimeConverter() } + }); + var c = serializer.Deserialize>(new JsonTextReader(new StringReader(@"[ ""2009-09-09T00:00:00Z"", ""I am not a date and will error!"", [ @@ -287,36 +287,36 @@ namespace Newtonsoft.Json.Tests.Serialization ]"))); - // 2009-09-09T00:00:00Z - // 1977-02-20T00:00:00Z - // 2000-12-01T00:00:00Z + // 2009-09-09T00:00:00Z + // 1977-02-20T00:00:00Z + // 2000-12-01T00:00:00Z - // The string was not recognized as a valid DateTime. There is a unknown word starting at index 0. - // Unexpected token parsing date. Expected String, got StartArray. - // Cannot convert null value to System.DateTime. + // The string was not recognized as a valid DateTime. There is a unknown word starting at index 0. + // Unexpected token parsing date. Expected String, got StartArray. + // Cannot convert null value to System.DateTime. - Assert.AreEqual(3, c.Count); - Assert.AreEqual(new DateTime(2009, 9, 9, 0, 0, 0, DateTimeKind.Utc), c[0]); - Assert.AreEqual(new DateTime(1977, 2, 20, 0, 0, 0, DateTimeKind.Utc), c[1]); - Assert.AreEqual(new DateTime(2000, 12, 1, 0, 0, 0, DateTimeKind.Utc), c[2]); + Assert.AreEqual(3, c.Count); + Assert.AreEqual(new DateTime(2009, 9, 9, 0, 0, 0, DateTimeKind.Utc), c[0]); + Assert.AreEqual(new DateTime(1977, 2, 20, 0, 0, 0, DateTimeKind.Utc), c[1]); + Assert.AreEqual(new DateTime(2000, 12, 1, 0, 0, 0, DateTimeKind.Utc), c[2]); - Assert.AreEqual(3, errors.Count); + Assert.AreEqual(3, errors.Count); #if !(NET20 || NET35 || WINDOWS_PHONE) - Assert.AreEqual("[1] - 1 - The string was not recognized as a valid DateTime. There is an unknown word starting at index 0.", errors[0]); + Assert.AreEqual("[1] - 1 - The string was not recognized as a valid DateTime. There is an unknown word starting at index 0.", errors[0]); #else Assert.AreEqual("[1] - 1 - The string was not recognized as a valid DateTime. There is a unknown word starting at index 0.", errors[0]); #endif - Assert.AreEqual("[2] - 2 - Unexpected token parsing date. Expected String, got StartArray. Path '[2]', line 4, position 10.", errors[1]); - Assert.AreEqual("[4] - 4 - Cannot convert null value to System.DateTime. Path '[4]', line 8, position 13.", errors[2]); - } + Assert.AreEqual("[2] - 2 - Unexpected token parsing date. Expected String, got StartArray. Path '[2]', line 4, position 10.", errors[1]); + Assert.AreEqual("[4] - 4 - Cannot convert null value to System.DateTime. Path '[4]', line 8, position 13.", errors[2]); + } - [Test] - public void DeserializingErrorInDateTimeCollectionWithAttributeWithEventNotCalled() - { - bool eventErrorHandlerCalled = false; + [Test] + public void DeserializingErrorInDateTimeCollectionWithAttributeWithEventNotCalled() + { + bool eventErrorHandlerCalled = false; - DateTimeErrorObjectCollection c = JsonConvert.DeserializeObject( - @"[ + DateTimeErrorObjectCollection c = JsonConvert.DeserializeObject( + @"[ ""2009-09-09T00:00:00Z"", ""kjhkjhkjhkjh"", [ @@ -326,500 +326,490 @@ namespace Newtonsoft.Json.Tests.Serialization null, ""2000-12-01T00:00:00Z"" ]", - new JsonSerializerSettings - { - Error = (s, a) => eventErrorHandlerCalled = true, - Converters = - { - new IsoDateTimeConverter() - } - }); + new JsonSerializerSettings + { + Error = (s, a) => eventErrorHandlerCalled = true, + Converters = + { + new IsoDateTimeConverter() + } + }); - Assert.AreEqual(3, c.Count); - Assert.AreEqual(new DateTime(2009, 9, 9, 0, 0, 0, DateTimeKind.Utc), c[0]); - Assert.AreEqual(new DateTime(1977, 2, 20, 0, 0, 0, DateTimeKind.Utc), c[1]); - Assert.AreEqual(new DateTime(2000, 12, 1, 0, 0, 0, DateTimeKind.Utc), c[2]); + Assert.AreEqual(3, c.Count); + Assert.AreEqual(new DateTime(2009, 9, 9, 0, 0, 0, DateTimeKind.Utc), c[0]); + Assert.AreEqual(new DateTime(1977, 2, 20, 0, 0, 0, DateTimeKind.Utc), c[1]); + Assert.AreEqual(new DateTime(2000, 12, 1, 0, 0, 0, DateTimeKind.Utc), c[2]); - Assert.AreEqual(false, eventErrorHandlerCalled); - } + Assert.AreEqual(false, eventErrorHandlerCalled); + } - [Test] - public void SerializePerson() - { - PersonError person = new PersonError + [Test] + public void SerializePerson() { - Name = "George Michael Bluth", - Age = 16, - Roles = null, - Title = "Mister Manager" - }; + PersonError person = new PersonError + { + Name = "George Michael Bluth", + Age = 16, + Roles = null, + Title = "Mister Manager" + }; - string json = JsonConvert.SerializeObject(person, Formatting.Indented); + string json = JsonConvert.SerializeObject(person, Formatting.Indented); - Console.WriteLine(json); - //{ - // "Name": "George Michael Bluth", - // "Age": 16, - // "Title": "Mister Manager" - //} + Console.WriteLine(json); + //{ + // "Name": "George Michael Bluth", + // "Age": 16, + // "Title": "Mister Manager" + //} - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Name"": ""George Michael Bluth"", ""Age"": 16, ""Title"": ""Mister Manager"" }", json); - } + } - [Test] - public void DeserializeNestedUnhandled() - { - List errors = new List(); - - string json = @"[[""kjhkjhkjhkjh""]]"; - - Exception e = null; - try - { - JsonSerializer serializer = new JsonSerializer(); - serializer.Error += delegate(object sender, ErrorEventArgs args) - { - // only log an error once - if (args.CurrentObject == args.ErrorContext.OriginalObject) - errors.Add(args.ErrorContext.Path + " - " + args.ErrorContext.Member + " - " + args.ErrorContext.Error.Message); - }; - - serializer.Deserialize(new StringReader(json), typeof (List>)); - } - catch (Exception ex) - { - e = ex; - } - - Assert.AreEqual(@"Could not convert string to DateTime: kjhkjhkjhkjh. Path '[0][0]', line 1, position 16.", e.Message); - - Assert.AreEqual(1, errors.Count); - Assert.AreEqual(@"[0][0] - 0 - Could not convert string to DateTime: kjhkjhkjhkjh. Path '[0][0]', line 1, position 16.", errors[0]); - } - - [Test] - public void MultipleRequiredPropertyErrors() - { - string json = "{}"; - List errors = new List(); - JsonSerializer serializer = new JsonSerializer(); - serializer.Error += delegate(object sender, ErrorEventArgs args) + [Test] + public void DeserializeNestedUnhandled() { - errors.Add(args.ErrorContext.Path + " - " + args.ErrorContext.Member + " - " + args.ErrorContext.Error.Message); - args.ErrorContext.Handled = true; - }; - serializer.Deserialize(new JsonTextReader(new StringReader(json)), typeof (MyTypeWithRequiredMembers)); + List errors = new List(); - Assert.AreEqual(2, errors.Count); - Assert.AreEqual(" - Required1 - Required property 'Required1' not found in JSON. Path '', line 1, position 2.", errors[0]); - Assert.AreEqual(" - Required2 - Required property 'Required2' not found in JSON. Path '', line 1, position 2.", errors[1]); - } + string json = @"[[""kjhkjhkjhkjh""]]"; - [Test] - public void HandlingArrayErrors() - { - string json = "[\"a\",\"b\",\"45\",34]"; + Exception e = null; + try + { + JsonSerializer serializer = new JsonSerializer(); + serializer.Error += delegate(object sender, ErrorEventArgs args) + { + // only log an error once + if (args.CurrentObject == args.ErrorContext.OriginalObject) + errors.Add(args.ErrorContext.Path + " - " + args.ErrorContext.Member + " - " + args.ErrorContext.Error.Message); + }; - List errors = new List(); + serializer.Deserialize(new StringReader(json), typeof(List>)); + } + catch (Exception ex) + { + e = ex; + } - JsonSerializer serializer = new JsonSerializer(); - serializer.Error += delegate(object sender, ErrorEventArgs args) + Assert.AreEqual(@"Could not convert string to DateTime: kjhkjhkjhkjh. Path '[0][0]', line 1, position 16.", e.Message); + + Assert.AreEqual(1, errors.Count); + Assert.AreEqual(@"[0][0] - 0 - Could not convert string to DateTime: kjhkjhkjhkjh. Path '[0][0]', line 1, position 16.", errors[0]); + } + + [Test] + public void MultipleRequiredPropertyErrors() { - errors.Add(args.ErrorContext.Path + " - " + args.ErrorContext.Member + " - " + args.ErrorContext.Error.Message); - args.ErrorContext.Handled = true; - }; + string json = "{}"; + List errors = new List(); + JsonSerializer serializer = new JsonSerializer(); + serializer.Error += delegate(object sender, ErrorEventArgs args) + { + errors.Add(args.ErrorContext.Path + " - " + args.ErrorContext.Member + " - " + args.ErrorContext.Error.Message); + args.ErrorContext.Handled = true; + }; + serializer.Deserialize(new JsonTextReader(new StringReader(json)), typeof(MyTypeWithRequiredMembers)); - serializer.Deserialize(new JsonTextReader(new StringReader(json)), typeof (int[])); + Assert.AreEqual(2, errors.Count); + Assert.AreEqual(" - Required1 - Required property 'Required1' not found in JSON. Path '', line 1, position 2.", errors[0]); + Assert.AreEqual(" - Required2 - Required property 'Required2' not found in JSON. Path '', line 1, position 2.", errors[1]); + } - Assert.AreEqual(2, errors.Count); - Assert.AreEqual("[0] - 0 - Could not convert string to integer: a. Path '[0]', line 1, position 4.", errors[0]); - Assert.AreEqual("[1] - 1 - Could not convert string to integer: b. Path '[1]', line 1, position 8.", errors[1]); - } - - [Test] - public void HandlingMultidimensionalArrayErrors() - { - string json = "[[\"a\",\"45\"],[\"b\",34]]"; - - List errors = new List(); - - JsonSerializer serializer = new JsonSerializer(); - serializer.Error += delegate(object sender, ErrorEventArgs args) + [Test] + public void HandlingArrayErrors() { - errors.Add(args.ErrorContext.Path + " - " + args.ErrorContext.Member + " - " + args.ErrorContext.Error.Message); - args.ErrorContext.Handled = true; - }; + string json = "[\"a\",\"b\",\"45\",34]"; - serializer.Deserialize(new JsonTextReader(new StringReader(json)), typeof (int[,])); + List errors = new List(); - Assert.AreEqual(2, errors.Count); - Assert.AreEqual("[0][0] - 0 - Could not convert string to integer: a. Path '[0][0]', line 1, position 5.", errors[0]); - Assert.AreEqual("[1][0] - 0 - Could not convert string to integer: b. Path '[1][0]', line 1, position 16.", errors[1]); - } + JsonSerializer serializer = new JsonSerializer(); + serializer.Error += delegate(object sender, ErrorEventArgs args) + { + errors.Add(args.ErrorContext.Path + " - " + args.ErrorContext.Member + " - " + args.ErrorContext.Error.Message); + args.ErrorContext.Handled = true; + }; - [Test] - public void ErrorHandlingAndAvoidingRecursiveDepthError() - { - string json = "{'A':{'A':{'A':{'A':{'A':{}}}}}}"; - JsonSerializer serializer = new JsonSerializer() {}; - IList errors = new List(); - serializer.Error += (sender, e) => + serializer.Deserialize(new JsonTextReader(new StringReader(json)), typeof(int[])); + + Assert.AreEqual(2, errors.Count); + Assert.AreEqual("[0] - 0 - Could not convert string to integer: a. Path '[0]', line 1, position 4.", errors[0]); + Assert.AreEqual("[1] - 1 - Could not convert string to integer: b. Path '[1]', line 1, position 8.", errors[1]); + } + + [Test] + public void HandlingMultidimensionalArrayErrors() { - e.ErrorContext.Handled = true; - errors.Add(e.ErrorContext.Path); - }; + string json = "[[\"a\",\"45\"],[\"b\",34]]"; - serializer.Deserialize(new JsonTextReader(new StringReader(json)) {MaxDepth = 3}); + List errors = new List(); - Assert.AreEqual(1, errors.Count); - Assert.AreEqual("A.A.A", errors[0]); - } + JsonSerializer serializer = new JsonSerializer(); + serializer.Error += delegate(object sender, ErrorEventArgs args) + { + errors.Add(args.ErrorContext.Path + " - " + args.ErrorContext.Member + " - " + args.ErrorContext.Error.Message); + args.ErrorContext.Handled = true; + }; - public class Nest - { - public Nest A { get; set; } - } + serializer.Deserialize(new JsonTextReader(new StringReader(json)), typeof(int[,])); - [Test] - public void InfiniteErrorHandlingLoopFromInputError() - { - IList errors = new List(); + Assert.AreEqual(2, errors.Count); + Assert.AreEqual("[0][0] - 0 - Could not convert string to integer: a. Path '[0][0]', line 1, position 5.", errors[0]); + Assert.AreEqual("[1][0] - 0 - Could not convert string to integer: b. Path '[1][0]', line 1, position 16.", errors[1]); + } - JsonSerializer serializer = new JsonSerializer(); - serializer.Error += (sender, e) => + [Test] + public void ErrorHandlingAndAvoidingRecursiveDepthError() { - errors.Add(e.ErrorContext.Error.Message); - e.ErrorContext.Handled = true; - }; + string json = "{'A':{'A':{'A':{'A':{'A':{}}}}}}"; + JsonSerializer serializer = new JsonSerializer() { }; + IList errors = new List(); + serializer.Error += (sender, e) => + { + e.ErrorContext.Handled = true; + errors.Add(e.ErrorContext.Path); + }; - ErrorPerson[] result = serializer.Deserialize(new JsonTextReader(new ThrowingReader())); + serializer.Deserialize(new JsonTextReader(new StringReader(json)) { MaxDepth = 3 }); - Assert.IsNull(result); - Assert.AreEqual(3, errors.Count); - Assert.AreEqual("too far", errors[0]); - Assert.AreEqual("too far", errors[1]); - Assert.AreEqual("Infinite loop detected from error handling. Path '[1023]', line 1, position 65536.", errors[2]); - } + Assert.AreEqual(1, errors.Count); + Assert.AreEqual("A.A.A", errors[0]); + } - [Test] - public void InfiniteLoopArrayHandling() - { - IList errors = new List(); + public class Nest + { + public Nest A { get; set; } + } - object o = JsonConvert.DeserializeObject( - "[0,x]", - typeof (int[]), - new JsonSerializerSettings - { - Error = (sender, arg) => - { - errors.Add(arg.ErrorContext.Error.Message); - arg.ErrorContext.Handled = true; - } - }); + [Test] + public void InfiniteErrorHandlingLoopFromInputError() + { + IList errors = new List(); - Assert.IsNull(o); + JsonSerializer serializer = new JsonSerializer(); + serializer.Error += (sender, e) => + { + errors.Add(e.ErrorContext.Error.Message); + e.ErrorContext.Handled = true; + }; - Assert.AreEqual(3, errors.Count); - Assert.AreEqual("Unexpected character encountered while parsing value: x. Path '[0]', line 1, position 3.", errors[0]); - Assert.AreEqual("Unexpected character encountered while parsing value: x. Path '[0]', line 1, position 3.", errors[1]); - Assert.AreEqual("Infinite loop detected from error handling. Path '[0]', line 1, position 3.", errors[2]); - } + ErrorPerson[] result = serializer.Deserialize(new JsonTextReader(new ThrowingReader())); - [Test] - public void InfiniteLoopArrayHandlingInObject() - { - IList errors = new List(); + Assert.IsNull(result); + Assert.AreEqual(3, errors.Count); + Assert.AreEqual("too far", errors[0]); + Assert.AreEqual("too far", errors[1]); + Assert.AreEqual("Infinite loop detected from error handling. Path '[1023]', line 1, position 65536.", errors[2]); + } - Dictionary o = JsonConvert.DeserializeObject>( - "{'badarray':[0,x,2],'goodarray':[0,1,2]}", - new JsonSerializerSettings - { - Error = (sender, arg) => - { - errors.Add(arg.ErrorContext.Error.Message); - arg.ErrorContext.Handled = true; - } - }); + [Test] + public void InfiniteLoopArrayHandling() + { + IList errors = new List(); - Assert.IsNull(o); + object o = JsonConvert.DeserializeObject( + "[0,x]", + typeof(int[]), + new JsonSerializerSettings + { + Error = (sender, arg) => + { + errors.Add(arg.ErrorContext.Error.Message); + arg.ErrorContext.Handled = true; + } + }); - Assert.AreEqual(4, errors.Count); - Assert.AreEqual("Unexpected character encountered while parsing value: x. Path 'badarray[0]', line 1, position 15.", errors[0]); - Assert.AreEqual("Unexpected character encountered while parsing value: x. Path 'badarray[0]', line 1, position 15.", errors[1]); - Assert.AreEqual("Infinite loop detected from error handling. Path 'badarray[0]', line 1, position 15.", errors[2]); - Assert.AreEqual("Unexpected character encountered while parsing value: x. Path 'badarray[0]', line 1, position 15.", errors[3]); - } + Assert.IsNull(o); - [Test] - public void ErrorHandlingEndOfContent() - { - IList errors = new List(); + Assert.AreEqual(3, errors.Count); + Assert.AreEqual("Unexpected character encountered while parsing value: x. Path '[0]', line 1, position 3.", errors[0]); + Assert.AreEqual("Unexpected character encountered while parsing value: x. Path '[0]', line 1, position 3.", errors[1]); + Assert.AreEqual("Infinite loop detected from error handling. Path '[0]', line 1, position 3.", errors[2]); + } - const string input = "{\"events\":[{\"code\":64411},{\"code\":64411,\"prio"; + [Test] + public void InfiniteLoopArrayHandlingInObject() + { + IList errors = new List(); - const int maxDepth = 256; - using (var jsonTextReader = new JsonTextReader(new StringReader(input)) {MaxDepth = maxDepth}) - { - JsonSerializer jsonSerializer = JsonSerializer.Create(new JsonSerializerSettings {MaxDepth = maxDepth}); - jsonSerializer.Error += (sender, e) => - { - errors.Add(e.ErrorContext.Error.Message); - e.ErrorContext.Handled = true; - }; + Dictionary o = JsonConvert.DeserializeObject>( + "{'badarray':[0,x,2],'goodarray':[0,1,2]}", + new JsonSerializerSettings + { + Error = (sender, arg) => + { + errors.Add(arg.ErrorContext.Error.Message); + arg.ErrorContext.Handled = true; + } + }); - LogMessage logMessage = jsonSerializer.Deserialize(jsonTextReader); + Assert.IsNull(o); - Assert.IsNotNull(logMessage.Events); - Assert.AreEqual(1, logMessage.Events.Count); - Assert.AreEqual("64411", logMessage.Events[0].Code); - } + Assert.AreEqual(4, errors.Count); + Assert.AreEqual("Unexpected character encountered while parsing value: x. Path 'badarray[0]', line 1, position 15.", errors[0]); + Assert.AreEqual("Unexpected character encountered while parsing value: x. Path 'badarray[0]', line 1, position 15.", errors[1]); + Assert.AreEqual("Infinite loop detected from error handling. Path 'badarray[0]', line 1, position 15.", errors[2]); + Assert.AreEqual("Unexpected character encountered while parsing value: x. Path 'badarray[0]', line 1, position 15.", errors[3]); + } - Assert.AreEqual(3, errors.Count); - Assert.AreEqual(@"Unterminated string. Expected delimiter: "". Path 'events[1].code', line 1, position 45.", errors[0]); - Assert.AreEqual(@"Unexpected end when deserializing array. Path 'events[1].code', line 1, position 45.", errors[1]); - Assert.AreEqual(@"Unexpected end when deserializing object. Path 'events[1].code', line 1, position 45.", errors[2]); - } + [Test] + public void ErrorHandlingEndOfContent() + { + IList errors = new List(); - [Test] - public void ErrorHandlingEndOfContentDictionary() - { - IList errors = new List(); + const string input = "{\"events\":[{\"code\":64411},{\"code\":64411,\"prio"; - const string input = "{\"events\":{\"code\":64411},\"events2\":{\"code\":64412,"; + const int maxDepth = 256; + using (var jsonTextReader = new JsonTextReader(new StringReader(input)) { MaxDepth = maxDepth }) + { + JsonSerializer jsonSerializer = JsonSerializer.Create(new JsonSerializerSettings { MaxDepth = maxDepth }); + jsonSerializer.Error += (sender, e) => + { + errors.Add(e.ErrorContext.Error.Message); + e.ErrorContext.Handled = true; + }; - const int maxDepth = 256; - using (var jsonTextReader = new JsonTextReader(new StringReader(input)) {MaxDepth = maxDepth}) - { - JsonSerializer jsonSerializer = JsonSerializer.Create(new JsonSerializerSettings {MaxDepth = maxDepth}); - jsonSerializer.Error += (sender, e) => - { - errors.Add(e.ErrorContext.Error.Message); - e.ErrorContext.Handled = true; - }; + LogMessage logMessage = jsonSerializer.Deserialize(jsonTextReader); - IDictionary logEvents = jsonSerializer.Deserialize>(jsonTextReader); + Assert.IsNotNull(logMessage.Events); + Assert.AreEqual(1, logMessage.Events.Count); + Assert.AreEqual("64411", logMessage.Events[0].Code); + } - Assert.IsNotNull(logEvents); - Assert.AreEqual(2, logEvents.Count); - Assert.AreEqual("64411", logEvents["events"].Code); - Assert.AreEqual("64412", logEvents["events2"].Code); - } + Assert.AreEqual(3, errors.Count); + Assert.AreEqual(@"Unterminated string. Expected delimiter: "". Path 'events[1].code', line 1, position 45.", errors[0]); + Assert.AreEqual(@"Unexpected end when deserializing array. Path 'events[1].code', line 1, position 45.", errors[1]); + Assert.AreEqual(@"Unexpected end when deserializing object. Path 'events[1].code', line 1, position 45.", errors[2]); + } - Assert.AreEqual(2, errors.Count); - Assert.AreEqual(@"Unexpected end when deserializing object. Path 'events2.code', line 1, position 49.", errors[0]); - Assert.AreEqual(@"Unexpected end when deserializing object. Path 'events2.code', line 1, position 49.", errors[1]); - } + [Test] + public void ErrorHandlingEndOfContentDictionary() + { + IList errors = new List(); + + const string input = "{\"events\":{\"code\":64411},\"events2\":{\"code\":64412,"; + + const int maxDepth = 256; + using (var jsonTextReader = new JsonTextReader(new StringReader(input)) { MaxDepth = maxDepth }) + { + JsonSerializer jsonSerializer = JsonSerializer.Create(new JsonSerializerSettings { MaxDepth = maxDepth }); + jsonSerializer.Error += (sender, e) => + { + errors.Add(e.ErrorContext.Error.Message); + e.ErrorContext.Handled = true; + }; + + IDictionary logEvents = jsonSerializer.Deserialize>(jsonTextReader); + + Assert.IsNotNull(logEvents); + Assert.AreEqual(2, logEvents.Count); + Assert.AreEqual("64411", logEvents["events"].Code); + Assert.AreEqual("64412", logEvents["events2"].Code); + } + + Assert.AreEqual(2, errors.Count); + Assert.AreEqual(@"Unexpected end when deserializing object. Path 'events2.code', line 1, position 49.", errors[0]); + Assert.AreEqual(@"Unexpected end when deserializing object. Path 'events2.code', line 1, position 49.", errors[1]); + } #if !(NET35 || NET20 || PORTABLE40) - [Test] - public void ErrorHandlingEndOfContentDynamic() - { - IList errors = new List(); + [Test] + public void ErrorHandlingEndOfContentDynamic() + { + IList errors = new List(); - string json = @"{ + string json = @"{ ""Explicit"": true, ""Decimal"": 99.9, ""Int"": 1, ""ChildObject"": { ""Integer"": 123"; - TestDynamicObject newDynamicObject = JsonConvert.DeserializeObject(json, new JsonSerializerSettings - { - Error = (sender, e) => - { - errors.Add(e.ErrorContext.Error.Message); - e.ErrorContext.Handled = true; - } - }); - Assert.AreEqual(true, newDynamicObject.Explicit); + TestDynamicObject newDynamicObject = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + Error = (sender, e) => + { + errors.Add(e.ErrorContext.Error.Message); + e.ErrorContext.Handled = true; + } + }); + Assert.AreEqual(true, newDynamicObject.Explicit); - dynamic d = newDynamicObject; + dynamic d = newDynamicObject; - Assert.AreEqual(99.9, d.Decimal); - Assert.AreEqual(1, d.Int); - Assert.AreEqual(123, d.ChildObject.Integer); + Assert.AreEqual(99.9, d.Decimal); + Assert.AreEqual(1, d.Int); + Assert.AreEqual(123, d.ChildObject.Integer); - Assert.AreEqual(2, errors.Count); - Assert.AreEqual(@"Unexpected end when deserializing object. Path 'ChildObject.Integer', line 6, position 19.", errors[0]); - Assert.AreEqual(@"Unexpected end when deserializing object. Path 'ChildObject.Integer', line 6, position 19.", errors[1]); - } + Assert.AreEqual(2, errors.Count); + Assert.AreEqual(@"Unexpected end when deserializing object. Path 'ChildObject.Integer', line 6, position 19.", errors[0]); + 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"}, - }; - - Dictionary> dictionary = data.GroupBy(person => person.FirstName).ToDictionary(group => @group.Key, group => @group.Cast()); - string output = JsonConvert.SerializeObject(dictionary, Formatting.None, settings); - Assert.AreEqual(@"{""Scott"":[]}", output); - } - - [Test] - public void WriteEndOnPropertyState2() - { - JsonSerializerSettings settings = new JsonSerializerSettings(); - settings.Error += (obj, args) => + [Test] + public void WriteEndOnPropertyState() { - args.ErrorContext.Handled = true; - }; + 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 data = new List() + { + new ErrorPerson2 { FirstName = "Scott", LastName = "Hanselman" }, + new ErrorPerson2 { FirstName = "Scott", LastName = "Hunter" }, + new ErrorPerson2 { FirstName = "Scott", LastName = "Guthrie" }, + }; - Dictionary> dictionary = data.GroupBy(person => person.FirstName).ToDictionary(group => @group.Key, group => @group.Cast()); - string output = JsonConvert.SerializeObject(dictionary, Formatting.None, settings); - - Assert.AreEqual(@"{""Scott"":[],""James"":[]}", output); - } - - [Test] - public void NoObjectWithEvent() - { - string json = "{\"}"; - byte[] byteArray = Encoding.UTF8.GetBytes(json); - MemoryStream stream = new MemoryStream(byteArray); - JsonTextReader jReader = new JsonTextReader(new StreamReader(stream)); - JsonSerializer s = new JsonSerializer(); - s.Error += (sender, args) => - { - args.ErrorContext.Handled = true; - }; - ErrorPerson2 obj = s.Deserialize(jReader); - - Assert.IsNull(obj); - } - - [Test] - public void NoObjectWithAttribute() - { - string json = "{\"}"; - byte[] byteArray = Encoding.UTF8.GetBytes(json); - MemoryStream stream = new MemoryStream(byteArray); - JsonTextReader jReader = new JsonTextReader(new StreamReader(stream)); - JsonSerializer s = new JsonSerializer(); - - ExceptionAssert.Throws( - @"Unterminated string. Expected delimiter: "". Path '', line 1, position 3.", - () => - { - ErrorTestObject obj = s.Deserialize(jReader); - }); - } - } - - 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 - { - private int _position = 0; - private static string element = "{\"FirstName\":\"Din\",\"LastName\":\"Rav\",\"Item\":{\"ItemName\":\"temp\"}}"; - private bool _firstRead = true; - private bool _readComma = false; - - public ThrowingReader() - { - } - - public override int Read(char[] buffer, int index, int count) - { - char[] temp = new char[buffer.Length]; - int charsRead = 0; - if (_firstRead) - { - charsRead = new StringReader("[").Read(temp, index, count); - _firstRead = false; - } - else - { - if (_readComma) - { - charsRead = new StringReader(",").Read(temp, index, count); - _readComma = false; + Dictionary> dictionary = data.GroupBy(person => person.FirstName).ToDictionary(group => @group.Key, group => @group.Cast()); + string output = JsonConvert.SerializeObject(dictionary, Formatting.None, settings); + Assert.AreEqual(@"{""Scott"":[]}", output); } - else + + [Test] + public void WriteEndOnPropertyState2() { - charsRead = new StringReader(element).Read(temp, index, count); - _readComma = true; + 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" }, + }; + + Dictionary> dictionary = data.GroupBy(person => person.FirstName).ToDictionary(group => @group.Key, group => @group.Cast()); + string output = JsonConvert.SerializeObject(dictionary, Formatting.None, settings); + + Assert.AreEqual(@"{""Scott"":[],""James"":[]}", output); } - } - _position += charsRead; - if (_position > 65536) - { - throw new Exception("too far"); - } - Array.Copy(temp, index, buffer, index, charsRead); - return charsRead; + [Test] + public void NoObjectWithEvent() + { + string json = "{\"}"; + byte[] byteArray = Encoding.UTF8.GetBytes(json); + MemoryStream stream = new MemoryStream(byteArray); + JsonTextReader jReader = new JsonTextReader(new StreamReader(stream)); + JsonSerializer s = new JsonSerializer(); + s.Error += (sender, args) => { args.ErrorContext.Handled = true; }; + ErrorPerson2 obj = s.Deserialize(jReader); + + Assert.IsNull(obj); + } + + [Test] + public void NoObjectWithAttribute() + { + string json = "{\"}"; + byte[] byteArray = Encoding.UTF8.GetBytes(json); + MemoryStream stream = new MemoryStream(byteArray); + JsonTextReader jReader = new JsonTextReader(new StreamReader(stream)); + JsonSerializer s = new JsonSerializer(); + + ExceptionAssert.Throws( + @"Unterminated string. Expected delimiter: "". Path '', line 1, position 3.", + () => { ErrorTestObject obj = s.Deserialize(jReader); }); + } } - } - public class ErrorPerson - { - public string FirstName { get; set; } - public string LastName { get; set; } - public ErrorItem Item { get; set; } - } - - public class ErrorItem - { - public string ItemName { get; set; } - } - - [JsonObject] - public class MyTypeWithRequiredMembers - { - [JsonProperty(Required = Required.AllowNull)] public string Required1; - [JsonProperty(Required = Required.AllowNull)] public string Required2; - } - - public class LogMessage - { - public string DeviceId { get; set; } - public IList Events { get; set; } - } - - public class LogEvent - { - public string Code { get; set; } - public int Priority { get; set; } - } - - public class ErrorTestObject - { - [OnError] - internal void OnError(StreamingContext context, ErrorContext errorContext) + internal interface IErrorPerson2 { } - } + + internal class ErrorPerson2 //:IPerson - oops! Forgot to implement the person interface + { + public string LastName { get; set; } + public string FirstName { get; set; } + } + + public class ThrowingReader : TextReader + { + private int _position = 0; + private static string element = "{\"FirstName\":\"Din\",\"LastName\":\"Rav\",\"Item\":{\"ItemName\":\"temp\"}}"; + private bool _firstRead = true; + private bool _readComma = false; + + public ThrowingReader() + { + } + + public override int Read(char[] buffer, int index, int count) + { + char[] temp = new char[buffer.Length]; + int charsRead = 0; + if (_firstRead) + { + charsRead = new StringReader("[").Read(temp, index, count); + _firstRead = false; + } + else + { + if (_readComma) + { + charsRead = new StringReader(",").Read(temp, index, count); + _readComma = false; + } + else + { + charsRead = new StringReader(element).Read(temp, index, count); + _readComma = true; + } + } + + _position += charsRead; + if (_position > 65536) + { + throw new Exception("too far"); + } + Array.Copy(temp, index, buffer, index, charsRead); + return charsRead; + } + } + + public class ErrorPerson + { + public string FirstName { get; set; } + public string LastName { get; set; } + public ErrorItem Item { get; set; } + } + + public class ErrorItem + { + public string ItemName { get; set; } + } + + [JsonObject] + public class MyTypeWithRequiredMembers + { + [JsonProperty(Required = Required.AllowNull)] + public string Required1; + + [JsonProperty(Required = Required.AllowNull)] + public string Required2; + } + + public class LogMessage + { + public string DeviceId { get; set; } + public IList Events { get; set; } + } + + public class LogEvent + { + public string Code { get; set; } + public int Priority { get; set; } + } + + public class ErrorTestObject + { + [OnError] + internal void OnError(StreamingContext context, ErrorContext errorContext) + { + } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Serialization/SerializationEventAttributeTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/SerializationEventAttributeTests.cs index dc57a47d..7cc31a1e 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/SerializationEventAttributeTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/SerializationEventAttributeTests.cs @@ -49,109 +49,109 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Tests.Serialization { - [TestFixture] - public class SerializationEventAttributeTests : TestFixtureBase - { - [Test] - public void ObjectEvents() + [TestFixture] + public class SerializationEventAttributeTests : TestFixtureBase { - SerializationEventTestObject[] objs = new[] {new SerializationEventTestObject(), new DerivedSerializationEventTestObject()}; + [Test] + public void ObjectEvents() + { + SerializationEventTestObject[] objs = new[] { new SerializationEventTestObject(), new DerivedSerializationEventTestObject() }; - foreach (SerializationEventTestObject current in objs) - { - SerializationEventTestObject obj = current; + foreach (SerializationEventTestObject current in objs) + { + SerializationEventTestObject obj = current; - Assert.AreEqual(11, obj.Member1); - Assert.AreEqual("Hello World!", obj.Member2); - Assert.AreEqual("This is a nonserialized value", obj.Member3); - Assert.AreEqual(null, obj.Member4); - Assert.AreEqual(null, obj.Member5); + Assert.AreEqual(11, obj.Member1); + Assert.AreEqual("Hello World!", obj.Member2); + Assert.AreEqual("This is a nonserialized value", obj.Member3); + Assert.AreEqual(null, obj.Member4); + Assert.AreEqual(null, obj.Member5); - string json = JsonConvert.SerializeObject(obj, Formatting.Indented); - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(obj, Formatting.Indented); + Assert.AreEqual(@"{ ""Member1"": 11, ""Member2"": ""This value went into the data file during serialization."", ""Member4"": null }", json); - Assert.AreEqual(11, obj.Member1); - Assert.AreEqual("This value was reset after serialization.", obj.Member2); - Assert.AreEqual("This is a nonserialized value", obj.Member3); - Assert.AreEqual(null, obj.Member4); + Assert.AreEqual(11, obj.Member1); + Assert.AreEqual("This value was reset after serialization.", obj.Member2); + Assert.AreEqual("This is a nonserialized value", obj.Member3); + Assert.AreEqual(null, obj.Member4); - string expectedError = String.Format("Error message for member Member6 = Error getting value from 'Member6' on '{0}'.", obj.GetType().FullName); - Assert.AreEqual(expectedError, obj.Member5); + string expectedError = String.Format("Error message for member Member6 = Error getting value from 'Member6' on '{0}'.", obj.GetType().FullName); + Assert.AreEqual(expectedError, obj.Member5); - JObject o = JObject.Parse(@"{ + JObject o = JObject.Parse(@"{ ""Member1"": 11, ""Member2"": ""This value went into the data file during serialization."", ""Member4"": null }"); - o["Member6"] = "Dummy text for error"; + o["Member6"] = "Dummy text for error"; - obj = (SerializationEventTestObject) JsonConvert.DeserializeObject(o.ToString(), obj.GetType()); + obj = (SerializationEventTestObject)JsonConvert.DeserializeObject(o.ToString(), obj.GetType()); - Assert.AreEqual(11, obj.Member1); - Assert.AreEqual("This value went into the data file during serialization.", obj.Member2); - Assert.AreEqual("This value was set during deserialization", obj.Member3); - Assert.AreEqual("This value was set after deserialization.", obj.Member4); + Assert.AreEqual(11, obj.Member1); + Assert.AreEqual("This value went into the data file during serialization.", obj.Member2); + Assert.AreEqual("This value was set during deserialization", obj.Member3); + Assert.AreEqual("This value was set after deserialization.", obj.Member4); - expectedError = String.Format("Error message for member Member6 = Error setting value to 'Member6' on '{0}'.", obj.GetType()); - Assert.AreEqual(expectedError, obj.Member5); + expectedError = String.Format("Error message for member Member6 = Error setting value to 'Member6' on '{0}'.", obj.GetType()); + Assert.AreEqual(expectedError, obj.Member5); - DerivedSerializationEventTestObject derivedObj = obj as DerivedSerializationEventTestObject; - if (derivedObj != null) Assert.AreEqual("This value was set after deserialization.", derivedObj.Member7); - } - } + DerivedSerializationEventTestObject derivedObj = obj as DerivedSerializationEventTestObject; + if (derivedObj != null) Assert.AreEqual("This value was set after deserialization.", derivedObj.Member7); + } + } - [Test] - public void ObjectWithConstructorEvents() - { - SerializationEventTestObjectWithConstructor obj = new SerializationEventTestObjectWithConstructor(11, "Hello World!", null); + [Test] + public void ObjectWithConstructorEvents() + { + SerializationEventTestObjectWithConstructor obj = new SerializationEventTestObjectWithConstructor(11, "Hello World!", null); - Assert.AreEqual(11, obj.Member1); - Assert.AreEqual("Hello World!", obj.Member2); - Assert.AreEqual("This is a nonserialized value", obj.Member3); - Assert.AreEqual(null, obj.Member4); + Assert.AreEqual(11, obj.Member1); + Assert.AreEqual("Hello World!", obj.Member2); + Assert.AreEqual("This is a nonserialized value", obj.Member3); + Assert.AreEqual(null, obj.Member4); - string json = JsonConvert.SerializeObject(obj, Formatting.Indented); - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(obj, Formatting.Indented); + Assert.AreEqual(@"{ ""Member1"": 11, ""Member2"": ""This value went into the data file during serialization."", ""Member4"": null }", json); - Assert.AreEqual(11, obj.Member1); - Assert.AreEqual("This value was reset after serialization.", obj.Member2); - Assert.AreEqual("This is a nonserialized value", obj.Member3); - Assert.AreEqual(null, obj.Member4); + Assert.AreEqual(11, obj.Member1); + Assert.AreEqual("This value was reset after serialization.", obj.Member2); + Assert.AreEqual("This is a nonserialized value", obj.Member3); + Assert.AreEqual(null, obj.Member4); - obj = JsonConvert.DeserializeObject(json); + obj = JsonConvert.DeserializeObject(json); - Assert.AreEqual(11, obj.Member1); - Assert.AreEqual("This value went into the data file during serialization.", obj.Member2); - Assert.AreEqual("This value was set during deserialization", obj.Member3); - Assert.AreEqual("This value was set after deserialization.", obj.Member4); - } + Assert.AreEqual(11, obj.Member1); + Assert.AreEqual("This value went into the data file during serialization.", obj.Member2); + Assert.AreEqual("This value was set during deserialization", obj.Member3); + Assert.AreEqual("This value was set after deserialization.", obj.Member4); + } - [Test] - public void ListEvents() - { - SerializationEventTestList obj = new SerializationEventTestList + [Test] + public void ListEvents() { - 1.1m, - 2.222222222m, - int.MaxValue, - Convert.ToDecimal(Math.PI) - }; + SerializationEventTestList obj = new SerializationEventTestList + { + 1.1m, + 2.222222222m, + int.MaxValue, + Convert.ToDecimal(Math.PI) + }; - Assert.AreEqual(11, obj.Member1); - Assert.AreEqual("Hello World!", obj.Member2); - Assert.AreEqual("This is a nonserialized value", obj.Member3); - Assert.AreEqual(null, obj.Member4); + Assert.AreEqual(11, obj.Member1); + Assert.AreEqual("Hello World!", obj.Member2); + Assert.AreEqual("This is a nonserialized value", obj.Member3); + Assert.AreEqual(null, obj.Member4); - string json = JsonConvert.SerializeObject(obj, Formatting.Indented); - Assert.AreEqual(@"[ + string json = JsonConvert.SerializeObject(obj, Formatting.Indented); + Assert.AreEqual(@"[ -1.0, 1.1, 2.222222222, @@ -159,37 +159,37 @@ namespace Newtonsoft.Json.Tests.Serialization 3.14159265358979 ]", json); - Assert.AreEqual(11, obj.Member1); - Assert.AreEqual("This value was reset after serialization.", obj.Member2); - Assert.AreEqual("This is a nonserialized value", obj.Member3); - Assert.AreEqual(null, obj.Member4); + Assert.AreEqual(11, obj.Member1); + Assert.AreEqual("This value was reset after serialization.", obj.Member2); + Assert.AreEqual("This is a nonserialized value", obj.Member3); + Assert.AreEqual(null, obj.Member4); - obj = JsonConvert.DeserializeObject(json); + obj = JsonConvert.DeserializeObject(json); - Assert.AreEqual(11, obj.Member1); - Assert.AreEqual("Hello World!", obj.Member2); - Assert.AreEqual("This value was set during deserialization", obj.Member3); - Assert.AreEqual("This value was set after deserialization.", obj.Member4); - } + Assert.AreEqual(11, obj.Member1); + Assert.AreEqual("Hello World!", obj.Member2); + Assert.AreEqual("This value was set during deserialization", obj.Member3); + Assert.AreEqual("This value was set after deserialization.", obj.Member4); + } - [Test] - public void DictionaryEvents() - { - SerializationEventTestDictionary obj = new SerializationEventTestDictionary + [Test] + public void DictionaryEvents() { - { 1.1m, "first" }, - { 2.222222222m, "second" }, - { int.MaxValue, "third" }, - { Convert.ToDecimal(Math.PI), "fourth" } - }; + SerializationEventTestDictionary obj = new SerializationEventTestDictionary + { + { 1.1m, "first" }, + { 2.222222222m, "second" }, + { int.MaxValue, "third" }, + { Convert.ToDecimal(Math.PI), "fourth" } + }; - Assert.AreEqual(11, obj.Member1); - Assert.AreEqual("Hello World!", obj.Member2); - Assert.AreEqual("This is a nonserialized value", obj.Member3); - Assert.AreEqual(null, obj.Member4); + Assert.AreEqual(11, obj.Member1); + Assert.AreEqual("Hello World!", obj.Member2); + Assert.AreEqual("This is a nonserialized value", obj.Member3); + Assert.AreEqual(null, obj.Member4); - string json = JsonConvert.SerializeObject(obj, Formatting.Indented); - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(obj, Formatting.Indented); + Assert.AreEqual(@"{ ""1.1"": ""first"", ""2.222222222"": ""second"", ""2147483647"": ""third"", @@ -197,176 +197,177 @@ namespace Newtonsoft.Json.Tests.Serialization ""79228162514264337593543950335"": ""Inserted on serializing"" }", json); - Assert.AreEqual(11, obj.Member1); - Assert.AreEqual("This value was reset after serialization.", obj.Member2); - Assert.AreEqual("This is a nonserialized value", obj.Member3); - Assert.AreEqual(null, obj.Member4); + Assert.AreEqual(11, obj.Member1); + Assert.AreEqual("This value was reset after serialization.", obj.Member2); + Assert.AreEqual("This is a nonserialized value", obj.Member3); + Assert.AreEqual(null, obj.Member4); - obj = JsonConvert.DeserializeObject(json); + obj = JsonConvert.DeserializeObject(json); - Assert.AreEqual(11, obj.Member1); - Assert.AreEqual("Hello World!", obj.Member2); - Assert.AreEqual("This value was set during deserialization", obj.Member3); - Assert.AreEqual("This value was set after deserialization.", obj.Member4); - } + Assert.AreEqual(11, obj.Member1); + Assert.AreEqual("Hello World!", obj.Member2); + Assert.AreEqual("This value was set during deserialization", obj.Member3); + Assert.AreEqual("This value was set after deserialization.", obj.Member4); + } - [Test] - public void ObjectEventsDocumentationExample() - { - SerializationEventTestObject obj = new SerializationEventTestObject(); + [Test] + public void ObjectEventsDocumentationExample() + { + SerializationEventTestObject obj = new SerializationEventTestObject(); - Console.WriteLine(obj.Member1); - // 11 - Console.WriteLine(obj.Member2); - // Hello World! - Console.WriteLine(obj.Member3); - // This is a nonserialized value - Console.WriteLine(obj.Member4); - // null - Console.WriteLine(obj.Member5); - // null + Console.WriteLine(obj.Member1); + // 11 + Console.WriteLine(obj.Member2); + // Hello World! + Console.WriteLine(obj.Member3); + // This is a nonserialized value + Console.WriteLine(obj.Member4); + // null + Console.WriteLine(obj.Member5); + // null - string json = JsonConvert.SerializeObject(obj, Formatting.Indented); - // { - // "Member1": 11, - // "Member2": "This value went into the data file during serialization.", - // "Member4": null - // } + string json = JsonConvert.SerializeObject(obj, Formatting.Indented); + // { + // "Member1": 11, + // "Member2": "This value went into the data file during serialization.", + // "Member4": null + // } - Console.WriteLine(obj.Member1); - // 11 - Console.WriteLine(obj.Member2); - // This value was reset after serialization. - Console.WriteLine(obj.Member3); - // This is a nonserialized value - Console.WriteLine(obj.Member4); - // null - Console.WriteLine(obj.Member5); - // Error message for member Member6 = Exception has been thrown by the target of an invocation. + Console.WriteLine(obj.Member1); + // 11 + Console.WriteLine(obj.Member2); + // This value was reset after serialization. + Console.WriteLine(obj.Member3); + // This is a nonserialized value + Console.WriteLine(obj.Member4); + // null + Console.WriteLine(obj.Member5); + // Error message for member Member6 = Exception has been thrown by the target of an invocation. - obj = JsonConvert.DeserializeObject(json); + obj = JsonConvert.DeserializeObject(json); - Console.WriteLine(obj.Member1); - // 11 - Console.WriteLine(obj.Member2); - // This value went into the data file during serialization. - Console.WriteLine(obj.Member3); - // This value was set during deserialization - Console.WriteLine(obj.Member4); - // This value was set after deserialization. - } + Console.WriteLine(obj.Member1); + // 11 + Console.WriteLine(obj.Member2); + // This value went into the data file during serialization. + Console.WriteLine(obj.Member3); + // This value was set during deserialization + Console.WriteLine(obj.Member4); + // This value was set after deserialization. + } - public class SerializationEventBaseTestObject - { - public string TestMember { get; set; } + public class SerializationEventBaseTestObject + { + public string TestMember { get; set; } - [OnSerializing] - internal void OnSerializingMethod(StreamingContext context) - { - TestMember = "Set!"; - } - } + [OnSerializing] + internal void OnSerializingMethod(StreamingContext context) + { + TestMember = "Set!"; + } + } - public class SerializationEventContextSubClassTestObject : SerializationEventBaseTestObject - { - } + public class SerializationEventContextSubClassTestObject : SerializationEventBaseTestObject + { + } - [Test] - public void SerializationEventContextTestObjectSubClassTest() - { - SerializationEventContextSubClassTestObject obj = new SerializationEventContextSubClassTestObject(); + [Test] + public void SerializationEventContextTestObjectSubClassTest() + { + SerializationEventContextSubClassTestObject obj = new SerializationEventContextSubClassTestObject(); - string json = JsonConvert.SerializeObject(obj, Formatting.Indented); - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(obj, Formatting.Indented); + Assert.AreEqual(@"{ ""TestMember"": ""Set!"" }", json); - } + } #if !(SILVERLIGHT || NETFX_CORE || PORTABLE) - public class SerializationEventContextTestObject - { - public string TestMember { get; set; } + public class SerializationEventContextTestObject + { + public string TestMember { get; set; } - [OnSerializing] - internal void OnSerializingMethod(StreamingContext context) - { - TestMember = context.State + " " + context.Context; - } - } + [OnSerializing] + internal void OnSerializingMethod(StreamingContext context) + { + TestMember = context.State + " " + context.Context; + } + } - [Test] - public void SerializationEventContextTest() - { - SerializationEventContextTestObject value = new SerializationEventContextTestObject(); + [Test] + public void SerializationEventContextTest() + { + SerializationEventContextTestObject value = new SerializationEventContextTestObject(); - string json = JsonConvert.SerializeObject(value, Formatting.Indented, new JsonSerializerSettings - { - Context = - new StreamingContext( - StreamingContextStates.Remoting, - "ContextValue") - }); + string json = JsonConvert.SerializeObject(value, Formatting.Indented, new JsonSerializerSettings + { + Context = + new StreamingContext( + StreamingContextStates.Remoting, + "ContextValue") + }); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""TestMember"": ""Remoting ContextValue"" }", json); - } + } #endif #if !PORTABLE - public void WhenSerializationErrorDetectedBySerializer_ThenCallbackIsCalled() - { - // Verify contract is properly finding our callback - var resolver = new DefaultContractResolver().ResolveContract(typeof(FooEvent)); + public void WhenSerializationErrorDetectedBySerializer_ThenCallbackIsCalled() + { + // Verify contract is properly finding our callback + var resolver = new DefaultContractResolver().ResolveContract(typeof(FooEvent)); #pragma warning disable 612,618 - Debug.Assert(resolver.OnError != null); - Debug.Assert(resolver.OnError == typeof(FooEvent).GetMethod("OnError", BindingFlags.Instance | BindingFlags.NonPublic)); + Debug.Assert(resolver.OnError != null); + Debug.Assert(resolver.OnError == typeof(FooEvent).GetMethod("OnError", BindingFlags.Instance | BindingFlags.NonPublic)); #pragma warning restore 612,618 - var serializer = JsonSerializer.Create(new JsonSerializerSettings - { - // If I don't specify Error here, the callback isn't called - // either, but no exception is thrown. - MissingMemberHandling = MissingMemberHandling.Error, - }); + var serializer = JsonSerializer.Create(new JsonSerializerSettings + { + // If I don't specify Error here, the callback isn't called + // either, but no exception is thrown. + MissingMemberHandling = MissingMemberHandling.Error, + }); - // This throws with missing member exception, rather than calling my callback. - var foo = serializer.Deserialize(new JsonTextReader(new StringReader("{ Id: 25 }"))); + // This throws with missing member exception, rather than calling my callback. + var foo = serializer.Deserialize(new JsonTextReader(new StringReader("{ Id: 25 }"))); - // When fixed, this would pass. - Debug.Assert(foo.Identifier == 25); - } + // When fixed, this would pass. + Debug.Assert(foo.Identifier == 25); + } #endif - public class FooEvent - { - public int Identifier { get; set; } - [OnError] - private void OnError(StreamingContext context, ErrorContext error) - { - this.Identifier = 25; + public class FooEvent + { + public int Identifier { get; set; } - // Here we could for example manually copy the - // persisted "Id" value into the renamed "Identifier" - // property, etc. - error.Handled = true; + [OnError] + private void OnError(StreamingContext context, ErrorContext error) + { + Identifier = 25; - // We never get here :( - Console.WriteLine("Error has been fixed"); - } - } + // Here we could for example manually copy the + // persisted "Id" value into the renamed "Identifier" + // property, etc. + error.Handled = true; - [Test] - public void DerivedSerializationEvents() - { - var c = JsonConvert.DeserializeObject("{}"); + // We never get here :( + Console.WriteLine("Error has been fixed"); + } + } - JsonConvert.SerializeObject(c, Formatting.Indented); + [Test] + public void DerivedSerializationEvents() + { + var c = JsonConvert.DeserializeObject("{}"); - IList e = c.GetEvents(); + JsonConvert.SerializeObject(c, Formatting.Indented); - Assert.AreEqual(@"OnDeserializing + IList e = c.GetEvents(); + + Assert.AreEqual(@"OnDeserializing OnDeserializing_Derived OnDeserialized OnDeserialized_Derived @@ -374,18 +375,18 @@ OnSerializing OnSerializing_Derived OnSerialized OnSerialized_Derived", string.Join(Environment.NewLine, e.ToArray())); - } + } - [Test] - public void DerivedDerivedSerializationEvents() - { - var c = JsonConvert.DeserializeObject("{}"); + [Test] + public void DerivedDerivedSerializationEvents() + { + var c = JsonConvert.DeserializeObject("{}"); - JsonConvert.SerializeObject(c, Formatting.Indented); + JsonConvert.SerializeObject(c, Formatting.Indented); - IList e = c.GetEvents(); + IList e = c.GetEvents(); - Assert.AreEqual(@"OnDeserializing + Assert.AreEqual(@"OnDeserializing OnDeserializing_Derived OnDeserializing_Derived_Derived OnDeserialized @@ -397,24 +398,24 @@ OnSerializing_Derived_Derived OnSerialized OnSerialized_Derived OnSerialized_Derived_Derived", string.Join(Environment.NewLine, e.ToArray())); - } + } #if !(NET20 || SILVERLIGHT) - [Test] - public void DerivedDerivedSerializationEvents_DataContractSerializer() - { - string xml = @""; + [Test] + public void DerivedDerivedSerializationEvents_DataContractSerializer() + { + string xml = @""; - DataContractSerializer ss = new DataContractSerializer(typeof(DerivedDerivedSerializationEventOrderTestObject)); + DataContractSerializer ss = new DataContractSerializer(typeof(DerivedDerivedSerializationEventOrderTestObject)); - DerivedDerivedSerializationEventOrderTestObject c = (DerivedDerivedSerializationEventOrderTestObject)ss.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(xml))); + DerivedDerivedSerializationEventOrderTestObject c = (DerivedDerivedSerializationEventOrderTestObject)ss.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(xml))); - MemoryStream ms = new MemoryStream(); - ss.WriteObject(ms, c); + MemoryStream ms = new MemoryStream(); + ss.WriteObject(ms, c); - IList e = c.GetEvents(); + IList e = c.GetEvents(); - Assert.AreEqual(@"OnDeserializing + Assert.AreEqual(@"OnDeserializing OnDeserializing_Derived OnDeserializing_Derived_Derived OnDeserialized @@ -426,100 +427,100 @@ OnSerializing_Derived_Derived OnSerialized OnSerialized_Derived OnSerialized_Derived_Derived", string.Join(Environment.NewLine, e.ToArray())); - } + } #endif - } - - public class SerializationEventOrderTestObject - { - protected IList Events { get; private set; } - - public SerializationEventOrderTestObject() - { - Events = new List(); } - public IList GetEvents() + public class SerializationEventOrderTestObject { - return Events; + protected IList Events { get; private set; } + + public SerializationEventOrderTestObject() + { + Events = new List(); + } + + public IList GetEvents() + { + return Events; + } + + [OnSerializing] + internal void OnSerializingMethod(StreamingContext context) + { + Events.Add("OnSerializing"); + } + + [OnSerialized] + internal void OnSerializedMethod(StreamingContext context) + { + Events.Add("OnSerialized"); + } + + [OnDeserializing] + internal void OnDeserializingMethod(StreamingContext context) + { + Events.Add("OnDeserializing"); + } + + [OnDeserialized] + internal void OnDeserializedMethod(StreamingContext context) + { + Events.Add("OnDeserialized"); + } } - [OnSerializing] - internal void OnSerializingMethod(StreamingContext context) + public class DerivedSerializationEventOrderTestObject : SerializationEventOrderTestObject { - Events.Add("OnSerializing"); + [OnSerializing] + internal new void OnSerializingMethod(StreamingContext context) + { + Events.Add("OnSerializing_Derived"); + } + + [OnSerialized] + internal new void OnSerializedMethod(StreamingContext context) + { + Events.Add("OnSerialized_Derived"); + } + + [OnDeserializing] + internal new void OnDeserializingMethod(StreamingContext context) + { + Events.Add("OnDeserializing_Derived"); + } + + [OnDeserialized] + internal new void OnDeserializedMethod(StreamingContext context) + { + Events.Add("OnDeserialized_Derived"); + } } - [OnSerialized] - internal void OnSerializedMethod(StreamingContext context) + public class DerivedDerivedSerializationEventOrderTestObject : DerivedSerializationEventOrderTestObject { - Events.Add("OnSerialized"); - } + [OnSerializing] + internal new void OnSerializingMethod(StreamingContext context) + { + Events.Add("OnSerializing_Derived_Derived"); + } - [OnDeserializing] - internal void OnDeserializingMethod(StreamingContext context) - { - Events.Add("OnDeserializing"); - } + [OnSerialized] + internal new void OnSerializedMethod(StreamingContext context) + { + Events.Add("OnSerialized_Derived_Derived"); + } - [OnDeserialized] - internal void OnDeserializedMethod(StreamingContext context) - { - Events.Add("OnDeserialized"); - } - } + [OnDeserializing] + internal new void OnDeserializingMethod(StreamingContext context) + { + Events.Add("OnDeserializing_Derived_Derived"); + } - public class DerivedSerializationEventOrderTestObject : SerializationEventOrderTestObject - { - [OnSerializing] - internal new void OnSerializingMethod(StreamingContext context) - { - Events.Add("OnSerializing_Derived"); + [OnDeserialized] + internal new void OnDeserializedMethod(StreamingContext context) + { + Events.Add("OnDeserialized_Derived_Derived"); + } } - - [OnSerialized] - internal new void OnSerializedMethod(StreamingContext context) - { - Events.Add("OnSerialized_Derived"); - } - - [OnDeserializing] - internal new void OnDeserializingMethod(StreamingContext context) - { - Events.Add("OnDeserializing_Derived"); - } - - [OnDeserialized] - internal new void OnDeserializedMethod(StreamingContext context) - { - Events.Add("OnDeserialized_Derived"); - } - } - - public class DerivedDerivedSerializationEventOrderTestObject : DerivedSerializationEventOrderTestObject - { - [OnSerializing] - internal new void OnSerializingMethod(StreamingContext context) - { - Events.Add("OnSerializing_Derived_Derived"); - } - - [OnSerialized] - internal new void OnSerializedMethod(StreamingContext context) - { - Events.Add("OnSerialized_Derived_Derived"); - } - - [OnDeserializing] - internal new void OnDeserializingMethod(StreamingContext context) - { - Events.Add("OnDeserializing_Derived_Derived"); - } - - [OnDeserialized] - internal new void OnDeserializedMethod(StreamingContext context) - { - Events.Add("OnDeserialized_Derived_Derived"); - } - } } \ 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 530b2349..edfb34fd 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/TraceWriterTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/TraceWriterTests.cs @@ -23,82 +23,83 @@ using Newtonsoft.Json.Tests.TestObjects; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json.Tests.Serialization { - public class Staff - { - public string Name { get; set; } - public DateTime StartDate { get; set; } - public IList Roles { get; set; } - } - - [TestFixture] - public class TraceWriterTests : TestFixtureBase - { -#if !(SILVERLIGHT || PORTABLE || NETFX_CORE || PORTABLE40) - [Test] - public void DiagnosticsTraceWriterTest() + public class Staff { - StringWriter sw = new StringWriter(); - TextWriterTraceListener listener = new TextWriterTraceListener(sw); + public string Name { get; set; } + public DateTime StartDate { get; set; } + public IList Roles { get; set; } + } - try - { - Trace.AutoFlush = true; - Trace.Listeners.Add(listener); + [TestFixture] + public class TraceWriterTests : TestFixtureBase + { +#if !(SILVERLIGHT || PORTABLE || NETFX_CORE || PORTABLE40) + [Test] + public void DiagnosticsTraceWriterTest() + { + StringWriter sw = new StringWriter(); + TextWriterTraceListener listener = new TextWriterTraceListener(sw); - DiagnosticsTraceWriter traceWriter = new DiagnosticsTraceWriter(); - traceWriter.Trace(TraceLevel.Verbose, "Verbose!", null); - traceWriter.Trace(TraceLevel.Info, "Info!", null); - traceWriter.Trace(TraceLevel.Warning, "Warning!", null); - traceWriter.Trace(TraceLevel.Error, "Error!", null); - traceWriter.Trace(TraceLevel.Off, "Off!", null); + try + { + Trace.AutoFlush = true; + Trace.Listeners.Add(listener); - Assert.AreEqual(@"Newtonsoft.Json Verbose: 0 : Verbose! + DiagnosticsTraceWriter traceWriter = new DiagnosticsTraceWriter(); + traceWriter.Trace(TraceLevel.Verbose, "Verbose!", null); + traceWriter.Trace(TraceLevel.Info, "Info!", null); + traceWriter.Trace(TraceLevel.Warning, "Warning!", null); + traceWriter.Trace(TraceLevel.Error, "Error!", null); + traceWriter.Trace(TraceLevel.Off, "Off!", null); + + Assert.AreEqual(@"Newtonsoft.Json Verbose: 0 : Verbose! Newtonsoft.Json Information: 0 : Info! Newtonsoft.Json Warning: 0 : Warning! Newtonsoft.Json Error: 0 : Error! ", sw.ToString()); - } - finally - { - Trace.Listeners.Remove(listener); - Trace.AutoFlush = false; - } - } + } + finally + { + Trace.Listeners.Remove(listener); + Trace.AutoFlush = false; + } + } #endif - [Test] - public void MemoryTraceWriterSerializeTest() - { - 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); + [Test] + public void MemoryTraceWriterSerializeTest() + { + 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(); + ITraceWriter traceWriter = new MemoryTraceWriter(); - JsonConvert.SerializeObject( - staff, - new JsonSerializerSettings {TraceWriter = traceWriter, Converters = {new JavaScriptDateTimeConverter()}}); + 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 ''. + 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 ''. - MemoryTraceWriter memoryTraceWriter = (MemoryTraceWriter)traceWriter; - string output = memoryTraceWriter.ToString(); + MemoryTraceWriter memoryTraceWriter = (MemoryTraceWriter)traceWriter; + string output = memoryTraceWriter.ToString(); - Assert.AreEqual(916, output.Length); - Assert.AreEqual(7, memoryTraceWriter.GetTraceMessages().Count()); + Assert.AreEqual(916, output.Length); + Assert.AreEqual(7, memoryTraceWriter.GetTraceMessages().Count()); - string json = @"Serialized JSON: + string json = @"Serialized JSON: { ""Name"": ""Arnie Admin"", ""StartDate"": new Date( @@ -109,13 +110,13 @@ Newtonsoft.Json Error: 0 : Error! ] }"; - Assert.IsTrue(output.Contains(json)); - } + Assert.IsTrue(output.Contains(json)); + } - [Test] - public void MemoryTraceWriterDeserializeTest() - { - string json = @"{ + [Test] + public void MemoryTraceWriterDeserializeTest() + { + string json = @"{ ""Name"": ""Arnie Admin"", ""StartDate"": new Date( 976623132000 @@ -125,115 +126,115 @@ Newtonsoft.Json Error: 0 : Error! ] }"; - 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); + 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(); + ITraceWriter traceWriter = new MemoryTraceWriter(); - JsonConvert.DeserializeObject( - json, - new JsonSerializerSettings { TraceWriter = traceWriter, Converters = { new JavaScriptDateTimeConverter() } }); + 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" - // ] - // } + 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(); + MemoryTraceWriter memoryTraceWriter = (MemoryTraceWriter)traceWriter; + string output = memoryTraceWriter.ToString(); - Assert.AreEqual(1059, output.Length); - Assert.AreEqual(7, memoryTraceWriter.GetTraceMessages().Count()); + Assert.AreEqual(1059, output.Length); + Assert.AreEqual(7, memoryTraceWriter.GetTraceMessages().Count()); - Assert.IsTrue(output.Contains(json)); - } + Assert.IsTrue(output.Contains(json)); + } - [Test] - public void MemoryTraceWriterLimitTest() - { - MemoryTraceWriter traceWriter = new MemoryTraceWriter(); + [Test] + public void MemoryTraceWriterLimitTest() + { + MemoryTraceWriter traceWriter = new MemoryTraceWriter(); - for (int i = 0; i < 1005; i++) - { - traceWriter.Trace(TraceLevel.Verbose, (i + 1).ToString(CultureInfo.InvariantCulture), null); - } - - IList traceMessages = traceWriter.GetTraceMessages().ToList(); - - Assert.AreEqual(1000, traceMessages.Count); - - Assert.IsTrue(traceMessages.First().EndsWith(" 6")); - Assert.IsTrue(traceMessages.Last().EndsWith(" 1005")); - } - - [Test] - public void Serialize() - { - var traceWriter = new InMemoryTraceWriter - { - LevelFilter = TraceLevel.Info - }; - - string json = - JsonConvert.SerializeObject( - new TraceTestObject + for (int i = 0; i < 1005; i++) { - StringArray = new[] {"1", "2"}, - IntList = new List {1, 2}, - Version = new Version(1, 2, 3, 4), - StringDictionary = - new Dictionary - { - {"1", "!"}, - {"Two", "!!"}, - {"III", "!!!"} - } - }, - new JsonSerializerSettings + traceWriter.Trace(TraceLevel.Verbose, (i + 1).ToString(CultureInfo.InvariantCulture), null); + } + + IList traceMessages = traceWriter.GetTraceMessages().ToList(); + + Assert.AreEqual(1000, traceMessages.Count); + + Assert.IsTrue(traceMessages.First().EndsWith(" 6")); + Assert.IsTrue(traceMessages.Last().EndsWith(" 1005")); + } + + [Test] + public void Serialize() + { + var traceWriter = new InMemoryTraceWriter { - TraceWriter = traceWriter, - Formatting = Formatting.Indented - }); + LevelFilter = TraceLevel.Info + }; - Assert.AreEqual("Started serializing Newtonsoft.Json.Tests.Serialization.TraceTestObject. Path ''.", traceWriter.TraceRecords[0].Message); - Assert.AreEqual("Started serializing System.Collections.Generic.List`1[System.Int32]. Path 'IntList'.", traceWriter.TraceRecords[1].Message); - Assert.AreEqual("Finished serializing System.Collections.Generic.List`1[System.Int32]. Path 'IntList'.", traceWriter.TraceRecords[2].Message); - Assert.AreEqual("Started serializing System.String[]. Path 'StringArray'.", traceWriter.TraceRecords[3].Message); - Assert.AreEqual("Finished serializing System.String[]. Path 'StringArray'.", traceWriter.TraceRecords[4].Message); - Assert.AreEqual("Started serializing System.Version. Path 'Version'.", traceWriter.TraceRecords[5].Message); - Assert.AreEqual("Finished serializing System.Version. Path 'Version'.", traceWriter.TraceRecords[6].Message); - 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); + string json = + JsonConvert.SerializeObject( + new TraceTestObject + { + StringArray = new[] { "1", "2" }, + IntList = new List { 1, 2 }, + Version = new Version(1, 2, 3, 4), + StringDictionary = + new Dictionary + { + { "1", "!" }, + { "Two", "!!" }, + { "III", "!!!" } + } + }, + new JsonSerializerSettings + { + TraceWriter = traceWriter, + Formatting = Formatting.Indented + }); - Assert.IsFalse(traceWriter.TraceRecords.Any(r => r.Level == TraceLevel.Verbose)); - } + Assert.AreEqual("Started serializing Newtonsoft.Json.Tests.Serialization.TraceTestObject. Path ''.", traceWriter.TraceRecords[0].Message); + Assert.AreEqual("Started serializing System.Collections.Generic.List`1[System.Int32]. Path 'IntList'.", traceWriter.TraceRecords[1].Message); + Assert.AreEqual("Finished serializing System.Collections.Generic.List`1[System.Int32]. Path 'IntList'.", traceWriter.TraceRecords[2].Message); + Assert.AreEqual("Started serializing System.String[]. Path 'StringArray'.", traceWriter.TraceRecords[3].Message); + Assert.AreEqual("Finished serializing System.String[]. Path 'StringArray'.", traceWriter.TraceRecords[4].Message); + Assert.AreEqual("Started serializing System.Version. Path 'Version'.", traceWriter.TraceRecords[5].Message); + Assert.AreEqual("Finished serializing System.Version. Path 'Version'.", traceWriter.TraceRecords[6].Message); + 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); - [Test] - public void Deserialize() - { - InMemoryTraceWriter traceWriter = new InMemoryTraceWriter - { - LevelFilter = TraceLevel.Info - }; + Assert.IsFalse(traceWriter.TraceRecords.Any(r => r.Level == TraceLevel.Verbose)); + } - TraceTestObject o2 = JsonConvert.DeserializeObject( - @"{ + [Test] + public void Deserialize() + { + InMemoryTraceWriter traceWriter = new InMemoryTraceWriter + { + LevelFilter = TraceLevel.Info + }; + + TraceTestObject o2 = JsonConvert.DeserializeObject( + @"{ ""IntList"": [ 1, 2 @@ -256,127 +257,127 @@ Newtonsoft.Json Error: 0 : Error! ""III"": ""!!!"" } }", - new JsonSerializerSettings - { - TraceWriter = traceWriter - }); - - Assert.AreEqual(2, o2.IntList.Count); - Assert.AreEqual(2, o2.StringArray.Length); - Assert.AreEqual(1, o2.Version.Major); - Assert.AreEqual(2, o2.Version.Minor); - Assert.AreEqual(3, o2.StringDictionary.Count); - - Assert.AreEqual("Started deserializing Newtonsoft.Json.Tests.Serialization.TraceTestObject. Path 'IntList', line 2, position 13.", traceWriter.TraceRecords[0].Message); - Assert.AreEqual("Started deserializing System.Collections.Generic.IList`1[System.Int32]. Path 'IntList', line 2, position 15.", traceWriter.TraceRecords[1].Message); - Assert.AreEqual("Finished deserializing System.Collections.Generic.IList`1[System.Int32]. Path 'IntList', line 5, position 4.", traceWriter.TraceRecords[2].Message); - Assert.AreEqual("Started deserializing System.String[]. Path 'StringArray', line 6, position 19.", traceWriter.TraceRecords[3].Message); - Assert.AreEqual("Finished deserializing System.String[]. Path 'StringArray', line 9, position 4.", traceWriter.TraceRecords[4].Message); - Assert.AreEqual("Deserializing System.Version using a non-default constructor 'Void .ctor(Int32, Int32, Int32, Int32)'. Path 'Version.Major', line 11, position 13.", traceWriter.TraceRecords[5].Message); - Assert.AreEqual("Started deserializing System.Version. Path 'Version', line 17, position 4.", traceWriter.TraceRecords[6].Message); - Assert.AreEqual("Finished deserializing System.Version. Path 'Version', line 17, position 4.", traceWriter.TraceRecords[7].Message); - 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] - public void ErrorDeserializing() - { - string json = @"{""Integer"":""hi""}"; - - var traceWriter = new InMemoryTraceWriter - { - LevelFilter = TraceLevel.Info - }; - - ExceptionAssert.Throws( - "Could not convert string to integer: hi. Path 'Integer', line 1, position 15.", - () => - { - JsonConvert.DeserializeObject( - json, - new JsonSerializerSettings + new JsonSerializerSettings { - TraceWriter = traceWriter + TraceWriter = traceWriter }); - }); - Assert.AreEqual(2, traceWriter.TraceRecords.Count); + Assert.AreEqual(2, o2.IntList.Count); + Assert.AreEqual(2, o2.StringArray.Length); + Assert.AreEqual(1, o2.Version.Major); + Assert.AreEqual(2, o2.Version.Minor); + Assert.AreEqual(3, o2.StringDictionary.Count); - Assert.AreEqual(TraceLevel.Info, traceWriter.TraceRecords[0].Level); - Assert.AreEqual("Started deserializing Newtonsoft.Json.Tests.Serialization.IntegerTestClass. Path 'Integer', line 1, position 11.", traceWriter.TraceRecords[0].Message); - - Assert.AreEqual(TraceLevel.Error, traceWriter.TraceRecords[1].Level); - Assert.AreEqual("Error deserializing Newtonsoft.Json.Tests.Serialization.IntegerTestClass. Could not convert string to integer: hi. Path 'Integer', line 1, position 15.", traceWriter.TraceRecords[1].Message); - } + Assert.AreEqual("Started deserializing Newtonsoft.Json.Tests.Serialization.TraceTestObject. Path 'IntList', line 2, position 13.", traceWriter.TraceRecords[0].Message); + Assert.AreEqual("Started deserializing System.Collections.Generic.IList`1[System.Int32]. Path 'IntList', line 2, position 15.", traceWriter.TraceRecords[1].Message); + Assert.AreEqual("Finished deserializing System.Collections.Generic.IList`1[System.Int32]. Path 'IntList', line 5, position 4.", traceWriter.TraceRecords[2].Message); + Assert.AreEqual("Started deserializing System.String[]. Path 'StringArray', line 6, position 19.", traceWriter.TraceRecords[3].Message); + Assert.AreEqual("Finished deserializing System.String[]. Path 'StringArray', line 9, position 4.", traceWriter.TraceRecords[4].Message); + Assert.AreEqual("Deserializing System.Version using a non-default constructor 'Void .ctor(Int32, Int32, Int32, Int32)'. Path 'Version.Major', line 11, position 13.", traceWriter.TraceRecords[5].Message); + Assert.AreEqual("Started deserializing System.Version. Path 'Version', line 17, position 4.", traceWriter.TraceRecords[6].Message); + Assert.AreEqual("Finished deserializing System.Version. Path 'Version', line 17, position 4.", traceWriter.TraceRecords[7].Message); + 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); - [Test] - public void ErrorDeserializingNested() - { - string json = @"{""IntList"":[1, ""two""]}"; + Assert.IsFalse(traceWriter.TraceRecords.Any(r => r.Level == TraceLevel.Verbose)); + } - var traceWriter = new InMemoryTraceWriter - { - LevelFilter = TraceLevel.Info - }; - - ExceptionAssert.Throws( - "Could not convert string to integer: two. Path 'IntList[1]', line 1, position 20.", - () => + [Test] + public void ErrorDeserializing() { - JsonConvert.DeserializeObject( - json, - new JsonSerializerSettings + string json = @"{""Integer"":""hi""}"; + + var traceWriter = new InMemoryTraceWriter { - TraceWriter = traceWriter - }); - }); + LevelFilter = TraceLevel.Info + }; - Assert.AreEqual(3, traceWriter.TraceRecords.Count); + ExceptionAssert.Throws( + "Could not convert string to integer: hi. Path 'Integer', line 1, position 15.", + () => + { + JsonConvert.DeserializeObject( + json, + new JsonSerializerSettings + { + TraceWriter = traceWriter + }); + }); - Assert.AreEqual(TraceLevel.Info, traceWriter.TraceRecords[0].Level); - Assert.AreEqual("Started deserializing Newtonsoft.Json.Tests.Serialization.TraceTestObject. Path 'IntList', line 1, position 11.", traceWriter.TraceRecords[0].Message); + Assert.AreEqual(2, traceWriter.TraceRecords.Count); - Assert.AreEqual(TraceLevel.Info, traceWriter.TraceRecords[1].Level); - Assert.AreEqual("Started deserializing System.Collections.Generic.IList`1[System.Int32]. Path 'IntList', line 1, position 12.", traceWriter.TraceRecords[1].Message); + Assert.AreEqual(TraceLevel.Info, traceWriter.TraceRecords[0].Level); + Assert.AreEqual("Started deserializing Newtonsoft.Json.Tests.Serialization.IntegerTestClass. Path 'Integer', line 1, position 11.", traceWriter.TraceRecords[0].Message); - Assert.AreEqual(TraceLevel.Error, traceWriter.TraceRecords[2].Level); - Assert.AreEqual("Error deserializing System.Collections.Generic.IList`1[System.Int32]. Could not convert string to integer: two. Path 'IntList[1]', line 1, position 20.", traceWriter.TraceRecords[2].Message); - } + Assert.AreEqual(TraceLevel.Error, traceWriter.TraceRecords[1].Level); + Assert.AreEqual("Error deserializing Newtonsoft.Json.Tests.Serialization.IntegerTestClass. Could not convert string to integer: hi. Path 'Integer', line 1, position 15.", traceWriter.TraceRecords[1].Message); + } - [Test] - public void SerializeDictionarysWithPreserveObjectReferences() - { - PreserveReferencesHandlingTests.CircularDictionary circularDictionary = new PreserveReferencesHandlingTests.CircularDictionary(); - circularDictionary.Add("other", new PreserveReferencesHandlingTests.CircularDictionary { { "blah", null } }); - circularDictionary.Add("self", circularDictionary); + [Test] + public void ErrorDeserializingNested() + { + string json = @"{""IntList"":[1, ""two""]}"; - InMemoryTraceWriter traceWriter = new InMemoryTraceWriter - { - LevelFilter = TraceLevel.Verbose - }; + var traceWriter = new InMemoryTraceWriter + { + LevelFilter = TraceLevel.Info + }; - JsonConvert.SerializeObject( - circularDictionary, - Formatting.Indented, - new JsonSerializerSettings - { - PreserveReferencesHandling = PreserveReferencesHandling.All, - TraceWriter = traceWriter - }); + ExceptionAssert.Throws( + "Could not convert string to integer: two. Path 'IntList[1]', line 1, position 20.", + () => + { + JsonConvert.DeserializeObject( + json, + new JsonSerializerSettings + { + TraceWriter = traceWriter + }); + }); - Assert.IsTrue(traceWriter.TraceRecords.Any(r => r.Message == "Writing object reference Id '1' for Newtonsoft.Json.Tests.Serialization.PreserveReferencesHandlingTests+CircularDictionary. Path ''.")); - Assert.IsTrue(traceWriter.TraceRecords.Any(r => r.Message == "Writing object reference Id '2' for Newtonsoft.Json.Tests.Serialization.PreserveReferencesHandlingTests+CircularDictionary. Path 'other'.")); - Assert.IsTrue(traceWriter.TraceRecords.Any(r => r.Message == "Writing object reference to Id '1' for Newtonsoft.Json.Tests.Serialization.PreserveReferencesHandlingTests+CircularDictionary. Path 'self'.")); - } + Assert.AreEqual(3, traceWriter.TraceRecords.Count); - [Test] - public void DeserializeDictionarysWithPreserveObjectReferences() - { - string json = @"{ + Assert.AreEqual(TraceLevel.Info, traceWriter.TraceRecords[0].Level); + Assert.AreEqual("Started deserializing Newtonsoft.Json.Tests.Serialization.TraceTestObject. Path 'IntList', line 1, position 11.", traceWriter.TraceRecords[0].Message); + + Assert.AreEqual(TraceLevel.Info, traceWriter.TraceRecords[1].Level); + Assert.AreEqual("Started deserializing System.Collections.Generic.IList`1[System.Int32]. Path 'IntList', line 1, position 12.", traceWriter.TraceRecords[1].Message); + + Assert.AreEqual(TraceLevel.Error, traceWriter.TraceRecords[2].Level); + Assert.AreEqual("Error deserializing System.Collections.Generic.IList`1[System.Int32]. Could not convert string to integer: two. Path 'IntList[1]', line 1, position 20.", traceWriter.TraceRecords[2].Message); + } + + [Test] + public void SerializeDictionarysWithPreserveObjectReferences() + { + PreserveReferencesHandlingTests.CircularDictionary circularDictionary = new PreserveReferencesHandlingTests.CircularDictionary(); + circularDictionary.Add("other", new PreserveReferencesHandlingTests.CircularDictionary { { "blah", null } }); + circularDictionary.Add("self", circularDictionary); + + InMemoryTraceWriter traceWriter = new InMemoryTraceWriter + { + LevelFilter = TraceLevel.Verbose + }; + + JsonConvert.SerializeObject( + circularDictionary, + Formatting.Indented, + new JsonSerializerSettings + { + PreserveReferencesHandling = PreserveReferencesHandling.All, + TraceWriter = traceWriter + }); + + Assert.IsTrue(traceWriter.TraceRecords.Any(r => r.Message == "Writing object reference Id '1' for Newtonsoft.Json.Tests.Serialization.PreserveReferencesHandlingTests+CircularDictionary. Path ''.")); + Assert.IsTrue(traceWriter.TraceRecords.Any(r => r.Message == "Writing object reference Id '2' for Newtonsoft.Json.Tests.Serialization.PreserveReferencesHandlingTests+CircularDictionary. Path 'other'.")); + Assert.IsTrue(traceWriter.TraceRecords.Any(r => r.Message == "Writing object reference to Id '1' for Newtonsoft.Json.Tests.Serialization.PreserveReferencesHandlingTests+CircularDictionary. Path 'self'.")); + } + + [Test] + public void DeserializeDictionarysWithPreserveObjectReferences() + { + string json = @"{ ""$id"": ""1"", ""other"": { ""$id"": ""2"", @@ -387,113 +388,113 @@ Newtonsoft.Json Error: 0 : Error! } }"; - InMemoryTraceWriter traceWriter = new InMemoryTraceWriter - { - LevelFilter = TraceLevel.Verbose - }; + InMemoryTraceWriter traceWriter = new InMemoryTraceWriter + { + LevelFilter = TraceLevel.Verbose + }; - JsonConvert.DeserializeObject(json, - new JsonSerializerSettings + JsonConvert.DeserializeObject(json, + new JsonSerializerSettings + { + PreserveReferencesHandling = PreserveReferencesHandling.All, + TraceWriter = traceWriter + }); + + Assert.IsTrue(traceWriter.TraceRecords.Any(r => r.Message == "Read object reference Id '1' for Newtonsoft.Json.Tests.Serialization.PreserveReferencesHandlingTests+CircularDictionary. Path 'other', line 3, position 11.")); + Assert.IsTrue(traceWriter.TraceRecords.Any(r => r.Message == "Read object reference Id '2' for Newtonsoft.Json.Tests.Serialization.PreserveReferencesHandlingTests+CircularDictionary. Path 'other.blah', line 5, position 12.")); + Assert.IsTrue(traceWriter.TraceRecords.Any(r => r.Message == "Resolved object reference '1' to Newtonsoft.Json.Tests.Serialization.PreserveReferencesHandlingTests+CircularDictionary. Path 'self', line 9, position 4.")); + } + + [Test] + public void WriteTypeNameForObjects() { - PreserveReferencesHandling = PreserveReferencesHandling.All, - TraceWriter = traceWriter - }); + InMemoryTraceWriter traceWriter = new InMemoryTraceWriter + { + LevelFilter = TraceLevel.Verbose + }; - Assert.IsTrue(traceWriter.TraceRecords.Any(r => r.Message == "Read object reference Id '1' for Newtonsoft.Json.Tests.Serialization.PreserveReferencesHandlingTests+CircularDictionary. Path 'other', line 3, position 11.")); - Assert.IsTrue(traceWriter.TraceRecords.Any(r => r.Message == "Read object reference Id '2' for Newtonsoft.Json.Tests.Serialization.PreserveReferencesHandlingTests+CircularDictionary. Path 'other.blah', line 5, position 12.")); - Assert.IsTrue(traceWriter.TraceRecords.Any(r => r.Message == "Resolved object reference '1' to Newtonsoft.Json.Tests.Serialization.PreserveReferencesHandlingTests+CircularDictionary. Path 'self', line 9, position 4.")); - } + IList l = new List + { + new Dictionary { { "key!", "value!" } }, + new Version(1, 2, 3, 4) + }; - [Test] - public void WriteTypeNameForObjects() - { - InMemoryTraceWriter traceWriter = new InMemoryTraceWriter - { - LevelFilter = TraceLevel.Verbose - }; + JsonConvert.SerializeObject(l, Formatting.Indented, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.All, + TraceWriter = traceWriter + }); - IList l = new List - { - new Dictionary { {"key!", "value!"}}, - new Version(1, 2, 3, 4) - }; + Assert.AreEqual("Started serializing System.Collections.Generic.List`1[System.Object]. Path ''.", traceWriter.TraceRecords[0].Message); + Assert.AreEqual("Writing type name 'System.Collections.Generic.List`1[[System.Object, mscorlib]], mscorlib' for System.Collections.Generic.List`1[System.Object]. Path ''.", traceWriter.TraceRecords[1].Message); + Assert.AreEqual("Started serializing System.Collections.Generic.Dictionary`2[System.String,System.String]. Path '$values'.", traceWriter.TraceRecords[2].Message); + Assert.AreEqual("Writing type name 'System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.String, mscorlib]], mscorlib' for System.Collections.Generic.Dictionary`2[System.String,System.String]. Path '$values[0]'.", traceWriter.TraceRecords[3].Message); + Assert.AreEqual("Finished serializing System.Collections.Generic.Dictionary`2[System.String,System.String]. Path '$values[0]'.", traceWriter.TraceRecords[4].Message); + Assert.AreEqual("Started serializing System.Version. Path '$values[0]'.", traceWriter.TraceRecords[5].Message); + Assert.AreEqual("Writing type name 'System.Version, mscorlib' for System.Version. Path '$values[1]'.", traceWriter.TraceRecords[6].Message); + Assert.AreEqual("Finished serializing System.Version. Path '$values[1]'.", traceWriter.TraceRecords[7].Message); + Assert.AreEqual("Finished serializing System.Collections.Generic.List`1[System.Object]. Path ''.", traceWriter.TraceRecords[8].Message); + } - JsonConvert.SerializeObject(l, Formatting.Indented, new JsonSerializerSettings - { - TypeNameHandling = TypeNameHandling.All, - TraceWriter = traceWriter - }); + [Test] + public void SerializeConverter() + { + InMemoryTraceWriter traceWriter = new InMemoryTraceWriter + { + LevelFilter = TraceLevel.Verbose + }; - Assert.AreEqual("Started serializing System.Collections.Generic.List`1[System.Object]. Path ''.", traceWriter.TraceRecords[0].Message); - Assert.AreEqual("Writing type name 'System.Collections.Generic.List`1[[System.Object, mscorlib]], mscorlib' for System.Collections.Generic.List`1[System.Object]. Path ''.", traceWriter.TraceRecords[1].Message); - Assert.AreEqual("Started serializing System.Collections.Generic.Dictionary`2[System.String,System.String]. Path '$values'.", traceWriter.TraceRecords[2].Message); - Assert.AreEqual("Writing type name 'System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.String, mscorlib]], mscorlib' for System.Collections.Generic.Dictionary`2[System.String,System.String]. Path '$values[0]'.", traceWriter.TraceRecords[3].Message); - Assert.AreEqual("Finished serializing System.Collections.Generic.Dictionary`2[System.String,System.String]. Path '$values[0]'.", traceWriter.TraceRecords[4].Message); - Assert.AreEqual("Started serializing System.Version. Path '$values[0]'.", traceWriter.TraceRecords[5].Message); - Assert.AreEqual("Writing type name 'System.Version, mscorlib' for System.Version. Path '$values[1]'.", traceWriter.TraceRecords[6].Message); - Assert.AreEqual("Finished serializing System.Version. Path '$values[1]'.", traceWriter.TraceRecords[7].Message); - Assert.AreEqual("Finished serializing System.Collections.Generic.List`1[System.Object]. Path ''.", traceWriter.TraceRecords[8].Message); - } + IList d = new List + { + new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc) + }; - [Test] - public void SerializeConverter() - { - InMemoryTraceWriter traceWriter = new InMemoryTraceWriter - { - LevelFilter = TraceLevel.Verbose - }; + string json = JsonConvert.SerializeObject(d, Formatting.Indented, new JsonSerializerSettings + { + Converters = { new JavaScriptDateTimeConverter() }, + TraceWriter = traceWriter + }); - IList d = new List - { - new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc) - }; + Assert.AreEqual("Started serializing System.Collections.Generic.List`1[System.DateTime]. Path ''.", traceWriter.TraceRecords[0].Message); + Assert.AreEqual("Started serializing System.DateTime with converter Newtonsoft.Json.Converters.JavaScriptDateTimeConverter. Path ''.", traceWriter.TraceRecords[1].Message); + Assert.AreEqual("Finished serializing System.DateTime with converter Newtonsoft.Json.Converters.JavaScriptDateTimeConverter. Path '[0]'.", traceWriter.TraceRecords[2].Message); + Assert.AreEqual("Finished serializing System.Collections.Generic.List`1[System.DateTime]. Path ''.", traceWriter.TraceRecords[3].Message); + } - string json = JsonConvert.SerializeObject(d, Formatting.Indented, new JsonSerializerSettings - { - Converters = { new JavaScriptDateTimeConverter() }, - TraceWriter = traceWriter - }); + [Test] + public void DeserializeConverter() + { + string json = @"[new Date(976623132000)]"; - Assert.AreEqual("Started serializing System.Collections.Generic.List`1[System.DateTime]. Path ''.", traceWriter.TraceRecords[0].Message); - Assert.AreEqual("Started serializing System.DateTime with converter Newtonsoft.Json.Converters.JavaScriptDateTimeConverter. Path ''.", traceWriter.TraceRecords[1].Message); - Assert.AreEqual("Finished serializing System.DateTime with converter Newtonsoft.Json.Converters.JavaScriptDateTimeConverter. Path '[0]'.", traceWriter.TraceRecords[2].Message); - Assert.AreEqual("Finished serializing System.Collections.Generic.List`1[System.DateTime]. Path ''.", traceWriter.TraceRecords[3].Message); - } + InMemoryTraceWriter traceWriter = + new InMemoryTraceWriter + { + LevelFilter = TraceLevel.Verbose + }; - [Test] - public void DeserializeConverter() - { - string json = @"[new Date(976623132000)]"; + JsonConvert.DeserializeObject>( + json, + new JsonSerializerSettings + { + Converters = { new JavaScriptDateTimeConverter() }, + TraceWriter = traceWriter + }); - InMemoryTraceWriter traceWriter = - new InMemoryTraceWriter - { - LevelFilter = TraceLevel.Verbose - }; + Assert.AreEqual("Started deserializing System.Collections.Generic.List`1[System.DateTime]. Path '', line 1, position 1.", traceWriter.TraceRecords[0].Message); + Assert.AreEqual("Started deserializing System.DateTime with converter Newtonsoft.Json.Converters.JavaScriptDateTimeConverter. Path '[0]', line 1, position 10.", traceWriter.TraceRecords[1].Message); + Assert.AreEqual("Finished deserializing System.DateTime with converter Newtonsoft.Json.Converters.JavaScriptDateTimeConverter. Path '[0]', line 1, position 23.", traceWriter.TraceRecords[2].Message); + Assert.AreEqual("Finished deserializing System.Collections.Generic.List`1[System.DateTime]. Path '', line 1, position 24.", traceWriter.TraceRecords[3].Message); + } - JsonConvert.DeserializeObject>( - json, - new JsonSerializerSettings - { - Converters = {new JavaScriptDateTimeConverter()}, - TraceWriter = traceWriter - }); + [Test] + public void DeserializeTypeName() + { + InMemoryTraceWriter traceWriter = new InMemoryTraceWriter + { + LevelFilter = TraceLevel.Verbose + }; - Assert.AreEqual("Started deserializing System.Collections.Generic.List`1[System.DateTime]. Path '', line 1, position 1.", traceWriter.TraceRecords[0].Message); - Assert.AreEqual("Started deserializing System.DateTime with converter Newtonsoft.Json.Converters.JavaScriptDateTimeConverter. Path '[0]', line 1, position 10.", traceWriter.TraceRecords[1].Message); - Assert.AreEqual("Finished deserializing System.DateTime with converter Newtonsoft.Json.Converters.JavaScriptDateTimeConverter. Path '[0]', line 1, position 23.", traceWriter.TraceRecords[2].Message); - Assert.AreEqual("Finished deserializing System.Collections.Generic.List`1[System.DateTime]. Path '', line 1, position 24.", traceWriter.TraceRecords[3].Message); - } - - [Test] - public void DeserializeTypeName() - { - InMemoryTraceWriter traceWriter = new InMemoryTraceWriter - { - LevelFilter = TraceLevel.Verbose - }; - - string json = @"{ + string json = @"{ ""$type"": ""System.Collections.Generic.List`1[[System.Object, mscorlib]], mscorlib"", ""$values"": [ { @@ -512,81 +513,81 @@ Newtonsoft.Json Error: 0 : Error! ] }"; - JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings - { - TypeNameHandling = TypeNameHandling.All, - TraceWriter = traceWriter - }); + JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.All, + TraceWriter = traceWriter + }); - Assert.AreEqual("Resolved type 'System.Collections.Generic.List`1[[System.Object, mscorlib]], mscorlib' to System.Collections.Generic.List`1[System.Object]. Path '$type', line 2, position 84.", traceWriter.TraceRecords[0].Message); - Assert.AreEqual("Started deserializing System.Collections.Generic.List`1[System.Object]. Path '$values', line 3, position 15.", traceWriter.TraceRecords[1].Message); - Assert.AreEqual("Resolved type 'System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.String, mscorlib]], mscorlib' to System.Collections.Generic.Dictionary`2[System.String,System.String]. Path '$values[0].$type', line 5, position 120.", traceWriter.TraceRecords[2].Message); - Assert.AreEqual("Started deserializing System.Collections.Generic.Dictionary`2[System.String,System.String]. Path '$values[0].key!', line 6, position 14.", traceWriter.TraceRecords[3].Message); - Assert.AreEqual("Finished deserializing System.Collections.Generic.Dictionary`2[System.String,System.String]. Path '$values[0]', line 7, position 6.", traceWriter.TraceRecords[4].Message); - Assert.AreEqual("Resolved type 'System.Version, mscorlib' to System.Version. Path '$values[1].$type', line 9, position 42.", traceWriter.TraceRecords[5].Message); - Assert.AreEqual("Deserializing System.Version using a non-default constructor 'Void .ctor(Int32, Int32, Int32, Int32)'. Path '$values[1].Major', line 10, position 15.", traceWriter.TraceRecords[6].Message); - Assert.AreEqual("Started deserializing System.Version. Path '$values[1]', line 16, position 6.", traceWriter.TraceRecords[7].Message); - Assert.AreEqual("Finished deserializing System.Version. Path '$values[1]', line 16, position 6.", traceWriter.TraceRecords[8].Message); - Assert.AreEqual("Finished deserializing System.Collections.Generic.List`1[System.Object]. Path '$values', line 17, position 4.", traceWriter.TraceRecords[9].Message); - } + Assert.AreEqual("Resolved type 'System.Collections.Generic.List`1[[System.Object, mscorlib]], mscorlib' to System.Collections.Generic.List`1[System.Object]. Path '$type', line 2, position 84.", traceWriter.TraceRecords[0].Message); + Assert.AreEqual("Started deserializing System.Collections.Generic.List`1[System.Object]. Path '$values', line 3, position 15.", traceWriter.TraceRecords[1].Message); + Assert.AreEqual("Resolved type 'System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.String, mscorlib]], mscorlib' to System.Collections.Generic.Dictionary`2[System.String,System.String]. Path '$values[0].$type', line 5, position 120.", traceWriter.TraceRecords[2].Message); + Assert.AreEqual("Started deserializing System.Collections.Generic.Dictionary`2[System.String,System.String]. Path '$values[0].key!', line 6, position 14.", traceWriter.TraceRecords[3].Message); + Assert.AreEqual("Finished deserializing System.Collections.Generic.Dictionary`2[System.String,System.String]. Path '$values[0]', line 7, position 6.", traceWriter.TraceRecords[4].Message); + Assert.AreEqual("Resolved type 'System.Version, mscorlib' to System.Version. Path '$values[1].$type', line 9, position 42.", traceWriter.TraceRecords[5].Message); + Assert.AreEqual("Deserializing System.Version using a non-default constructor 'Void .ctor(Int32, Int32, Int32, Int32)'. Path '$values[1].Major', line 10, position 15.", traceWriter.TraceRecords[6].Message); + Assert.AreEqual("Started deserializing System.Version. Path '$values[1]', line 16, position 6.", traceWriter.TraceRecords[7].Message); + Assert.AreEqual("Finished deserializing System.Version. Path '$values[1]', line 16, position 6.", traceWriter.TraceRecords[8].Message); + Assert.AreEqual("Finished deserializing System.Collections.Generic.List`1[System.Object]. Path '$values', line 17, position 4.", traceWriter.TraceRecords[9].Message); + } #if !(NETFX_CORE || PORTABLE || SILVERLIGHT || PORTABLE40) - [Test] - public void DeserializeISerializable() - { - InMemoryTraceWriter traceWriter = new InMemoryTraceWriter - { - LevelFilter = TraceLevel.Verbose - }; + [Test] + public void DeserializeISerializable() + { + InMemoryTraceWriter traceWriter = new InMemoryTraceWriter + { + LevelFilter = TraceLevel.Verbose + }; - ExceptionAssert.Throws( - "Member 'ClassName' was not found.", - () => - { - JsonConvert.DeserializeObject( - "{}", - new JsonSerializerSettings + ExceptionAssert.Throws( + "Member 'ClassName' was not found.", + () => { - TraceWriter = traceWriter + JsonConvert.DeserializeObject( + "{}", + new JsonSerializerSettings + { + TraceWriter = traceWriter + }); }); - }); - Assert.AreEqual("Deserializing System.Exception using ISerializable constructor. Path '', line 1, position 2.", traceWriter.TraceRecords[0].Message); - Assert.AreEqual(TraceLevel.Info, traceWriter.TraceRecords[0].Level); - Assert.AreEqual("Error deserializing System.Exception. Member 'ClassName' was not found. Path '', line 1, position 2.", traceWriter.TraceRecords[1].Message); - Assert.AreEqual(TraceLevel.Error, traceWriter.TraceRecords[1].Level); - } + Assert.AreEqual("Deserializing System.Exception using ISerializable constructor. Path '', line 1, position 2.", traceWriter.TraceRecords[0].Message); + Assert.AreEqual(TraceLevel.Info, traceWriter.TraceRecords[0].Level); + Assert.AreEqual("Error deserializing System.Exception. Member 'ClassName' was not found. Path '', line 1, position 2.", traceWriter.TraceRecords[1].Message); + Assert.AreEqual(TraceLevel.Error, traceWriter.TraceRecords[1].Level); + } #endif - [Test] - public void DeserializeMissingMember() - { - InMemoryTraceWriter traceWriter = new InMemoryTraceWriter - { - LevelFilter = TraceLevel.Verbose - }; + [Test] + public void DeserializeMissingMember() + { + InMemoryTraceWriter traceWriter = new InMemoryTraceWriter + { + LevelFilter = TraceLevel.Verbose + }; - JsonConvert.DeserializeObject( - "{'MissingMemberProperty':'!!'}", - new JsonSerializerSettings - { - TraceWriter = traceWriter - }); + JsonConvert.DeserializeObject( + "{'MissingMemberProperty':'!!'}", + new JsonSerializerSettings + { + TraceWriter = traceWriter + }); - Assert.AreEqual("Started deserializing Newtonsoft.Json.Tests.TestObjects.Person. Path 'MissingMemberProperty', line 1, position 25.", traceWriter.TraceRecords[0].Message); - Assert.AreEqual("Could not find member 'MissingMemberProperty' on Newtonsoft.Json.Tests.TestObjects.Person. Path 'MissingMemberProperty', line 1, position 25.", traceWriter.TraceRecords[1].Message); - Assert.AreEqual("Finished deserializing Newtonsoft.Json.Tests.TestObjects.Person. Path '', line 1, position 30.", traceWriter.TraceRecords[2].Message); - } + Assert.AreEqual("Started deserializing Newtonsoft.Json.Tests.TestObjects.Person. Path 'MissingMemberProperty', line 1, position 25.", traceWriter.TraceRecords[0].Message); + Assert.AreEqual("Could not find member 'MissingMemberProperty' on Newtonsoft.Json.Tests.TestObjects.Person. Path 'MissingMemberProperty', line 1, position 25.", traceWriter.TraceRecords[1].Message); + Assert.AreEqual("Finished deserializing Newtonsoft.Json.Tests.TestObjects.Person. Path '', line 1, position 30.", traceWriter.TraceRecords[2].Message); + } - [Test] - public void DeserializeMissingMemberConstructor() - { - InMemoryTraceWriter traceWriter = new InMemoryTraceWriter - { - LevelFilter = TraceLevel.Verbose - }; + [Test] + public void DeserializeMissingMemberConstructor() + { + InMemoryTraceWriter traceWriter = new InMemoryTraceWriter + { + LevelFilter = TraceLevel.Verbose + }; - string json = @"{ + string json = @"{ ""Major"": 1, ""Minor"": 2, ""Build"": 3, @@ -596,98 +597,98 @@ Newtonsoft.Json Error: 0 : Error! ""MissingMemberProperty"": null }"; - JsonConvert.DeserializeObject(json, new JsonSerializerSettings - { - TraceWriter = traceWriter - }); + JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + TraceWriter = traceWriter + }); - Assert.AreEqual("Deserializing System.Version using a non-default constructor 'Void .ctor(Int32, Int32, Int32, Int32)'. Path 'Major', line 2, position 11.", traceWriter.TraceRecords[0].Message); - Assert.AreEqual("Could not find member 'MissingMemberProperty' on System.Version. Path 'MissingMemberProperty', line 8, position 32.", traceWriter.TraceRecords[1].Message); - 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); - } + Assert.AreEqual("Deserializing System.Version using a non-default constructor 'Void .ctor(Int32, Int32, Int32, Int32)'. Path 'Major', line 2, position 11.", traceWriter.TraceRecords[0].Message); + Assert.AreEqual("Could not find member 'MissingMemberProperty' on System.Version. Path 'MissingMemberProperty', line 8, position 32.", traceWriter.TraceRecords[1].Message); + 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; + [Test] + public void ShouldSerializeTestClass() + { + ShouldSerializeTestClass c = new ShouldSerializeTestClass(); + c.Age = 29; + c.Name = "Jim"; + c._shouldSerializeName = true; - InMemoryTraceWriter traceWriter = new InMemoryTraceWriter - { - LevelFilter = TraceLevel.Verbose - }; + InMemoryTraceWriter traceWriter = new InMemoryTraceWriter + { + LevelFilter = TraceLevel.Verbose + }; - JsonConvert.SerializeObject(c, new JsonSerializerSettings {TraceWriter = traceWriter}); + 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); + 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 - }; + traceWriter = new InMemoryTraceWriter + { + LevelFilter = TraceLevel.Verbose + }; - c._shouldSerializeName = false; + c._shouldSerializeName = false; - JsonConvert.SerializeObject(c, new JsonSerializerSettings { TraceWriter = traceWriter }); + 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); - } + 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; + [Test] + public void SpecifiedTest() + { + SpecifiedTestClass c = new SpecifiedTestClass(); + c.Name = "James"; + c.Age = 27; + c.NameSpecified = false; - InMemoryTraceWriter traceWriter = new InMemoryTraceWriter - { - LevelFilter = TraceLevel.Verbose - }; + InMemoryTraceWriter traceWriter = new InMemoryTraceWriter + { + LevelFilter = TraceLevel.Verbose + }; - string json = JsonConvert.SerializeObject(c, Formatting.Indented, new JsonSerializerSettings { TraceWriter = traceWriter }); + 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("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(@"{ + Assert.AreEqual(@"{ ""Age"": 27 }", json); - traceWriter = new InMemoryTraceWriter - { - LevelFilter = TraceLevel.Verbose - }; + traceWriter = new InMemoryTraceWriter + { + LevelFilter = TraceLevel.Verbose + }; - SpecifiedTestClass deserialized = JsonConvert.DeserializeObject(json, new JsonSerializerSettings { TraceWriter = traceWriter }); + 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.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); + 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); + c.NameSpecified = true; + c.WeightSpecified = true; + c.HeightSpecified = true; + c.FavoriteNumber = 23; + json = JsonConvert.SerializeObject(c, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Name"": ""James"", ""Age"": 27, ""Weight"": 0, @@ -695,97 +696,97 @@ Newtonsoft.Json Error: 0 : Error! ""FavoriteNumber"": 23 }", json); - traceWriter = new InMemoryTraceWriter - { - LevelFilter = TraceLevel.Verbose - }; + traceWriter = new InMemoryTraceWriter + { + LevelFilter = TraceLevel.Verbose + }; - deserialized = JsonConvert.DeserializeObject(json, new JsonSerializerSettings { TraceWriter = traceWriter }); + 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("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); - } + 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); + } #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); + [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.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((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(); + 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()); + Console.WriteLine(traceWriter.GetJson()); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Array"": [ ""String!"", ""2000-12-12T12:12:12Z"", @@ -837,12 +838,12 @@ Newtonsoft.Json Error: 0 : Error! /*A comment*/ ] }", traceWriter.GetJson()); - } + } - [Test] - public void TraceJsonReaderTest() - { - string json = @"{ + [Test] + public void TraceJsonReaderTest() + { + string json = @"{ ""Array"": [ ""String!"", ""2000-12-12T12:12:12Z"", @@ -861,152 +862,152 @@ Newtonsoft.Json Error: 0 : Error! ] }"; - StringReader sw = new StringReader(json); - JsonTextReader w = new JsonTextReader(sw); - TraceJsonReader traceReader = new TraceJsonReader(w); + 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.StartObject, traceReader.TokenType); - traceReader.Read(); - Assert.AreEqual(JsonToken.PropertyName, traceReader.TokenType); - Assert.AreEqual("Array", traceReader.Value); + 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.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); + 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); + // 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.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.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.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); - CollectionAssert.AreEqual(Encoding.UTF8.GetBytes("String!"), (byte[])traceReader.Value); + traceReader.ReadAsBytes(); + Assert.AreEqual(JsonToken.Bytes, traceReader.TokenType); + CollectionAssert.AreEqual(Encoding.UTF8.GetBytes("String!"), (byte[])traceReader.Value); - traceReader.ReadAsInt32(); - Assert.AreEqual(JsonToken.Integer, traceReader.TokenType); - Assert.AreEqual(1, 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.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.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.Null, traceReader.TokenType); - traceReader.Read(); - Assert.AreEqual(JsonToken.Undefined, traceReader.TokenType); + traceReader.Read(); + Assert.AreEqual(JsonToken.Undefined, traceReader.TokenType); - traceReader.Read(); - Assert.AreEqual(JsonToken.StartConstructor, traceReader.TokenType); + traceReader.Read(); + Assert.AreEqual(JsonToken.StartConstructor, traceReader.TokenType); - traceReader.Read(); - Assert.AreEqual(JsonToken.Integer, traceReader.TokenType); - Assert.AreEqual(1L, traceReader.Value); + traceReader.Read(); + Assert.AreEqual(JsonToken.Integer, traceReader.TokenType); + Assert.AreEqual(1L, traceReader.Value); - traceReader.Read(); - Assert.AreEqual(JsonToken.EndConstructor, traceReader.TokenType); + 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.Comment, traceReader.TokenType); + Assert.AreEqual("A comment", traceReader.Value); - traceReader.Read(); - Assert.AreEqual(JsonToken.EndArray, traceReader.TokenType); + traceReader.Read(); + Assert.AreEqual(JsonToken.EndArray, traceReader.TokenType); - traceReader.Read(); - Assert.AreEqual(JsonToken.EndObject, traceReader.TokenType); + traceReader.Read(); + Assert.AreEqual(JsonToken.EndObject, traceReader.TokenType); - Assert.IsFalse(traceReader.Read()); + Assert.IsFalse(traceReader.Read()); - traceReader.Close(); + traceReader.Close(); - Console.WriteLine(traceReader.GetJson()); + Console.WriteLine(traceReader.GetJson()); - Assert.AreEqual(json, traceReader.GetJson()); - } + Assert.AreEqual(json, traceReader.GetJson()); + } #endif - } - - public class TraceRecord - { - public string Message { get; set; } - public TraceLevel Level { get; set; } - public Exception Exception { get; set; } - - public override string ToString() - { - return Level + " - " + Message; - } - } - - public class InMemoryTraceWriter : ITraceWriter - { - public TraceLevel LevelFilter { get; set; } - public IList TraceRecords { get; set; } - - public InMemoryTraceWriter() - { - LevelFilter = TraceLevel.Verbose; - TraceRecords = new List(); } - public void Trace(TraceLevel level, string message, Exception ex) + public class TraceRecord { - TraceRecords.Add( - new TraceRecord + public string Message { get; set; } + public TraceLevel Level { get; set; } + public Exception Exception { get; set; } + + public override string ToString() { - Level = level, - Message = message, - Exception = ex - }); + return Level + " - " + Message; + } } - public override string ToString() + public class InMemoryTraceWriter : ITraceWriter { - StringBuilder sb = new StringBuilder(); - foreach (var traceRecord in TraceRecords) - { - sb.AppendLine(traceRecord.Message); - } + public TraceLevel LevelFilter { get; set; } + public IList TraceRecords { get; set; } - return sb.ToString(); + public InMemoryTraceWriter() + { + LevelFilter = TraceLevel.Verbose; + TraceRecords = new List(); + } + + public void Trace(TraceLevel level, string message, Exception ex) + { + TraceRecords.Add( + new TraceRecord + { + Level = level, + Message = message, + Exception = ex + }); + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + foreach (var traceRecord in TraceRecords) + { + sb.AppendLine(traceRecord.Message); + } + + return sb.ToString(); + } } - } - public class TraceTestObject - { - public IList IntList { get; set; } - public string[] StringArray { get; set; } - public Version Version { get; set; } - public IDictionary StringDictionary { get; set; } - } + public class TraceTestObject + { + public IList IntList { get; set; } + public string[] StringArray { get; set; } + public Version Version { get; set; } + public IDictionary StringDictionary { get; set; } + } - public class IntegerTestClass - { - public int Integer { get; set; } - } + public class IntegerTestClass + { + public int Integer { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs index a129f595..34fcf81b 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs @@ -51,38 +51,38 @@ using global::System.IO; namespace Newtonsoft.Json.Tests.Serialization { - [TestFixture] - public class TypeNameHandlingTests : TestFixtureBase - { - [Test] - public void NestedValueObjects() + [TestFixture] + public class TypeNameHandlingTests : TestFixtureBase { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < 10000; i++) - { - sb.Append(@"{""$value"":"); - } - - ExceptionAssert.Throws("Unexpected token when deserializing primitive value: StartObject. Path '$value', line 1, position 11.", () => + [Test] + public void NestedValueObjects() { - var reader = new JsonTextReader(new StringReader(sb.ToString())); - var ser = new JsonSerializer(); - ser.Deserialize(reader); - }); - } + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < 10000; i++) + { + sb.Append(@"{""$value"":"); + } - [Test] - public void SerializeRootTypeNameIfDerivedWithAuto() - { - var serializer = new JsonSerializer() + ExceptionAssert.Throws("Unexpected token when deserializing primitive value: StartObject. Path '$value', line 1, position 11.", () => + { + var reader = new JsonTextReader(new StringReader(sb.ToString())); + var ser = new JsonSerializer(); + ser.Deserialize(reader); + }); + } + + [Test] + public void SerializeRootTypeNameIfDerivedWithAuto() { - TypeNameHandling = TypeNameHandling.Auto - }; - var sw = new StringWriter(); - serializer.Serialize(new JsonTextWriter(sw) { Formatting = Formatting.Indented }, new WagePerson(), typeof(Person)); - var result = sw.ToString(); - - Assert.AreEqual(@"{ + var serializer = new JsonSerializer() + { + TypeNameHandling = TypeNameHandling.Auto + }; + var sw = new StringWriter(); + serializer.Serialize(new JsonTextWriter(sw) { Formatting = Formatting.Indented }, new WagePerson(), typeof(Person)); + var result = sw.ToString(); + + Assert.AreEqual(@"{ ""$type"": ""Newtonsoft.Json.Tests.TestObjects.WagePerson, Newtonsoft.Json.Tests"", ""HourlyWage"": 0.0, ""Name"": null, @@ -90,57 +90,57 @@ namespace Newtonsoft.Json.Tests.Serialization ""LastModified"": ""0001-01-01T00:00:00"" }", result); - Assert.IsTrue(result.Contains("WagePerson")); - using (var rd = new JsonTextReader(new StringReader(result))) - { - var person = serializer.Deserialize(rd); + Assert.IsTrue(result.Contains("WagePerson")); + using (var rd = new JsonTextReader(new StringReader(result))) + { + var person = serializer.Deserialize(rd); - CustomAssert.IsInstanceOfType(typeof(WagePerson), person); - } - } + CustomAssert.IsInstanceOfType(typeof(WagePerson), person); + } + } - [Test] - public void SerializeRootTypeNameAutoWithJsonConvert() - { - string json = JsonConvert.SerializeObject(new WagePerson(), typeof(object), Formatting.Indented, new JsonSerializerSettings + [Test] + public void SerializeRootTypeNameAutoWithJsonConvert() { - TypeNameHandling = TypeNameHandling.Auto - }); + string json = JsonConvert.SerializeObject(new WagePerson(), typeof(object), Formatting.Indented, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Auto + }); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""$type"": ""Newtonsoft.Json.Tests.TestObjects.WagePerson, Newtonsoft.Json.Tests"", ""HourlyWage"": 0.0, ""Name"": null, ""BirthDate"": ""0001-01-01T00:00:00"", ""LastModified"": ""0001-01-01T00:00:00"" }", json); - } + } - public class Wrapper - { - public IList Array { get; set; } - public IDictionary Dictionary { get; set; } - } - - [Test] - public void SerializeWrapper() - { - Wrapper wrapper = new Wrapper(); - wrapper.Array = new List + public class Wrapper { - new EmployeeReference() - }; - wrapper.Dictionary = new Dictionary - { - {"First", new EmployeeReference()} - }; + public IList Array { get; set; } + public IDictionary Dictionary { get; set; } + } - string json = JsonConvert.SerializeObject(wrapper, Formatting.Indented, new JsonSerializerSettings + [Test] + public void SerializeWrapper() { - TypeNameHandling = TypeNameHandling.Auto - }); + Wrapper wrapper = new Wrapper(); + wrapper.Array = new List + { + new EmployeeReference() + }; + wrapper.Dictionary = new Dictionary + { + { "First", new EmployeeReference() } + }; - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(wrapper, Formatting.Indented, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Auto + }); + + Assert.AreEqual(@"{ ""Array"": [ { ""$id"": ""1"", @@ -157,102 +157,102 @@ namespace Newtonsoft.Json.Tests.Serialization } }", json); - Wrapper w2 = JsonConvert.DeserializeObject(json); - CustomAssert.IsInstanceOfType(typeof (List), w2.Array); - CustomAssert.IsInstanceOfType(typeof (Dictionary), w2.Dictionary); - } + Wrapper w2 = JsonConvert.DeserializeObject(json); + CustomAssert.IsInstanceOfType(typeof(List), w2.Array); + CustomAssert.IsInstanceOfType(typeof(Dictionary), w2.Dictionary); + } - [Test] - public void WriteTypeNameForObjects() - { - string employeeRef = ReflectionUtils.GetTypeName(typeof(EmployeeReference), FormatterAssemblyStyle.Simple, null); - - EmployeeReference employee = new EmployeeReference(); - - string json = JsonConvert.SerializeObject(employee, Formatting.Indented, new JsonSerializerSettings + [Test] + public void WriteTypeNameForObjects() { - TypeNameHandling = TypeNameHandling.Objects - }); + string employeeRef = ReflectionUtils.GetTypeName(typeof(EmployeeReference), FormatterAssemblyStyle.Simple, null); - Assert.AreEqual(@"{ + EmployeeReference employee = new EmployeeReference(); + + string json = JsonConvert.SerializeObject(employee, Formatting.Indented, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Objects + }); + + Assert.AreEqual(@"{ ""$id"": ""1"", ""$type"": """ + employeeRef + @""", ""Name"": null, ""Manager"": null }", json); - } + } - [Test] - public void DeserializeTypeName() - { - string employeeRef = ReflectionUtils.GetTypeName(typeof(EmployeeReference), FormatterAssemblyStyle.Simple, null); + [Test] + public void DeserializeTypeName() + { + string employeeRef = ReflectionUtils.GetTypeName(typeof(EmployeeReference), FormatterAssemblyStyle.Simple, null); - string json = @"{ + string json = @"{ ""$id"": ""1"", ""$type"": """ + employeeRef + @""", ""Name"": ""Name!"", ""Manager"": null }"; - object employee = JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings - { - TypeNameHandling = TypeNameHandling.Objects - }); + object employee = JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Objects + }); - CustomAssert.IsInstanceOfType(typeof (EmployeeReference), employee); - Assert.AreEqual("Name!", ((EmployeeReference) employee).Name); - } + CustomAssert.IsInstanceOfType(typeof(EmployeeReference), employee); + Assert.AreEqual("Name!", ((EmployeeReference)employee).Name); + } #if !(SILVERLIGHT || NETFX_CORE || PORTABLE) - [Test] - public void DeserializeTypeNameFromGacAssembly() - { - string cookieRef = ReflectionUtils.GetTypeName(typeof (Cookie), FormatterAssemblyStyle.Simple, null); + [Test] + public void DeserializeTypeNameFromGacAssembly() + { + string cookieRef = ReflectionUtils.GetTypeName(typeof(Cookie), FormatterAssemblyStyle.Simple, null); - string json = @"{ + string json = @"{ ""$id"": ""1"", ""$type"": """ + cookieRef + @""" }"; - object cookie = JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings - { - TypeNameHandling = TypeNameHandling.Objects - }); + object cookie = JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Objects + }); - CustomAssert.IsInstanceOfType(typeof (Cookie), cookie); - } + CustomAssert.IsInstanceOfType(typeof(Cookie), cookie); + } #endif - [Test] - public void SerializeGenericObjectListWithTypeName() - { - string employeeRef = typeof (EmployeeReference).AssemblyQualifiedName; - string personRef = typeof (Person).AssemblyQualifiedName; - - List values = new List + [Test] + public void SerializeGenericObjectListWithTypeName() { - new EmployeeReference - { - Name = "Bob", - Manager = new EmployeeReference {Name = "Frank"} - }, - new Person - { - Department = "Department", - BirthDate = new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc), - LastModified = new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc) - }, - "String!", - int.MinValue - }; + string employeeRef = typeof(EmployeeReference).AssemblyQualifiedName; + string personRef = typeof(Person).AssemblyQualifiedName; - string json = JsonConvert.SerializeObject(values, Formatting.Indented, new JsonSerializerSettings - { - TypeNameHandling = TypeNameHandling.Objects, - TypeNameAssemblyFormat = FormatterAssemblyStyle.Full - }); + List values = new List + { + new EmployeeReference + { + Name = "Bob", + Manager = new EmployeeReference { Name = "Frank" } + }, + new Person + { + Department = "Department", + BirthDate = new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc), + LastModified = new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc) + }, + "String!", + int.MinValue + }; - Assert.AreEqual(@"[ + string json = JsonConvert.SerializeObject(values, Formatting.Indented, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Objects, + TypeNameAssemblyFormat = FormatterAssemblyStyle.Full + }); + + Assert.AreEqual(@"[ { ""$id"": ""1"", ""$type"": """ + employeeRef + @""", @@ -273,15 +273,15 @@ namespace Newtonsoft.Json.Tests.Serialization ""String!"", -2147483648 ]", json); - } + } - [Test] - public void DeserializeGenericObjectListWithTypeName() - { - string employeeRef = typeof (EmployeeReference).AssemblyQualifiedName; - string personRef = typeof (Person).AssemblyQualifiedName; + [Test] + public void DeserializeGenericObjectListWithTypeName() + { + string employeeRef = typeof(EmployeeReference).AssemblyQualifiedName; + string personRef = typeof(Person).AssemblyQualifiedName; - string json = @"[ + string json = @"[ { ""$id"": ""1"", ""$type"": """ + employeeRef + @""", @@ -303,126 +303,126 @@ namespace Newtonsoft.Json.Tests.Serialization -2147483648 ]"; - List values = (List) JsonConvert.DeserializeObject(json, typeof (List), new JsonSerializerSettings + List values = (List)JsonConvert.DeserializeObject(json, typeof(List), new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Objects, + TypeNameAssemblyFormat = FormatterAssemblyStyle.Full + }); + + Assert.AreEqual(4, values.Count); + + EmployeeReference e = (EmployeeReference)values[0]; + Person p = (Person)values[1]; + + Assert.AreEqual("Bob", e.Name); + Assert.AreEqual("Frank", e.Manager.Name); + + Assert.AreEqual(null, p.Name); + Assert.AreEqual(new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc), p.BirthDate); + Assert.AreEqual(new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc), p.LastModified); + + Assert.AreEqual("String!", values[2]); + Assert.AreEqual((long)int.MinValue, values[3]); + } + + [Test] + public void DeserializeWithBadTypeName() { - TypeNameHandling = TypeNameHandling.Objects, - TypeNameAssemblyFormat = FormatterAssemblyStyle.Full - }); + string employeeRef = typeof(EmployeeReference).AssemblyQualifiedName; + string personRef = typeof(Person).AssemblyQualifiedName; - Assert.AreEqual(4, values.Count); - - EmployeeReference e = (EmployeeReference) values[0]; - Person p = (Person) values[1]; - - Assert.AreEqual("Bob", e.Name); - Assert.AreEqual("Frank", e.Manager.Name); - - Assert.AreEqual(null, p.Name); - Assert.AreEqual(new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc), p.BirthDate); - Assert.AreEqual(new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc), p.LastModified); - - Assert.AreEqual("String!", values[2]); - Assert.AreEqual((long) int.MinValue, values[3]); - } - - [Test] - public void DeserializeWithBadTypeName() - { - string employeeRef = typeof (EmployeeReference).AssemblyQualifiedName; - string personRef = typeof (Person).AssemblyQualifiedName; - - string json = @"{ + string json = @"{ ""$id"": ""1"", ""$type"": """ + employeeRef + @""", ""Name"": ""Name!"", ""Manager"": null }"; - try - { - JsonConvert.DeserializeObject(json, typeof (Person), new JsonSerializerSettings - { - TypeNameHandling = TypeNameHandling.Objects, - TypeNameAssemblyFormat = FormatterAssemblyStyle.Full - }); - } - catch (JsonSerializationException ex) - { - Assert.IsTrue(ex.Message.StartsWith(@"Type specified in JSON '" + employeeRef + @"' is not compatible with '" + personRef + @"'.")); - } - } + try + { + JsonConvert.DeserializeObject(json, typeof(Person), new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Objects, + TypeNameAssemblyFormat = FormatterAssemblyStyle.Full + }); + } + catch (JsonSerializationException ex) + { + Assert.IsTrue(ex.Message.StartsWith(@"Type specified in JSON '" + employeeRef + @"' is not compatible with '" + personRef + @"'.")); + } + } - [Test] - public void DeserializeTypeNameWithNoTypeNameHandling() - { - string employeeRef = typeof (EmployeeReference).AssemblyQualifiedName; + [Test] + public void DeserializeTypeNameWithNoTypeNameHandling() + { + string employeeRef = typeof(EmployeeReference).AssemblyQualifiedName; - string json = @"{ + string json = @"{ ""$id"": ""1"", ""$type"": """ + employeeRef + @""", ""Name"": ""Name!"", ""Manager"": null }"; - JObject o = (JObject) JsonConvert.DeserializeObject(json); + JObject o = (JObject)JsonConvert.DeserializeObject(json); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Name"": ""Name!"", ""Manager"": null }", o.ToString()); - } + } - [Test] - public void DeserializeTypeNameOnly() - { - string json = @"{ + [Test] + public void DeserializeTypeNameOnly() + { + string json = @"{ ""$id"": ""1"", ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Employee"", ""Name"": ""Name!"", ""Manager"": null }"; - ExceptionAssert.Throws( - "Type specified in JSON 'Newtonsoft.Json.Tests.TestObjects.Employee' was not resolved. Path '$type', line 3, position 56.", - () => - { - JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings - { - TypeNameHandling = TypeNameHandling.Objects - }); - }); - } + ExceptionAssert.Throws( + "Type specified in JSON 'Newtonsoft.Json.Tests.TestObjects.Employee' was not resolved. Path '$type', line 3, position 56.", + () => + { + JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Objects + }); + }); + } - public interface ICorrelatedMessage - { - string CorrelationId { get; set; } - } + public interface ICorrelatedMessage + { + string CorrelationId { get; set; } + } - public class SendHttpRequest : ICorrelatedMessage - { - public SendHttpRequest() - { - RequestEncoding = "UTF-8"; - Method = "GET"; - } + public class SendHttpRequest : ICorrelatedMessage + { + public SendHttpRequest() + { + RequestEncoding = "UTF-8"; + Method = "GET"; + } - public string Method { get; set; } - public Dictionary Headers { get; set; } - public string Url { get; set; } - public Dictionary RequestData; - public string RequestBodyText { get; set; } - public string User { get; set; } - public string Passwd { get; set; } - public string RequestEncoding { get; set; } - public string CorrelationId { get; set; } - } + public string Method { get; set; } + public Dictionary Headers { get; set; } + public string Url { get; set; } + public Dictionary RequestData; + public string RequestBodyText { get; set; } + public string User { get; set; } + public string Passwd { get; set; } + public string RequestEncoding { get; set; } + public string CorrelationId { get; set; } + } - [Test] - public void DeserializeGenericTypeName() - { - string typeName = typeof (SendHttpRequest).AssemblyQualifiedName; + [Test] + public void DeserializeGenericTypeName() + { + string typeName = typeof(SendHttpRequest).AssemblyQualifiedName; - string json = @"{ + string json = @"{ ""$type"": """ + typeName + @""", ""RequestData"": { ""$type"": ""System.Collections.Generic.Dictionary`2[[System.String, mscorlib,Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"", @@ -435,41 +435,41 @@ namespace Newtonsoft.Json.Tests.Serialization ""CorrelationId"": ""xyz"" }"; - ICorrelatedMessage message = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + ICorrelatedMessage message = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Objects, + TypeNameAssemblyFormat = FormatterAssemblyStyle.Full + }); + + CustomAssert.IsInstanceOfType(typeof(SendHttpRequest), message); + + SendHttpRequest request = (SendHttpRequest)message; + Assert.AreEqual("xyz", request.CorrelationId); + Assert.AreEqual(2, request.RequestData.Count); + Assert.AreEqual("siedemnaście", request.RequestData["Id"]); + } + + [Test] + public void SerializeObjectWithMultipleGenericLists() { - TypeNameHandling = TypeNameHandling.Objects, - TypeNameAssemblyFormat = FormatterAssemblyStyle.Full - }); + string containerTypeName = typeof(Container).AssemblyQualifiedName; + string productListTypeName = typeof(List).AssemblyQualifiedName; - CustomAssert.IsInstanceOfType(typeof (SendHttpRequest), message); + Container container = new Container + { + In = new List(), + Out = new List() + }; - SendHttpRequest request = (SendHttpRequest) message; - Assert.AreEqual("xyz", request.CorrelationId); - Assert.AreEqual(2, request.RequestData.Count); - Assert.AreEqual("siedemnaście", request.RequestData["Id"]); - } + string json = JsonConvert.SerializeObject(container, Formatting.Indented, + new JsonSerializerSettings + { + NullValueHandling = NullValueHandling.Ignore, + TypeNameHandling = TypeNameHandling.All, + TypeNameAssemblyFormat = FormatterAssemblyStyle.Full + }); - [Test] - public void SerializeObjectWithMultipleGenericLists() - { - string containerTypeName = typeof (Container).AssemblyQualifiedName; - string productListTypeName = typeof (List).AssemblyQualifiedName; - - Container container = new Container - { - In = new List(), - Out = new List() - }; - - string json = JsonConvert.SerializeObject(container, Formatting.Indented, - new JsonSerializerSettings - { - NullValueHandling = NullValueHandling.Ignore, - TypeNameHandling = TypeNameHandling.All, - TypeNameAssemblyFormat = FormatterAssemblyStyle.Full - }); - - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""$type"": """ + containerTypeName + @""", ""In"": { ""$type"": """ + productListTypeName + @""", @@ -480,33 +480,33 @@ namespace Newtonsoft.Json.Tests.Serialization ""$values"": [] } }", json); - } + } - public class TypeNameProperty - { - public string Name { get; set; } - - [JsonProperty(TypeNameHandling = TypeNameHandling.All)] - public object Value { get; set; } - } - - [Test] - public void WriteObjectTypeNameForProperty() - { - string typeNamePropertyRef = ReflectionUtils.GetTypeName(typeof (TypeNameProperty), FormatterAssemblyStyle.Simple, null); - - TypeNameProperty typeNameProperty = new TypeNameProperty + public class TypeNameProperty { - Name = "Name!", - Value = new TypeNameProperty + public string Name { get; set; } + + [JsonProperty(TypeNameHandling = TypeNameHandling.All)] + public object Value { get; set; } + } + + [Test] + public void WriteObjectTypeNameForProperty() + { + string typeNamePropertyRef = ReflectionUtils.GetTypeName(typeof(TypeNameProperty), FormatterAssemblyStyle.Simple, null); + + TypeNameProperty typeNameProperty = new TypeNameProperty { - Name = "Nested!" - } - }; + Name = "Name!", + Value = new TypeNameProperty + { + Name = "Nested!" + } + }; - string json = JsonConvert.SerializeObject(typeNameProperty, Formatting.Indented); + string json = JsonConvert.SerializeObject(typeNameProperty, Formatting.Indented); - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""Name"": ""Name!"", ""Value"": { ""$type"": """ + typeNamePropertyRef + @""", @@ -515,29 +515,29 @@ namespace Newtonsoft.Json.Tests.Serialization } }", json); - TypeNameProperty deserialized = JsonConvert.DeserializeObject(json); - Assert.AreEqual("Name!", deserialized.Name); - CustomAssert.IsInstanceOfType(typeof (TypeNameProperty), deserialized.Value); + TypeNameProperty deserialized = JsonConvert.DeserializeObject(json); + Assert.AreEqual("Name!", deserialized.Name); + CustomAssert.IsInstanceOfType(typeof(TypeNameProperty), deserialized.Value); - TypeNameProperty nested = (TypeNameProperty) deserialized.Value; - Assert.AreEqual("Nested!", nested.Name); - Assert.AreEqual(null, nested.Value); - } + TypeNameProperty nested = (TypeNameProperty)deserialized.Value; + Assert.AreEqual("Nested!", nested.Name); + Assert.AreEqual(null, nested.Value); + } - [Test] - public void WriteListTypeNameForProperty() - { - string listRef = ReflectionUtils.GetTypeName(typeof (List), FormatterAssemblyStyle.Simple, null); - - TypeNameProperty typeNameProperty = new TypeNameProperty + [Test] + public void WriteListTypeNameForProperty() { - Name = "Name!", - Value = new List {1, 2, 3, 4, 5} - }; + string listRef = ReflectionUtils.GetTypeName(typeof(List), FormatterAssemblyStyle.Simple, null); - string json = JsonConvert.SerializeObject(typeNameProperty, Formatting.Indented); + TypeNameProperty typeNameProperty = new TypeNameProperty + { + Name = "Name!", + Value = new List { 1, 2, 3, 4, 5 } + }; - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(typeNameProperty, Formatting.Indented); + + Assert.AreEqual(@"{ ""Name"": ""Name!"", ""Value"": { ""$type"": """ + listRef + @""", @@ -551,90 +551,90 @@ namespace Newtonsoft.Json.Tests.Serialization } }", json); - TypeNameProperty deserialized = JsonConvert.DeserializeObject(json); - Assert.AreEqual("Name!", deserialized.Name); - CustomAssert.IsInstanceOfType(typeof (List), deserialized.Value); + TypeNameProperty deserialized = JsonConvert.DeserializeObject(json); + Assert.AreEqual("Name!", deserialized.Name); + CustomAssert.IsInstanceOfType(typeof(List), deserialized.Value); - List nested = (List) deserialized.Value; - Assert.AreEqual(5, nested.Count); - Assert.AreEqual(1, nested[0]); - Assert.AreEqual(2, nested[1]); - Assert.AreEqual(3, nested[2]); - Assert.AreEqual(4, nested[3]); - Assert.AreEqual(5, nested[4]); - } + List nested = (List)deserialized.Value; + Assert.AreEqual(5, nested.Count); + Assert.AreEqual(1, nested[0]); + Assert.AreEqual(2, nested[1]); + Assert.AreEqual(3, nested[2]); + Assert.AreEqual(4, nested[3]); + Assert.AreEqual(5, nested[4]); + } - [Test] - public void DeserializeUsingCustomBinder() - { - string json = @"{ + [Test] + public void DeserializeUsingCustomBinder() + { + string json = @"{ ""$id"": ""1"", ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Employee"", ""Name"": ""Name!"" }"; - object p = JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings + object p = JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Objects, + Binder = new CustomSerializationBinder() + }); + + CustomAssert.IsInstanceOfType(typeof(Person), p); + + Person person = (Person)p; + + Assert.AreEqual("Name!", person.Name); + } + + public class CustomSerializationBinder : SerializationBinder { - TypeNameHandling = TypeNameHandling.Objects, - Binder = new CustomSerializationBinder() - }); - - CustomAssert.IsInstanceOfType(typeof (Person), p); - - Person person = (Person) p; - - Assert.AreEqual("Name!", person.Name); - } - - public class CustomSerializationBinder : SerializationBinder - { - public override Type BindToType(string assemblyName, string typeName) - { - return typeof (Person); - } - } + public override Type BindToType(string assemblyName, string typeName) + { + return typeof(Person); + } + } #if !(NET20 || NET35) - [Test] - public void SerializeUsingCustomBinder() - { - TypeNameSerializationBinder binder = new TypeNameSerializationBinder("Newtonsoft.Json.Tests.Serialization.{0}, Newtonsoft.Json.Tests"); - - IList values = new List + [Test] + public void SerializeUsingCustomBinder() { - new Customer + TypeNameSerializationBinder binder = new TypeNameSerializationBinder("Newtonsoft.Json.Tests.Serialization.{0}, Newtonsoft.Json.Tests"); + + IList values = new List { - Name = "Caroline Customer" - }, - new Purchase + new Customer + { + Name = "Caroline Customer" + }, + new Purchase + { + ProductName = "Elbow Grease", + Price = 5.99m, + Quantity = 1 + } + }; + + string json = JsonConvert.SerializeObject(values, Formatting.Indented, new JsonSerializerSettings { - ProductName = "Elbow Grease", - Price = 5.99m, - Quantity = 1 - } - }; + TypeNameHandling = TypeNameHandling.Auto, + Binder = binder + }); - string json = JsonConvert.SerializeObject(values, Formatting.Indented, new JsonSerializerSettings - { - TypeNameHandling = TypeNameHandling.Auto, - Binder = binder - }); - - //[ - // { - // "$type": "Customer", - // "Name": "Caroline Customer" - // }, - // { - // "$type": "Purchase", - // "ProductName": "Elbow Grease", - // "Price": 5.99, - // "Quantity": 1 - // } - //] + //[ + // { + // "$type": "Customer", + // "Name": "Caroline Customer" + // }, + // { + // "$type": "Purchase", + // "ProductName": "Elbow Grease", + // "Price": 5.99, + // "Quantity": 1 + // } + //] - Assert.AreEqual(@"[ + Assert.AreEqual(@"[ { ""$type"": ""Customer"", ""Name"": ""Caroline Customer"" @@ -647,73 +647,73 @@ namespace Newtonsoft.Json.Tests.Serialization } ]", json); - IList newValues = JsonConvert.DeserializeObject>(json, new JsonSerializerSettings + IList newValues = JsonConvert.DeserializeObject>(json, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Auto, + Binder = new TypeNameSerializationBinder("Newtonsoft.Json.Tests.Serialization.{0}, Newtonsoft.Json.Tests") + }); + + CustomAssert.IsInstanceOfType(typeof(Customer), newValues[0]); + Customer customer = (Customer)newValues[0]; + Assert.AreEqual("Caroline Customer", customer.Name); + + CustomAssert.IsInstanceOfType(typeof(Purchase), newValues[1]); + Purchase purchase = (Purchase)newValues[1]; + Assert.AreEqual("Elbow Grease", purchase.ProductName); + } + + public class TypeNameSerializationBinder : SerializationBinder { - TypeNameHandling = TypeNameHandling.Auto, - Binder = new TypeNameSerializationBinder("Newtonsoft.Json.Tests.Serialization.{0}, Newtonsoft.Json.Tests") - }); + public string TypeFormat { get; private set; } - CustomAssert.IsInstanceOfType(typeof (Customer), newValues[0]); - Customer customer = (Customer) newValues[0]; - Assert.AreEqual("Caroline Customer", customer.Name); + public TypeNameSerializationBinder(string typeFormat) + { + TypeFormat = typeFormat; + } - CustomAssert.IsInstanceOfType(typeof (Purchase), newValues[1]); - Purchase purchase = (Purchase) newValues[1]; - Assert.AreEqual("Elbow Grease", purchase.ProductName); - } + public override void BindToName(Type serializedType, out string assemblyName, out string typeName) + { + assemblyName = null; + typeName = serializedType.Name; + } - public class TypeNameSerializationBinder : SerializationBinder - { - public string TypeFormat { get; private set; } + public override Type BindToType(string assemblyName, string typeName) + { + string resolvedTypeName = string.Format(TypeFormat, typeName); - public TypeNameSerializationBinder(string typeFormat) - { - TypeFormat = typeFormat; - } - - public override void BindToName(Type serializedType, out string assemblyName, out string typeName) - { - assemblyName = null; - typeName = serializedType.Name; - } - - public override Type BindToType(string assemblyName, string typeName) - { - string resolvedTypeName = string.Format(TypeFormat, typeName); - - return Type.GetType(resolvedTypeName, true); - } - } + return Type.GetType(resolvedTypeName, true); + } + } #endif - [Test] - public void CollectionWithAbstractItems() - { - HolderClass testObject = new HolderClass(); - testObject.TestMember = new ContentSubClass("First One"); - testObject.AnotherTestMember = new Dictionary>(); - testObject.AnotherTestMember.Add(1, new List()); - testObject.AnotherTestMember[1].Add(new ContentSubClass("Second One")); - testObject.AThirdTestMember = new ContentSubClass("Third One"); + [Test] + public void CollectionWithAbstractItems() + { + HolderClass testObject = new HolderClass(); + testObject.TestMember = new ContentSubClass("First One"); + testObject.AnotherTestMember = new Dictionary>(); + testObject.AnotherTestMember.Add(1, new List()); + testObject.AnotherTestMember[1].Add(new ContentSubClass("Second One")); + testObject.AThirdTestMember = new ContentSubClass("Third One"); - JsonSerializer serializingTester = new JsonSerializer(); - serializingTester.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; + JsonSerializer serializingTester = new JsonSerializer(); + serializingTester.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; - StringWriter sw = new StringWriter(); - using (JsonTextWriter jsonWriter = new JsonTextWriter(sw)) - { - jsonWriter.Formatting = Formatting.Indented; - serializingTester.TypeNameHandling = TypeNameHandling.Auto; - serializingTester.Serialize(jsonWriter, testObject); - } + StringWriter sw = new StringWriter(); + using (JsonTextWriter jsonWriter = new JsonTextWriter(sw)) + { + jsonWriter.Formatting = Formatting.Indented; + serializingTester.TypeNameHandling = TypeNameHandling.Auto; + serializingTester.Serialize(jsonWriter, testObject); + } - string json = sw.ToString(); + string json = sw.ToString(); - string contentSubClassRef = ReflectionUtils.GetTypeName(typeof (ContentSubClass), FormatterAssemblyStyle.Simple, null); - string dictionaryRef = ReflectionUtils.GetTypeName(typeof (Dictionary>), FormatterAssemblyStyle.Simple, null); - string listRef = ReflectionUtils.GetTypeName(typeof (List), FormatterAssemblyStyle.Simple, null); + string contentSubClassRef = ReflectionUtils.GetTypeName(typeof(ContentSubClass), FormatterAssemblyStyle.Simple, null); + string dictionaryRef = ReflectionUtils.GetTypeName(typeof(Dictionary>), FormatterAssemblyStyle.Simple, null); + string listRef = ReflectionUtils.GetTypeName(typeof(List), FormatterAssemblyStyle.Simple, null); - string expected = @"{ + string expected = @"{ ""TestMember"": { ""$type"": """ + contentSubClassRef + @""", ""SomeString"": ""First One"" @@ -733,92 +733,92 @@ namespace Newtonsoft.Json.Tests.Serialization } }"; - Assert.AreEqual(expected, json); + Assert.AreEqual(expected, json); - StringReader sr = new StringReader(json); + StringReader sr = new StringReader(json); - JsonSerializer deserializingTester = new JsonSerializer(); + JsonSerializer deserializingTester = new JsonSerializer(); - HolderClass anotherTestObject; + HolderClass anotherTestObject; - using (JsonTextReader jsonReader = new JsonTextReader(sr)) - { - deserializingTester.TypeNameHandling = TypeNameHandling.Auto; + using (JsonTextReader jsonReader = new JsonTextReader(sr)) + { + deserializingTester.TypeNameHandling = TypeNameHandling.Auto; - anotherTestObject = deserializingTester.Deserialize(jsonReader); - } - - Assert.IsNotNull(anotherTestObject); - CustomAssert.IsInstanceOfType(typeof (ContentSubClass), anotherTestObject.TestMember); - CustomAssert.IsInstanceOfType(typeof (Dictionary>), anotherTestObject.AnotherTestMember); - Assert.AreEqual(1, anotherTestObject.AnotherTestMember.Count); - - IList list = anotherTestObject.AnotherTestMember[1]; - - CustomAssert.IsInstanceOfType(typeof (List), list); - Assert.AreEqual(1, list.Count); - CustomAssert.IsInstanceOfType(typeof (ContentSubClass), list[0]); - } - - [Test] - public void WriteObjectTypeNameForPropertyDemo() - { - Message message = new Message(); - message.Address = "http://www.google.com"; - message.Body = new SearchDetails - { - Query = "Json.NET", - Language = "en-us" - }; - - string json = JsonConvert.SerializeObject(message, Formatting.Indented); - // { - // "Address": "http://www.google.com", - // "Body": { - // "$type": "Newtonsoft.Json.Tests.Serialization.SearchDetails, Newtonsoft.Json.Tests", - // "Query": "Json.NET", - // "Language": "en-us" - // } - // } - - Message deserialized = JsonConvert.DeserializeObject(json); - - SearchDetails searchDetails = (SearchDetails) deserialized.Body; - // Json.NET - } - - public class UrlStatus - { - public int Status { get; set; } - public string Url { get; set; } - } - - - [Test] - public void GenericDictionaryObject() - { - Dictionary collection = new Dictionary() - { - {"First", new UrlStatus {Status = 404, Url = @"http://www.bing.com"}}, - {"Second", new UrlStatus {Status = 400, Url = @"http://www.google.com"}}, - { - "List", new List - { - new UrlStatus {Status = 300, Url = @"http://www.yahoo.com"}, - new UrlStatus {Status = 200, Url = @"http://www.askjeeves.com"} - } + anotherTestObject = deserializingTester.Deserialize(jsonReader); } - }; - string json = JsonConvert.SerializeObject(collection, Formatting.Indented, new JsonSerializerSettings + Assert.IsNotNull(anotherTestObject); + CustomAssert.IsInstanceOfType(typeof(ContentSubClass), anotherTestObject.TestMember); + CustomAssert.IsInstanceOfType(typeof(Dictionary>), anotherTestObject.AnotherTestMember); + Assert.AreEqual(1, anotherTestObject.AnotherTestMember.Count); + + IList list = anotherTestObject.AnotherTestMember[1]; + + CustomAssert.IsInstanceOfType(typeof(List), list); + Assert.AreEqual(1, list.Count); + CustomAssert.IsInstanceOfType(typeof(ContentSubClass), list[0]); + } + + [Test] + public void WriteObjectTypeNameForPropertyDemo() { - TypeNameHandling = TypeNameHandling.All, - TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple - }); + Message message = new Message(); + message.Address = "http://www.google.com"; + message.Body = new SearchDetails + { + Query = "Json.NET", + Language = "en-us" + }; - string urlStatusTypeName = ReflectionUtils.GetTypeName(typeof (UrlStatus), FormatterAssemblyStyle.Simple, null); + string json = JsonConvert.SerializeObject(message, Formatting.Indented); + // { + // "Address": "http://www.google.com", + // "Body": { + // "$type": "Newtonsoft.Json.Tests.Serialization.SearchDetails, Newtonsoft.Json.Tests", + // "Query": "Json.NET", + // "Language": "en-us" + // } + // } - Assert.AreEqual(@"{ + Message deserialized = JsonConvert.DeserializeObject(json); + + SearchDetails searchDetails = (SearchDetails)deserialized.Body; + // Json.NET + } + + public class UrlStatus + { + public int Status { get; set; } + public string Url { get; set; } + } + + + [Test] + public void GenericDictionaryObject() + { + Dictionary collection = new Dictionary() + { + { "First", new UrlStatus { Status = 404, Url = @"http://www.bing.com" } }, + { "Second", new UrlStatus { Status = 400, Url = @"http://www.google.com" } }, + { + "List", new List + { + new UrlStatus { Status = 300, Url = @"http://www.yahoo.com" }, + new UrlStatus { Status = 200, Url = @"http://www.askjeeves.com" } + } + } + }; + + string json = JsonConvert.SerializeObject(collection, Formatting.Indented, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.All, + TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple + }); + + string urlStatusTypeName = ReflectionUtils.GetTypeName(typeof(UrlStatus), FormatterAssemblyStyle.Simple, null); + + Assert.AreEqual(@"{ ""$type"": ""System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Object, mscorlib]], mscorlib"", ""First"": { ""$type"": """ + urlStatusTypeName + @""", @@ -847,113 +847,113 @@ namespace Newtonsoft.Json.Tests.Serialization } }", json); - object c = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + object c = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.All, + TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple + }); + + CustomAssert.IsInstanceOfType(typeof(Dictionary), c); + + Dictionary newCollection = (Dictionary)c; + Assert.AreEqual(3, newCollection.Count); + Assert.AreEqual(@"http://www.bing.com", ((UrlStatus)newCollection["First"]).Url); + + List statues = (List)newCollection["List"]; + Assert.AreEqual(2, statues.Count); + } + + + [Test] + public void SerializingIEnumerableOfTShouldRetainGenericTypeInfo() { - TypeNameHandling = TypeNameHandling.All, - TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple - }); + string productClassRef = ReflectionUtils.GetTypeName(typeof(CustomEnumerable), FormatterAssemblyStyle.Simple, null); - CustomAssert.IsInstanceOfType(typeof (Dictionary), c); + CustomEnumerable products = new CustomEnumerable(); - Dictionary newCollection = (Dictionary) c; - Assert.AreEqual(3, newCollection.Count); - Assert.AreEqual(@"http://www.bing.com", ((UrlStatus) newCollection["First"]).Url); + string json = JsonConvert.SerializeObject(products, Formatting.Indented, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All }); - List statues = (List) newCollection["List"]; - Assert.AreEqual(2, statues.Count); - } - - - [Test] - public void SerializingIEnumerableOfTShouldRetainGenericTypeInfo() - { - string productClassRef = ReflectionUtils.GetTypeName(typeof(CustomEnumerable), FormatterAssemblyStyle.Simple, null); - - CustomEnumerable products = new CustomEnumerable(); - - string json = JsonConvert.SerializeObject(products, Formatting.Indented, new JsonSerializerSettings {TypeNameHandling = TypeNameHandling.All}); - - Assert.AreEqual(@"{ + Assert.AreEqual(@"{ ""$type"": """ + productClassRef + @""", ""$values"": [] }", json); - } - - public class CustomEnumerable : IEnumerable - { - //NOTE: a simple linked list - private readonly T value; - private readonly CustomEnumerable next; - private readonly int count; - - private CustomEnumerable(T value, CustomEnumerable next) - { - this.value = value; - this.next = next; - count = this.next.count + 1; - } - - public CustomEnumerable() - { - count = 0; - } - - public CustomEnumerable AddFirst(T newVal) - { - return new CustomEnumerable(newVal, this); - } - - public IEnumerator GetEnumerator() - { - if (count == 0) // last node - yield break; - yield return value; - - var nextInLine = next; - while (nextInLine != null) - { - if (nextInLine.count != 0) - yield return nextInLine.value; - nextInLine = nextInLine.next; } - } - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } + public class CustomEnumerable : IEnumerable + { + //NOTE: a simple linked list + private readonly T value; + private readonly CustomEnumerable next; + private readonly int count; - public class Car - { - // included in JSON - public string Model { get; set; } - public DateTime Year { get; set; } - public List Features { get; set; } - public object[] Objects { get; set; } + private CustomEnumerable(T value, CustomEnumerable next) + { + this.value = value; + this.next = next; + count = this.next.count + 1; + } - // ignored - [JsonIgnore] - public DateTime LastModified { get; set; } - } + public CustomEnumerable() + { + count = 0; + } - [Test] - public void ByteArrays() - { - Car testerObject = new Car(); - testerObject.Year = new DateTime(2000, 10, 5, 1, 1, 1, DateTimeKind.Utc); - byte[] data = new byte[] {75, 65, 82, 73, 82, 65}; - testerObject.Objects = new object[] {data, "prueba"}; + public CustomEnumerable AddFirst(T newVal) + { + return new CustomEnumerable(newVal, this); + } - JsonSerializerSettings jsonSettings = new JsonSerializerSettings(); - jsonSettings.NullValueHandling = NullValueHandling.Ignore; - jsonSettings.TypeNameHandling = TypeNameHandling.All; + public IEnumerator GetEnumerator() + { + if (count == 0) // last node + yield break; + yield return value; - string output = JsonConvert.SerializeObject(testerObject, Formatting.Indented, jsonSettings); + var nextInLine = next; + while (nextInLine != null) + { + if (nextInLine.count != 0) + yield return nextInLine.value; + nextInLine = nextInLine.next; + } + } - string carClassRef = ReflectionUtils.GetTypeName(typeof (Car), FormatterAssemblyStyle.Simple, null); + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } - Assert.AreEqual(output, @"{ + public class Car + { + // included in JSON + public string Model { get; set; } + public DateTime Year { get; set; } + public List Features { get; set; } + public object[] Objects { get; set; } + + // ignored + [JsonIgnore] + public DateTime LastModified { get; set; } + } + + [Test] + public void ByteArrays() + { + Car testerObject = new Car(); + testerObject.Year = new DateTime(2000, 10, 5, 1, 1, 1, DateTimeKind.Utc); + byte[] data = new byte[] { 75, 65, 82, 73, 82, 65 }; + testerObject.Objects = new object[] { data, "prueba" }; + + JsonSerializerSettings jsonSettings = new JsonSerializerSettings(); + jsonSettings.NullValueHandling = NullValueHandling.Ignore; + jsonSettings.TypeNameHandling = TypeNameHandling.All; + + string output = JsonConvert.SerializeObject(testerObject, Formatting.Indented, jsonSettings); + + string carClassRef = ReflectionUtils.GetTypeName(typeof(Car), FormatterAssemblyStyle.Simple, null); + + Assert.AreEqual(output, @"{ ""$type"": """ + carClassRef + @""", ""Year"": ""2000-10-05T01:01:01Z"", ""Objects"": { @@ -967,89 +967,89 @@ namespace Newtonsoft.Json.Tests.Serialization ] } }"); - Car obj = JsonConvert.DeserializeObject(output, jsonSettings); + Car obj = JsonConvert.DeserializeObject(output, jsonSettings); - Assert.IsNotNull(obj); + Assert.IsNotNull(obj); - Assert.IsTrue(obj.Objects[0] is byte[]); + Assert.IsTrue(obj.Objects[0] is byte[]); - byte[] d = (byte[]) obj.Objects[0]; - CollectionAssert.AreEquivalent(data, d); - } + byte[] d = (byte[])obj.Objects[0]; + CollectionAssert.AreEquivalent(data, d); + } #if !(WINDOWS_PHONE || SILVERLIGHT || NETFX_CORE) - [Test] - public void ISerializableTypeNameHandlingTest() - { - //Create an instance of our example type - IExample e = new Example("Rob"); - - SerializableWrapper w = new SerializableWrapper + [Test] + public void ISerializableTypeNameHandlingTest() { - Content = e - }; + //Create an instance of our example type + IExample e = new Example("Rob"); - //Test Binary Serialization Round Trip - //This will work find because the Binary Formatter serializes type names - //this.TestBinarySerializationRoundTrip(e); + SerializableWrapper w = new SerializableWrapper + { + Content = e + }; - //Test Json Serialization - //This fails because the JsonSerializer doesn't serialize type names correctly for ISerializable objects - //Type Names should be serialized for All, Auto and Object modes - this.TestJsonSerializationRoundTrip(w, TypeNameHandling.All); - this.TestJsonSerializationRoundTrip(w, TypeNameHandling.Auto); - this.TestJsonSerializationRoundTrip(w, TypeNameHandling.Objects); - } + //Test Binary Serialization Round Trip + //This will work find because the Binary Formatter serializes type names + //this.TestBinarySerializationRoundTrip(e); - private void TestJsonSerializationRoundTrip(SerializableWrapper e, TypeNameHandling flag) - { - Console.WriteLine("Type Name Handling: " + flag.ToString()); - StringWriter writer = new StringWriter(); + //Test Json Serialization + //This fails because the JsonSerializer doesn't serialize type names correctly for ISerializable objects + //Type Names should be serialized for All, Auto and Object modes + TestJsonSerializationRoundTrip(w, TypeNameHandling.All); + TestJsonSerializationRoundTrip(w, TypeNameHandling.Auto); + TestJsonSerializationRoundTrip(w, TypeNameHandling.Objects); + } - //Create our serializer and set Type Name Handling appropriately - JsonSerializer serializer = new JsonSerializer(); - serializer.TypeNameHandling = flag; + private void TestJsonSerializationRoundTrip(SerializableWrapper e, TypeNameHandling flag) + { + Console.WriteLine("Type Name Handling: " + flag.ToString()); + StringWriter writer = new StringWriter(); - //Do the actual serialization and dump to Console for inspection - serializer.Serialize(new JsonTextWriter(writer), e); - Console.WriteLine(writer.ToString()); - Console.WriteLine(); + //Create our serializer and set Type Name Handling appropriately + JsonSerializer serializer = new JsonSerializer(); + serializer.TypeNameHandling = flag; - //Now try to deserialize - //Json.Net will cause an error here as it will try and instantiate - //the interface directly because it failed to respect the - //TypeNameHandling property on serialization - SerializableWrapper f = serializer.Deserialize(new JsonTextReader(new StringReader(writer.ToString()))); + //Do the actual serialization and dump to Console for inspection + serializer.Serialize(new JsonTextWriter(writer), e); + Console.WriteLine(writer.ToString()); + Console.WriteLine(); - //Check Round Trip - Assert.AreEqual(e, f, "Objects should be equal after round trip json serialization"); - } + //Now try to deserialize + //Json.Net will cause an error here as it will try and instantiate + //the interface directly because it failed to respect the + //TypeNameHandling property on serialization + SerializableWrapper f = serializer.Deserialize(new JsonTextReader(new StringReader(writer.ToString()))); + + //Check Round Trip + Assert.AreEqual(e, f, "Objects should be equal after round trip json serialization"); + } #endif #if !(NET20 || NET35) - [Test] - public void SerializationBinderWithFullName() - { - Message message = new Message + [Test] + public void SerializationBinderWithFullName() { - Address = "jamesnk@testtown.com", - Body = new Version(1, 2, 3, 4) - }; - - string json = JsonConvert.SerializeObject(message, Formatting.Indented, new JsonSerializerSettings - { - TypeNameHandling = TypeNameHandling.All, - TypeNameAssemblyFormat = FormatterAssemblyStyle.Full, - Binder = new MetroBinder(), - ContractResolver = new DefaultContractResolver + Message message = new Message { -#if !(SILVERLIGHT || NETFX_CORE || PORTABLE) - IgnoreSerializableAttribute = true -#endif - } - }); + Address = "jamesnk@testtown.com", + Body = new Version(1, 2, 3, 4) + }; - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(message, Formatting.Indented, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.All, + TypeNameAssemblyFormat = FormatterAssemblyStyle.Full, + Binder = new MetroBinder(), + ContractResolver = new DefaultContractResolver + { +#if !(SILVERLIGHT || NETFX_CORE || PORTABLE) + IgnoreSerializableAttribute = true +#endif + } + }); + + Assert.AreEqual(@"{ ""$type"": "":::MESSAGE:::, AssemblyName"", ""Address"": ""jamesnk@testtown.com"", ""Body"": { @@ -1062,60 +1062,60 @@ namespace Newtonsoft.Json.Tests.Serialization ""MinorRevision"": 4 } }", json); - } + } - public class MetroBinder : SerializationBinder - { - public override Type BindToType(string assemblyName, string typeName) - { - return null; - } + public class MetroBinder : SerializationBinder + { + public override Type BindToType(string assemblyName, string typeName) + { + return null; + } - public override void BindToName(Type serializedType, out string assemblyName, out string typeName) - { - assemblyName = "AssemblyName"; + public override void BindToName(Type serializedType, out string assemblyName, out string typeName) + { + assemblyName = "AssemblyName"; #if !NETFX_CORE - typeName = ":::" + serializedType.Name.ToUpper(CultureInfo.InvariantCulture) + ":::"; + typeName = ":::" + serializedType.Name.ToUpper(CultureInfo.InvariantCulture) + ":::"; #else typeName = ":::" + serializedType.Name.ToUpper() + ":::"; #endif - } - } + } + } #endif - [Test] - public void TypeNameIntList() - { - TypeNameList l = new TypeNameList(); - l.Add(1); - l.Add(2); - l.Add(3); + [Test] + public void TypeNameIntList() + { + TypeNameList l = new TypeNameList(); + l.Add(1); + l.Add(2); + l.Add(3); - string json = JsonConvert.SerializeObject(l, Formatting.Indented); - Assert.AreEqual(@"[ + string json = JsonConvert.SerializeObject(l, Formatting.Indented); + Assert.AreEqual(@"[ 1, 2, 3 ]", json); - } + } - [Test] - public void TypeNameComponentList() - { - var c1 = new TestComponentSimple(); - - TypeNameList l = new TypeNameList(); - l.Add(c1); - l.Add(new Employee + [Test] + public void TypeNameComponentList() { - BirthDate = new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc), - Department = "Department!" - }); - l.Add("String!"); - l.Add(long.MaxValue); + var c1 = new TestComponentSimple(); - string json = JsonConvert.SerializeObject(l, Formatting.Indented); - Assert.AreEqual(@"[ + TypeNameList l = new TypeNameList(); + l.Add(c1); + l.Add(new Employee + { + BirthDate = new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc), + Department = "Department!" + }); + l.Add("String!"); + l.Add(long.MaxValue); + + string json = JsonConvert.SerializeObject(l, Formatting.Indented); + Assert.AreEqual(@"[ { ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"", ""MyProperty"": 0 @@ -1132,25 +1132,25 @@ namespace Newtonsoft.Json.Tests.Serialization 9223372036854775807 ]", json); - TypeNameList l2 = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(4, l2.Count); + TypeNameList l2 = JsonConvert.DeserializeObject>(json); + Assert.AreEqual(4, l2.Count); - CustomAssert.IsInstanceOfType(typeof (TestComponentSimple), l2[0]); - CustomAssert.IsInstanceOfType(typeof (Employee), l2[1]); - CustomAssert.IsInstanceOfType(typeof (string), l2[2]); - CustomAssert.IsInstanceOfType(typeof (long), l2[3]); - } + CustomAssert.IsInstanceOfType(typeof(TestComponentSimple), l2[0]); + CustomAssert.IsInstanceOfType(typeof(Employee), l2[1]); + CustomAssert.IsInstanceOfType(typeof(string), l2[2]); + CustomAssert.IsInstanceOfType(typeof(long), l2[3]); + } - [Test] - public void TypeNameDictionary() - { - TypeNameDictionary l = new TypeNameDictionary(); - l.Add("First", new TestComponentSimple {MyProperty = 1}); - l.Add("Second", "String!"); - l.Add("Third", long.MaxValue); + [Test] + public void TypeNameDictionary() + { + TypeNameDictionary l = new TypeNameDictionary(); + l.Add("First", new TestComponentSimple { MyProperty = 1 }); + l.Add("Second", "String!"); + l.Add("Third", long.MaxValue); - string json = JsonConvert.SerializeObject(l, Formatting.Indented); - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(l, Formatting.Indented); + Assert.AreEqual(@"{ ""First"": { ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"", ""MyProperty"": 1 @@ -1159,28 +1159,28 @@ namespace Newtonsoft.Json.Tests.Serialization ""Third"": 9223372036854775807 }", json); - TypeNameDictionary l2 = JsonConvert.DeserializeObject>(json); - Assert.AreEqual(3, l2.Count); + TypeNameDictionary l2 = JsonConvert.DeserializeObject>(json); + Assert.AreEqual(3, l2.Count); - CustomAssert.IsInstanceOfType(typeof (TestComponentSimple), l2["First"]); - Assert.AreEqual(1, ((TestComponentSimple) l2["First"]).MyProperty); - CustomAssert.IsInstanceOfType(typeof (string), l2["Second"]); - CustomAssert.IsInstanceOfType(typeof (long), l2["Third"]); - } + CustomAssert.IsInstanceOfType(typeof(TestComponentSimple), l2["First"]); + Assert.AreEqual(1, ((TestComponentSimple)l2["First"]).MyProperty); + CustomAssert.IsInstanceOfType(typeof(string), l2["Second"]); + CustomAssert.IsInstanceOfType(typeof(long), l2["Third"]); + } - [Test] - public void TypeNameObjectItems() - { - TypeNameObject o1 = new TypeNameObject(); + [Test] + public void TypeNameObjectItems() + { + TypeNameObject o1 = new TypeNameObject(); - o1.Object1 = new TestComponentSimple {MyProperty = 1}; - o1.Object2 = 123; - o1.ObjectNotHandled = new TestComponentSimple {MyProperty = int.MaxValue}; - o1.String = "String!"; - o1.Integer = int.MaxValue; + o1.Object1 = new TestComponentSimple { MyProperty = 1 }; + o1.Object2 = 123; + o1.ObjectNotHandled = new TestComponentSimple { MyProperty = int.MaxValue }; + o1.String = "String!"; + o1.Integer = int.MaxValue; - string json = JsonConvert.SerializeObject(o1, Formatting.Indented); - string expected = @"{ + string json = JsonConvert.SerializeObject(o1, Formatting.Indented); + string expected = @"{ ""Object1"": { ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"", ""MyProperty"": 1 @@ -1192,33 +1192,33 @@ namespace Newtonsoft.Json.Tests.Serialization ""String"": ""String!"", ""Integer"": 2147483647 }"; - Assert.AreEqual(expected, json); + Assert.AreEqual(expected, json); - TypeNameObject o2 = JsonConvert.DeserializeObject(json); - Assert.IsNotNull(o2); + TypeNameObject o2 = JsonConvert.DeserializeObject(json); + Assert.IsNotNull(o2); - CustomAssert.IsInstanceOfType(typeof (TestComponentSimple), o2.Object1); - Assert.AreEqual(1, ((TestComponentSimple) o2.Object1).MyProperty); - CustomAssert.IsInstanceOfType(typeof (long), o2.Object2); - CustomAssert.IsInstanceOfType(typeof (JObject), o2.ObjectNotHandled); - Assert.AreEqual(@"{ + CustomAssert.IsInstanceOfType(typeof(TestComponentSimple), o2.Object1); + Assert.AreEqual(1, ((TestComponentSimple)o2.Object1).MyProperty); + CustomAssert.IsInstanceOfType(typeof(long), o2.Object2); + CustomAssert.IsInstanceOfType(typeof(JObject), o2.ObjectNotHandled); + Assert.AreEqual(@"{ ""MyProperty"": 2147483647 }", o2.ObjectNotHandled.ToString()); - } + } - [Test] - public void PropertyItemTypeNameHandling() - { - PropertyItemTypeNameHandling c1 = new PropertyItemTypeNameHandling(); - c1.Data = new List + [Test] + public void PropertyItemTypeNameHandling() { - 1, - "two", - new TestComponentSimple {MyProperty = 1} - }; + PropertyItemTypeNameHandling c1 = new PropertyItemTypeNameHandling(); + c1.Data = new List + { + 1, + "two", + new TestComponentSimple { MyProperty = 1 } + }; - string json = JsonConvert.SerializeObject(c1, Formatting.Indented); - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(c1, Formatting.Indented); + Assert.AreEqual(@"{ ""Data"": [ 1, ""two"", @@ -1229,36 +1229,36 @@ namespace Newtonsoft.Json.Tests.Serialization ] }", json); - PropertyItemTypeNameHandling c2 = JsonConvert.DeserializeObject(json); - Assert.AreEqual(3, c2.Data.Count); + PropertyItemTypeNameHandling c2 = JsonConvert.DeserializeObject(json); + Assert.AreEqual(3, c2.Data.Count); - CustomAssert.IsInstanceOfType(typeof (long), c2.Data[0]); - CustomAssert.IsInstanceOfType(typeof (string), c2.Data[1]); - CustomAssert.IsInstanceOfType(typeof (TestComponentSimple), c2.Data[2]); - TestComponentSimple c = (TestComponentSimple) c2.Data[2]; - Assert.AreEqual(1, c.MyProperty); - } + CustomAssert.IsInstanceOfType(typeof(long), c2.Data[0]); + CustomAssert.IsInstanceOfType(typeof(string), c2.Data[1]); + CustomAssert.IsInstanceOfType(typeof(TestComponentSimple), c2.Data[2]); + TestComponentSimple c = (TestComponentSimple)c2.Data[2]; + Assert.AreEqual(1, c.MyProperty); + } - [Test] - public void PropertyItemTypeNameHandlingNestedCollections() - { - PropertyItemTypeNameHandling c1 = new PropertyItemTypeNameHandling + [Test] + public void PropertyItemTypeNameHandlingNestedCollections() { - Data = new List + PropertyItemTypeNameHandling c1 = new PropertyItemTypeNameHandling { - new TestComponentSimple {MyProperty = 1}, - new List + Data = new List { - new List + new TestComponentSimple { MyProperty = 1 }, + new List { - new List() + new List + { + new List() + } } } - } - }; + }; - string json = JsonConvert.SerializeObject(c1, Formatting.Indented); - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(c1, Formatting.Indented); + Assert.AreEqual(@"{ ""Data"": [ { ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"", @@ -1275,15 +1275,15 @@ namespace Newtonsoft.Json.Tests.Serialization ] }", json); - PropertyItemTypeNameHandling c2 = JsonConvert.DeserializeObject(json); - Assert.AreEqual(2, c2.Data.Count); + PropertyItemTypeNameHandling c2 = JsonConvert.DeserializeObject(json); + Assert.AreEqual(2, c2.Data.Count); - CustomAssert.IsInstanceOfType(typeof (TestComponentSimple), c2.Data[0]); - CustomAssert.IsInstanceOfType(typeof (List), c2.Data[1]); - List c = (List) c2.Data[1]; - CustomAssert.IsInstanceOfType(typeof (JArray), c[0]); + CustomAssert.IsInstanceOfType(typeof(TestComponentSimple), c2.Data[0]); + CustomAssert.IsInstanceOfType(typeof(List), c2.Data[1]); + List c = (List)c2.Data[1]; + CustomAssert.IsInstanceOfType(typeof(JArray), c[0]); - json = @"{ + json = @"{ ""Data"": [ { ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"", @@ -1301,43 +1301,43 @@ namespace Newtonsoft.Json.Tests.Serialization ] }"; - c2 = JsonConvert.DeserializeObject(json); - Assert.AreEqual(2, c2.Data.Count); + c2 = JsonConvert.DeserializeObject(json); + Assert.AreEqual(2, c2.Data.Count); - CustomAssert.IsInstanceOfType(typeof (TestComponentSimple), c2.Data[0]); - CustomAssert.IsInstanceOfType(typeof (List), c2.Data[1]); - c = (List) c2.Data[1]; - CustomAssert.IsInstanceOfType(typeof (JObject), c[0]); - JObject o = (JObject) c[0]; - Assert.AreEqual(1, (int) o["MyProperty"]); - } + CustomAssert.IsInstanceOfType(typeof(TestComponentSimple), c2.Data[0]); + CustomAssert.IsInstanceOfType(typeof(List), c2.Data[1]); + c = (List)c2.Data[1]; + CustomAssert.IsInstanceOfType(typeof(JObject), c[0]); + JObject o = (JObject)c[0]; + Assert.AreEqual(1, (int)o["MyProperty"]); + } - [Test] - public void PropertyItemTypeNameHandlingNestedDictionaries() - { - PropertyItemTypeNameHandlingDictionary c1 = new PropertyItemTypeNameHandlingDictionary() + [Test] + public void PropertyItemTypeNameHandlingNestedDictionaries() { - Data = new Dictionary + PropertyItemTypeNameHandlingDictionary c1 = new PropertyItemTypeNameHandlingDictionary() { - { - "one", new TestComponentSimple {MyProperty = 1} - }, - { - "two", new Dictionary - { + Data = new Dictionary + { { - "one", new Dictionary - { - {"one", 1} - } + "one", new TestComponentSimple { MyProperty = 1 } + }, + { + "two", new Dictionary + { + { + "one", new Dictionary + { + { "one", 1 } + } + } + } } - } - } - } - }; + } + }; - string json = JsonConvert.SerializeObject(c1, Formatting.Indented); - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(c1, Formatting.Indented); + Assert.AreEqual(@"{ ""Data"": { ""one"": { ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"", @@ -1352,15 +1352,15 @@ namespace Newtonsoft.Json.Tests.Serialization } }", json); - PropertyItemTypeNameHandlingDictionary c2 = JsonConvert.DeserializeObject(json); - Assert.AreEqual(2, c2.Data.Count); + PropertyItemTypeNameHandlingDictionary c2 = JsonConvert.DeserializeObject(json); + Assert.AreEqual(2, c2.Data.Count); - CustomAssert.IsInstanceOfType(typeof (TestComponentSimple), c2.Data["one"]); - CustomAssert.IsInstanceOfType(typeof(Dictionary), c2.Data["two"]); - Dictionary c = (Dictionary)c2.Data["two"]; - CustomAssert.IsInstanceOfType(typeof (JObject), c["one"]); + CustomAssert.IsInstanceOfType(typeof(TestComponentSimple), c2.Data["one"]); + CustomAssert.IsInstanceOfType(typeof(Dictionary), c2.Data["two"]); + Dictionary c = (Dictionary)c2.Data["two"]; + CustomAssert.IsInstanceOfType(typeof(JObject), c["one"]); - json = @"{ + json = @"{ ""Data"": { ""one"": { ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"", @@ -1376,43 +1376,43 @@ namespace Newtonsoft.Json.Tests.Serialization } }"; - c2 = JsonConvert.DeserializeObject(json); - Assert.AreEqual(2, c2.Data.Count); + c2 = JsonConvert.DeserializeObject(json); + Assert.AreEqual(2, c2.Data.Count); - CustomAssert.IsInstanceOfType(typeof(TestComponentSimple), c2.Data["one"]); - CustomAssert.IsInstanceOfType(typeof(Dictionary), c2.Data["two"]); - c = (Dictionary)c2.Data["two"]; - CustomAssert.IsInstanceOfType(typeof(JObject), c["one"]); + CustomAssert.IsInstanceOfType(typeof(TestComponentSimple), c2.Data["one"]); + CustomAssert.IsInstanceOfType(typeof(Dictionary), c2.Data["two"]); + c = (Dictionary)c2.Data["two"]; + CustomAssert.IsInstanceOfType(typeof(JObject), c["one"]); - JObject o = (JObject) c["one"]; - Assert.AreEqual(1, (int) o["MyProperty"]); - } + JObject o = (JObject)c["one"]; + Assert.AreEqual(1, (int)o["MyProperty"]); + } - [Test] - public void PropertyItemTypeNameHandlingObject() - { - PropertyItemTypeNameHandlingObject o1 = new PropertyItemTypeNameHandlingObject + [Test] + public void PropertyItemTypeNameHandlingObject() { - Data = new TypeNameHandlingTestObject + PropertyItemTypeNameHandlingObject o1 = new PropertyItemTypeNameHandlingObject { - Prop1 = new List + Data = new TypeNameHandlingTestObject { - new TestComponentSimple + Prop1 = new List { - MyProperty = 1 - } - }, - Prop2 = new TestComponentSimple - { - MyProperty = 1 - }, - Prop3 = 3, - Prop4 = new JObject() - } - }; + new TestComponentSimple + { + MyProperty = 1 + } + }, + Prop2 = new TestComponentSimple + { + MyProperty = 1 + }, + Prop3 = 3, + Prop4 = new JObject() + } + }; - string json = JsonConvert.SerializeObject(o1, Formatting.Indented); - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(o1, Formatting.Indented); + Assert.AreEqual(@"{ ""Data"": { ""Prop1"": { ""$type"": ""System.Collections.Generic.List`1[[System.Object, mscorlib]], mscorlib"", @@ -1431,44 +1431,44 @@ namespace Newtonsoft.Json.Tests.Serialization } }", json); - PropertyItemTypeNameHandlingObject o2 = JsonConvert.DeserializeObject(json); - Assert.IsNotNull(o2); - Assert.IsNotNull(o2.Data); + PropertyItemTypeNameHandlingObject o2 = JsonConvert.DeserializeObject(json); + Assert.IsNotNull(o2); + Assert.IsNotNull(o2.Data); - CustomAssert.IsInstanceOfType(typeof(List), o2.Data.Prop1); - CustomAssert.IsInstanceOfType(typeof(TestComponentSimple), o2.Data.Prop2); - CustomAssert.IsInstanceOfType(typeof(long), o2.Data.Prop3); - CustomAssert.IsInstanceOfType(typeof(JObject), o2.Data.Prop4); + CustomAssert.IsInstanceOfType(typeof(List), o2.Data.Prop1); + CustomAssert.IsInstanceOfType(typeof(TestComponentSimple), o2.Data.Prop2); + CustomAssert.IsInstanceOfType(typeof(long), o2.Data.Prop3); + CustomAssert.IsInstanceOfType(typeof(JObject), o2.Data.Prop4); - List o = (List)o2.Data.Prop1; - JObject j = (JObject)o[0]; - Assert.AreEqual(1, (int)j["MyProperty"]); - } + List o = (List)o2.Data.Prop1; + JObject j = (JObject)o[0]; + Assert.AreEqual(1, (int)j["MyProperty"]); + } #if !(NET35 || NET20 || PORTABLE40) - [Test] - public void PropertyItemTypeNameHandlingDynamic() - { - PropertyItemTypeNameHandlingDynamic d1 = new PropertyItemTypeNameHandlingDynamic(); - - dynamic data = new DynamicDictionary(); - data.one = new TestComponentSimple + [Test] + public void PropertyItemTypeNameHandlingDynamic() { - MyProperty = 1 - }; + PropertyItemTypeNameHandlingDynamic d1 = new PropertyItemTypeNameHandlingDynamic(); - dynamic data2 = new DynamicDictionary(); - data2.one = new TestComponentSimple - { - MyProperty = 2 - }; + dynamic data = new DynamicDictionary(); + data.one = new TestComponentSimple + { + MyProperty = 1 + }; - data.two = data2; + dynamic data2 = new DynamicDictionary(); + data2.one = new TestComponentSimple + { + MyProperty = 2 + }; - d1.Data = (DynamicDictionary)data; + data.two = data2; - string json = JsonConvert.SerializeObject(d1, Formatting.Indented); - Assert.AreEqual(@"{ + d1.Data = (DynamicDictionary)data; + + string json = JsonConvert.SerializeObject(d1, Formatting.Indented); + Assert.AreEqual(@"{ ""Data"": { ""one"": { ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"", @@ -1483,19 +1483,19 @@ namespace Newtonsoft.Json.Tests.Serialization } }", json); - PropertyItemTypeNameHandlingDynamic d2 = JsonConvert.DeserializeObject(json); - Assert.IsNotNull(d2); - Assert.IsNotNull(d2.Data); + PropertyItemTypeNameHandlingDynamic d2 = JsonConvert.DeserializeObject(json); + Assert.IsNotNull(d2); + Assert.IsNotNull(d2.Data); - dynamic data3 = d2.Data; - TestComponentSimple c = (TestComponentSimple)data3.one; - Assert.AreEqual(1, c.MyProperty); + dynamic data3 = d2.Data; + TestComponentSimple c = (TestComponentSimple)data3.one; + Assert.AreEqual(1, c.MyProperty); - dynamic data4 = data3.two; - JObject o = (JObject)data4.one; - Assert.AreEqual(2, (int)o["MyProperty"]); + dynamic data4 = data3.two; + JObject o = (JObject)data4.one; + Assert.AreEqual(2, (int)o["MyProperty"]); - json = @"{ + json = @"{ ""Data"": { ""one"": { ""$type"": ""Newtonsoft.Json.Tests.Serialization.TestComponentSimple, Newtonsoft.Json.Tests"", @@ -1511,95 +1511,95 @@ namespace Newtonsoft.Json.Tests.Serialization } }"; - d2 = JsonConvert.DeserializeObject(json); - data3 = d2.Data; - data4 = data3.two; - o = (JObject)data4.one; - Assert.AreEqual(2, (int)o["MyProperty"]); - } + d2 = JsonConvert.DeserializeObject(json); + data3 = d2.Data; + data4 = data3.two; + o = (JObject)data4.one; + Assert.AreEqual(2, (int)o["MyProperty"]); + } #endif #if !NETFX_CORE - [Test] - public void SerializeDeserialize_DictionaryContextContainsGuid_DeserializesItemAsGuid() - { - const string contextKey = "k1"; - var someValue = Guid.NewGuid(); - - Dictionary inputContext = new Dictionary(); - inputContext.Add(contextKey, someValue); - - JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings() + [Test] + public void SerializeDeserialize_DictionaryContextContainsGuid_DeserializesItemAsGuid() { - Formatting = Formatting.Indented, - TypeNameHandling = TypeNameHandling.All - }; - string serializedString = JsonConvert.SerializeObject(inputContext, jsonSerializerSettings); + const string contextKey = "k1"; + var someValue = Guid.NewGuid(); - var deserializedObject = (Dictionary)JsonConvert.DeserializeObject(serializedString, jsonSerializerSettings); + Dictionary inputContext = new Dictionary(); + inputContext.Add(contextKey, someValue); - Assert.AreEqual(someValue, deserializedObject[contextKey]); - } + JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings() + { + Formatting = Formatting.Indented, + TypeNameHandling = TypeNameHandling.All + }; + string serializedString = JsonConvert.SerializeObject(inputContext, jsonSerializerSettings); - [Test] - public void TypeNameHandlingWithISerializableValues() - { - MyParent p = new MyParent - { - Child = new MyChild - { - MyProperty = "string!" + var deserializedObject = (Dictionary)JsonConvert.DeserializeObject(serializedString, jsonSerializerSettings); + + Assert.AreEqual(someValue, deserializedObject[contextKey]); } - }; - JsonSerializerSettings settings = new JsonSerializerSettings - { - TypeNameHandling = TypeNameHandling.Auto, - DateFormatHandling = DateFormatHandling.IsoDateFormat, - MissingMemberHandling = MissingMemberHandling.Ignore, - DefaultValueHandling = DefaultValueHandling.Ignore, - NullValueHandling = NullValueHandling.Ignore, - Formatting = Formatting.Indented - }; + [Test] + public void TypeNameHandlingWithISerializableValues() + { + MyParent p = new MyParent + { + Child = new MyChild + { + MyProperty = "string!" + } + }; - string json = JsonConvert.SerializeObject(p, settings); + JsonSerializerSettings settings = new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Auto, + DateFormatHandling = DateFormatHandling.IsoDateFormat, + MissingMemberHandling = MissingMemberHandling.Ignore, + DefaultValueHandling = DefaultValueHandling.Ignore, + NullValueHandling = NullValueHandling.Ignore, + Formatting = Formatting.Indented + }; - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(p, settings); + + Assert.AreEqual(@"{ ""c"": { ""$type"": ""Newtonsoft.Json.Tests.Serialization.MyChild, Newtonsoft.Json.Tests"", ""p"": ""string!"" } }", json); - MyParent p2 = JsonConvert.DeserializeObject(json, settings); - CustomAssert.IsInstanceOfType(typeof(MyChild), p2.Child); - Assert.AreEqual("string!", ((MyChild)p2.Child).MyProperty); - } - - [Test] - public void TypeNameHandlingWithISerializableValuesAndArray() - { - MyParent p = new MyParent - { - Child = new MyChildList - { - "string!" + MyParent p2 = JsonConvert.DeserializeObject(json, settings); + CustomAssert.IsInstanceOfType(typeof(MyChild), p2.Child); + Assert.AreEqual("string!", ((MyChild)p2.Child).MyProperty); } - }; - JsonSerializerSettings settings = new JsonSerializerSettings - { - TypeNameHandling = TypeNameHandling.Auto, - DateFormatHandling = DateFormatHandling.IsoDateFormat, - MissingMemberHandling = MissingMemberHandling.Ignore, - DefaultValueHandling = DefaultValueHandling.Ignore, - NullValueHandling = NullValueHandling.Ignore, - Formatting = Formatting.Indented - }; + [Test] + public void TypeNameHandlingWithISerializableValuesAndArray() + { + MyParent p = new MyParent + { + Child = new MyChildList + { + "string!" + } + }; - string json = JsonConvert.SerializeObject(p, settings); + JsonSerializerSettings settings = new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Auto, + DateFormatHandling = DateFormatHandling.IsoDateFormat, + MissingMemberHandling = MissingMemberHandling.Ignore, + DefaultValueHandling = DefaultValueHandling.Ignore, + NullValueHandling = NullValueHandling.Ignore, + Formatting = Formatting.Indented + }; - Assert.AreEqual(@"{ + string json = JsonConvert.SerializeObject(p, settings); + + Assert.AreEqual(@"{ ""c"": { ""$type"": ""Newtonsoft.Json.Tests.Serialization.MyChildList, Newtonsoft.Json.Tests"", ""$values"": [ @@ -1608,37 +1608,37 @@ namespace Newtonsoft.Json.Tests.Serialization } }", json); - MyParent p2 = JsonConvert.DeserializeObject(json, settings); - CustomAssert.IsInstanceOfType(typeof(MyChildList), p2.Child); - Assert.AreEqual(1, ((MyChildList)p2.Child).Count); - Assert.AreEqual("string!", ((MyChildList)p2.Child)[0]); - } - - [Test] - public void ParentTypeNameHandlingWithISerializableValues() - { - ParentParent pp = new ParentParent(); - - pp.ParentProp = new MyParent - { - Child = new MyChild - { - MyProperty = "string!" + MyParent p2 = JsonConvert.DeserializeObject(json, settings); + CustomAssert.IsInstanceOfType(typeof(MyChildList), p2.Child); + Assert.AreEqual(1, ((MyChildList)p2.Child).Count); + Assert.AreEqual("string!", ((MyChildList)p2.Child)[0]); } - }; - JsonSerializerSettings settings = new JsonSerializerSettings - { - DateFormatHandling = DateFormatHandling.IsoDateFormat, - MissingMemberHandling = MissingMemberHandling.Ignore, - DefaultValueHandling = DefaultValueHandling.Ignore, - NullValueHandling = NullValueHandling.Ignore, - Formatting = Formatting.Indented - }; + [Test] + public void ParentTypeNameHandlingWithISerializableValues() + { + ParentParent pp = new ParentParent(); - string json = JsonConvert.SerializeObject(pp, settings); + pp.ParentProp = new MyParent + { + Child = new MyChild + { + MyProperty = "string!" + } + }; - Assert.AreEqual(@"{ + JsonSerializerSettings settings = new JsonSerializerSettings + { + DateFormatHandling = DateFormatHandling.IsoDateFormat, + MissingMemberHandling = MissingMemberHandling.Ignore, + DefaultValueHandling = DefaultValueHandling.Ignore, + NullValueHandling = NullValueHandling.Ignore, + Formatting = Formatting.Indented + }; + + string json = JsonConvert.SerializeObject(pp, settings); + + Assert.AreEqual(@"{ ""ParentProp"": { ""c"": { ""$type"": ""Newtonsoft.Json.Tests.Serialization.MyChild, Newtonsoft.Json.Tests"", @@ -1647,213 +1647,213 @@ namespace Newtonsoft.Json.Tests.Serialization } }", json); - ParentParent pp2 = JsonConvert.DeserializeObject(json, settings); - MyParent p2 = pp2.ParentProp; - CustomAssert.IsInstanceOfType(typeof(MyChild), p2.Child); - Assert.AreEqual("string!", ((MyChild)p2.Child).MyProperty); - } + ParentParent pp2 = JsonConvert.DeserializeObject(json, settings); + MyParent p2 = pp2.ParentProp; + CustomAssert.IsInstanceOfType(typeof(MyChild), p2.Child); + Assert.AreEqual("string!", ((MyChild)p2.Child).MyProperty); + } #endif - } + } #if !NETFX_CORE - public class ParentParent - { - [JsonProperty(ItemTypeNameHandling = TypeNameHandling.Auto)] - public MyParent ParentProp { get; set; } - } - - [Serializable] - public class MyParent : ISerializable - { - public ISomeBase Child { get; internal set; } - - public MyParent(SerializationInfo info, StreamingContext context) + public class ParentParent { - Child = (ISomeBase)info.GetValue("c", typeof(ISomeBase)); + [JsonProperty(ItemTypeNameHandling = TypeNameHandling.Auto)] + public MyParent ParentProp { get; set; } } - public MyParent() + [Serializable] + public class MyParent : ISerializable + { + public ISomeBase Child { get; internal set; } + + public MyParent(SerializationInfo info, StreamingContext context) + { + Child = (ISomeBase)info.GetValue("c", typeof(ISomeBase)); + } + + public MyParent() + { + } + + void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("c", Child); + } + } + + public class MyChild : ISomeBase + { + [JsonProperty("p")] + public String MyProperty { get; internal set; } + } + + public class MyChildList : List, ISomeBase { } - void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) + public interface ISomeBase { - info.AddValue("c", Child); } - } - - public class MyChild : ISomeBase - { - [JsonProperty("p")] - public String MyProperty { get; internal set; } - } - - public class MyChildList : List, ISomeBase - { - } - - public interface ISomeBase - { - } #endif - public class Message - { - public string Address { get; set; } + public class Message + { + public string Address { get; set; } - [JsonProperty(TypeNameHandling = TypeNameHandling.All)] - public object Body { get; set; } - } + [JsonProperty(TypeNameHandling = TypeNameHandling.All)] + public object Body { get; set; } + } - public class SearchDetails - { - public string Query { get; set; } - public string Language { get; set; } - } + public class SearchDetails + { + public string Query { get; set; } + public string Language { get; set; } + } - public class Customer - { - public string Name { get; set; } - } + public class Customer + { + public string Name { get; set; } + } - public class Purchase - { - public string ProductName { get; set; } - public decimal Price { get; set; } - public int Quantity { get; set; } - } + public class Purchase + { + public string ProductName { get; set; } + public decimal Price { get; set; } + public int Quantity { get; set; } + } #if !(WINDOWS_PHONE || SILVERLIGHT || NETFX_CORE) - public class SerializableWrapper - { - public object Content { get; set; } - - public override bool Equals(object obj) + public class SerializableWrapper { - SerializableWrapper w = obj as SerializableWrapper; + public object Content { get; set; } - if (w == null) - return false; + public override bool Equals(object obj) + { + SerializableWrapper w = obj as SerializableWrapper; - return Equals(w.Content, Content); + if (w == null) + return false; + + return Equals(w.Content, Content); + } + + public override int GetHashCode() + { + if (Content == null) + return 0; + + return Content.GetHashCode(); + } } - public override int GetHashCode() + public interface IExample + : ISerializable { - if (Content == null) - return 0; - - return Content.GetHashCode(); - } - } - - public interface IExample - : ISerializable - { - String Name - { - get; - } - } - - [Serializable] - public class Example - : IExample - { - public Example(String name) - { - this.Name = name; + String Name { get; } } - protected Example(SerializationInfo info, StreamingContext context) + [Serializable] + public class Example + : IExample { - this.Name = info.GetString("name"); + public Example(String name) + { + Name = name; + } + + protected Example(SerializationInfo info, StreamingContext context) + { + Name = info.GetString("name"); + } + + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("name", Name); + } + + public String Name { get; set; } + + public override bool Equals(object obj) + { + if (obj == null) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj is IExample) + { + return Name.Equals(((IExample)obj).Name); + } + else + { + return false; + } + } + + public override int GetHashCode() + { + if (Name == null) + return 0; + + return Name.GetHashCode(); + } } - - public void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue("name", this.Name); - } - - public String Name { get; set; } - - public override bool Equals(object obj) - { - if (obj == null) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj is IExample) - { - return this.Name.Equals(((IExample)obj).Name); - } - else - { - return false; - } - } - - public override int GetHashCode() - { - if (Name == null) - return 0; - - return Name.GetHashCode(); - } - } #endif - public class PropertyItemTypeNameHandlingObject - { - [JsonProperty(ItemTypeNameHandling = TypeNameHandling.All)] - public TypeNameHandlingTestObject Data { get; set; } - } + public class PropertyItemTypeNameHandlingObject + { + [JsonProperty(ItemTypeNameHandling = TypeNameHandling.All)] + public TypeNameHandlingTestObject Data { get; set; } + } #if !(NET35 || NET20 || PORTABLE40) - public class PropertyItemTypeNameHandlingDynamic - { - [JsonProperty(ItemTypeNameHandling = TypeNameHandling.All)] - public DynamicDictionary Data { get; set; } - } + public class PropertyItemTypeNameHandlingDynamic + { + [JsonProperty(ItemTypeNameHandling = TypeNameHandling.All)] + public DynamicDictionary Data { get; set; } + } #endif - public class TypeNameHandlingTestObject - { - public object Prop1 { get; set; } - public object Prop2 { get; set; } - public object Prop3 { get; set; } - public object Prop4 { get; set; } - } + public class TypeNameHandlingTestObject + { + public object Prop1 { get; set; } + public object Prop2 { get; set; } + public object Prop3 { get; set; } + public object Prop4 { get; set; } + } - public class PropertyItemTypeNameHandlingDictionary - { - [JsonProperty(ItemTypeNameHandling = TypeNameHandling.All)] - public IDictionary Data { get; set; } - } + public class PropertyItemTypeNameHandlingDictionary + { + [JsonProperty(ItemTypeNameHandling = TypeNameHandling.All)] + public IDictionary Data { get; set; } + } - public class PropertyItemTypeNameHandling - { - [JsonProperty(ItemTypeNameHandling = TypeNameHandling.All)] - public IList Data { get; set; } - } + public class PropertyItemTypeNameHandling + { + [JsonProperty(ItemTypeNameHandling = TypeNameHandling.All)] + public IList Data { get; set; } + } - [JsonArray(ItemTypeNameHandling = TypeNameHandling.All)] - public class TypeNameList : List - { - } + [JsonArray(ItemTypeNameHandling = TypeNameHandling.All)] + public class TypeNameList : List + { + } - [JsonDictionary(ItemTypeNameHandling = TypeNameHandling.All)] - public class TypeNameDictionary : Dictionary - { - } + [JsonDictionary(ItemTypeNameHandling = TypeNameHandling.All)] + public class TypeNameDictionary : Dictionary + { + } - [JsonObject(ItemTypeNameHandling = TypeNameHandling.All)] - public class TypeNameObject - { - public object Object1 { get; set; } - public object Object2 { get; set; } - [JsonProperty(TypeNameHandling = TypeNameHandling.None)] - public object ObjectNotHandled { get; set; } - public string String { get; set; } - public int Integer { get; set; } - } + [JsonObject(ItemTypeNameHandling = TypeNameHandling.All)] + public class TypeNameObject + { + public object Object1 { get; set; } + public object Object2 { get; set; } + + [JsonProperty(TypeNameHandling = TypeNameHandling.None)] + public object ObjectNotHandled { get; set; } + + public string String { get; set; } + public int Integer { get; set; } + } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Serialization/WebApiIntegrationTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/WebApiIntegrationTests.cs index 936cd0db..b9d79457 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/WebApiIntegrationTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/WebApiIntegrationTests.cs @@ -44,120 +44,114 @@ using Newtonsoft.Json.Serialization; namespace Newtonsoft.Json.Tests.Serialization { - [TestFixture] - public class WebApiIntegrationTests : TestFixtureBase - { - [Test] - public void SerializeSerializableType() + [TestFixture] + public class WebApiIntegrationTests : TestFixtureBase { - SerializableType serializableType = new SerializableType("protected") + [Test] + public void SerializeSerializableType() { - publicField = "public", - protectedInternalField = "protected internal", - internalField = "internal", - PublicProperty = "private", - nonSerializedField = "Error" - }; + SerializableType serializableType = new SerializableType("protected") + { + publicField = "public", + protectedInternalField = "protected internal", + internalField = "internal", + PublicProperty = "private", + nonSerializedField = "Error" + }; #if !(SILVERLIGHT || NETFX_CORE || NET20 || PORTABLE || PORTABLE40) - MemoryStream ms = new MemoryStream(); - DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(typeof(SerializableType)); - dataContractJsonSerializer.WriteObject(ms, serializableType); + MemoryStream ms = new MemoryStream(); + DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(typeof(SerializableType)); + dataContractJsonSerializer.WriteObject(ms, serializableType); - string dtJson = Encoding.UTF8.GetString(ms.ToArray()); - string dtExpected = @"{""internalField"":""internal"",""privateField"":""private"",""protectedField"":""protected"",""protectedInternalField"":""protected internal"",""publicField"":""public""}"; + string dtJson = Encoding.UTF8.GetString(ms.ToArray()); + string dtExpected = @"{""internalField"":""internal"",""privateField"":""private"",""protectedField"":""protected"",""protectedInternalField"":""protected internal"",""publicField"":""public""}"; - Assert.AreEqual(dtExpected, dtJson); + Assert.AreEqual(dtExpected, dtJson); #endif - string expected = "{\"publicField\":\"public\",\"internalField\":\"internal\",\"protectedInternalField\":\"protected internal\",\"protectedField\":\"protected\",\"privateField\":\"private\"}"; - string json = JsonConvert.SerializeObject(serializableType, new JsonSerializerSettings + string expected = "{\"publicField\":\"public\",\"internalField\":\"internal\",\"protectedInternalField\":\"protected internal\",\"protectedField\":\"protected\",\"privateField\":\"private\"}"; + string json = JsonConvert.SerializeObject(serializableType, new JsonSerializerSettings + { + ContractResolver = new DefaultContractResolver + { +#if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) + IgnoreSerializableAttribute = false +#endif + } + }); + + Assert.AreEqual(expected, json); + } + +#if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) + [Test] + public void SerializeInheritedType() { - ContractResolver = new DefaultContractResolver - { -#if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - IgnoreSerializableAttribute = false + InheritedType serializableType = new InheritedType("protected") + { + publicField = "public", + protectedInternalField = "protected internal", + internalField = "internal", + PublicProperty = "private", + nonSerializedField = "Error", + inheritedTypeField = "inherited" + }; + + string json = JsonConvert.SerializeObject(serializableType); + + Assert.AreEqual(@"{""inheritedTypeField"":""inherited"",""publicField"":""public"",""PublicProperty"":""private""}", json); + } #endif - } - }); + } - Assert.AreEqual(expected, json); + public class InheritedType : SerializableType + { + public string inheritedTypeField; + + public InheritedType(string protectedFieldValue) : base(protectedFieldValue) + { + } } #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - [Test] - public void SerializeInheritedType() - { - InheritedType serializableType = new InheritedType("protected") - { - publicField = "public", - protectedInternalField = "protected internal", - internalField = "internal", - PublicProperty = "private", - nonSerializedField = "Error", - inheritedTypeField = "inherited" - }; - - string json = JsonConvert.SerializeObject(serializableType); - - Assert.AreEqual(@"{""inheritedTypeField"":""inherited"",""publicField"":""public"",""PublicProperty"":""private""}", json); - } -#endif - } - - public class InheritedType : SerializableType - { - public string inheritedTypeField; - - public InheritedType(string protectedFieldValue) : base(protectedFieldValue) - { - } - } - -#if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - [Serializable] + [Serializable] #else - [JsonObject(MemberSerialization.Fields)] + [JsonObject(MemberSerialization.Fields)] #endif - public class SerializableType : IEquatable - { - public SerializableType(string protectedFieldValue) + public class SerializableType : IEquatable { - this.protectedField = protectedFieldValue; - } + public SerializableType(string protectedFieldValue) + { + protectedField = protectedFieldValue; + } - public string publicField; - internal string internalField; - protected internal string protectedInternalField; - protected string protectedField; - private string privateField; + public string publicField; + internal string internalField; + protected internal string protectedInternalField; + protected string protectedField; + private string privateField; - public string PublicProperty - { - get - { - return privateField; - } - set - { - this.privateField = value; - } - } + public string PublicProperty + { + get { return privateField; } + set { privateField = value; } + } #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - [NonSerialized] + [NonSerialized] #else - [JsonIgnore] + [JsonIgnore] #endif - public string nonSerializedField; + public string nonSerializedField; - public bool Equals(SerializableType other) - { - return this.publicField == other.publicField && - this.internalField == other.internalField && - this.protectedInternalField == other.protectedInternalField && - this.protectedField == other.protectedField && - this.privateField == other.privateField; + public bool Equals(SerializableType other) + { + return publicField == other.publicField && + internalField == other.internalField && + protectedInternalField == other.protectedInternalField && + protectedField == other.protectedField && + privateField == other.privateField; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/SilverlightTests.cs b/Src/Newtonsoft.Json.Tests/SilverlightTests.cs index c7a4b7d0..6d0c5238 100644 --- a/Src/Newtonsoft.Json.Tests/SilverlightTests.cs +++ b/Src/Newtonsoft.Json.Tests/SilverlightTests.cs @@ -27,6 +27,7 @@ using System; using System.Reflection; #if !NETFX_CORE using NUnit.Framework; + #else using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; @@ -35,7 +36,7 @@ using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAtt namespace Newtonsoft.Json.Tests { - // todo: need to fix this to get WP unit tests running off right dlls + // todo: need to fix this to get WP unit tests running off right dlls #if SILVERLIGHT [TestFixture] public class SilverlightTests diff --git a/Src/Newtonsoft.Json.Tests/TestFixtureBase.cs b/Src/Newtonsoft.Json.Tests/TestFixtureBase.cs index 20d0e356..391b8860 100644 --- a/Src/Newtonsoft.Json.Tests/TestFixtureBase.cs +++ b/Src/Newtonsoft.Json.Tests/TestFixtureBase.cs @@ -48,96 +48,97 @@ using System.Collections; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json.Tests { - [TestFixture] - public abstract class TestFixtureBase - { -#if !NET20 - protected string GetDataContractJsonSerializeResult(object o) + [TestFixture] + public abstract class TestFixtureBase { - MemoryStream ms = new MemoryStream(); - DataContractJsonSerializer s = new DataContractJsonSerializer(o.GetType()); - s.WriteObject(ms, o); +#if !NET20 + protected string GetDataContractJsonSerializeResult(object o) + { + MemoryStream ms = new MemoryStream(); + DataContractJsonSerializer s = new DataContractJsonSerializer(o.GetType()); + s.WriteObject(ms, o); - var data = ms.ToArray(); - return Encoding.UTF8.GetString(data, 0, data.Length); - } + var data = ms.ToArray(); + return Encoding.UTF8.GetString(data, 0, data.Length); + } #endif - protected string GetOffset(DateTime d, DateFormatHandling dateFormatHandling) - { - char[] chars = new char[8]; - int pos = DateTimeUtils.WriteDateTimeOffset(chars, 0, DateTime.SpecifyKind(d, DateTimeKind.Local).GetUtcOffset(), dateFormatHandling); + protected string GetOffset(DateTime d, DateFormatHandling dateFormatHandling) + { + char[] chars = new char[8]; + int pos = DateTimeUtils.WriteDateTimeOffset(chars, 0, DateTime.SpecifyKind(d, DateTimeKind.Local).GetUtcOffset(), dateFormatHandling); - return new string(chars, 0, pos); + return new string(chars, 0, pos); + } + + protected string BytesToHex(byte[] bytes) + { + return BytesToHex(bytes, false); + } + + protected string BytesToHex(byte[] bytes, bool removeDashes) + { + string hex = BitConverter.ToString(bytes); + if (removeDashes) + hex = hex.Replace("-", ""); + + return hex; + } + + protected byte[] HexToBytes(string hex) + { + string fixedHex = hex.Replace("-", string.Empty); + + // array to put the result in + byte[] bytes = new byte[fixedHex.Length / 2]; + // variable to determine shift of high/low nibble + int shift = 4; + // offset of the current byte in the array + int offset = 0; + // loop the characters in the string + foreach (char c in fixedHex) + { + // get character code in range 0-9, 17-22 + // the % 32 handles lower case characters + int b = (c - '0') % 32; + // correction for a-f + if (b > 9) b -= 7; + // store nibble (4 bits) in byte array + bytes[offset] |= (byte)(b << shift); + // toggle the shift variable between 0 and 4 + shift ^= 4; + // move to next byte + if (shift != 0) offset++; + } + return bytes; + } + + [SetUp] + protected void TestSetup() + { + //CultureInfo turkey = CultureInfo.CreateSpecificCulture("tr"); + //Thread.CurrentThread.CurrentCulture = turkey; + //Thread.CurrentThread.CurrentUICulture = turkey; + + JsonConvert.DefaultSettings = null; + } + + protected void WriteEscapedJson(string json) + { + Console.WriteLine(EscapeJson(json)); + } + + protected string EscapeJson(string json) + { + return @"@""" + json.Replace(@"""", @"""""") + @""""; + } } - protected string BytesToHex(byte[] bytes) - { - return BytesToHex(bytes, false); - } - - protected string BytesToHex(byte[] bytes, bool removeDashes) - { - string hex = BitConverter.ToString(bytes); - if (removeDashes) - hex = hex.Replace("-", ""); - - return hex; - } - - protected byte[] HexToBytes(string hex) - { - string fixedHex = hex.Replace("-", string.Empty); - - // array to put the result in - byte[] bytes = new byte[fixedHex.Length / 2]; - // variable to determine shift of high/low nibble - int shift = 4; - // offset of the current byte in the array - int offset = 0; - // loop the characters in the string - foreach (char c in fixedHex) - { - // get character code in range 0-9, 17-22 - // the % 32 handles lower case characters - int b = (c - '0') % 32; - // correction for a-f - if (b > 9) b -= 7; - // store nibble (4 bits) in byte array - bytes[offset] |= (byte)(b << shift); - // toggle the shift variable between 0 and 4 - shift ^= 4; - // move to next byte - if (shift != 0) offset++; - } - return bytes; - } - - [SetUp] - protected void TestSetup() - { - //CultureInfo turkey = CultureInfo.CreateSpecificCulture("tr"); - //Thread.CurrentThread.CurrentCulture = turkey; - //Thread.CurrentThread.CurrentUICulture = turkey; - - JsonConvert.DefaultSettings = null; - } - - protected void WriteEscapedJson(string json) - { - Console.WriteLine(EscapeJson(json)); - } - - protected string EscapeJson(string json) - { - return @"@""" + json.Replace(@"""", @"""""") + @""""; - } - } - #if NETFX_CORE public static class Console { @@ -147,51 +148,51 @@ namespace Newtonsoft.Json.Tests } #endif - public static class CustomAssert - { - public static void IsInstanceOfType(Type t, object instance) + public static class CustomAssert { + public static void IsInstanceOfType(Type t, object instance) + { #if (WINDOWS_PHONE || SILVERLIGHT) Assert.IsInstanceOfType(t, instance); #elif NETFX_CORE if (!instance.GetType().IsAssignableFrom(t)) throw new Exception("Not instance of type"); #else - Assert.IsInstanceOf(t, instance); + Assert.IsInstanceOf(t, instance); #endif - } + } - public static void Contains(IList collection, object value) - { + public static void Contains(IList collection, object value) + { #if !NETFX_CORE - Assert.Contains(value, collection); + Assert.Contains(value, collection); #else if (!collection.Cast().Any(i => i.Equals(value))) throw new Exception("Value not found in collection."); #endif + } } - } - public static class ExceptionAssert - { - public static void Throws(string message, Action action) - where TException : Exception + public static class ExceptionAssert { - try - { - action(); + public static void Throws(string message, Action action) + where TException : Exception + { + try + { + action(); - Assert.Fail("Exception of type {0} expected; got none exception", typeof(TException).Name); - } - catch (TException ex) - { - if (message != null) - Assert.AreEqual(message, ex.Message, "Unexpected exception message." + Environment.NewLine + "Expected: " + message + Environment.NewLine + "Got: " + ex.Message + Environment.NewLine + Environment.NewLine + ex); - } - catch (Exception ex) - { - throw new Exception(string.Format("Exception of type {0} expected; got exception of type {1}.", typeof(TException).Name, ex.GetType().Name), ex); - } + Assert.Fail("Exception of type {0} expected; got none exception", typeof(TException).Name); + } + catch (TException ex) + { + if (message != null) + Assert.AreEqual(message, ex.Message, "Unexpected exception message." + Environment.NewLine + "Expected: " + message + Environment.NewLine + "Got: " + ex.Message + Environment.NewLine + Environment.NewLine + ex); + } + catch (Exception ex) + { + throw new Exception(string.Format("Exception of type {0} expected; got exception of type {1}.", typeof(TException).Name, ex.GetType().Name), ex); + } + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/AbstractGenericBase.cs b/Src/Newtonsoft.Json.Tests/TestObjects/AbstractGenericBase.cs index 942f6840..a04ae3da 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/AbstractGenericBase.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/AbstractGenericBase.cs @@ -25,8 +25,8 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public abstract class AbstractGenericBase - { - public abstract TKey Id { get; set; } - } + public abstract class AbstractGenericBase + { + public abstract TKey Id { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/ArgumentConverterPrecedenceClassConverter.cs b/Src/Newtonsoft.Json.Tests/TestObjects/ArgumentConverterPrecedenceClassConverter.cs index 9c29d1a8..419ea981 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/ArgumentConverterPrecedenceClassConverter.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/ArgumentConverterPrecedenceClassConverter.cs @@ -25,11 +25,11 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class ArgumentConverterPrecedenceClassConverter : ConverterPrecedenceClassConverter - { - public override string ConverterType + public class ArgumentConverterPrecedenceClassConverter : ConverterPrecedenceClassConverter { - get { return "Argument"; } + public override string ConverterType + { + get { return "Argument"; } + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/Article.cs b/Src/Newtonsoft.Json.Tests/TestObjects/Article.cs index dfde60c0..a904e5ee 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/Article.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/Article.cs @@ -25,17 +25,17 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class Article - { - public string Name; - - public Article() + public class Article { - } + public string Name; - public Article(string name) - { - Name = name; + public Article() + { + } + + public Article(string name) + { + Name = name; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/ArticleCollection.cs b/Src/Newtonsoft.Json.Tests/TestObjects/ArticleCollection.cs index e7f4ae14..248d9222 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/ArticleCollection.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/ArticleCollection.cs @@ -27,7 +27,7 @@ using System.Collections.Generic; namespace Newtonsoft.Json.Tests.TestObjects { - public class ArticleCollection : List
- { - } + public class ArticleCollection : List
+ { + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/BadJsonPropertyClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/BadJsonPropertyClass.cs index 18d0a03b..37879c2c 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/BadJsonPropertyClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/BadJsonPropertyClass.cs @@ -25,11 +25,11 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class BadJsonPropertyClass - { - [JsonProperty("pie")] - public string Pie = "Yum"; + public class BadJsonPropertyClass + { + [JsonProperty("pie")] + public string Pie = "Yum"; - public string pie = "PieChart!"; - } + public string pie = "PieChart!"; + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/Bar.cs b/Src/Newtonsoft.Json.Tests/TestObjects/Bar.cs index d70adc65..8a25dc81 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/Bar.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/Bar.cs @@ -25,8 +25,8 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class Bar - { - public int Id { get; set; } - } + public class Bar + { + public int Id { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/Car.cs b/Src/Newtonsoft.Json.Tests/TestObjects/Car.cs index 643dd7f3..8650b1c5 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/Car.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/Car.cs @@ -28,15 +28,15 @@ using System.Collections.Generic; namespace Newtonsoft.Json.Tests.TestObjects { - public class Car - { - // included in JSON - public string Model { get; set; } - public DateTime Year { get; set; } - public List Features { get; set; } + public class Car + { + // included in JSON + public string Model { get; set; } + public DateTime Year { get; set; } + public List Features { get; set; } - // ignored - [JsonIgnore] - public DateTime LastModified { get; set; } - } -} + // ignored + [JsonIgnore] + public DateTime LastModified { get; set; } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/CircularReferenceClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/CircularReferenceClass.cs index 49e831b1..5a47301c 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/CircularReferenceClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/CircularReferenceClass.cs @@ -25,11 +25,12 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class CircularReferenceClass - { - [JsonProperty(Required = Required.Always)] - public string Name { get; set; } - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] - public CircularReferenceClass Child { get; set; } - } + public class CircularReferenceClass + { + [JsonProperty(Required = Required.Always)] + public string Name { get; set; } + + [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] + public CircularReferenceClass Child { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/CircularReferenceWithIdClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/CircularReferenceWithIdClass.cs index 4c06a2ea..3afa72d7 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/CircularReferenceWithIdClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/CircularReferenceWithIdClass.cs @@ -25,11 +25,12 @@ namespace Newtonsoft.Json.Tests.TestObjects { - [JsonObject(Id = "MyExplicitId")] - public class CircularReferenceWithIdClass - { - [JsonProperty(Required = Required.AllowNull)] - public string Name { get; set; } - public CircularReferenceWithIdClass Child { get; set; } - } -} + [JsonObject(Id = "MyExplicitId")] + public class CircularReferenceWithIdClass + { + [JsonProperty(Required = Required.AllowNull)] + public string Name { get; set; } + + public CircularReferenceWithIdClass Child { get; set; } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/ClassAndMemberConverterClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/ClassAndMemberConverterClass.cs index 98bd253a..e01affc1 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/ClassAndMemberConverterClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/ClassAndMemberConverterClass.cs @@ -25,10 +25,11 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class ClassAndMemberConverterClass - { - public ConverterPrecedenceClass DefaultConverter { get; set; } - [JsonConverter(typeof(MemberConverterPrecedenceClassConverter))] - public ConverterPrecedenceClass MemberConverter { get; set; } - } + public class ClassAndMemberConverterClass + { + public ConverterPrecedenceClass DefaultConverter { get; set; } + + [JsonConverter(typeof(MemberConverterPrecedenceClassConverter))] + public ConverterPrecedenceClass MemberConverter { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/ClassConverterPrecedenceClassConverter.cs b/Src/Newtonsoft.Json.Tests/TestObjects/ClassConverterPrecedenceClassConverter.cs index 892fe29f..f48e1037 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/ClassConverterPrecedenceClassConverter.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/ClassConverterPrecedenceClassConverter.cs @@ -25,11 +25,11 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class ClassConverterPrecedenceClassConverter : ConverterPrecedenceClassConverter - { - public override string ConverterType + public class ClassConverterPrecedenceClassConverter : ConverterPrecedenceClassConverter { - get { return "Class"; } + public override string ConverterType + { + get { return "Class"; } + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/ClassWithArray.cs b/Src/Newtonsoft.Json.Tests/TestObjects/ClassWithArray.cs index 74c042ee..79201436 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/ClassWithArray.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/ClassWithArray.cs @@ -28,27 +28,27 @@ using System.Collections.Generic; namespace Newtonsoft.Json.Tests.TestObjects { - public class ClassWithArray - { - private readonly IList bar; - private string foo; - - public ClassWithArray() + public class ClassWithArray { - bar = new List() { int.MaxValue }; - } + private readonly IList bar; + private string foo; - [JsonProperty("foo")] - public string Foo - { - get { return foo; } - set { foo = value; } - } + public ClassWithArray() + { + bar = new List() { int.MaxValue }; + } - [JsonProperty(PropertyName = "bar")] - public IList Bar - { - get { return bar; } + [JsonProperty("foo")] + public string Foo + { + get { return foo; } + set { foo = value; } + } + + [JsonProperty(PropertyName = "bar")] + public IList Bar + { + get { return bar; } + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/ClassWithGuid.cs b/Src/Newtonsoft.Json.Tests/TestObjects/ClassWithGuid.cs index 82e345ac..fee54c7f 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/ClassWithGuid.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/ClassWithGuid.cs @@ -27,8 +27,8 @@ using System; namespace Newtonsoft.Json.Tests.TestObjects { - public class ClassWithGuid - { - public Guid GuidField; - } + public class ClassWithGuid + { + public Guid GuidField; + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/Computer.cs b/Src/Newtonsoft.Json.Tests/TestObjects/Computer.cs index 26745e65..5820f932 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/Computer.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/Computer.cs @@ -27,22 +27,25 @@ using System; using System.Runtime.Serialization; #if !NET20 + namespace Newtonsoft.Json.Tests.TestObjects { - [DataContract] - public class Computer - { - // included in JSON - [DataMember] - public string Name { get; set; } - [DataMember] - public decimal SalePrice { get; set; } + [DataContract] + public class Computer + { + // included in JSON + [DataMember] + public string Name { get; set; } - // ignored - public string Manufacture { get; set; } - public int StockCount { get; set; } - public decimal WholeSalePrice { get; set; } - public DateTime NextShipmentDate { get; set; } - } + [DataMember] + public decimal SalePrice { get; set; } + + // ignored + public string Manufacture { get; set; } + public int StockCount { get; set; } + public decimal WholeSalePrice { get; set; } + public DateTime NextShipmentDate { get; set; } + } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/ConstructorCaseSensitivityClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/ConstructorCaseSensitivityClass.cs index 17edf25d..e5b43a6c 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/ConstructorCaseSensitivityClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/ConstructorCaseSensitivityClass.cs @@ -25,17 +25,17 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class ConstructorCaseSensitivityClass - { - public string param1 { get; set; } - public string Param1 { get; set; } - public string Param2 { get; set; } - - public ConstructorCaseSensitivityClass(string param1, string Param1, string param2) + public class ConstructorCaseSensitivityClass { - this.param1 = param1; - this.Param1 = Param1; - this.Param2 = param2; + public string param1 { get; set; } + public string Param1 { get; set; } + public string Param2 { get; set; } + + public ConstructorCaseSensitivityClass(string param1, string Param1, string param2) + { + this.param1 = param1; + this.Param1 = Param1; + Param2 = param2; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/ConstructorReadonlyFields.cs b/Src/Newtonsoft.Json.Tests/TestObjects/ConstructorReadonlyFields.cs index 4bbaf35d..44cca55e 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/ConstructorReadonlyFields.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/ConstructorReadonlyFields.cs @@ -25,15 +25,15 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class ConstructorReadonlyFields - { - public readonly string A; - public readonly int B; - - public ConstructorReadonlyFields(string a, int b) + public class ConstructorReadonlyFields { - A = a; - B = b; + public readonly string A; + public readonly int B; + + public ConstructorReadonlyFields(string a, int b) + { + A = a; + B = b; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/Container.cs b/Src/Newtonsoft.Json.Tests/TestObjects/Container.cs index 2325036f..f6d4b9b1 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/Container.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/Container.cs @@ -27,9 +27,9 @@ using System.Collections.Generic; namespace Newtonsoft.Json.Tests.TestObjects { - public class Container - { - public IList In { get; set; } - public IList Out { get; set; } - } + public class Container + { + public IList In { get; set; } + public IList Out { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/Content.cs b/Src/Newtonsoft.Json.Tests/TestObjects/Content.cs index 6f8ae787..d1a871f3 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/Content.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/Content.cs @@ -28,22 +28,23 @@ using System.Collections.Generic; namespace Newtonsoft.Json.Tests.TestObjects { - [JsonObject(MemberSerialization = MemberSerialization.OptIn)] - public class Content : IEnumerable - { - [JsonProperty] - public List Children; - [JsonProperty] - public string Text; - - public IEnumerator GetEnumerator() + [JsonObject(MemberSerialization = MemberSerialization.OptIn)] + public class Content : IEnumerable { - return Children.GetEnumerator(); - } + [JsonProperty] + public List Children; - IEnumerator IEnumerable.GetEnumerator() - { - return Children.GetEnumerator(); + [JsonProperty] + public string Text; + + public IEnumerator GetEnumerator() + { + return Children.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return Children.GetEnumerator(); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/ContentBaseClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/ContentBaseClass.cs index 32b4e301..cb11d2d9 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/ContentBaseClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/ContentBaseClass.cs @@ -25,7 +25,7 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public abstract class ContentBaseClass - { - } + public abstract class ContentBaseClass + { + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/ContentSubClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/ContentSubClass.cs index 4519b95d..e48df1d5 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/ContentSubClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/ContentSubClass.cs @@ -25,14 +25,17 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class ContentSubClass : ContentBaseClass - { - public ContentSubClass() { } - public ContentSubClass(string EasyIn) + public class ContentSubClass : ContentBaseClass { - SomeString = EasyIn; - } + public ContentSubClass() + { + } - public string SomeString { get; set; } - } -} + public ContentSubClass(string EasyIn) + { + SomeString = EasyIn; + } + + public string SomeString { get; set; } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/ConverableMembers.cs b/Src/Newtonsoft.Json.Tests/TestObjects/ConverableMembers.cs index b1b002cd..4d6f54a8 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/ConverableMembers.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/ConverableMembers.cs @@ -27,24 +27,24 @@ using System; namespace Newtonsoft.Json.Tests.TestObjects { - [JsonObject] - public class ConverableMembers - { - public string String = "string"; - public int Int32 = int.MaxValue; - public uint UInt32 = uint.MaxValue; - public byte Byte = byte.MaxValue; - public sbyte SByte = sbyte.MaxValue; - public short Short = short.MaxValue; - public ushort UShort = ushort.MaxValue; - public long Long = long.MaxValue; - public ulong ULong = long.MaxValue; - public double Double = double.MaxValue; - public float Float = float.MaxValue; + [JsonObject] + public class ConverableMembers + { + public string String = "string"; + public int Int32 = int.MaxValue; + public uint UInt32 = uint.MaxValue; + public byte Byte = byte.MaxValue; + public sbyte SByte = sbyte.MaxValue; + public short Short = short.MaxValue; + public ushort UShort = ushort.MaxValue; + public long Long = long.MaxValue; + public ulong ULong = long.MaxValue; + public double Double = double.MaxValue; + public float Float = float.MaxValue; #if !(NETFX_CORE || PORTABLE) - public DBNull DBNull = DBNull.Value; + public DBNull DBNull = DBNull.Value; #endif - public bool Bool = true; - public char Char = '\0'; - } + public bool Bool = true; + public char Char = '\0'; + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/ConverterPrecedenceClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/ConverterPrecedenceClass.cs index 145427cc..89234f60 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/ConverterPrecedenceClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/ConverterPrecedenceClass.cs @@ -25,14 +25,14 @@ namespace Newtonsoft.Json.Tests.TestObjects { - [JsonConverter(typeof(ClassConverterPrecedenceClassConverter))] - public class ConverterPrecedenceClass - { - public string TestValue { get; set; } - - public ConverterPrecedenceClass(string testValue) + [JsonConverter(typeof(ClassConverterPrecedenceClassConverter))] + public class ConverterPrecedenceClass { - TestValue = testValue; + public string TestValue { get; set; } + + public ConverterPrecedenceClass(string testValue) + { + TestValue = testValue; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/ConverterPrecedenceClassConverter.cs b/Src/Newtonsoft.Json.Tests/TestObjects/ConverterPrecedenceClassConverter.cs index f605b22b..d7531a48 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/ConverterPrecedenceClassConverter.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/ConverterPrecedenceClassConverter.cs @@ -30,34 +30,34 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Tests.TestObjects { - public abstract class ConverterPrecedenceClassConverter : JsonConverter - { - public abstract string ConverterType { get; } - - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + public abstract class ConverterPrecedenceClassConverter : JsonConverter { - ConverterPrecedenceClass c = (ConverterPrecedenceClass)value; + public abstract string ConverterType { get; } - JToken j = new JArray(ConverterType, c.TestValue); + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + ConverterPrecedenceClass c = (ConverterPrecedenceClass)value; - j.WriteTo(writer); + JToken j = new JArray(ConverterType, c.TestValue); + + j.WriteTo(writer); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + JToken j = JArray.Load(reader); + + string converter = (string)j[0]; + if (converter != ConverterType) + throw new Exception(StringUtils.FormatWith("Serialize converter {0} and deserialize converter {1} do not match.", CultureInfo.InvariantCulture, converter, ConverterType)); + + string testValue = (string)j[1]; + return new ConverterPrecedenceClass(testValue); + } + + public override bool CanConvert(Type objectType) + { + return (objectType == typeof(ConverterPrecedenceClass)); + } } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - JToken j = JArray.Load(reader); - - string converter = (string)j[0]; - if (converter != ConverterType) - throw new Exception(StringUtils.FormatWith("Serialize converter {0} and deserialize converter {1} do not match.", CultureInfo.InvariantCulture, converter, ConverterType)); - - string testValue = (string)j[1]; - return new ConverterPrecedenceClass(testValue); - } - - public override bool CanConvert(Type objectType) - { - return (objectType == typeof(ConverterPrecedenceClass)); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/CustomerDataSet.cs b/Src/Newtonsoft.Json.Tests/TestObjects/CustomerDataSet.cs index 61a60b19..50eebf22 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/CustomerDataSet.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/CustomerDataSet.cs @@ -30,693 +30,659 @@ using System.Text; namespace Newtonsoft.Json.Tests.TestObjects { - /// - ///Represents a strongly typed in-memory cache of data. - /// - [global::System.Serializable()] - [global::System.ComponentModel.DesignerCategoryAttribute("code")] - [global::System.ComponentModel.ToolboxItem(true)] - [global::System.Xml.Serialization.XmlSchemaProviderAttribute("GetTypedDataSetSchema")] - [global::System.Xml.Serialization.XmlRootAttribute("CustomerDataSet")] - [global::System.ComponentModel.Design.HelpKeywordAttribute("vs.data.DataSet")] - public partial class CustomerDataSet : global::System.Data.DataSet - { - - private CustomersDataTable tableCustomers; - - private global::System.Data.SchemaSerializationMode _schemaSerializationMode = global::System.Data.SchemaSerializationMode.IncludeSchema; - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - public CustomerDataSet() - { - this.BeginInit(); - this.InitClass(); - global::System.ComponentModel.CollectionChangeEventHandler schemaChangedHandler = new global::System.ComponentModel.CollectionChangeEventHandler(this.SchemaChanged); - base.Tables.CollectionChanged += schemaChangedHandler; - base.Relations.CollectionChanged += schemaChangedHandler; - this.EndInit(); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - protected CustomerDataSet(global::System.Runtime.Serialization.SerializationInfo info, global::System.Runtime.Serialization.StreamingContext context) : - base(info, context, false) - { - if ((this.IsBinarySerialized(info, context) == true)) - { - this.InitVars(false); - global::System.ComponentModel.CollectionChangeEventHandler schemaChangedHandler1 = new global::System.ComponentModel.CollectionChangeEventHandler(this.SchemaChanged); - this.Tables.CollectionChanged += schemaChangedHandler1; - this.Relations.CollectionChanged += schemaChangedHandler1; - return; - } - string strSchema = ((string)(info.GetValue("XmlSchema", typeof(string)))); - if ((this.DetermineSchemaSerializationMode(info, context) == global::System.Data.SchemaSerializationMode.IncludeSchema)) - { - global::System.Data.DataSet ds = new global::System.Data.DataSet(); - ds.ReadXmlSchema(new global::System.Xml.XmlTextReader(new global::System.IO.StringReader(strSchema))); - if ((ds.Tables["Customers"] != null)) - { - base.Tables.Add(new CustomersDataTable(ds.Tables["Customers"])); - } - this.DataSetName = ds.DataSetName; - this.Prefix = ds.Prefix; - this.Namespace = ds.Namespace; - this.Locale = ds.Locale; - this.CaseSensitive = ds.CaseSensitive; - this.EnforceConstraints = ds.EnforceConstraints; - this.Merge(ds, false, global::System.Data.MissingSchemaAction.Add); - this.InitVars(); - } - else - { - this.ReadXmlSchema(new global::System.Xml.XmlTextReader(new global::System.IO.StringReader(strSchema))); - } - this.GetSerializationData(info, context); - global::System.ComponentModel.CollectionChangeEventHandler schemaChangedHandler = new global::System.ComponentModel.CollectionChangeEventHandler(this.SchemaChanged); - base.Tables.CollectionChanged += schemaChangedHandler; - this.Relations.CollectionChanged += schemaChangedHandler; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - [global::System.ComponentModel.Browsable(false)] - [global::System.ComponentModel.DesignerSerializationVisibility(global::System.ComponentModel.DesignerSerializationVisibility.Content)] - public CustomersDataTable Customers - { - get - { - return this.tableCustomers; - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - [global::System.ComponentModel.BrowsableAttribute(true)] - [global::System.ComponentModel.DesignerSerializationVisibilityAttribute(global::System.ComponentModel.DesignerSerializationVisibility.Visible)] - public override global::System.Data.SchemaSerializationMode SchemaSerializationMode - { - get - { - return this._schemaSerializationMode; - } - set - { - this._schemaSerializationMode = value; - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - [global::System.ComponentModel.DesignerSerializationVisibilityAttribute(global::System.ComponentModel.DesignerSerializationVisibility.Hidden)] - public new global::System.Data.DataTableCollection Tables - { - get - { - return base.Tables; - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - [global::System.ComponentModel.DesignerSerializationVisibilityAttribute(global::System.ComponentModel.DesignerSerializationVisibility.Hidden)] - public new global::System.Data.DataRelationCollection Relations - { - get - { - return base.Relations; - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - protected override void InitializeDerivedDataSet() - { - this.BeginInit(); - this.InitClass(); - this.EndInit(); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - public override global::System.Data.DataSet Clone() - { - CustomerDataSet cln = ((CustomerDataSet)(base.Clone())); - cln.InitVars(); - cln.SchemaSerializationMode = this.SchemaSerializationMode; - return cln; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - protected override bool ShouldSerializeTables() - { - return false; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - protected override bool ShouldSerializeRelations() - { - return false; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - protected override void ReadXmlSerializable(global::System.Xml.XmlReader reader) - { - if ((this.DetermineSchemaSerializationMode(reader) == global::System.Data.SchemaSerializationMode.IncludeSchema)) - { - this.Reset(); - global::System.Data.DataSet ds = new global::System.Data.DataSet(); - ds.ReadXml(reader); - if ((ds.Tables["Customers"] != null)) - { - base.Tables.Add(new CustomersDataTable(ds.Tables["Customers"])); - } - this.DataSetName = ds.DataSetName; - this.Prefix = ds.Prefix; - this.Namespace = ds.Namespace; - this.Locale = ds.Locale; - this.CaseSensitive = ds.CaseSensitive; - this.EnforceConstraints = ds.EnforceConstraints; - this.Merge(ds, false, global::System.Data.MissingSchemaAction.Add); - this.InitVars(); - } - else - { - this.ReadXml(reader); - this.InitVars(); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - protected override global::System.Xml.Schema.XmlSchema GetSchemaSerializable() - { - global::System.IO.MemoryStream stream = new global::System.IO.MemoryStream(); - this.WriteXmlSchema(new global::System.Xml.XmlTextWriter(stream, null)); - stream.Position = 0; - return global::System.Xml.Schema.XmlSchema.Read(new global::System.Xml.XmlTextReader(stream), null); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - internal void InitVars() - { - this.InitVars(true); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - internal void InitVars(bool initTable) - { - this.tableCustomers = ((CustomersDataTable)(base.Tables["Customers"])); - if ((initTable == true)) - { - if ((this.tableCustomers != null)) - { - this.tableCustomers.InitVars(); - } - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - private void InitClass() - { - this.DataSetName = "CustomerDataSet"; - this.Prefix = ""; - this.EnforceConstraints = true; - this.SchemaSerializationMode = global::System.Data.SchemaSerializationMode.IncludeSchema; - this.tableCustomers = new CustomersDataTable(); - base.Tables.Add(this.tableCustomers); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - private bool ShouldSerializeCustomers() - { - return false; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - private void SchemaChanged(object sender, global::System.ComponentModel.CollectionChangeEventArgs e) - { - if ((e.Action == global::System.ComponentModel.CollectionChangeAction.Remove)) - { - this.InitVars(); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - public static global::System.Xml.Schema.XmlSchemaComplexType GetTypedDataSetSchema(global::System.Xml.Schema.XmlSchemaSet xs) - { - CustomerDataSet ds = new CustomerDataSet(); - global::System.Xml.Schema.XmlSchemaComplexType type = new global::System.Xml.Schema.XmlSchemaComplexType(); - global::System.Xml.Schema.XmlSchemaSequence sequence = new global::System.Xml.Schema.XmlSchemaSequence(); - global::System.Xml.Schema.XmlSchemaAny any = new global::System.Xml.Schema.XmlSchemaAny(); - any.Namespace = ds.Namespace; - sequence.Items.Add(any); - type.Particle = sequence; - global::System.Xml.Schema.XmlSchema dsSchema = ds.GetSchemaSerializable(); - if (xs.Contains(dsSchema.TargetNamespace)) - { - global::System.IO.MemoryStream s1 = new global::System.IO.MemoryStream(); - global::System.IO.MemoryStream s2 = new global::System.IO.MemoryStream(); - try - { - global::System.Xml.Schema.XmlSchema schema = null; - dsSchema.Write(s1); - for (global::System.Collections.IEnumerator schemas = xs.Schemas(dsSchema.TargetNamespace).GetEnumerator(); schemas.MoveNext(); ) - { - schema = ((global::System.Xml.Schema.XmlSchema)(schemas.Current)); - s2.SetLength(0); - schema.Write(s2); - if ((s1.Length == s2.Length)) - { - s1.Position = 0; - s2.Position = 0; - for (; ((s1.Position != s1.Length) - && (s1.ReadByte() == s2.ReadByte())); ) - { - ; - } - if ((s1.Position == s1.Length)) - { - return type; - } - } - } - } - finally - { - if ((s1 != null)) - { - s1.Close(); - } - if ((s2 != null)) - { - s2.Close(); - } - } - } - xs.Add(dsSchema); - return type; - } - - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - public delegate void CustomersRowChangeEventHandler(object sender, CustomersRowChangeEvent e); - /// - ///Represents the strongly named DataTable class. + ///Represents a strongly typed in-memory cache of data. /// [global::System.Serializable()] - [global::System.Xml.Serialization.XmlSchemaProviderAttribute("GetTypedTableSchema")] - public partial class CustomersDataTable : global::System.Data.DataTable, global::System.Collections.IEnumerable + [global::System.ComponentModel.DesignerCategoryAttribute("code")] + [global::System.ComponentModel.ToolboxItem(true)] + [global::System.Xml.Serialization.XmlSchemaProviderAttribute("GetTypedDataSetSchema")] + [global::System.Xml.Serialization.XmlRootAttribute("CustomerDataSet")] + [global::System.ComponentModel.Design.HelpKeywordAttribute("vs.data.DataSet")] + public partial class CustomerDataSet : global::System.Data.DataSet { + private CustomersDataTable tableCustomers; - private global::System.Data.DataColumn columnCustomerID; + private global::System.Data.SchemaSerializationMode _schemaSerializationMode = global::System.Data.SchemaSerializationMode.IncludeSchema; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - public CustomersDataTable() - { - this.TableName = "Customers"; - this.BeginInit(); - this.InitClass(); - this.EndInit(); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - internal CustomersDataTable(global::System.Data.DataTable table) - { - this.TableName = table.TableName; - if ((table.CaseSensitive != table.DataSet.CaseSensitive)) + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + public CustomerDataSet() { - this.CaseSensitive = table.CaseSensitive; + BeginInit(); + InitClass(); + global::System.ComponentModel.CollectionChangeEventHandler schemaChangedHandler = new global::System.ComponentModel.CollectionChangeEventHandler(SchemaChanged); + base.Tables.CollectionChanged += schemaChangedHandler; + base.Relations.CollectionChanged += schemaChangedHandler; + EndInit(); } - if ((table.Locale.ToString() != table.DataSet.Locale.ToString())) + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + protected CustomerDataSet(global::System.Runtime.Serialization.SerializationInfo info, global::System.Runtime.Serialization.StreamingContext context) : + base(info, context, false) { - this.Locale = table.Locale; - } - if ((table.Namespace != table.DataSet.Namespace)) - { - this.Namespace = table.Namespace; - } - this.Prefix = table.Prefix; - this.MinimumCapacity = table.MinimumCapacity; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - protected CustomersDataTable(global::System.Runtime.Serialization.SerializationInfo info, global::System.Runtime.Serialization.StreamingContext context) : - base(info, context) - { - this.InitVars(); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - public global::System.Data.DataColumn CustomerIDColumn - { - get - { - return this.columnCustomerID; - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - [global::System.ComponentModel.Browsable(false)] - public int Count - { - get - { - return this.Rows.Count; - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - public CustomersRow this[int index] - { - get - { - return ((CustomersRow)(this.Rows[index])); - } - } - - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - public event CustomersRowChangeEventHandler CustomersRowChanging; - - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - public event CustomersRowChangeEventHandler CustomersRowChanged; - - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - public event CustomersRowChangeEventHandler CustomersRowDeleting; - - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - public event CustomersRowChangeEventHandler CustomersRowDeleted; - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - public void AddCustomersRow(CustomersRow row) - { - this.Rows.Add(row); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - public CustomersRow AddCustomersRow(string CustomerID) - { - CustomersRow rowCustomersRow = ((CustomersRow)(this.NewRow())); - object[] columnValuesArray = new object[] { - CustomerID}; - rowCustomersRow.ItemArray = columnValuesArray; - this.Rows.Add(rowCustomersRow); - return rowCustomersRow; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - public virtual global::System.Collections.IEnumerator GetEnumerator() - { - return this.Rows.GetEnumerator(); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - public override global::System.Data.DataTable Clone() - { - CustomersDataTable cln = ((CustomersDataTable)(base.Clone())); - cln.InitVars(); - return cln; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - protected override global::System.Data.DataTable CreateInstance() - { - return new CustomersDataTable(); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - internal void InitVars() - { - this.columnCustomerID = base.Columns["CustomerID"]; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - private void InitClass() - { - this.columnCustomerID = new global::System.Data.DataColumn("CustomerID", typeof(string), null, global::System.Data.MappingType.Element); - base.Columns.Add(this.columnCustomerID); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - public CustomersRow NewCustomersRow() - { - return ((CustomersRow)(this.NewRow())); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - protected override global::System.Data.DataRow NewRowFromBuilder(global::System.Data.DataRowBuilder builder) - { - return new CustomersRow(builder); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - protected override global::System.Type GetRowType() - { - return typeof(CustomersRow); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - protected override void OnRowChanged(global::System.Data.DataRowChangeEventArgs e) - { - base.OnRowChanged(e); - if ((this.CustomersRowChanged != null)) - { - this.CustomersRowChanged(this, new CustomersRowChangeEvent(((CustomersRow)(e.Row)), e.Action)); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - protected override void OnRowChanging(global::System.Data.DataRowChangeEventArgs e) - { - base.OnRowChanging(e); - if ((this.CustomersRowChanging != null)) - { - this.CustomersRowChanging(this, new CustomersRowChangeEvent(((CustomersRow)(e.Row)), e.Action)); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - protected override void OnRowDeleted(global::System.Data.DataRowChangeEventArgs e) - { - base.OnRowDeleted(e); - if ((this.CustomersRowDeleted != null)) - { - this.CustomersRowDeleted(this, new CustomersRowChangeEvent(((CustomersRow)(e.Row)), e.Action)); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - protected override void OnRowDeleting(global::System.Data.DataRowChangeEventArgs e) - { - base.OnRowDeleting(e); - if ((this.CustomersRowDeleting != null)) - { - this.CustomersRowDeleting(this, new CustomersRowChangeEvent(((CustomersRow)(e.Row)), e.Action)); - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - public void RemoveCustomersRow(CustomersRow row) - { - this.Rows.Remove(row); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - public static global::System.Xml.Schema.XmlSchemaComplexType GetTypedTableSchema(global::System.Xml.Schema.XmlSchemaSet xs) - { - global::System.Xml.Schema.XmlSchemaComplexType type = new global::System.Xml.Schema.XmlSchemaComplexType(); - global::System.Xml.Schema.XmlSchemaSequence sequence = new global::System.Xml.Schema.XmlSchemaSequence(); - CustomerDataSet ds = new CustomerDataSet(); - global::System.Xml.Schema.XmlSchemaAny any1 = new global::System.Xml.Schema.XmlSchemaAny(); - any1.Namespace = "http://www.w3.org/2001/XMLSchema"; - any1.MinOccurs = new decimal(0); - any1.MaxOccurs = decimal.MaxValue; - any1.ProcessContents = global::System.Xml.Schema.XmlSchemaContentProcessing.Lax; - sequence.Items.Add(any1); - global::System.Xml.Schema.XmlSchemaAny any2 = new global::System.Xml.Schema.XmlSchemaAny(); - any2.Namespace = "urn:schemas-microsoft-com:xml-diffgram-v1"; - any2.MinOccurs = new decimal(1); - any2.ProcessContents = global::System.Xml.Schema.XmlSchemaContentProcessing.Lax; - sequence.Items.Add(any2); - global::System.Xml.Schema.XmlSchemaAttribute attribute1 = new global::System.Xml.Schema.XmlSchemaAttribute(); - attribute1.Name = "namespace"; - attribute1.FixedValue = ds.Namespace; - type.Attributes.Add(attribute1); - global::System.Xml.Schema.XmlSchemaAttribute attribute2 = new global::System.Xml.Schema.XmlSchemaAttribute(); - attribute2.Name = "tableTypeName"; - attribute2.FixedValue = "CustomersDataTable"; - type.Attributes.Add(attribute2); - type.Particle = sequence; - global::System.Xml.Schema.XmlSchema dsSchema = ds.GetSchemaSerializable(); - if (xs.Contains(dsSchema.TargetNamespace)) - { - global::System.IO.MemoryStream s1 = new global::System.IO.MemoryStream(); - global::System.IO.MemoryStream s2 = new global::System.IO.MemoryStream(); - try - { - global::System.Xml.Schema.XmlSchema schema = null; - dsSchema.Write(s1); - for (global::System.Collections.IEnumerator schemas = xs.Schemas(dsSchema.TargetNamespace).GetEnumerator(); schemas.MoveNext(); ) + if ((IsBinarySerialized(info, context) == true)) { - schema = ((global::System.Xml.Schema.XmlSchema)(schemas.Current)); - s2.SetLength(0); - schema.Write(s2); - if ((s1.Length == s2.Length)) - { - s1.Position = 0; - s2.Position = 0; - for (; ((s1.Position != s1.Length) - && (s1.ReadByte() == s2.ReadByte())); ) + InitVars(false); + global::System.ComponentModel.CollectionChangeEventHandler schemaChangedHandler1 = new global::System.ComponentModel.CollectionChangeEventHandler(SchemaChanged); + Tables.CollectionChanged += schemaChangedHandler1; + Relations.CollectionChanged += schemaChangedHandler1; + return; + } + string strSchema = ((string)(info.GetValue("XmlSchema", typeof(string)))); + if ((DetermineSchemaSerializationMode(info, context) == global::System.Data.SchemaSerializationMode.IncludeSchema)) + { + global::System.Data.DataSet ds = new global::System.Data.DataSet(); + ds.ReadXmlSchema(new global::System.Xml.XmlTextReader(new global::System.IO.StringReader(strSchema))); + if ((ds.Tables["Customers"] != null)) { - ; + base.Tables.Add(new CustomersDataTable(ds.Tables["Customers"])); } - if ((s1.Position == s1.Length)) + DataSetName = ds.DataSetName; + Prefix = ds.Prefix; + Namespace = ds.Namespace; + Locale = ds.Locale; + CaseSensitive = ds.CaseSensitive; + EnforceConstraints = ds.EnforceConstraints; + Merge(ds, false, global::System.Data.MissingSchemaAction.Add); + InitVars(); + } + else + { + ReadXmlSchema(new global::System.Xml.XmlTextReader(new global::System.IO.StringReader(strSchema))); + } + GetSerializationData(info, context); + global::System.ComponentModel.CollectionChangeEventHandler schemaChangedHandler = new global::System.ComponentModel.CollectionChangeEventHandler(SchemaChanged); + base.Tables.CollectionChanged += schemaChangedHandler; + Relations.CollectionChanged += schemaChangedHandler; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + [global::System.ComponentModel.Browsable(false)] + [global::System.ComponentModel.DesignerSerializationVisibility(global::System.ComponentModel.DesignerSerializationVisibility.Content)] + public CustomersDataTable Customers + { + get { return tableCustomers; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + [global::System.ComponentModel.BrowsableAttribute(true)] + [global::System.ComponentModel.DesignerSerializationVisibilityAttribute(global::System.ComponentModel.DesignerSerializationVisibility.Visible)] + public override global::System.Data.SchemaSerializationMode SchemaSerializationMode + { + get { return _schemaSerializationMode; } + set { _schemaSerializationMode = value; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + [global::System.ComponentModel.DesignerSerializationVisibilityAttribute(global::System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public new global::System.Data.DataTableCollection Tables + { + get { return base.Tables; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + [global::System.ComponentModel.DesignerSerializationVisibilityAttribute(global::System.ComponentModel.DesignerSerializationVisibility.Hidden)] + public new global::System.Data.DataRelationCollection Relations + { + get { return base.Relations; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + protected override void InitializeDerivedDataSet() + { + BeginInit(); + InitClass(); + EndInit(); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + public override global::System.Data.DataSet Clone() + { + CustomerDataSet cln = ((CustomerDataSet)(base.Clone())); + cln.InitVars(); + cln.SchemaSerializationMode = SchemaSerializationMode; + return cln; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + protected override bool ShouldSerializeTables() + { + return false; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + protected override bool ShouldSerializeRelations() + { + return false; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + protected override void ReadXmlSerializable(global::System.Xml.XmlReader reader) + { + if ((DetermineSchemaSerializationMode(reader) == global::System.Data.SchemaSerializationMode.IncludeSchema)) + { + Reset(); + global::System.Data.DataSet ds = new global::System.Data.DataSet(); + ds.ReadXml(reader); + if ((ds.Tables["Customers"] != null)) { - return type; + base.Tables.Add(new CustomersDataTable(ds.Tables["Customers"])); } - } + DataSetName = ds.DataSetName; + Prefix = ds.Prefix; + Namespace = ds.Namespace; + Locale = ds.Locale; + CaseSensitive = ds.CaseSensitive; + EnforceConstraints = ds.EnforceConstraints; + Merge(ds, false, global::System.Data.MissingSchemaAction.Add); + InitVars(); } - } - finally - { - if ((s1 != null)) + else { - s1.Close(); + ReadXml(reader); + InitVars(); } - if ((s2 != null)) + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + protected override global::System.Xml.Schema.XmlSchema GetSchemaSerializable() + { + global::System.IO.MemoryStream stream = new global::System.IO.MemoryStream(); + WriteXmlSchema(new global::System.Xml.XmlTextWriter(stream, null)); + stream.Position = 0; + return global::System.Xml.Schema.XmlSchema.Read(new global::System.Xml.XmlTextReader(stream), null); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + internal void InitVars() + { + InitVars(true); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + internal void InitVars(bool initTable) + { + tableCustomers = ((CustomersDataTable)(base.Tables["Customers"])); + if ((initTable == true)) { - s2.Close(); + if ((tableCustomers != null)) + { + tableCustomers.InitVars(); + } + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + private void InitClass() + { + DataSetName = "CustomerDataSet"; + Prefix = ""; + EnforceConstraints = true; + SchemaSerializationMode = global::System.Data.SchemaSerializationMode.IncludeSchema; + tableCustomers = new CustomersDataTable(); + base.Tables.Add(tableCustomers); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + private bool ShouldSerializeCustomers() + { + return false; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + private void SchemaChanged(object sender, global::System.ComponentModel.CollectionChangeEventArgs e) + { + if ((e.Action == global::System.ComponentModel.CollectionChangeAction.Remove)) + { + InitVars(); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + public static global::System.Xml.Schema.XmlSchemaComplexType GetTypedDataSetSchema(global::System.Xml.Schema.XmlSchemaSet xs) + { + CustomerDataSet ds = new CustomerDataSet(); + global::System.Xml.Schema.XmlSchemaComplexType type = new global::System.Xml.Schema.XmlSchemaComplexType(); + global::System.Xml.Schema.XmlSchemaSequence sequence = new global::System.Xml.Schema.XmlSchemaSequence(); + global::System.Xml.Schema.XmlSchemaAny any = new global::System.Xml.Schema.XmlSchemaAny(); + any.Namespace = ds.Namespace; + sequence.Items.Add(any); + type.Particle = sequence; + global::System.Xml.Schema.XmlSchema dsSchema = ds.GetSchemaSerializable(); + if (xs.Contains(dsSchema.TargetNamespace)) + { + global::System.IO.MemoryStream s1 = new global::System.IO.MemoryStream(); + global::System.IO.MemoryStream s2 = new global::System.IO.MemoryStream(); + try + { + global::System.Xml.Schema.XmlSchema schema = null; + dsSchema.Write(s1); + for (global::System.Collections.IEnumerator schemas = xs.Schemas(dsSchema.TargetNamespace).GetEnumerator(); schemas.MoveNext();) + { + schema = ((global::System.Xml.Schema.XmlSchema)(schemas.Current)); + s2.SetLength(0); + schema.Write(s2); + if ((s1.Length == s2.Length)) + { + s1.Position = 0; + s2.Position = 0; + for (; ((s1.Position != s1.Length) + && (s1.ReadByte() == s2.ReadByte()));) + { + ; + } + if ((s1.Position == s1.Length)) + { + return type; + } + } + } + } + finally + { + if ((s1 != null)) + { + s1.Close(); + } + if ((s2 != null)) + { + s2.Close(); + } + } + } + xs.Add(dsSchema); + return type; + } + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + public delegate void CustomersRowChangeEventHandler(object sender, CustomersRowChangeEvent e); + + /// + ///Represents the strongly named DataTable class. + /// + [global::System.Serializable()] + [global::System.Xml.Serialization.XmlSchemaProviderAttribute("GetTypedTableSchema")] + public partial class CustomersDataTable : global::System.Data.DataTable, global::System.Collections.IEnumerable + { + private global::System.Data.DataColumn columnCustomerID; + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + public CustomersDataTable() + { + TableName = "Customers"; + BeginInit(); + InitClass(); + EndInit(); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + internal CustomersDataTable(global::System.Data.DataTable table) + { + TableName = table.TableName; + if ((table.CaseSensitive != table.DataSet.CaseSensitive)) + { + CaseSensitive = table.CaseSensitive; + } + if ((table.Locale.ToString() != table.DataSet.Locale.ToString())) + { + Locale = table.Locale; + } + if ((table.Namespace != table.DataSet.Namespace)) + { + Namespace = table.Namespace; + } + Prefix = table.Prefix; + MinimumCapacity = table.MinimumCapacity; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + protected CustomersDataTable(global::System.Runtime.Serialization.SerializationInfo info, global::System.Runtime.Serialization.StreamingContext context) : + base(info, context) + { + InitVars(); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + public global::System.Data.DataColumn CustomerIDColumn + { + get { return columnCustomerID; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + [global::System.ComponentModel.Browsable(false)] + public int Count + { + get { return Rows.Count; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + public CustomersRow this[int index] + { + get { return ((CustomersRow)(Rows[index])); } + } + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + public event CustomersRowChangeEventHandler CustomersRowChanging; + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + public event CustomersRowChangeEventHandler CustomersRowChanged; + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + public event CustomersRowChangeEventHandler CustomersRowDeleting; + + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + public event CustomersRowChangeEventHandler CustomersRowDeleted; + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + public void AddCustomersRow(CustomersRow row) + { + Rows.Add(row); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + public CustomersRow AddCustomersRow(string CustomerID) + { + CustomersRow rowCustomersRow = ((CustomersRow)(NewRow())); + object[] columnValuesArray = new object[] + { + CustomerID + }; + rowCustomersRow.ItemArray = columnValuesArray; + Rows.Add(rowCustomersRow); + return rowCustomersRow; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + public virtual global::System.Collections.IEnumerator GetEnumerator() + { + return Rows.GetEnumerator(); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + public override global::System.Data.DataTable Clone() + { + CustomersDataTable cln = ((CustomersDataTable)(base.Clone())); + cln.InitVars(); + return cln; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + protected override global::System.Data.DataTable CreateInstance() + { + return new CustomersDataTable(); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + internal void InitVars() + { + columnCustomerID = base.Columns["CustomerID"]; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + private void InitClass() + { + columnCustomerID = new global::System.Data.DataColumn("CustomerID", typeof(string), null, global::System.Data.MappingType.Element); + base.Columns.Add(columnCustomerID); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + public CustomersRow NewCustomersRow() + { + return ((CustomersRow)(NewRow())); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + protected override global::System.Data.DataRow NewRowFromBuilder(global::System.Data.DataRowBuilder builder) + { + return new CustomersRow(builder); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + protected override global::System.Type GetRowType() + { + return typeof(CustomersRow); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + protected override void OnRowChanged(global::System.Data.DataRowChangeEventArgs e) + { + base.OnRowChanged(e); + if ((CustomersRowChanged != null)) + { + CustomersRowChanged(this, new CustomersRowChangeEvent(((CustomersRow)(e.Row)), e.Action)); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + protected override void OnRowChanging(global::System.Data.DataRowChangeEventArgs e) + { + base.OnRowChanging(e); + if ((CustomersRowChanging != null)) + { + CustomersRowChanging(this, new CustomersRowChangeEvent(((CustomersRow)(e.Row)), e.Action)); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + protected override void OnRowDeleted(global::System.Data.DataRowChangeEventArgs e) + { + base.OnRowDeleted(e); + if ((CustomersRowDeleted != null)) + { + CustomersRowDeleted(this, new CustomersRowChangeEvent(((CustomersRow)(e.Row)), e.Action)); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + protected override void OnRowDeleting(global::System.Data.DataRowChangeEventArgs e) + { + base.OnRowDeleting(e); + if ((CustomersRowDeleting != null)) + { + CustomersRowDeleting(this, new CustomersRowChangeEvent(((CustomersRow)(e.Row)), e.Action)); + } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + public void RemoveCustomersRow(CustomersRow row) + { + Rows.Remove(row); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + public static global::System.Xml.Schema.XmlSchemaComplexType GetTypedTableSchema(global::System.Xml.Schema.XmlSchemaSet xs) + { + global::System.Xml.Schema.XmlSchemaComplexType type = new global::System.Xml.Schema.XmlSchemaComplexType(); + global::System.Xml.Schema.XmlSchemaSequence sequence = new global::System.Xml.Schema.XmlSchemaSequence(); + CustomerDataSet ds = new CustomerDataSet(); + global::System.Xml.Schema.XmlSchemaAny any1 = new global::System.Xml.Schema.XmlSchemaAny(); + any1.Namespace = "http://www.w3.org/2001/XMLSchema"; + any1.MinOccurs = new decimal(0); + any1.MaxOccurs = decimal.MaxValue; + any1.ProcessContents = global::System.Xml.Schema.XmlSchemaContentProcessing.Lax; + sequence.Items.Add(any1); + global::System.Xml.Schema.XmlSchemaAny any2 = new global::System.Xml.Schema.XmlSchemaAny(); + any2.Namespace = "urn:schemas-microsoft-com:xml-diffgram-v1"; + any2.MinOccurs = new decimal(1); + any2.ProcessContents = global::System.Xml.Schema.XmlSchemaContentProcessing.Lax; + sequence.Items.Add(any2); + global::System.Xml.Schema.XmlSchemaAttribute attribute1 = new global::System.Xml.Schema.XmlSchemaAttribute(); + attribute1.Name = "namespace"; + attribute1.FixedValue = ds.Namespace; + type.Attributes.Add(attribute1); + global::System.Xml.Schema.XmlSchemaAttribute attribute2 = new global::System.Xml.Schema.XmlSchemaAttribute(); + attribute2.Name = "tableTypeName"; + attribute2.FixedValue = "CustomersDataTable"; + type.Attributes.Add(attribute2); + type.Particle = sequence; + global::System.Xml.Schema.XmlSchema dsSchema = ds.GetSchemaSerializable(); + if (xs.Contains(dsSchema.TargetNamespace)) + { + global::System.IO.MemoryStream s1 = new global::System.IO.MemoryStream(); + global::System.IO.MemoryStream s2 = new global::System.IO.MemoryStream(); + try + { + global::System.Xml.Schema.XmlSchema schema = null; + dsSchema.Write(s1); + for (global::System.Collections.IEnumerator schemas = xs.Schemas(dsSchema.TargetNamespace).GetEnumerator(); schemas.MoveNext();) + { + schema = ((global::System.Xml.Schema.XmlSchema)(schemas.Current)); + s2.SetLength(0); + schema.Write(s2); + if ((s1.Length == s2.Length)) + { + s1.Position = 0; + s2.Position = 0; + for (; ((s1.Position != s1.Length) + && (s1.ReadByte() == s2.ReadByte()));) + { + ; + } + if ((s1.Position == s1.Length)) + { + return type; + } + } + } + } + finally + { + if ((s1 != null)) + { + s1.Close(); + } + if ((s2 != null)) + { + s2.Close(); + } + } + } + xs.Add(dsSchema); + return type; + } + } + + /// + ///Represents strongly named DataRow class. + /// + public partial class CustomersRow : global::System.Data.DataRow + { + private CustomersDataTable tableCustomers; + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + internal CustomersRow(global::System.Data.DataRowBuilder rb) : + base(rb) + { + tableCustomers = ((CustomersDataTable)(Table)); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + public string CustomerID + { + get + { + try + { + return ((string)(this[tableCustomers.CustomerIDColumn])); + } + catch (global::System.InvalidCastException e) + { + throw new global::System.Data.StrongTypingException("The value for column \'CustomerID\' in table \'Customers\' is DBNull.", e); + } + } + set { this[tableCustomers.CustomerIDColumn] = value; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + public bool IsCustomerIDNull() + { + return IsNull(tableCustomers.CustomerIDColumn); + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + public void SetCustomerIDNull() + { + this[tableCustomers.CustomerIDColumn] = global::System.Convert.DBNull; + } + } + + /// + ///Row event argument class + /// + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + public class CustomersRowChangeEvent : global::System.EventArgs + { + private CustomersRow eventRow; + + private global::System.Data.DataRowAction eventAction; + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + public CustomersRowChangeEvent(CustomersRow row, global::System.Data.DataRowAction action) + { + eventRow = row; + eventAction = action; + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + public CustomersRow Row + { + get { return eventRow; } + } + + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] + public global::System.Data.DataRowAction Action + { + get { return eventAction; } } - } } - xs.Add(dsSchema); - return type; - } } - - /// - ///Represents strongly named DataRow class. - /// - public partial class CustomersRow : global::System.Data.DataRow - { - - private CustomersDataTable tableCustomers; - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - internal CustomersRow(global::System.Data.DataRowBuilder rb) : - base(rb) - { - this.tableCustomers = ((CustomersDataTable)(this.Table)); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - public string CustomerID - { - get - { - try - { - return ((string)(this[this.tableCustomers.CustomerIDColumn])); - } - catch (global::System.InvalidCastException e) - { - throw new global::System.Data.StrongTypingException("The value for column \'CustomerID\' in table \'Customers\' is DBNull.", e); - } - } - set - { - this[this.tableCustomers.CustomerIDColumn] = value; - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - public bool IsCustomerIDNull() - { - return this.IsNull(this.tableCustomers.CustomerIDColumn); - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - public void SetCustomerIDNull() - { - this[this.tableCustomers.CustomerIDColumn] = global::System.Convert.DBNull; - } - } - - /// - ///Row event argument class - /// - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - public class CustomersRowChangeEvent : global::System.EventArgs - { - - private CustomersRow eventRow; - - private global::System.Data.DataRowAction eventAction; - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - public CustomersRowChangeEvent(CustomersRow row, global::System.Data.DataRowAction action) - { - this.eventRow = row; - this.eventAction = action; - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - public CustomersRow Row - { - get - { - return this.eventRow; - } - } - - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Design.TypedDataSetGenerator", "4.0.0.0")] - public global::System.Data.DataRowAction Action - { - get - { - return this.eventAction; - } - } - } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/DateTimeErrorObjectCollection.cs b/Src/Newtonsoft.Json.Tests/TestObjects/DateTimeErrorObjectCollection.cs index 0f4d7242..d53728c7 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/DateTimeErrorObjectCollection.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/DateTimeErrorObjectCollection.cs @@ -30,12 +30,12 @@ using Newtonsoft.Json.Serialization; namespace Newtonsoft.Json.Tests.TestObjects { - public class DateTimeErrorObjectCollection : Collection - { - [OnError] - internal void OnErrorMethod(StreamingContext context, ErrorContext errorContext) + public class DateTimeErrorObjectCollection : Collection { - errorContext.Handled = true; + [OnError] + internal void OnErrorMethod(StreamingContext context, ErrorContext errorContext) + { + errorContext.Handled = true; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/DateTimeTestClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/DateTimeTestClass.cs index 5dc2b7a3..e6735f60 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/DateTimeTestClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/DateTimeTestClass.cs @@ -32,14 +32,17 @@ using System.Text; namespace Newtonsoft.Json.Tests.TestObjects { - public class DateTimeTestClass - { - public string PreField { get; set; } - [DefaultValue("")] - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public DateTime DateTimeField { get; set; } - public DateTimeOffset DateTimeOffsetField { get; set; } - public string PostField { get; set; } - } + public class DateTimeTestClass + { + public string PreField { get; set; } + + [DefaultValue("")] + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public DateTime DateTimeField { get; set; } + + public DateTimeOffset DateTimeOffsetField { get; set; } + public string PostField { get; set; } + } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/DefaultValueAttributeTestClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/DefaultValueAttributeTestClass.cs index fb5ccfcb..6953a066 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/DefaultValueAttributeTestClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/DefaultValueAttributeTestClass.cs @@ -28,14 +28,14 @@ using System.ComponentModel; namespace Newtonsoft.Json.Tests.TestObjects { #if !NETFX_CORE - [Description("DefaultValueAttributeTestClass description!")] + [Description("DefaultValueAttributeTestClass description!")] #endif - public sealed class DefaultValueAttributeTestClass - { - [DefaultValue("TestProperty1Value")] - public string TestProperty1 { get; set; } + public sealed class DefaultValueAttributeTestClass + { + [DefaultValue("TestProperty1Value")] + public string TestProperty1 { get; set; } - [DefaultValue(21)] - public int TestField1; - } + [DefaultValue(21)] + public int TestField1; + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/DictionaryInterfaceClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/DictionaryInterfaceClass.cs index 6d8e12a0..346628c7 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/DictionaryInterfaceClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/DictionaryInterfaceClass.cs @@ -28,30 +28,30 @@ using Newtonsoft.Json.Tests.TestObjects; namespace Newtonsoft.Json.Tests.TestObjects { - public class DictionaryInterfaceClass - { - public string Name { get; set; } - public IDictionary Dictionary { get; set; } - public ICollection Collection { get; set; } - public EmployeeReference Employee { get; set; } - public object Random { get; set; } - - public DictionaryInterfaceClass() + public class DictionaryInterfaceClass { - Dictionary = new Dictionary + public string Name { get; set; } + public IDictionary Dictionary { get; set; } + public ICollection Collection { get; set; } + public EmployeeReference Employee { get; set; } + public object Random { get; set; } + + public DictionaryInterfaceClass() { - { "existing", 1 } - }; - Collection = new List - { - 1, - 2, - 3 - }; - Employee = new EmployeeReference - { - Name = "EmployeeName!" - }; + Dictionary = new Dictionary + { + { "existing", 1 } + }; + Collection = new List + { + 1, + 2, + 3 + }; + Employee = new EmployeeReference + { + Name = "EmployeeName!" + }; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/DoubleClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/DoubleClass.cs index df110cbe..6101b9d4 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/DoubleClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/DoubleClass.cs @@ -25,8 +25,8 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class DoubleClass - { - public double? Height { get; set; } - } + public class DoubleClass + { + public double? Height { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/EmployeeReference.cs b/Src/Newtonsoft.Json.Tests/TestObjects/EmployeeReference.cs index c081d598..592f4703 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/EmployeeReference.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/EmployeeReference.cs @@ -25,10 +25,10 @@ namespace Newtonsoft.Json.Tests.TestObjects { - [JsonObject(IsReference = true)] - public class EmployeeReference - { - public string Name { get; set; } - public EmployeeReference Manager { get; set; } - } + [JsonObject(IsReference = true)] + public class EmployeeReference + { + public string Name { get; set; } + public EmployeeReference Manager { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/Event.cs b/Src/Newtonsoft.Json.Tests/TestObjects/Event.cs index b58b1264..cdb94caa 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/Event.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/Event.cs @@ -27,122 +27,128 @@ using System; namespace Newtonsoft.Json.Tests.TestObjects { - /// - /// What types of events are there? Just sticking to a basic set of four for now. - /// - /// - public enum EventType - { - Debug = 0, - Info = 1, - Warning = 2, - Error = 3 - } - - public sealed class Event - { - /// - /// If no current user is specified, returns Nothing (0 from VB) + /// What types of events are there? Just sticking to a basic set of four for now. /// - /// /// - private static int GetCurrentUserId() + public enum EventType { - return 0; + Debug = 0, + Info = 1, + Warning = 2, + Error = 3 } - /// - /// Gets either the application path or the current stack trace. - /// NOTE: You MUST call this from the top level entry point. Otherwise, - /// the stack trace will be buried in Logger itself. - /// - /// - /// - private static string GetCurrentSubLocation() + public sealed class Event { - return ""; - } + /// + /// If no current user is specified, returns Nothing (0 from VB) + /// + /// + /// + private static int GetCurrentUserId() + { + return 0; + } - private string _sublocation; - private int _userId; - private EventType _type; - private string _summary; - private string _details; - private string _stackTrace; - private string _tag; - private DateTime _time; + /// + /// Gets either the application path or the current stack trace. + /// NOTE: You MUST call this from the top level entry point. Otherwise, + /// the stack trace will be buried in Logger itself. + /// + /// + /// + private static string GetCurrentSubLocation() + { + return ""; + } - public Event(string summary) - { - _summary = summary; - _time = DateTime.Now; + private string _sublocation; + private int _userId; + private EventType _type; + private string _summary; + private string _details; + private string _stackTrace; + private string _tag; + private DateTime _time; - if (_userId == 0) _userId = GetCurrentUserId(); - //This call only works at top level for now. - //If _stackTrace = Nothing Then _stackTrace = Environment.StackTrace - if (_sublocation == null) _sublocation = GetCurrentSubLocation(); - } + public Event(string summary) + { + _summary = summary; + _time = DateTime.Now; - public Event(string sublocation, int userId, EventType type, string summary, string details, string stackTrace, string tag) - { - _sublocation = sublocation; - _userId = userId; - _type = type; - _summary = summary; - _details = details; - _stackTrace = stackTrace; - _tag = tag; - _time = DateTime.Now; + if (_userId == 0) _userId = GetCurrentUserId(); + //This call only works at top level for now. + //If _stackTrace = Nothing Then _stackTrace = Environment.StackTrace + if (_sublocation == null) _sublocation = GetCurrentSubLocation(); + } - if (_userId == 0) _userId = GetCurrentUserId(); - //If _stackTrace = Nothing Then _stackTrace = Environment.StackTrace - if (_sublocation == null) _sublocation = GetCurrentSubLocation(); - } + public Event(string sublocation, int userId, EventType type, string summary, string details, string stackTrace, string tag) + { + _sublocation = sublocation; + _userId = userId; + _type = type; + _summary = summary; + _details = details; + _stackTrace = stackTrace; + _tag = tag; + _time = DateTime.Now; - public override string ToString() - { - return string.Format("{{ sublocation = {0}, userId = {1}, type = {2}, summary = {3}, details = {4}, stackTrace = {5}, tag = {6} }}", _sublocation, _userId, _type, _summary, _details, _stackTrace, _tag); - } + if (_userId == 0) _userId = GetCurrentUserId(); + //If _stackTrace = Nothing Then _stackTrace = Environment.StackTrace + if (_sublocation == null) _sublocation = GetCurrentSubLocation(); + } - public string sublocation - { - get { return _sublocation; } - set { _sublocation = value; } + public override string ToString() + { + return string.Format("{{ sublocation = {0}, userId = {1}, type = {2}, summary = {3}, details = {4}, stackTrace = {5}, tag = {6} }}", _sublocation, _userId, _type, _summary, _details, _stackTrace, _tag); + } + + public string sublocation + { + get { return _sublocation; } + set { _sublocation = value; } + } + + public int userId + { + get { return _userId; } + set { _userId = value; } + } + + public EventType type + { + get { return _type; } + set { _type = value; } + } + + public string summary + { + get { return _summary; } + set { _summary = value; } + } + + public string details + { + get { return _details; } + set { _details = value; } + } + + public string stackTrace + { + get { return _stackTrace; } + set { _stackTrace = value; } + } + + public string tag + { + get { return _tag; } + set { _tag = value; } + } + + public DateTime time + { + get { return _time; } + } } - public int userId - { - get { return _userId; } - set { _userId = value; } - } - public EventType type - { - get { return _type; } - set { _type = value; } - } - public string summary - { - get { return _summary; } - set { _summary = value; } - } - public string details - { - get { return _details; } - set { _details = value; } - } - public string stackTrace - { - get { return _stackTrace; } - set { _stackTrace = value; } - } - public string tag - { - get { return _tag; } - set { _tag = value; } - } - public DateTime time - { - get { return _time; } - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/Foo.cs b/Src/Newtonsoft.Json.Tests/TestObjects/Foo.cs index 657037b1..3b153346 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/Foo.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/Foo.cs @@ -27,14 +27,14 @@ using System.Collections.Generic; namespace Newtonsoft.Json.Tests.TestObjects { - public class Foo - { - public Foo() + public class Foo { - Bars = new List(); - } + public Foo() + { + Bars = new List(); + } - [JsonConverter(typeof(ListOfIds))] - public List Bars { get; set; } - } + [JsonConverter(typeof(ListOfIds))] + public List Bars { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/GenericImpl.cs b/Src/Newtonsoft.Json.Tests/TestObjects/GenericImpl.cs index e4b82c8a..d7d2ef28 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/GenericImpl.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/GenericImpl.cs @@ -25,8 +25,8 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class GenericImpl : AbstractGenericBase - { - public override int Id { get; set; } - } + public class GenericImpl : AbstractGenericBase + { + public override int Id { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/GenericListAndDictionaryInterfaceProperties.cs b/Src/Newtonsoft.Json.Tests/TestObjects/GenericListAndDictionaryInterfaceProperties.cs index 34ea0d75..303d0b39 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/GenericListAndDictionaryInterfaceProperties.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/GenericListAndDictionaryInterfaceProperties.cs @@ -27,10 +27,10 @@ using System.Collections.Generic; namespace Newtonsoft.Json.Tests.TestObjects { - public class GenericListAndDictionaryInterfaceProperties - { - public IEnumerable IEnumerableProperty { get; set; } - public IList IListProperty { get; set; } - public IDictionary IDictionaryProperty { get; set; } - } + public class GenericListAndDictionaryInterfaceProperties + { + public IEnumerable IEnumerableProperty { get; set; } + public IList IListProperty { get; set; } + public IDictionary IDictionaryProperty { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/GetOnlyPropertyClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/GetOnlyPropertyClass.cs index 4243aa12..4973ef9f 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/GetOnlyPropertyClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/GetOnlyPropertyClass.cs @@ -25,13 +25,13 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class GetOnlyPropertyClass - { - public string Field = "Field"; - - public string GetOnlyProperty + public class GetOnlyPropertyClass { - get { return "GetOnlyProperty"; } + public string Field = "Field"; + + public string GetOnlyProperty + { + get { return "GetOnlyProperty"; } + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/GoogleMapGeocoderStructure.cs b/Src/Newtonsoft.Json.Tests/TestObjects/GoogleMapGeocoderStructure.cs index ceee06fa..23242893 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/GoogleMapGeocoderStructure.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/GoogleMapGeocoderStructure.cs @@ -27,69 +27,69 @@ using System.Collections.Generic; namespace Newtonsoft.Json.Tests.TestObjects { - public class GoogleMapGeocoderStructure - { - public string Name; - public Status Status; - public List Placemark; - } + public class GoogleMapGeocoderStructure + { + public string Name; + public Status Status; + public List Placemark; + } - public class Status - { - public string Request; - public string Code; - } + public class Status + { + public string Request; + public string Code; + } - public class Placemark - { - public string Address; - public AddressDetails AddressDetails; - public Point Point; - } + public class Placemark + { + public string Address; + public AddressDetails AddressDetails; + public Point Point; + } - public class AddressDetails - { - public int Accuracy; - public Country Country; - } + public class AddressDetails + { + public int Accuracy; + public Country Country; + } - public class Country - { - public string CountryNameCode; - public AdministrativeArea AdministrativeArea; - } + public class Country + { + public string CountryNameCode; + public AdministrativeArea AdministrativeArea; + } - public class AdministrativeArea - { - public string AdministrativeAreaName; - public SubAdministrativeArea SubAdministrativeArea; - } + public class AdministrativeArea + { + public string AdministrativeAreaName; + public SubAdministrativeArea SubAdministrativeArea; + } - public class SubAdministrativeArea - { - public string SubAdministrativeAreaName; - public Locality Locality; - } + public class SubAdministrativeArea + { + public string SubAdministrativeAreaName; + public Locality Locality; + } - public class Locality - { - public string LocalityName; - public Thoroughfare Thoroughfare; - public PostalCode PostalCode; - } + public class Locality + { + public string LocalityName; + public Thoroughfare Thoroughfare; + public PostalCode PostalCode; + } - public class Thoroughfare - { - public string ThoroughfareName; - } + public class Thoroughfare + { + public string ThoroughfareName; + } - public class PostalCode - { - public string PostalCodeNumber; - } + public class PostalCode + { + public string PostalCodeNumber; + } - public class Point - { - public List Coordinates; - } + public class Point + { + public List Coordinates; + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/HolderClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/HolderClass.cs index c8aa8599..bdde1adb 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/HolderClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/HolderClass.cs @@ -27,17 +27,18 @@ using System.Collections.Generic; namespace Newtonsoft.Json.Tests.TestObjects { - public class HolderClass - { - public HolderClass() { } + public class HolderClass + { + public HolderClass() + { + } - [Newtonsoft.Json.JsonProperty(TypeNameHandling = Newtonsoft.Json.TypeNameHandling.All)] - public ContentBaseClass TestMember { get; set; } + [Newtonsoft.Json.JsonProperty(TypeNameHandling = Newtonsoft.Json.TypeNameHandling.All)] + public ContentBaseClass TestMember { get; set; } - [Newtonsoft.Json.JsonProperty(TypeNameHandling = Newtonsoft.Json.TypeNameHandling.All)] - public Dictionary> AnotherTestMember { get; set; } + [Newtonsoft.Json.JsonProperty(TypeNameHandling = Newtonsoft.Json.TypeNameHandling.All)] + public Dictionary> AnotherTestMember { get; set; } - public ContentBaseClass AThirdTestMember { get; set; } - - } + public ContentBaseClass AThirdTestMember { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/IPrivateImplementationA.cs b/Src/Newtonsoft.Json.Tests/TestObjects/IPrivateImplementationA.cs index 3a20c985..530cb2c5 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/IPrivateImplementationA.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/IPrivateImplementationA.cs @@ -25,8 +25,8 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public interface IPrivateImplementationA - { - string PropertyA { get; set; } - } + public interface IPrivateImplementationA + { + string PropertyA { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/IPrivateImplementationB.cs b/Src/Newtonsoft.Json.Tests/TestObjects/IPrivateImplementationB.cs index 3d82e45a..8c373dfd 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/IPrivateImplementationB.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/IPrivateImplementationB.cs @@ -25,8 +25,8 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public interface IPrivateImplementationB - { - string PropertyB { get; set; } - } + public interface IPrivateImplementationB + { + string PropertyB { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/IPrivateOverriddenImplementation.cs b/Src/Newtonsoft.Json.Tests/TestObjects/IPrivateOverriddenImplementation.cs index 496a081a..2b3422b2 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/IPrivateOverriddenImplementation.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/IPrivateOverriddenImplementation.cs @@ -25,8 +25,8 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public interface IPrivateOverriddenImplementation - { - object OverriddenProperty { get; set; } - } + public interface IPrivateOverriddenImplementation + { + object OverriddenProperty { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/IncompatibleJsonAttributeClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/IncompatibleJsonAttributeClass.cs index d1f961e4..28b3a2db 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/IncompatibleJsonAttributeClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/IncompatibleJsonAttributeClass.cs @@ -27,8 +27,8 @@ using Newtonsoft.Json.Converters; namespace Newtonsoft.Json.Tests.TestObjects { - [JsonConverter(typeof(IsoDateTimeConverter))] - public class IncompatibleJsonAttributeClass - { - } + [JsonConverter(typeof(IsoDateTimeConverter))] + public class IncompatibleJsonAttributeClass + { + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/InterfacePropertyTestClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/InterfacePropertyTestClass.cs index 9a3eb568..62edfcbc 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/InterfacePropertyTestClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/InterfacePropertyTestClass.cs @@ -25,27 +25,27 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class Co : ICo - { - public string Name { get; set; } - } - - public interface ICo - { - string Name { get; set; } - } - - public interface IInterfacePropertyTestClass - { - ICo co { get; set; } - } - - public class InterfacePropertyTestClass : IInterfacePropertyTestClass - { - public ICo co { get; set; } - - public InterfacePropertyTestClass() + public class Co : ICo { + public string Name { get; set; } + } + + public interface ICo + { + string Name { get; set; } + } + + public interface IInterfacePropertyTestClass + { + ICo co { get; set; } + } + + public class InterfacePropertyTestClass : IInterfacePropertyTestClass + { + public ICo co { get; set; } + + public InterfacePropertyTestClass() + { + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/Invoice.cs b/Src/Newtonsoft.Json.Tests/TestObjects/Invoice.cs index bdce565f..7aed9bae 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/Invoice.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/Invoice.cs @@ -28,20 +28,21 @@ using System.ComponentModel; namespace Newtonsoft.Json.Tests.TestObjects { - public class Invoice - { - public string Company { get; set; } - public decimal Amount { get; set; } + public class Invoice + { + public string Company { get; set; } + public decimal Amount { get; set; } - // false is default value of bool - public bool Paid { get; set; } - // null is default value of nullable - public DateTime? PaidDate { get; set; } + // false is default value of bool + public bool Paid { get; set; } + // null is default value of nullable + public DateTime? PaidDate { get; set; } - // customize default values - [DefaultValue(30)] - public int FollowUpDays { get; set; } - [DefaultValue("")] - public string FollowUpEmailAddress { get; set; } - } + // customize default values + [DefaultValue(30)] + public int FollowUpDays { get; set; } + + [DefaultValue("")] + public string FollowUpEmailAddress { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/JaggedArray.cs b/Src/Newtonsoft.Json.Tests/TestObjects/JaggedArray.cs index 0d77eabb..c355b542 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/JaggedArray.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/JaggedArray.cs @@ -25,10 +25,10 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class JaggedArray - { - public string Before { get; set; } - public int[][] Coordinates { get; set; } - public string After { get; set; } - } + public class JaggedArray + { + public string Before { get; set; } + public int[][] Coordinates { get; set; } + public string After { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/JsonIgnoreAttributeOnClassTestClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/JsonIgnoreAttributeOnClassTestClass.cs index 27ff1365..258cc922 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/JsonIgnoreAttributeOnClassTestClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/JsonIgnoreAttributeOnClassTestClass.cs @@ -25,28 +25,28 @@ namespace Newtonsoft.Json.Tests.TestObjects { - [JsonObject(MemberSerialization.OptIn)] - public class JsonIgnoreAttributeOnClassTestClass - { - private int _property = 21; - private int _ignoredProperty = 12; - - [JsonProperty("TheField")] - public int Field; - - [JsonProperty] - public int Property + [JsonObject(MemberSerialization.OptIn)] + public class JsonIgnoreAttributeOnClassTestClass { - get { return _property; } - } + private int _property = 21; + private int _ignoredProperty = 12; - public int IgnoredField; + [JsonProperty("TheField")] + public int Field; - [JsonProperty] - [JsonIgnore] // JsonIgnore should take priority - public int IgnoredProperty - { - get { return _ignoredProperty; } + [JsonProperty] + public int Property + { + get { return _property; } + } + + public int IgnoredField; + + [JsonProperty] + [JsonIgnore] // JsonIgnore should take priority + public int IgnoredProperty + { + get { return _ignoredProperty; } + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/JsonIgnoreAttributeTestClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/JsonIgnoreAttributeTestClass.cs index cb1fbdee..1b67247c 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/JsonIgnoreAttributeTestClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/JsonIgnoreAttributeTestClass.cs @@ -25,27 +25,28 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class JsonIgnoreAttributeTestClass - { - private int _property = 21; - private int _ignoredProperty = 12; - - public int Field; - public int Property + public class JsonIgnoreAttributeTestClass { - get { return _property; } + private int _property = 21; + private int _ignoredProperty = 12; + + public int Field; + + public int Property + { + get { return _property; } + } + + [JsonIgnore] + public int IgnoredField; + + [JsonIgnore] + public int IgnoredProperty + { + get { return _ignoredProperty; } + } + + [JsonIgnore] + public Product IgnoredObject = new Product(); } - - [JsonIgnore] - public int IgnoredField; - - [JsonIgnore] - public int IgnoredProperty - { - get { return _ignoredProperty; } - } - - [JsonIgnore] - public Product IgnoredObject = new Product(); - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/JsonPropertyClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/JsonPropertyClass.cs index 1714f017..7832d68c 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/JsonPropertyClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/JsonPropertyClass.cs @@ -25,23 +25,23 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class JsonPropertyClass - { - [JsonProperty("pie")] - public string Pie = "Yum"; - - [JsonIgnore] - public string pie = "No pie for you!"; - - public string pie1 = "PieChart!"; - - private int _sweetCakesCount; - - [JsonProperty("sweet_cakes_count")] - public int SweetCakesCount + public class JsonPropertyClass { - get { return _sweetCakesCount; } - set { _sweetCakesCount = value; } + [JsonProperty("pie")] + public string Pie = "Yum"; + + [JsonIgnore] + public string pie = "No pie for you!"; + + public string pie1 = "PieChart!"; + + private int _sweetCakesCount; + + [JsonProperty("sweet_cakes_count")] + public int SweetCakesCount + { + get { return _sweetCakesCount; } + set { _sweetCakesCount = value; } + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/JsonPropertyWithHandlingValues.cs b/Src/Newtonsoft.Json.Tests/TestObjects/JsonPropertyWithHandlingValues.cs index e8721457..c56651d5 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/JsonPropertyWithHandlingValues.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/JsonPropertyWithHandlingValues.cs @@ -27,37 +27,37 @@ using System.ComponentModel; namespace Newtonsoft.Json.Tests.TestObjects { - public class JsonPropertyWithHandlingValues - { - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - [DefaultValue("Default!")] - public string DefaultValueHandlingIgnoreProperty { get; set; } + public class JsonPropertyWithHandlingValues + { + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + [DefaultValue("Default!")] + public string DefaultValueHandlingIgnoreProperty { get; set; } - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Include)] - [DefaultValue("Default!")] - public string DefaultValueHandlingIncludeProperty { get; set; } + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Include)] + [DefaultValue("Default!")] + public string DefaultValueHandlingIncludeProperty { get; set; } - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)] - [DefaultValue("Default!")] - public string DefaultValueHandlingPopulateProperty { get; set; } + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)] + [DefaultValue("Default!")] + public string DefaultValueHandlingPopulateProperty { get; set; } - [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] - [DefaultValue("Default!")] - public string DefaultValueHandlingIgnoreAndPopulateProperty { get; set; } + [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] + [DefaultValue("Default!")] + public string DefaultValueHandlingIgnoreAndPopulateProperty { get; set; } - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] - public string NullValueHandlingIgnoreProperty { get; set; } + [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] + public string NullValueHandlingIgnoreProperty { get; set; } - [JsonProperty(NullValueHandling = NullValueHandling.Include)] - public string NullValueHandlingIncludeProperty { get; set; } + [JsonProperty(NullValueHandling = NullValueHandling.Include)] + public string NullValueHandlingIncludeProperty { get; set; } - [JsonProperty(ReferenceLoopHandling = ReferenceLoopHandling.Error)] - public JsonPropertyWithHandlingValues ReferenceLoopHandlingErrorProperty { get; set; } + [JsonProperty(ReferenceLoopHandling = ReferenceLoopHandling.Error)] + public JsonPropertyWithHandlingValues ReferenceLoopHandlingErrorProperty { get; set; } - [JsonProperty(ReferenceLoopHandling = ReferenceLoopHandling.Ignore)] - public JsonPropertyWithHandlingValues ReferenceLoopHandlingIgnoreProperty { get; set; } + [JsonProperty(ReferenceLoopHandling = ReferenceLoopHandling.Ignore)] + public JsonPropertyWithHandlingValues ReferenceLoopHandlingIgnoreProperty { get; set; } - [JsonProperty(ReferenceLoopHandling = ReferenceLoopHandling.Serialize)] - public JsonPropertyWithHandlingValues ReferenceLoopHandlingSerializeProperty { get; set; } - } + [JsonProperty(ReferenceLoopHandling = ReferenceLoopHandling.Serialize)] + public JsonPropertyWithHandlingValues ReferenceLoopHandlingSerializeProperty { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/ListErrorObject.cs b/Src/Newtonsoft.Json.Tests/TestObjects/ListErrorObject.cs index 800e6823..8a3a8e4e 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/ListErrorObject.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/ListErrorObject.cs @@ -27,32 +27,33 @@ using System; namespace Newtonsoft.Json.Tests.TestObjects { - public class ListErrorObject - { - public string Member { get; set; } - - private string _throwError; - public string ThrowError + public class ListErrorObject { - get - { - if (_throwError != null) - return _throwError; + public string Member { get; set; } - throw new Exception("ListErrorObject.ThrowError get error!"); - } - set - { - if (value != null && value.StartsWith("Handle")) + private string _throwError; + + public string ThrowError { - _throwError = value; - return; + get + { + if (_throwError != null) + return _throwError; + + throw new Exception("ListErrorObject.ThrowError get error!"); + } + set + { + if (value != null && value.StartsWith("Handle")) + { + _throwError = value; + return; + } + + throw new Exception("ListErrorObject.ThrowError set error!"); + } } - throw new Exception("ListErrorObject.ThrowError set error!"); - } + public string Member2 { get; set; } } - - public string Member2 { get; set; } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/ListErrorObjectCollection.cs b/Src/Newtonsoft.Json.Tests/TestObjects/ListErrorObjectCollection.cs index 2b375014..f45a5293 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/ListErrorObjectCollection.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/ListErrorObjectCollection.cs @@ -29,12 +29,12 @@ using Newtonsoft.Json.Serialization; namespace Newtonsoft.Json.Tests.TestObjects { - public class ListErrorObjectCollection : Collection - { - [OnError] - internal void OnErrorMethod(StreamingContext context, ErrorContext errorContext) + public class ListErrorObjectCollection : Collection { - errorContext.Handled = true; + [OnError] + internal void OnErrorMethod(StreamingContext context, ErrorContext errorContext) + { + errorContext.Handled = true; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/ListOfIds.cs b/Src/Newtonsoft.Json.Tests/TestObjects/ListOfIds.cs index 25fb8c07..a34e3088 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/ListOfIds.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/ListOfIds.cs @@ -29,43 +29,43 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Tests.TestObjects { - public class ListOfIds : JsonConverter where T : Bar, new() - { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + public class ListOfIds : JsonConverter where T : Bar, new() { - IList list = (IList)value; + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + IList list = (IList)value; - writer.WriteStartArray(); - foreach (T item in list) - { - writer.WriteValue(item.Id); - } - writer.WriteEndArray(); + writer.WriteStartArray(); + foreach (T item in list) + { + writer.WriteValue(item.Id); + } + writer.WriteEndArray(); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + IList list = new List(); + + reader.Read(); + while (reader.TokenType != JsonToken.EndArray) + { + long id = (long)reader.Value; + + list.Add(new T + { + Id = Convert.ToInt32(id) + }); + + reader.Read(); + } + + return list; + } + + public override bool CanConvert(Type objectType) + { + return typeof(IList).IsAssignableFrom(objectType); + } } - - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - IList list = new List(); - - reader.Read(); - while (reader.TokenType != JsonToken.EndArray) - { - long id = (long)reader.Value; - - list.Add(new T - { - Id = Convert.ToInt32(id) - }); - - reader.Read(); - } - - return list; - } - - public override bool CanConvert(Type objectType) - { - return typeof(IList).IsAssignableFrom(objectType); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/ListTestClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/ListTestClass.cs index 74ea35d8..68e10795 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/ListTestClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/ListTestClass.cs @@ -27,19 +27,20 @@ using System.Collections.Generic; namespace Newtonsoft.Json.Tests.TestObjects { - [JsonObject(MemberSerialization.OptIn)] - public class ListTestClass - { - [JsonProperty] - public string id { get; set; } - [JsonProperty] - public List items { get; set; } - } + [JsonObject(MemberSerialization.OptIn)] + public class ListTestClass + { + [JsonProperty] + public string id { get; set; } - [JsonObject(MemberSerialization.OptIn)] - public class ListItem - { - [JsonProperty] - public string id { get; set; } - } + [JsonProperty] + public List items { get; set; } + } + + [JsonObject(MemberSerialization.OptIn)] + public class ListItem + { + [JsonProperty] + public string id { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/LogEntry.cs b/Src/Newtonsoft.Json.Tests/TestObjects/LogEntry.cs index 0dbd63ff..f3776c53 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/LogEntry.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/LogEntry.cs @@ -27,9 +27,9 @@ using System; namespace Newtonsoft.Json.Tests.TestObjects { - public class LogEntry - { - public string Details { get; set; } - public DateTime LogDate { get; set; } - } + public class LogEntry + { + public string Details { get; set; } + public DateTime LogDate { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/MemberConverterClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/MemberConverterClass.cs index 89ab7a6f..c990a4a2 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/MemberConverterClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/MemberConverterClass.cs @@ -28,10 +28,11 @@ using Newtonsoft.Json.Converters; namespace Newtonsoft.Json.Tests.TestObjects { - public class MemberConverterClass - { - public DateTime DefaultConverter { get; set; } - [JsonConverter(typeof(IsoDateTimeConverter))] - public DateTime MemberConverter { get; set; } - } + public class MemberConverterClass + { + public DateTime DefaultConverter { get; set; } + + [JsonConverter(typeof(IsoDateTimeConverter))] + public DateTime MemberConverter { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/MemberConverterPrecedenceClassConverter.cs b/Src/Newtonsoft.Json.Tests/TestObjects/MemberConverterPrecedenceClassConverter.cs index afe34989..dafee7e1 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/MemberConverterPrecedenceClassConverter.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/MemberConverterPrecedenceClassConverter.cs @@ -25,11 +25,11 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class MemberConverterPrecedenceClassConverter : ConverterPrecedenceClassConverter - { - public override string ConverterType + public class MemberConverterPrecedenceClassConverter : ConverterPrecedenceClassConverter { - get { return "Member"; } + public override string ConverterType + { + get { return "Member"; } + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/MethodExecutorObject.cs b/Src/Newtonsoft.Json.Tests/TestObjects/MethodExecutorObject.cs index 7586d057..10449d61 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/MethodExecutorObject.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/MethodExecutorObject.cs @@ -25,10 +25,10 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class MethodExecutorObject - { - public string serverClassName; - public object[] serverMethodParams; - public string clientGetResultFunction; - } + public class MethodExecutorObject + { + public string serverClassName; + public object[] serverMethodParams; + public string clientGetResultFunction; + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/Movie.cs b/Src/Newtonsoft.Json.Tests/TestObjects/Movie.cs index 0719a778..a9d0d0bd 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/Movie.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/Movie.cs @@ -28,28 +28,28 @@ using System.Collections.Generic; namespace Newtonsoft.Json.Tests.TestObjects { - public class Movie - { - public string Name { get; set; } - public string Description { get; set; } - public string Classification { get; set; } - public string Studio { get; set; } - public DateTime? ReleaseDate { get; set; } - public List ReleaseCountries { get; set; } - - public override string ToString() + public class Movie { - return base.ToString(); - } + public string Name { get; set; } + public string Description { get; set; } + public string Classification { get; set; } + public string Studio { get; set; } + public DateTime? ReleaseDate { get; set; } + public List ReleaseCountries { get; set; } - public override bool Equals(object obj) - { - return base.Equals(obj); - } + public override string ToString() + { + return base.ToString(); + } - public override int GetHashCode() - { - return base.GetHashCode(); + public override bool Equals(object obj) + { + return base.Equals(obj); + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/MyClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/MyClass.cs index d44da3dd..f2008913 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/MyClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/MyClass.cs @@ -25,10 +25,10 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class MyClass - { - public int PreProperty { get; set; } - //public DateTime DateProperty { get; set; } - public int PostProperty { get; set; } - } + public class MyClass + { + public int PreProperty { get; set; } + //public DateTime DateProperty { get; set; } + public int PostProperty { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/Name.cs b/Src/Newtonsoft.Json.Tests/TestObjects/Name.cs index 5e613364..4713053f 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/Name.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/Name.cs @@ -27,15 +27,15 @@ using System.Collections.Generic; namespace Newtonsoft.Json.Tests.TestObjects { - public class Name - { - public string personsName; - - public List pNumbers = new List(); - - public Name(string personsName) + public class Name { - this.personsName = personsName; + public string personsName; + + public List pNumbers = new List(); + + public Name(string personsName) + { + this.personsName = personsName; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/NonRequest.cs b/Src/Newtonsoft.Json.Tests/TestObjects/NonRequest.cs index 8f902685..4b515f25 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/NonRequest.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/NonRequest.cs @@ -28,10 +28,10 @@ using System.Collections.Generic; namespace Newtonsoft.Json.Tests.TestObjects { - public class NonRequest - { - public Guid Sid { get; set; } - public Guid Uid { get; set; } - public IList FidOrder { get; set; } - } + public class NonRequest + { + public Guid Sid { get; set; } + public Guid Uid { get; set; } + public IList FidOrder { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/NullableDateTimeTestClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/NullableDateTimeTestClass.cs index 9fba16b5..d7a4043d 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/NullableDateTimeTestClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/NullableDateTimeTestClass.cs @@ -31,12 +31,13 @@ using System.Text; namespace Newtonsoft.Json.Tests.TestObjects { - public class NullableDateTimeTestClass - { - public string PreField { get; set; } - public DateTime? DateTimeField { get; set; } - public DateTimeOffset? DateTimeOffsetField { get; set; } - public string PostField { get; set; } - } + public class NullableDateTimeTestClass + { + public string PreField { get; set; } + public DateTime? DateTimeField { get; set; } + public DateTimeOffset? DateTimeOffsetField { get; set; } + public string PostField { get; set; } + } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/ObjectArrayPropertyTest.cs b/Src/Newtonsoft.Json.Tests/TestObjects/ObjectArrayPropertyTest.cs index 1bea5473..1470e1c3 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/ObjectArrayPropertyTest.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/ObjectArrayPropertyTest.cs @@ -25,10 +25,10 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class ObjectArrayPropertyTest - { - public string Action { get; set; } - public string Method { get; set; } - public object[] Data { get; set; } - } + public class ObjectArrayPropertyTest + { + public string Action { get; set; } + public string Method { get; set; } + public object[] Data { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/Person.cs b/Src/Newtonsoft.Json.Tests/TestObjects/Person.cs index d6eb844c..18b523f9 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/Person.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/Person.cs @@ -28,44 +28,44 @@ using System.ComponentModel; namespace Newtonsoft.Json.Tests.TestObjects { - [JsonObject(Id = "Person", Title = "Title!", Description = "JsonObjectAttribute description!", MemberSerialization = MemberSerialization.OptIn)] + [JsonObject(Id = "Person", Title = "Title!", Description = "JsonObjectAttribute description!", MemberSerialization = MemberSerialization.OptIn)] #if !NETFX_CORE - [Description("DescriptionAttribute description!")] + [Description("DescriptionAttribute description!")] #endif - public class Person - { - // "John Smith" - [JsonProperty] - public string Name { get; set; } + public class Person + { + // "John Smith" + [JsonProperty] + public string Name { get; set; } - // "2000-12-15T22:11:03" - [JsonProperty] - //[JsonConverter(typeof(IsoDateTimeConverter))] - public DateTime BirthDate { get; set; } + // "2000-12-15T22:11:03" + [JsonProperty] + //[JsonConverter(typeof(IsoDateTimeConverter))] + public DateTime BirthDate { get; set; } - // new Date(976918263055) - [JsonProperty] - //[JsonConverter(typeof(JavaScriptDateTimeConverter))] - public DateTime LastModified { get; set; } + // new Date(976918263055) + [JsonProperty] + //[JsonConverter(typeof(JavaScriptDateTimeConverter))] + public DateTime LastModified { get; set; } - // not serialized - public string Department { get; set; } - } + // not serialized + public string Department { get; set; } + } - public interface IPerson - { - string FirstName { get; set; } - string LastName { get; set; } - DateTime BirthDate { get; set; } - } + public interface IPerson + { + string FirstName { get; set; } + string LastName { get; set; } + DateTime BirthDate { get; set; } + } - public class Employee : IPerson - { - public string FirstName { get; set; } - public string LastName { get; set; } - public DateTime BirthDate { get; set; } + public class Employee : IPerson + { + public string FirstName { get; set; } + public string LastName { get; set; } + public DateTime BirthDate { get; set; } - public string Department { get; set; } - public string JobTitle { get; set; } - } + public string Department { get; set; } + public string JobTitle { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/PersonError.cs b/Src/Newtonsoft.Json.Tests/TestObjects/PersonError.cs index bf569437..c3c9e79f 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/PersonError.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/PersonError.cs @@ -30,29 +30,31 @@ using Newtonsoft.Json.Serialization; namespace Newtonsoft.Json.Tests.TestObjects { - public class PersonError - { - private List _roles; - - public string Name { get; set; } - public int Age { get; set; } - public List Roles + public class PersonError { - get - { - if (_roles == null) - throw new Exception("Roles not loaded!"); + private List _roles; - return _roles; - } - set { _roles = value; } - } - public string Title { get; set; } + public string Name { get; set; } + public int Age { get; set; } - [OnError] - internal void HandleError(StreamingContext context, ErrorContext errorContext) - { - errorContext.Handled = true; + public List Roles + { + get + { + if (_roles == null) + throw new Exception("Roles not loaded!"); + + return _roles; + } + set { _roles = value; } + } + + public string Title { get; set; } + + [OnError] + internal void HandleError(StreamingContext context, ErrorContext errorContext) + { + errorContext.Handled = true; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/PersonPropertyClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/PersonPropertyClass.cs index 088c69ce..f46988d0 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/PersonPropertyClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/PersonPropertyClass.cs @@ -25,13 +25,13 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class PersonPropertyClass - { - public Person Person { get; set; } - - public PersonPropertyClass() + public class PersonPropertyClass { - Person = new WagePerson(); + public Person Person { get; set; } + + public PersonPropertyClass() + { + Person = new WagePerson(); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/PersonRaw.cs b/Src/Newtonsoft.Json.Tests/TestObjects/PersonRaw.cs index 82f67eea..e813b429 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/PersonRaw.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/PersonRaw.cs @@ -28,38 +28,38 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Tests.TestObjects { - public class PersonRaw - { - private Guid _internalId; - private string _firstName; - private string _lastName; - private JRaw _rawContent; - - [JsonIgnore] - public Guid InternalId + public class PersonRaw { - get { return _internalId; } - set { _internalId = value; } - } + private Guid _internalId; + private string _firstName; + private string _lastName; + private JRaw _rawContent; - [JsonProperty("first_name")] - public string FirstName - { - get { return _firstName; } - set { _firstName = value; } - } + [JsonIgnore] + public Guid InternalId + { + get { return _internalId; } + set { _internalId = value; } + } - public JRaw RawContent - { - get { return _rawContent; } - set { _rawContent = value; } - } + [JsonProperty("first_name")] + public string FirstName + { + get { return _firstName; } + set { _firstName = value; } + } - [JsonProperty("last_name")] - public string LastName - { - get { return _lastName; } - set { _lastName = value; } + public JRaw RawContent + { + get { return _rawContent; } + set { _rawContent = value; } + } + + [JsonProperty("last_name")] + public string LastName + { + get { return _lastName; } + set { _lastName = value; } + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/PhoneNumber.cs b/Src/Newtonsoft.Json.Tests/TestObjects/PhoneNumber.cs index 411c6a23..c5b313c7 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/PhoneNumber.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/PhoneNumber.cs @@ -25,13 +25,13 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class PhoneNumber - { - public string phoneNumber; - - public PhoneNumber(string phoneNumber) + public class PhoneNumber { - this.phoneNumber = phoneNumber; + public string phoneNumber; + + public PhoneNumber(string phoneNumber) + { + this.phoneNumber = phoneNumber; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/PrivateConstructorTestClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/PrivateConstructorTestClass.cs index 30cf5ebf..8eb063f6 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/PrivateConstructorTestClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/PrivateConstructorTestClass.cs @@ -25,23 +25,23 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class PrivateConstructorTestClass - { - public string Name { get; set; } - public int Age { get; set; } - - private PrivateConstructorTestClass() + public class PrivateConstructorTestClass { - } + public string Name { get; set; } + public int Age { get; set; } - // multiple constructors with arguments so the serializer doesn't know what to fall back to - private PrivateConstructorTestClass(object a) - { - } + private PrivateConstructorTestClass() + { + } - // multiple constructors with arguments so the serializer doesn't know what to fall back to - private PrivateConstructorTestClass(object a, object b) - { + // multiple constructors with arguments so the serializer doesn't know what to fall back to + private PrivateConstructorTestClass(object a) + { + } + + // multiple constructors with arguments so the serializer doesn't know what to fall back to + private PrivateConstructorTestClass(object a, object b) + { + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/PrivateConstructorWithPublicParametizedConstructorTestClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/PrivateConstructorWithPublicParametizedConstructorTestClass.cs index 7077d2b2..d63748fc 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/PrivateConstructorWithPublicParametizedConstructorTestClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/PrivateConstructorWithPublicParametizedConstructorTestClass.cs @@ -27,19 +27,19 @@ using System; namespace Newtonsoft.Json.Tests.TestObjects { - public class PrivateConstructorWithPublicParametizedConstructorTestClass - { - public string Name { get; set; } - public int Age { get; set; } - - private PrivateConstructorWithPublicParametizedConstructorTestClass() + public class PrivateConstructorWithPublicParametizedConstructorTestClass { - Age = 1; - } + public string Name { get; set; } + public int Age { get; set; } - public PrivateConstructorWithPublicParametizedConstructorTestClass(string dummy) - { - throw new Exception("Should never get here."); + private PrivateConstructorWithPublicParametizedConstructorTestClass() + { + Age = 1; + } + + public PrivateConstructorWithPublicParametizedConstructorTestClass(string dummy) + { + throw new Exception("Should never get here."); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/PrivateImplementationAClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/PrivateImplementationAClass.cs index 93dc7946..e3a47ce3 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/PrivateImplementationAClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/PrivateImplementationAClass.cs @@ -33,8 +33,8 @@ namespace Newtonsoft.Json.Tests.TestObjects [JsonProperty("PropertyA")] string IPrivateImplementationA.PropertyA { - get { return this.PropertyA; } - set { this.PropertyA = value; } + get { return PropertyA; } + set { PropertyA = value; } } } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/PrivateImplementationBClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/PrivateImplementationBClass.cs index 495468aa..35aa6670 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/PrivateImplementationBClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/PrivateImplementationBClass.cs @@ -25,33 +25,33 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class PrivateImplementationBClass : PrivateImplementationAClass, IPrivateImplementationB, IPrivateOverriddenImplementation - { - [JsonIgnore] - public string PropertyB { get; set; } - - [JsonProperty("PropertyB")] - string IPrivateImplementationB.PropertyB + public class PrivateImplementationBClass : PrivateImplementationAClass, IPrivateImplementationB, IPrivateOverriddenImplementation { - get { return this.PropertyB; } - set { this.PropertyB = value; } - } + [JsonIgnore] + public string PropertyB { get; set; } - [JsonProperty("OverriddenProperty")] - private string OverriddenPropertyString - { - get { return this.OverriddenProperty.ToString(); } - set { this.OverriddenProperty = value; } - } + [JsonProperty("PropertyB")] + string IPrivateImplementationB.PropertyB + { + get { return PropertyB; } + set { PropertyB = value; } + } - [JsonIgnore] - public object OverriddenProperty { get; set; } + [JsonProperty("OverriddenProperty")] + private string OverriddenPropertyString + { + get { return OverriddenProperty.ToString(); } + set { OverriddenProperty = value; } + } - [JsonIgnore] - object IPrivateOverriddenImplementation.OverriddenProperty - { - get { return this.OverriddenProperty; } - set { this.OverriddenProperty = value; } + [JsonIgnore] + public object OverriddenProperty { get; set; } + + [JsonIgnore] + object IPrivateOverriddenImplementation.OverriddenProperty + { + get { return OverriddenProperty; } + set { OverriddenProperty = value; } + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/PrivateMembersClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/PrivateMembersClass.cs index a9575fa4..4b7f0e5c 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/PrivateMembersClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/PrivateMembersClass.cs @@ -25,26 +25,26 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class PrivateMembersClass - { - public PrivateMembersClass(string privateString, string internalString) + public class PrivateMembersClass { - _privateString = privateString; - _internalString = internalString; - } + public PrivateMembersClass(string privateString, string internalString) + { + _privateString = privateString; + _internalString = internalString; + } - public PrivateMembersClass() - { - i = default(int); - } + public PrivateMembersClass() + { + i = default(int); + } - private string _privateString; - private readonly int i; - internal string _internalString; + private string _privateString; + private readonly int i; + internal string _internalString; - public int UseValue() - { - return i; + public int UseValue() + { + return i; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/Product.cs b/Src/Newtonsoft.Json.Tests/TestObjects/Product.cs index f0ba4e19..3e6a382d 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/Product.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/Product.cs @@ -27,28 +27,28 @@ using System; namespace Newtonsoft.Json.Tests.TestObjects { - public class Product - { - public string Name; - public DateTime ExpiryDate = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc); - public decimal Price; - public string[] Sizes; - - public override bool Equals(object obj) + public class Product { - if (obj is Product) - { - Product p = (Product)obj; + public string Name; + public DateTime ExpiryDate = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc); + public decimal Price; + public string[] Sizes; - return (p.Name == Name && p.ExpiryDate == ExpiryDate && p.Price == Price); - } + public override bool Equals(object obj) + { + if (obj is Product) + { + Product p = (Product)obj; - return base.Equals(obj); + return (p.Name == Name && p.ExpiryDate == ExpiryDate && p.Price == Price); + } + + return base.Equals(obj); + } + + public override int GetHashCode() + { + return (Name ?? string.Empty).GetHashCode(); + } } - - public override int GetHashCode() - { - return (Name ?? string.Empty).GetHashCode(); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/ProductCollection.cs b/Src/Newtonsoft.Json.Tests/TestObjects/ProductCollection.cs index 9e22492d..10da5e82 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/ProductCollection.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/ProductCollection.cs @@ -27,7 +27,7 @@ using System.Collections.Generic; namespace Newtonsoft.Json.Tests.TestObjects { - public class ProductCollection : List - { - } + public class ProductCollection : List + { + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/ProductShort.cs b/Src/Newtonsoft.Json.Tests/TestObjects/ProductShort.cs index 902f1dad..b24a6553 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/ProductShort.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/ProductShort.cs @@ -27,11 +27,11 @@ using System; namespace Newtonsoft.Json.Tests.TestObjects { - public class ProductShort - { - public string Name; - public DateTime ExpiryDate; - //public decimal Price; - public string[] Sizes; - } + public class ProductShort + { + public string Name; + public DateTime ExpiryDate; + //public decimal Price; + public string[] Sizes; + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/PropertyCase.cs b/Src/Newtonsoft.Json.Tests/TestObjects/PropertyCase.cs index e98e0705..36994c3b 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/PropertyCase.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/PropertyCase.cs @@ -25,11 +25,11 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class PropertyCase - { - public string firstName { get; set; } - public string FirstName { get; set; } - public string LastName { get; set; } - public string lastName { get; set; } - } + public class PropertyCase + { + public string firstName { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + public string lastName { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/PublicParametizedConstructorRequiringConverterTestClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/PublicParametizedConstructorRequiringConverterTestClass.cs index 9180d2c8..3c23aa90 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/PublicParametizedConstructorRequiringConverterTestClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/PublicParametizedConstructorRequiringConverterTestClass.cs @@ -27,80 +27,80 @@ using System; namespace Newtonsoft.Json.Tests.TestObjects { - public class NameContainer - { - public string Value { get; set; } - } - - public class NameContainerConverter : JsonConverter - { - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + public class NameContainer { - NameContainer nameContainer = value as NameContainer; - - if (nameContainer != null) - writer.WriteValue(nameContainer.Value); - else - writer.WriteNull(); + public string Value { get; set; } } - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + public class NameContainerConverter : JsonConverter { - NameContainer nameContainer = new NameContainer(); - nameContainer.Value = (string)reader.Value; + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + NameContainer nameContainer = value as NameContainer; - return nameContainer; + if (nameContainer != null) + writer.WriteValue(nameContainer.Value); + else + writer.WriteNull(); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + NameContainer nameContainer = new NameContainer(); + nameContainer.Value = (string)reader.Value; + + return nameContainer; + } + + public override bool CanConvert(Type objectType) + { + return objectType == typeof(NameContainer); + } } - public override bool CanConvert(Type objectType) + public class PublicParametizedConstructorRequiringConverterTestClass { - return objectType == typeof(NameContainer); - } - } + private readonly NameContainer _nameContainer; - public class PublicParametizedConstructorRequiringConverterTestClass - { - private readonly NameContainer _nameContainer; + public PublicParametizedConstructorRequiringConverterTestClass(NameContainer nameParameter) + { + _nameContainer = nameParameter; + } - public PublicParametizedConstructorRequiringConverterTestClass(NameContainer nameParameter) - { - _nameContainer = nameParameter; + public NameContainer Name + { + get { return _nameContainer; } + } } - public NameContainer Name + public class PublicParametizedConstructorRequiringConverterWithParameterAttributeTestClass { - get { return _nameContainer; } - } - } + private readonly NameContainer _nameContainer; - public class PublicParametizedConstructorRequiringConverterWithParameterAttributeTestClass - { - private readonly NameContainer _nameContainer; + public PublicParametizedConstructorRequiringConverterWithParameterAttributeTestClass([JsonConverter(typeof(NameContainerConverter))] NameContainer nameParameter) + { + _nameContainer = nameParameter; + } - public PublicParametizedConstructorRequiringConverterWithParameterAttributeTestClass([JsonConverter(typeof(NameContainerConverter))] NameContainer nameParameter) - { - _nameContainer = nameParameter; + public NameContainer Name + { + get { return _nameContainer; } + } } - public NameContainer Name + public class PublicParametizedConstructorRequiringConverterWithPropertyAttributeTestClass { - get { return _nameContainer; } - } - } + private readonly NameContainer _nameContainer; - public class PublicParametizedConstructorRequiringConverterWithPropertyAttributeTestClass - { - private readonly NameContainer _nameContainer; + public PublicParametizedConstructorRequiringConverterWithPropertyAttributeTestClass(NameContainer name) + { + _nameContainer = name; + } - public PublicParametizedConstructorRequiringConverterWithPropertyAttributeTestClass(NameContainer name) - { - _nameContainer = name; + [JsonConverter(typeof(NameContainerConverter))] + public NameContainer Name + { + get { return _nameContainer; } + } } - - [JsonConverter(typeof(NameContainerConverter))] - public NameContainer Name - { - get { return _nameContainer; } - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/PublicParametizedConstructorTestClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/PublicParametizedConstructorTestClass.cs index 98ec9784..24dd7871 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/PublicParametizedConstructorTestClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/PublicParametizedConstructorTestClass.cs @@ -25,18 +25,18 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class PublicParametizedConstructorTestClass - { - private readonly string _name; - - public PublicParametizedConstructorTestClass(string name) + public class PublicParametizedConstructorTestClass { - _name = name; - } + private readonly string _name; - public string Name - { - get { return _name; } + public PublicParametizedConstructorTestClass(string name) + { + _name = name; + } + + public string Name + { + get { return _name; } + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/PublicParametizedConstructorWithNonPropertyParameterTestClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/PublicParametizedConstructorWithNonPropertyParameterTestClass.cs index 67804408..6fb286f6 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/PublicParametizedConstructorWithNonPropertyParameterTestClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/PublicParametizedConstructorWithNonPropertyParameterTestClass.cs @@ -25,18 +25,18 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class PublicParametizedConstructorWithNonPropertyParameterTestClass - { - private readonly string _name; - - public PublicParametizedConstructorWithNonPropertyParameterTestClass(string nameParameter) + public class PublicParametizedConstructorWithNonPropertyParameterTestClass { - _name = nameParameter; - } + private readonly string _name; - public string Name - { - get { return _name; } + public PublicParametizedConstructorWithNonPropertyParameterTestClass(string nameParameter) + { + _name = nameParameter; + } + + public string Name + { + get { return _name; } + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/PublicParametizedConstructorWithPropertyNameConflict.cs b/Src/Newtonsoft.Json.Tests/TestObjects/PublicParametizedConstructorWithPropertyNameConflict.cs index cf4abe83..14b8c5cd 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/PublicParametizedConstructorWithPropertyNameConflict.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/PublicParametizedConstructorWithPropertyNameConflict.cs @@ -27,33 +27,33 @@ using System; namespace Newtonsoft.Json.Tests.TestObjects { - public class PublicParametizedConstructorWithPropertyNameConflict - { - private readonly int _value; - - public PublicParametizedConstructorWithPropertyNameConflict(string name) + public class PublicParametizedConstructorWithPropertyNameConflict { - _value = Convert.ToInt32(name); + private readonly int _value; + + public PublicParametizedConstructorWithPropertyNameConflict(string name) + { + _value = Convert.ToInt32(name); + } + + public int Name + { + get { return _value; } + } } - public int Name + public class PublicParametizedConstructorWithPropertyNameConflictWithAttribute { - get { return _value; } - } - } + private readonly int _value; - public class PublicParametizedConstructorWithPropertyNameConflictWithAttribute - { - private readonly int _value; + public PublicParametizedConstructorWithPropertyNameConflictWithAttribute([JsonProperty("name")] string nameParameter) + { + _value = Convert.ToInt32(nameParameter); + } - public PublicParametizedConstructorWithPropertyNameConflictWithAttribute([JsonProperty("name")]string nameParameter) - { - _value = Convert.ToInt32(nameParameter); + public int Name + { + get { return _value; } + } } - - public int Name - { - get { return _value; } - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/RequestOnly.cs b/Src/Newtonsoft.Json.Tests/TestObjects/RequestOnly.cs index 0b47bcea..fe19e9a7 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/RequestOnly.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/RequestOnly.cs @@ -25,8 +25,8 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class RequestOnly - { - public string Request { get; set; } - } + public class RequestOnly + { + public string Request { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/RequiredMembersClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/RequiredMembersClass.cs index a4ea1864..3da35f95 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/RequiredMembersClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/RequiredMembersClass.cs @@ -27,18 +27,18 @@ using System; namespace Newtonsoft.Json.Tests.TestObjects { - public class RequiredMembersClass - { - [JsonProperty(Required = Required.Always)] - public string FirstName { get; set; } + public class RequiredMembersClass + { + [JsonProperty(Required = Required.Always)] + public string FirstName { get; set; } - [JsonProperty] - public string MiddleName { get; set; } + [JsonProperty] + public string MiddleName { get; set; } - [JsonProperty(Required = Required.AllowNull)] - public string LastName { get; set; } + [JsonProperty(Required = Required.AllowNull)] + public string LastName { get; set; } - [JsonProperty(Required = Required.Default)] - public DateTime BirthDate { get; set; } - } + [JsonProperty(Required = Required.Default)] + public DateTime BirthDate { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/RoleTransfer.cs b/Src/Newtonsoft.Json.Tests/TestObjects/RoleTransfer.cs index c6fe92f5..8db468b3 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/RoleTransfer.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/RoleTransfer.cs @@ -25,22 +25,22 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public enum RoleTransferOperation - { - First, - Second - } + public enum RoleTransferOperation + { + First, + Second + } - public enum RoleTransferDirection - { - First, - Second - } + public enum RoleTransferDirection + { + First, + Second + } - public class RoleTransfer - { - public RoleTransferOperation Operation { get; set; } //This is enum type - public string RoleName { get; set; } - public RoleTransferDirection Direction { get; set; } //This is enum type - } + public class RoleTransfer + { + public RoleTransferOperation Operation { get; set; } //This is enum type + public string RoleName { get; set; } + public RoleTransferDirection Direction { get; set; } //This is enum type + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/SearchResult.cs b/Src/Newtonsoft.Json.Tests/TestObjects/SearchResult.cs index d326ef39..d32c9003 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/SearchResult.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/SearchResult.cs @@ -25,10 +25,10 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class SearchResult - { - public string Title { get; set; } - public string Content { get; set; } - public string Url { get; set; } - } + public class SearchResult + { + public string Title { get; set; } + public string Content { get; set; } + public string Url { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/SerializationEventTestDictionary.cs b/Src/Newtonsoft.Json.Tests/TestObjects/SerializationEventTestDictionary.cs index 390e16b0..77c5bdce 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/SerializationEventTestDictionary.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/SerializationEventTestDictionary.cs @@ -28,53 +28,53 @@ using System.Runtime.Serialization; namespace Newtonsoft.Json.Tests.TestObjects { - public class SerializationEventTestDictionary : Dictionary - { - // This member is serialized and deserialized with no change. - public int Member1 { get; private set; } - - // The value of this field is set and reset during and - // after serialization. - public string Member2 { get; private set; } - - // This field is not serialized. The OnDeserializedAttribute - // is used to set the member value after serialization. - public string Member3 { get; private set; } - - // This field is set to null, but populated after deserialization. - public string Member4 { get; private set; } - - public SerializationEventTestDictionary() + public class SerializationEventTestDictionary : Dictionary { - Member1 = 11; - Member2 = "Hello World!"; - Member3 = "This is a nonserialized value"; - Member4 = null; - } + // This member is serialized and deserialized with no change. + public int Member1 { get; private set; } - [OnSerializing] - internal void OnSerializingMethod(StreamingContext context) - { - Member2 = "This value went into the data file during serialization."; - Add(decimal.MaxValue, "Inserted on serializing"); - } + // The value of this field is set and reset during and + // after serialization. + public string Member2 { get; private set; } - [OnSerialized] - internal void OnSerializedMethod(StreamingContext context) - { - Member2 = "This value was reset after serialization."; - } + // This field is not serialized. The OnDeserializedAttribute + // is used to set the member value after serialization. + public string Member3 { get; private set; } - [OnDeserializing] - internal void OnDeserializingMethod(StreamingContext context) - { - Member3 = "This value was set during deserialization"; - } + // This field is set to null, but populated after deserialization. + public string Member4 { get; private set; } - [OnDeserialized] - internal void OnDeserializedMethod(StreamingContext context) - { - Member4 = "This value was set after deserialization."; + public SerializationEventTestDictionary() + { + Member1 = 11; + Member2 = "Hello World!"; + Member3 = "This is a nonserialized value"; + Member4 = null; + } + + [OnSerializing] + internal void OnSerializingMethod(StreamingContext context) + { + Member2 = "This value went into the data file during serialization."; + Add(decimal.MaxValue, "Inserted on serializing"); + } + + [OnSerialized] + internal void OnSerializedMethod(StreamingContext context) + { + Member2 = "This value was reset after serialization."; + } + + [OnDeserializing] + internal void OnDeserializingMethod(StreamingContext context) + { + Member3 = "This value was set during deserialization"; + } + + [OnDeserialized] + internal void OnDeserializedMethod(StreamingContext context) + { + Member4 = "This value was set after deserialization."; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/SerializationEventTestList.cs b/Src/Newtonsoft.Json.Tests/TestObjects/SerializationEventTestList.cs index 2bc0d0fb..ef4514fa 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/SerializationEventTestList.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/SerializationEventTestList.cs @@ -28,53 +28,53 @@ using System.Runtime.Serialization; namespace Newtonsoft.Json.Tests.TestObjects { - public class SerializationEventTestList : Collection - { - // This member is serialized and deserialized with no change. - public int Member1 { get; private set; } - - // The value of this field is set and reset during and - // after serialization. - public string Member2 { get; private set; } - - // This field is not serialized. The OnDeserializedAttribute - // is used to set the member value after serialization. - public string Member3 { get; private set; } - - // This field is set to null, but populated after deserialization. - public string Member4 { get; private set; } - - public SerializationEventTestList() + public class SerializationEventTestList : Collection { - Member1 = 11; - Member2 = "Hello World!"; - Member3 = "This is a nonserialized value"; - Member4 = null; - } + // This member is serialized and deserialized with no change. + public int Member1 { get; private set; } - [OnSerializing] - internal void OnSerializingMethod(StreamingContext context) - { - Member2 = "This value went into the data file during serialization."; - Insert(0, -1); - } + // The value of this field is set and reset during and + // after serialization. + public string Member2 { get; private set; } - [OnSerialized] - internal void OnSerializedMethod(StreamingContext context) - { - Member2 = "This value was reset after serialization."; - } + // This field is not serialized. The OnDeserializedAttribute + // is used to set the member value after serialization. + public string Member3 { get; private set; } - [OnDeserializing] - internal void OnDeserializingMethod(StreamingContext context) - { - Member3 = "This value was set during deserialization"; - } + // This field is set to null, but populated after deserialization. + public string Member4 { get; private set; } - [OnDeserialized] - internal void OnDeserializedMethod(StreamingContext context) - { - Member4 = "This value was set after deserialization."; + public SerializationEventTestList() + { + Member1 = 11; + Member2 = "Hello World!"; + Member3 = "This is a nonserialized value"; + Member4 = null; + } + + [OnSerializing] + internal void OnSerializingMethod(StreamingContext context) + { + Member2 = "This value went into the data file during serialization."; + Insert(0, -1); + } + + [OnSerialized] + internal void OnSerializedMethod(StreamingContext context) + { + Member2 = "This value was reset after serialization."; + } + + [OnDeserializing] + internal void OnDeserializingMethod(StreamingContext context) + { + Member3 = "This value was set during deserialization"; + } + + [OnDeserialized] + internal void OnDeserializedMethod(StreamingContext context) + { + Member4 = "This value was set after deserialization."; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/SerializationEventTestObject.cs b/Src/Newtonsoft.Json.Tests/TestObjects/SerializationEventTestObject.cs index b77e05b4..9f1371d2 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/SerializationEventTestObject.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/SerializationEventTestObject.cs @@ -29,107 +29,107 @@ using Newtonsoft.Json.Serialization; namespace Newtonsoft.Json.Tests.TestObjects { - public class SerializationEventTestObject - { - // This member is serialized and deserialized with no change. - public int Member1 { get; set; } - - // The value of this field is set and reset during and - // after serialization. - public string Member2 { get; set; } - - // This field is not serialized. The OnDeserializedAttribute - // is used to set the member value after serialization. - [JsonIgnore] - public string Member3 { get; set; } - - // This field is set to null, but populated after deserialization. - public string Member4 { get; set; } - - // This field is set to null, but populated after error. - [JsonIgnore] - public string Member5 { get; set; } - - // Getting or setting this field will throw an error. - public string Member6 + public class SerializationEventTestObject { - get { throw new Exception("Member5 get error!"); } - set { throw new Exception("Member5 set error!"); } + // This member is serialized and deserialized with no change. + public int Member1 { get; set; } + + // The value of this field is set and reset during and + // after serialization. + public string Member2 { get; set; } + + // This field is not serialized. The OnDeserializedAttribute + // is used to set the member value after serialization. + [JsonIgnore] + public string Member3 { get; set; } + + // This field is set to null, but populated after deserialization. + public string Member4 { get; set; } + + // This field is set to null, but populated after error. + [JsonIgnore] + public string Member5 { get; set; } + + // Getting or setting this field will throw an error. + public string Member6 + { + get { throw new Exception("Member5 get error!"); } + set { throw new Exception("Member5 set error!"); } + } + + public SerializationEventTestObject() + { + Member1 = 11; + Member2 = "Hello World!"; + Member3 = "This is a nonserialized value"; + Member4 = null; + } + + [OnSerializing] + internal void OnSerializingMethod(StreamingContext context) + { + Member2 = "This value went into the data file during serialization."; + } + + [OnSerialized] + internal void OnSerializedMethod(StreamingContext context) + { + Member2 = "This value was reset after serialization."; + } + + [OnDeserializing] + internal void OnDeserializingMethod(StreamingContext context) + { + Member3 = "This value was set during deserialization"; + } + + [OnDeserialized] + internal void OnDeserializedMethod(StreamingContext context) + { + Member4 = "This value was set after deserialization."; + } + + [OnError] + internal void OnErrorMethod(StreamingContext context, ErrorContext errorContext) + { + Member5 = "Error message for member " + errorContext.Member + " = " + errorContext.Error.Message; + errorContext.Handled = true; + } } - public SerializationEventTestObject() + public class DerivedSerializationEventTestObject : SerializationEventTestObject { - Member1 = 11; - Member2 = "Hello World!"; - Member3 = "This is a nonserialized value"; - Member4 = null; - } + // This field is set to null, but populated after deserialization, only + // in the derived class + [JsonIgnore] + public string Member7 { get; set; } - [OnSerializing] - internal void OnSerializingMethod(StreamingContext context) - { - Member2 = "This value went into the data file during serialization."; - } + // These empty methods exist to make sure we're not covering up the base + // methods + [OnSerializing] + internal void OnDerivedSerializingMethod(StreamingContext context) + { + } - [OnSerialized] - internal void OnSerializedMethod(StreamingContext context) - { - Member2 = "This value was reset after serialization."; - } + [OnSerialized] + internal void OnDerivedSerializedMethod(StreamingContext context) + { + } - [OnDeserializing] - internal void OnDeserializingMethod(StreamingContext context) - { - Member3 = "This value was set during deserialization"; - } + [OnDeserializing] + internal void OnDerivedDeserializingMethod(StreamingContext context) + { + } - [OnDeserialized] - internal void OnDeserializedMethod(StreamingContext context) - { - Member4 = "This value was set after deserialization."; - } + [OnDeserialized] + internal void OnDerivedDeserializedMethod(StreamingContext context) + { + Member7 = "This value was set after deserialization."; + } - [OnError] - internal void OnErrorMethod(StreamingContext context, ErrorContext errorContext) - { - Member5 = "Error message for member " + errorContext.Member + " = " + errorContext.Error.Message; - errorContext.Handled = true; + [OnError] + internal void OnDerivedErrorMethod(StreamingContext context, ErrorContext errorContext) + { + } } - } - - public class DerivedSerializationEventTestObject : SerializationEventTestObject - { - // This field is set to null, but populated after deserialization, only - // in the derived class - [JsonIgnore] - public string Member7 { get; set; } - - // These empty methods exist to make sure we're not covering up the base - // methods - [OnSerializing] - internal void OnDerivedSerializingMethod(StreamingContext context) - { - } - - [OnSerialized] - internal void OnDerivedSerializedMethod(StreamingContext context) - { - } - - [OnDeserializing] - internal void OnDerivedDeserializingMethod(StreamingContext context) - { - } - - [OnDeserialized] - internal void OnDerivedDeserializedMethod(StreamingContext context) - { - Member7 = "This value was set after deserialization."; - } - - [OnError] - internal void OnDerivedErrorMethod(StreamingContext context, ErrorContext errorContext) - { - } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/SerializationEventTestObjectWithConstructor.cs b/Src/Newtonsoft.Json.Tests/TestObjects/SerializationEventTestObjectWithConstructor.cs index 3e3a557e..c933800b 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/SerializationEventTestObjectWithConstructor.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/SerializationEventTestObjectWithConstructor.cs @@ -29,55 +29,55 @@ using Newtonsoft.Json.Serialization; namespace Newtonsoft.Json.Tests.TestObjects { - public class SerializationEventTestObjectWithConstructor - { - // This member is serialized and deserialized with no change. - public int Member1 { get; private set; } - - // The value of this field is set and reset during and - // after serialization. - public string Member2 { get; private set; } - - // This field is not serialized. The OnDeserializedAttribute - // is used to set the member value after serialization. - [JsonIgnore] - public string Member3 { get; private set; } - - // This field is set to null, but populated after deserialization. - public string Member4 { get; private set; } - - public SerializationEventTestObjectWithConstructor(int member1, - string member2, - string member4) + public class SerializationEventTestObjectWithConstructor { - Member1 = member1; - Member2 = member2; - Member3 = "This is a nonserialized value"; - Member4 = member4; - } + // This member is serialized and deserialized with no change. + public int Member1 { get; private set; } - [OnSerializing] - internal void OnSerializingMethod(StreamingContext context) - { - Member2 = "This value went into the data file during serialization."; - } + // The value of this field is set and reset during and + // after serialization. + public string Member2 { get; private set; } - [OnSerialized] - internal void OnSerializedMethod(StreamingContext context) - { - Member2 = "This value was reset after serialization."; - } + // This field is not serialized. The OnDeserializedAttribute + // is used to set the member value after serialization. + [JsonIgnore] + public string Member3 { get; private set; } - [OnDeserializing] - internal void OnDeserializingMethod(StreamingContext context) - { - Member3 = "This value was set during deserialization"; - } + // This field is set to null, but populated after deserialization. + public string Member4 { get; private set; } - [OnDeserialized] - internal void OnDeserializedMethod(StreamingContext context) - { - Member4 = "This value was set after deserialization."; + public SerializationEventTestObjectWithConstructor(int member1, + string member2, + string member4) + { + Member1 = member1; + Member2 = member2; + Member3 = "This is a nonserialized value"; + Member4 = member4; + } + + [OnSerializing] + internal void OnSerializingMethod(StreamingContext context) + { + Member2 = "This value went into the data file during serialization."; + } + + [OnSerialized] + internal void OnSerializedMethod(StreamingContext context) + { + Member2 = "This value was reset after serialization."; + } + + [OnDeserializing] + internal void OnDeserializingMethod(StreamingContext context) + { + Member3 = "This value was set during deserialization"; + } + + [OnDeserialized] + internal void OnDeserializedMethod(StreamingContext context) + { + Member4 = "This value was set after deserialization."; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/SetOnlyPropertyClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/SetOnlyPropertyClass.cs index da57e655..7810d26b 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/SetOnlyPropertyClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/SetOnlyPropertyClass.cs @@ -25,13 +25,13 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class SetOnlyPropertyClass - { - public string Field = "Field"; - - public string SetOnlyProperty + public class SetOnlyPropertyClass { - set { } + public string Field = "Field"; + + public string SetOnlyProperty + { + set { } + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/SetOnlyPropertyClass2.cs b/Src/Newtonsoft.Json.Tests/TestObjects/SetOnlyPropertyClass2.cs index 6b6d0bef..f7f57a33 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/SetOnlyPropertyClass2.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/SetOnlyPropertyClass2.cs @@ -25,16 +25,18 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class SetOnlyPropertyClass2 - { - private object _value; - public object SetOnlyProperty + public class SetOnlyPropertyClass2 { - set { _value = value; } + private object _value; + + public object SetOnlyProperty + { + set { _value = value; } + } + + public object GetValue() + { + return _value; + } } - public object GetValue() - { - return _value; - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/Shortie.cs b/Src/Newtonsoft.Json.Tests/TestObjects/Shortie.cs index 365315e1..61e7ccbe 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/Shortie.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/Shortie.cs @@ -25,17 +25,17 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class Shortie - { - public string Original { get; set; } - public string Shortened { get; set; } - public string Short { get; set; } - public ShortieException Error { get; set; } - } + public class Shortie + { + public string Original { get; set; } + public string Shortened { get; set; } + public string Short { get; set; } + public ShortieException Error { get; set; } + } - public class ShortieException - { - public int Code { get; set; } - public string ErrorMessage { get; set; } - } + public class ShortieException + { + public int Code { get; set; } + public string ErrorMessage { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/Store.cs b/Src/Newtonsoft.Json.Tests/TestObjects/Store.cs index a8d41c75..828a0fe6 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/Store.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/Store.cs @@ -1,4 +1,4 @@ -#region License +#region License // Copyright (c) 2007 James Newton-King // // Permission is hereby granted, free of charge, to any person @@ -28,37 +28,40 @@ using System.Collections.Generic; namespace Newtonsoft.Json.Tests.TestObjects { - public class Store - { - public StoreColor Color = StoreColor.Yellow; - public DateTime Establised = new DateTime(2010, 1, 22, 1, 1, 1, DateTimeKind.Utc); - public double Width = 1.1; - public int Employees = 999; - public int[] RoomsPerFloor = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - public bool Open = false; - public char Symbol = '@'; - [JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace)] - public List Mottos = new List(); - public decimal Cost = 100980.1M; - public string Escape = "\r\n\t\f\b?{\\r\\n\"\'"; - [JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace)] - public List product = new List(); - - public Store() + public class Store { - Mottos.Add("Hello World"); - Mottos.Add("öäüÖÄÜ\\'{new Date(12345);}[222]_µ@²³~"); - Mottos.Add(null); - Mottos.Add(" "); + public StoreColor Color = StoreColor.Yellow; + public DateTime Establised = new DateTime(2010, 1, 22, 1, 1, 1, DateTimeKind.Utc); + public double Width = 1.1; + public int Employees = 999; + public int[] RoomsPerFloor = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + public bool Open = false; + public char Symbol = '@'; - Product rocket = new Product(); - rocket.Name = "Rocket"; - rocket.ExpiryDate = new DateTime(2000, 2, 2, 23, 1, 30, DateTimeKind.Utc); - Product alien = new Product(); - alien.Name = "Alien"; + [JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace)] + public List Mottos = new List(); - product.Add(rocket); - product.Add(alien); + public decimal Cost = 100980.1M; + public string Escape = "\r\n\t\f\b?{\\r\\n\"\'"; + + [JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace)] + public List product = new List(); + + public Store() + { + Mottos.Add("Hello World"); + Mottos.Add("öäüÖÄÜ\\'{new Date(12345);}[222]_µ@²³~"); + Mottos.Add(null); + Mottos.Add(" "); + + Product rocket = new Product(); + rocket.Name = "Rocket"; + rocket.ExpiryDate = new DateTime(2000, 2, 2, 23, 1, 30, DateTimeKind.Utc); + Product alien = new Product(); + alien.Name = "Alien"; + + product.Add(rocket); + product.Add(alien); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/StoreColor.cs b/Src/Newtonsoft.Json.Tests/TestObjects/StoreColor.cs index bc384b16..5d042cc5 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/StoreColor.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/StoreColor.cs @@ -27,13 +27,13 @@ using System; namespace Newtonsoft.Json.Tests.TestObjects { - [Flags] - public enum StoreColor - { - Black = 1, - Red = 2, - Yellow = 4, - White = 8, - DarkGoldenrod = 16 - } + [Flags] + public enum StoreColor + { + Black = 1, + Red = 2, + Yellow = 4, + White = 8, + DarkGoldenrod = 16 + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/StructTest.cs b/Src/Newtonsoft.Json.Tests/TestObjects/StructTest.cs index 45d492f2..4a0143d5 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/StructTest.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/StructTest.cs @@ -25,11 +25,11 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public struct StructTest - { - public string StringProperty { get; set; } - public string StringField; - public int IntProperty { get; set; } - public int IntField; - } + public struct StructTest + { + public string StringProperty { get; set; } + public string StringField; + public int IntProperty { get; set; } + public int IntField; + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/SubKlass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/SubKlass.cs index 9294a8ed..ac8cf629 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/SubKlass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/SubKlass.cs @@ -25,9 +25,13 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class SubKlass : SuperKlass - { - public string SubProp { get; set; } - public SubKlass(string subprop) { SubProp = subprop; } - } + public class SubKlass : SuperKlass + { + public string SubProp { get; set; } + + public SubKlass(string subprop) + { + SubProp = subprop; + } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/SuperKlass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/SuperKlass.cs index 2c581ac9..74d853ce 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/SuperKlass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/SuperKlass.cs @@ -25,9 +25,13 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class SuperKlass - { - public string SuperProp { get; set; } - public SuperKlass() { SuperProp = "default superprop"; } - } + public class SuperKlass + { + public string SuperProp { get; set; } + + public SuperKlass() + { + SuperProp = "default superprop"; + } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/TypeClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/TypeClass.cs index 21333a98..4df1eb4a 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/TypeClass.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/TypeClass.cs @@ -27,8 +27,8 @@ using System; namespace Newtonsoft.Json.Tests.TestObjects { - public class TypeClass - { - public Type TypeProperty { get; set; } - } + public class TypeClass + { + public Type TypeProperty { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/TypedSubHashtable.cs b/Src/Newtonsoft.Json.Tests/TestObjects/TypedSubHashtable.cs index f61ca2fa..eb0b38a5 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/TypedSubHashtable.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/TypedSubHashtable.cs @@ -28,10 +28,10 @@ using System.Collections; namespace Newtonsoft.Json.Tests.TestObjects { #if !SILVERLIGHT && !NETFX_CORE - public class TypedSubHashtable - { - public string Name; - public Hashtable Hash; - } + public class TypedSubHashtable + { + public string Name; + public Hashtable Hash; + } #endif } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/UserNullable.cs b/Src/Newtonsoft.Json.Tests/TestObjects/UserNullable.cs index 8fb8cf68..30119d95 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/UserNullable.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/UserNullable.cs @@ -27,14 +27,14 @@ using System; namespace Newtonsoft.Json.Tests.TestObjects { - public class UserNullable - { - public Guid Id; - public string FName; - public string LName; - public int RoleId; - public int? NullableRoleId; - public int? NullRoleId; - public bool? Active; - } + public class UserNullable + { + public Guid Id; + public string FName; + public string LName; + public int RoleId; + public int? NullableRoleId; + public int? NullRoleId; + public bool? Active; + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/VersionKeyedCollection.cs b/Src/Newtonsoft.Json.Tests/TestObjects/VersionKeyedCollection.cs index 3c4106a7..f283963c 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/VersionKeyedCollection.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/VersionKeyedCollection.cs @@ -33,41 +33,41 @@ using Newtonsoft.Json.Tests.TestObjects; namespace Newtonsoft.Json.Tests.TestObjects { - public class VersionKeyedCollection : KeyedCollection, IEnumerable - { - public List Messages { get; set; } - - public VersionKeyedCollection() + public class VersionKeyedCollection : KeyedCollection, IEnumerable { - Messages = new List(); - } + public List Messages { get; set; } - protected override string GetKeyForItem(Person item) - { - return item.Name; - } + public VersionKeyedCollection() + { + Messages = new List(); + } - [OnError] - internal void OnErrorMethod(StreamingContext context, ErrorContext errorContext) - { - Messages.Add(errorContext.Path + " - Error message for member " + errorContext.Member + " = " + errorContext.Error.Message); - errorContext.Handled = true; - } + protected override string GetKeyForItem(Person item) + { + return item.Name; + } - IEnumerator IEnumerable.GetEnumerator() - { - for (int i = 0; i < Count; i++) - { - if (i % 2 == 0) - throw new Exception("Index even: " + i); + [OnError] + internal void OnErrorMethod(StreamingContext context, ErrorContext errorContext) + { + Messages.Add(errorContext.Path + " - Error message for member " + errorContext.Member + " = " + errorContext.Error.Message); + errorContext.Handled = true; + } - yield return this[i]; - } - } + IEnumerator IEnumerable.GetEnumerator() + { + for (int i = 0; i < Count; i++) + { + if (i % 2 == 0) + throw new Exception("Index even: " + i); - IEnumerator IEnumerable.GetEnumerator() - { - return ((IEnumerable) this).GetEnumerator(); + yield return this[i]; + } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return ((IEnumerable)this).GetEnumerator(); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/WagePerson.cs b/Src/Newtonsoft.Json.Tests/TestObjects/WagePerson.cs index f6f64356..f4e05ce7 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/WagePerson.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/WagePerson.cs @@ -25,9 +25,9 @@ namespace Newtonsoft.Json.Tests.TestObjects { - public class WagePerson : Person - { - [JsonProperty] - public decimal HourlyWage { get; set; } - } + public class WagePerson : Person + { + [JsonProperty] + public decimal HourlyWage { get; set; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Utilities/DateTimeUtilsTests.cs b/Src/Newtonsoft.Json.Tests/Utilities/DateTimeUtilsTests.cs index 31822fd9..06444eef 100644 --- a/Src/Newtonsoft.Json.Tests/Utilities/DateTimeUtilsTests.cs +++ b/Src/Newtonsoft.Json.Tests/Utilities/DateTimeUtilsTests.cs @@ -39,188 +39,188 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Tests.Utilities { - [TestFixture] - public class DateTimeUtilsTests : TestFixtureBase - { - [Test] - public void RoundTripDateTimeMinAndMax() + [TestFixture] + public class DateTimeUtilsTests : TestFixtureBase { - RoundtripDateIso(DateTime.MinValue); - RoundtripDateIso(DateTime.MaxValue); - } + [Test] + public void RoundTripDateTimeMinAndMax() + { + RoundtripDateIso(DateTime.MinValue); + RoundtripDateIso(DateTime.MaxValue); + } - private static void RoundtripDateIso(DateTime value) - { - StringWriter sw = new StringWriter(); - DateTimeUtils.WriteDateTimeString(sw, value, DateFormatHandling.IsoDateFormat, null, CultureInfo.InvariantCulture); - string minDateText = sw.ToString(); + private static void RoundtripDateIso(DateTime value) + { + StringWriter sw = new StringWriter(); + DateTimeUtils.WriteDateTimeString(sw, value, DateFormatHandling.IsoDateFormat, null, CultureInfo.InvariantCulture); + string minDateText = sw.ToString(); - object dt; - DateTimeUtils.TryParseDateIso(minDateText, DateParseHandling.DateTime, DateTimeZoneHandling.RoundtripKind, out dt); + object dt; + DateTimeUtils.TryParseDateIso(minDateText, DateParseHandling.DateTime, DateTimeZoneHandling.RoundtripKind, out dt); - DateTime parsedDt = (DateTime) dt; - Assert.AreEqual(value, parsedDt); - } + DateTime parsedDt = (DateTime)dt; + Assert.AreEqual(value, parsedDt); + } - [Test] - public void NewDateTimeParse() - { - AssertNewDateTimeParseEqual("999x-12-31T23:59:59"); - AssertNewDateTimeParseEqual("9999x12-31T23:59:59"); - AssertNewDateTimeParseEqual("9999-1x-31T23:59:59"); - AssertNewDateTimeParseEqual("9999-12x31T23:59:59"); - AssertNewDateTimeParseEqual("9999-12-3xT23:59:59"); - AssertNewDateTimeParseEqual("9999-12-31x23:59:59"); - AssertNewDateTimeParseEqual("9999-12-31T2x:59:59"); - AssertNewDateTimeParseEqual("9999-12-31T23x59:59"); - AssertNewDateTimeParseEqual("9999-12-31T23:5x:59"); - AssertNewDateTimeParseEqual("9999-12-31T23:59x59"); - AssertNewDateTimeParseEqual("9999-12-31T23:59:5x"); - AssertNewDateTimeParseEqual("9999-12-31T23:59:5"); - AssertNewDateTimeParseEqual("9999-12-31T23:59:59.x"); - AssertNewDateTimeParseEqual("9999-12-31T23:59:59.99999999"); - //AssertNewDateTimeParseEqual("9999-12-31T23:59:59.", null); // DateTime.TryParse is bugged and should return null + [Test] + public void NewDateTimeParse() + { + AssertNewDateTimeParseEqual("999x-12-31T23:59:59"); + AssertNewDateTimeParseEqual("9999x12-31T23:59:59"); + AssertNewDateTimeParseEqual("9999-1x-31T23:59:59"); + AssertNewDateTimeParseEqual("9999-12x31T23:59:59"); + AssertNewDateTimeParseEqual("9999-12-3xT23:59:59"); + AssertNewDateTimeParseEqual("9999-12-31x23:59:59"); + AssertNewDateTimeParseEqual("9999-12-31T2x:59:59"); + AssertNewDateTimeParseEqual("9999-12-31T23x59:59"); + AssertNewDateTimeParseEqual("9999-12-31T23:5x:59"); + AssertNewDateTimeParseEqual("9999-12-31T23:59x59"); + AssertNewDateTimeParseEqual("9999-12-31T23:59:5x"); + AssertNewDateTimeParseEqual("9999-12-31T23:59:5"); + AssertNewDateTimeParseEqual("9999-12-31T23:59:59.x"); + AssertNewDateTimeParseEqual("9999-12-31T23:59:59.99999999"); + //AssertNewDateTimeParseEqual("9999-12-31T23:59:59.", null); // DateTime.TryParse is bugged and should return null - AssertNewDateTimeParseEqual("2000-12-15T22:11:03.055Z"); - AssertNewDateTimeParseEqual("2000-12-15T22:11:03.055"); - AssertNewDateTimeParseEqual("2000-12-15T22:11:03.055+00:00"); - AssertNewDateTimeParseEqual("2000-12-15T22:11:03.055+23:30"); - AssertNewDateTimeParseEqual("2000-12-15T22:11:03.055-23:30"); - AssertNewDateTimeParseEqual("2000-12-15T22:11:03.055+11:30"); - AssertNewDateTimeParseEqual("2000-12-15T22:11:03.055-11:30"); + AssertNewDateTimeParseEqual("2000-12-15T22:11:03.055Z"); + AssertNewDateTimeParseEqual("2000-12-15T22:11:03.055"); + AssertNewDateTimeParseEqual("2000-12-15T22:11:03.055+00:00"); + AssertNewDateTimeParseEqual("2000-12-15T22:11:03.055+23:30"); + AssertNewDateTimeParseEqual("2000-12-15T22:11:03.055-23:30"); + AssertNewDateTimeParseEqual("2000-12-15T22:11:03.055+11:30"); + AssertNewDateTimeParseEqual("2000-12-15T22:11:03.055-11:30"); - AssertNewDateTimeParseEqual("2000-12-15T22:11:03Z"); - AssertNewDateTimeParseEqual("2000-12-15T22:11:03"); - AssertNewDateTimeParseEqual("2000-12-15T22:11:03+00:00"); - AssertNewDateTimeParseEqual("2000-12-15T22:11:03+23:30"); - AssertNewDateTimeParseEqual("2000-12-15T22:11:03-23:30"); - AssertNewDateTimeParseEqual("2000-12-15T22:11:03+11:30"); - AssertNewDateTimeParseEqual("2000-12-15T22:11:03-11:30"); + AssertNewDateTimeParseEqual("2000-12-15T22:11:03Z"); + AssertNewDateTimeParseEqual("2000-12-15T22:11:03"); + AssertNewDateTimeParseEqual("2000-12-15T22:11:03+00:00"); + AssertNewDateTimeParseEqual("2000-12-15T22:11:03+23:30"); + AssertNewDateTimeParseEqual("2000-12-15T22:11:03-23:30"); + AssertNewDateTimeParseEqual("2000-12-15T22:11:03+11:30"); + AssertNewDateTimeParseEqual("2000-12-15T22:11:03-11:30"); - AssertNewDateTimeParseEqual("0001-01-01T00:00:00Z"); - AssertNewDateTimeParseEqual("0001-01-01T00:00:00"); // this is DateTime.MinDate - //AssertNewDateTimeParseEqual("0001-01-01T00:00:00+00:00"); // when the timezone is negative then this breaks - //AssertNewDateTimeParseEqual("0001-01-01T00:00:00+23:30"); // I don't know why a different value is returned from DateTime.TryParse, I think it is a bug in .NET - AssertNewDateTimeParseEqual("0001-01-01T00:00:00-23:30"); - //AssertNewDateTimeParseEqual("0001-01-01T00:00:00+11:30"); // when the timezone is negative then this breaks - AssertNewDateTimeParseEqual("0001-01-01T00:00:00-12:00"); + AssertNewDateTimeParseEqual("0001-01-01T00:00:00Z"); + AssertNewDateTimeParseEqual("0001-01-01T00:00:00"); // this is DateTime.MinDate + //AssertNewDateTimeParseEqual("0001-01-01T00:00:00+00:00"); // when the timezone is negative then this breaks + //AssertNewDateTimeParseEqual("0001-01-01T00:00:00+23:30"); // I don't know why a different value is returned from DateTime.TryParse, I think it is a bug in .NET + AssertNewDateTimeParseEqual("0001-01-01T00:00:00-23:30"); + //AssertNewDateTimeParseEqual("0001-01-01T00:00:00+11:30"); // when the timezone is negative then this breaks + AssertNewDateTimeParseEqual("0001-01-01T00:00:00-12:00"); - AssertNewDateTimeParseEqual("9999-12-31T23:59:59.9999999Z"); - AssertNewDateTimeParseEqual("9999-12-31T23:59:59.9999999"); // this is DateTime.MaxDate - AssertNewDateTimeParseEqual("9999-12-31T23:59:59.9999999+00:00", DateTime.MaxValue); // DateTime.TryParse fails instead of returning MaxDate in some timezones - AssertNewDateTimeParseEqual("9999-12-31T23:59:59.9999999+23:30"); - AssertNewDateTimeParseEqual("9999-12-31T23:59:59.9999999-23:30", DateTime.MaxValue); // DateTime.TryParse fails instead of returning MaxDate in some timezones - AssertNewDateTimeParseEqual("9999-12-31T23:59:59.9999999+11:30", DateTime.MaxValue); // DateTime.TryParse fails instead of returning MaxDate in some timezones - AssertNewDateTimeParseEqual("9999-12-31T23:59:59.9999999-11:30", DateTime.MaxValue); // DateTime.TryParse fails instead of returning MaxDate in some timezones - } + AssertNewDateTimeParseEqual("9999-12-31T23:59:59.9999999Z"); + AssertNewDateTimeParseEqual("9999-12-31T23:59:59.9999999"); // this is DateTime.MaxDate + AssertNewDateTimeParseEqual("9999-12-31T23:59:59.9999999+00:00", DateTime.MaxValue); // DateTime.TryParse fails instead of returning MaxDate in some timezones + AssertNewDateTimeParseEqual("9999-12-31T23:59:59.9999999+23:30"); + AssertNewDateTimeParseEqual("9999-12-31T23:59:59.9999999-23:30", DateTime.MaxValue); // DateTime.TryParse fails instead of returning MaxDate in some timezones + AssertNewDateTimeParseEqual("9999-12-31T23:59:59.9999999+11:30", DateTime.MaxValue); // DateTime.TryParse fails instead of returning MaxDate in some timezones + AssertNewDateTimeParseEqual("9999-12-31T23:59:59.9999999-11:30", DateTime.MaxValue); // DateTime.TryParse fails instead of returning MaxDate in some timezones + } - private void AssertNewDateTimeParseEqual(string text, object oldDate) - { - object oldDt; - if (TryParseDateIso(text, DateParseHandling.DateTime, DateTimeZoneHandling.RoundtripKind, out oldDt)) - { - oldDate = oldDt; - } + private void AssertNewDateTimeParseEqual(string text, object oldDate) + { + object oldDt; + if (TryParseDateIso(text, DateParseHandling.DateTime, DateTimeZoneHandling.RoundtripKind, out oldDt)) + { + oldDate = oldDt; + } - object newDt; - DateTimeUtils.TryParseDateIso(text, DateParseHandling.DateTime, DateTimeZoneHandling.RoundtripKind, out newDt); + object newDt; + DateTimeUtils.TryParseDateIso(text, DateParseHandling.DateTime, DateTimeZoneHandling.RoundtripKind, out newDt); - if (!Equals(oldDate, newDt)) - { - Assert.AreEqual(oldDate, newDt, "DateTime parse not equal. Text: '{0}' Old ticks: {1} New ticks: {2}".FormatWith( - CultureInfo.InvariantCulture, - text, - oldDate != null ? ((DateTime)oldDate).Ticks : (long?)null, - newDt != null ? ((DateTime)newDt).Ticks : (long?)null - )); - } - } + if (!Equals(oldDate, newDt)) + { + Assert.AreEqual(oldDate, newDt, "DateTime parse not equal. Text: '{0}' Old ticks: {1} New ticks: {2}".FormatWith( + CultureInfo.InvariantCulture, + text, + oldDate != null ? ((DateTime)oldDate).Ticks : (long?)null, + newDt != null ? ((DateTime)newDt).Ticks : (long?)null + )); + } + } - private void AssertNewDateTimeParseEqual(string text) - { - object oldDt; - TryParseDateIso(text, DateParseHandling.DateTime, DateTimeZoneHandling.RoundtripKind, out oldDt); + private void AssertNewDateTimeParseEqual(string text) + { + object oldDt; + TryParseDateIso(text, DateParseHandling.DateTime, DateTimeZoneHandling.RoundtripKind, out oldDt); - AssertNewDateTimeParseEqual(text, oldDt); - } + AssertNewDateTimeParseEqual(text, oldDt); + } #if !NET20 - [Test] - public void NewDateTimeOffsetParse() - { - AssertNewDateTimeOffsetParseEqual("0001-01-01T00:00:00"); + [Test] + public void NewDateTimeOffsetParse() + { + AssertNewDateTimeOffsetParseEqual("0001-01-01T00:00:00"); - AssertNewDateTimeOffsetParseEqual("2000-12-15T22:11:03.055Z"); - AssertNewDateTimeOffsetParseEqual("2000-12-15T22:11:03.055"); - AssertNewDateTimeOffsetParseEqual("2000-12-15T22:11:03.055+00:00"); - AssertNewDateTimeOffsetParseEqual("2000-12-15T22:11:03.055+13:30"); - AssertNewDateTimeOffsetParseEqual("2000-12-15T22:11:03.055-13:30"); + AssertNewDateTimeOffsetParseEqual("2000-12-15T22:11:03.055Z"); + AssertNewDateTimeOffsetParseEqual("2000-12-15T22:11:03.055"); + AssertNewDateTimeOffsetParseEqual("2000-12-15T22:11:03.055+00:00"); + AssertNewDateTimeOffsetParseEqual("2000-12-15T22:11:03.055+13:30"); + AssertNewDateTimeOffsetParseEqual("2000-12-15T22:11:03.055-13:30"); - AssertNewDateTimeOffsetParseEqual("2000-12-15T22:11:03Z"); - AssertNewDateTimeOffsetParseEqual("2000-12-15T22:11:03"); - AssertNewDateTimeOffsetParseEqual("2000-12-15T22:11:03+00:00"); - AssertNewDateTimeOffsetParseEqual("2000-12-15T22:11:03+13:30"); - AssertNewDateTimeOffsetParseEqual("2000-12-15T22:11:03-13:30"); + AssertNewDateTimeOffsetParseEqual("2000-12-15T22:11:03Z"); + AssertNewDateTimeOffsetParseEqual("2000-12-15T22:11:03"); + AssertNewDateTimeOffsetParseEqual("2000-12-15T22:11:03+00:00"); + AssertNewDateTimeOffsetParseEqual("2000-12-15T22:11:03+13:30"); + AssertNewDateTimeOffsetParseEqual("2000-12-15T22:11:03-13:30"); - AssertNewDateTimeOffsetParseEqual("0001-01-01T00:00:00Z"); - AssertNewDateTimeOffsetParseEqual("0001-01-01T00:00:00+00:00"); - AssertNewDateTimeOffsetParseEqual("0001-01-01T00:00:00+13:30"); - AssertNewDateTimeOffsetParseEqual("0001-01-01T00:00:00-13:30"); + AssertNewDateTimeOffsetParseEqual("0001-01-01T00:00:00Z"); + AssertNewDateTimeOffsetParseEqual("0001-01-01T00:00:00+00:00"); + AssertNewDateTimeOffsetParseEqual("0001-01-01T00:00:00+13:30"); + AssertNewDateTimeOffsetParseEqual("0001-01-01T00:00:00-13:30"); - AssertNewDateTimeOffsetParseEqual("9999-12-31T23:59:59.9999999Z"); - AssertNewDateTimeOffsetParseEqual("9999-12-31T23:59:59.9999999"); - AssertNewDateTimeOffsetParseEqual("9999-12-31T23:59:59.9999999+00:00"); - AssertNewDateTimeOffsetParseEqual("9999-12-31T23:59:59.9999999+13:30"); - AssertNewDateTimeOffsetParseEqual("9999-12-31T23:59:59.9999999-13:30"); - } + AssertNewDateTimeOffsetParseEqual("9999-12-31T23:59:59.9999999Z"); + AssertNewDateTimeOffsetParseEqual("9999-12-31T23:59:59.9999999"); + AssertNewDateTimeOffsetParseEqual("9999-12-31T23:59:59.9999999+00:00"); + AssertNewDateTimeOffsetParseEqual("9999-12-31T23:59:59.9999999+13:30"); + AssertNewDateTimeOffsetParseEqual("9999-12-31T23:59:59.9999999-13:30"); + } - private void AssertNewDateTimeOffsetParseEqual(string text) - { - object oldDt; - object newDt; - TryParseDateIso(text, DateParseHandling.DateTimeOffset, DateTimeZoneHandling.Unspecified, out oldDt); - DateTimeUtils.TryParseDateIso(text, DateParseHandling.DateTimeOffset, DateTimeZoneHandling.Unspecified, out newDt); + private void AssertNewDateTimeOffsetParseEqual(string text) + { + object oldDt; + object newDt; + TryParseDateIso(text, DateParseHandling.DateTimeOffset, DateTimeZoneHandling.Unspecified, out oldDt); + DateTimeUtils.TryParseDateIso(text, DateParseHandling.DateTimeOffset, DateTimeZoneHandling.Unspecified, out newDt); - if (!Equals(oldDt, newDt)) - { - Assert.AreEqual(oldDt, newDt, "DateTimeOffset parse not equal. Text: '{0}' Old ticks: {1} New ticks: {2}".FormatWith( - CultureInfo.InvariantCulture, - text, - ((DateTime)oldDt).Ticks, - ((DateTime)newDt).Ticks)); - } - } + if (!Equals(oldDt, newDt)) + { + Assert.AreEqual(oldDt, newDt, "DateTimeOffset parse not equal. Text: '{0}' Old ticks: {1} New ticks: {2}".FormatWith( + CultureInfo.InvariantCulture, + text, + ((DateTime)oldDt).Ticks, + ((DateTime)newDt).Ticks)); + } + } #endif - internal static bool TryParseDateIso(string text, DateParseHandling dateParseHandling, DateTimeZoneHandling dateTimeZoneHandling, out object dt) - { - const string isoDateFormat = "yyyy-MM-ddTHH:mm:ss.FFFFFFFK"; + internal static bool TryParseDateIso(string text, DateParseHandling dateParseHandling, DateTimeZoneHandling dateTimeZoneHandling, out object dt) + { + const string isoDateFormat = "yyyy-MM-ddTHH:mm:ss.FFFFFFFK"; #if !NET20 - if (dateParseHandling == DateParseHandling.DateTimeOffset) - { - DateTimeOffset dateTimeOffset; - if (DateTimeOffset.TryParseExact(text, isoDateFormat, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out dateTimeOffset)) - { - dt = dateTimeOffset; - return true; - } - } - else + if (dateParseHandling == DateParseHandling.DateTimeOffset) + { + DateTimeOffset dateTimeOffset; + if (DateTimeOffset.TryParseExact(text, isoDateFormat, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out dateTimeOffset)) + { + dt = dateTimeOffset; + return true; + } + } + else #endif - { - DateTime dateTime; - if (DateTime.TryParseExact(text, isoDateFormat, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out dateTime)) - { - dateTime = DateTimeUtils.EnsureDateTime(dateTime, dateTimeZoneHandling); + { + DateTime dateTime; + if (DateTime.TryParseExact(text, isoDateFormat, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out dateTime)) + { + dateTime = DateTimeUtils.EnsureDateTime(dateTime, dateTimeZoneHandling); - dt = dateTime; - return true; + dt = dateTime; + return true; + } + } + + dt = null; + return false; } - } - - dt = null; - return false; } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Utilities/DynamicReflectionDelegateFactoryTests.cs b/Src/Newtonsoft.Json.Tests/Utilities/DynamicReflectionDelegateFactoryTests.cs index 24d32a28..ff6aafac 100644 --- a/Src/Newtonsoft.Json.Tests/Utilities/DynamicReflectionDelegateFactoryTests.cs +++ b/Src/Newtonsoft.Json.Tests/Utilities/DynamicReflectionDelegateFactoryTests.cs @@ -41,92 +41,93 @@ using Newtonsoft.Json.Tests.Serialization; namespace Newtonsoft.Json.Tests.Utilities { - [TestFixture] - public class DynamicReflectionDelegateFactoryTests : TestFixtureBase - { - [Test] - public void CreateGetWithBadObjectTarget() + [TestFixture] + public class DynamicReflectionDelegateFactoryTests : TestFixtureBase { - ExceptionAssert.Throws("Unable to cast object of type 'Newtonsoft.Json.Tests.TestObjects.Person' to type 'Newtonsoft.Json.Tests.TestObjects.Movie'.", - () => - { - Person p = new Person(); - p.Name = "Hi"; + [Test] + public void CreateGetWithBadObjectTarget() + { + ExceptionAssert.Throws("Unable to cast object of type 'Newtonsoft.Json.Tests.TestObjects.Person' to type 'Newtonsoft.Json.Tests.TestObjects.Movie'.", + () => + { + Person p = new Person(); + p.Name = "Hi"; - Func setter = DynamicReflectionDelegateFactory.Instance.CreateGet(typeof(Movie).GetProperty("Name")); + Func setter = DynamicReflectionDelegateFactory.Instance.CreateGet(typeof(Movie).GetProperty("Name")); - setter(p); - }); + setter(p); + }); + } + + [Test] + public void CreateSetWithBadObjectTarget() + { + ExceptionAssert.Throws("Unable to cast object of type 'Newtonsoft.Json.Tests.TestObjects.Person' to type 'Newtonsoft.Json.Tests.TestObjects.Movie'.", + () => + { + Person p = new Person(); + Movie m = new Movie(); + + Action setter = DynamicReflectionDelegateFactory.Instance.CreateSet(typeof(Movie).GetProperty("Name")); + + setter(m, "Hi"); + + Assert.AreEqual(m.Name, "Hi"); + + setter(p, "Hi"); + + Assert.AreEqual(p.Name, "Hi"); + }); + } + + [Test] + public void CreateSetWithBadTarget() + { + ExceptionAssert.Throws("Specified cast is not valid.", + () => + { + object structTest = new StructTest(); + + Action setter = DynamicReflectionDelegateFactory.Instance.CreateSet(typeof(StructTest).GetProperty("StringProperty")); + + setter(structTest, "Hi"); + + Assert.AreEqual("Hi", ((StructTest)structTest).StringProperty); + + setter(new TimeSpan(), "Hi"); + }); + } + + [Test] + public void CreateSetWithBadObjectValue() + { + ExceptionAssert.Throws("Unable to cast object of type 'System.Version' to type 'System.String'.", + () => + { + Movie m = new Movie(); + + Action setter = DynamicReflectionDelegateFactory.Instance.CreateSet(typeof(Movie).GetProperty("Name")); + + setter(m, new Version("1.1.1.1")); + }); + } + + [Test] + public void CreateStaticMethodCall() + { + MethodInfo castMethodInfo = typeof(JsonSerializerTest.DictionaryKey).GetMethod("op_Implicit", new[] { typeof(string) }); + + Assert.IsNotNull(castMethodInfo); + + MethodCall call = DynamicReflectionDelegateFactory.Instance.CreateMethodCall(castMethodInfo); + + object result = call(null, "First!"); + Assert.IsNotNull(result); + + JsonSerializerTest.DictionaryKey key = (JsonSerializerTest.DictionaryKey)result; + Assert.AreEqual("First!", key.Value); + } } - - [Test] - public void CreateSetWithBadObjectTarget() - { - ExceptionAssert.Throws("Unable to cast object of type 'Newtonsoft.Json.Tests.TestObjects.Person' to type 'Newtonsoft.Json.Tests.TestObjects.Movie'.", - () => - { - Person p = new Person(); - Movie m = new Movie(); - - Action setter = DynamicReflectionDelegateFactory.Instance.CreateSet(typeof(Movie).GetProperty("Name")); - - setter(m, "Hi"); - - Assert.AreEqual(m.Name, "Hi"); - - setter(p, "Hi"); - - Assert.AreEqual(p.Name, "Hi"); - }); - } - - [Test] - public void CreateSetWithBadTarget() - { - ExceptionAssert.Throws("Specified cast is not valid.", - () => - { - object structTest = new StructTest(); - - Action setter = DynamicReflectionDelegateFactory.Instance.CreateSet(typeof(StructTest).GetProperty("StringProperty")); - - setter(structTest, "Hi"); - - Assert.AreEqual("Hi", ((StructTest)structTest).StringProperty); - - setter(new TimeSpan(), "Hi"); - }); - } - - [Test] - public void CreateSetWithBadObjectValue() - { - ExceptionAssert.Throws("Unable to cast object of type 'System.Version' to type 'System.String'.", - () => - { - Movie m = new Movie(); - - Action setter = DynamicReflectionDelegateFactory.Instance.CreateSet(typeof(Movie).GetProperty("Name")); - - setter(m, new Version("1.1.1.1")); - }); - } - - [Test] - public void CreateStaticMethodCall() - { - MethodInfo castMethodInfo = typeof(JsonSerializerTest.DictionaryKey).GetMethod("op_Implicit", new[] { typeof(string) }); - - Assert.IsNotNull(castMethodInfo); - - MethodCall call = DynamicReflectionDelegateFactory.Instance.CreateMethodCall(castMethodInfo); - - object result = call(null, "First!"); - Assert.IsNotNull(result); - - JsonSerializerTest.DictionaryKey key = (JsonSerializerTest.DictionaryKey) result; - Assert.AreEqual("First!", key.Value); - } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Utilities/ExpressionReflectionDelegateFactoryTests.cs b/Src/Newtonsoft.Json.Tests/Utilities/ExpressionReflectionDelegateFactoryTests.cs index 36d3f50c..72f310c3 100644 --- a/Src/Newtonsoft.Json.Tests/Utilities/ExpressionReflectionDelegateFactoryTests.cs +++ b/Src/Newtonsoft.Json.Tests/Utilities/ExpressionReflectionDelegateFactoryTests.cs @@ -41,262 +41,263 @@ using Newtonsoft.Json.Tests.Serialization; namespace Newtonsoft.Json.Tests.Utilities { - [TestFixture] - public class ExpressionReflectionDelegateFactoryTests : TestFixtureBase - { - [Test] - public void DefaultConstructor() + [TestFixture] + public class ExpressionReflectionDelegateFactoryTests : TestFixtureBase { - Func create = ExpressionReflectionDelegateFactory.Instance.CreateDefaultConstructor(typeof(Movie)); + [Test] + public void DefaultConstructor() + { + Func create = ExpressionReflectionDelegateFactory.Instance.CreateDefaultConstructor(typeof(Movie)); - Movie m = (Movie)create(); - Assert.IsNotNull(m); + Movie m = (Movie)create(); + Assert.IsNotNull(m); + } + + [Test] + public void DefaultConstructor_Struct() + { + Func create = ExpressionReflectionDelegateFactory.Instance.CreateDefaultConstructor(typeof(StructTest)); + + StructTest m = (StructTest)create(); + Assert.IsNotNull(m); + } + + [Test] + public void DefaultConstructor_Abstract() + { + ExceptionAssert.Throws("Cannot create an abstract class.", + () => + { + Func create = ExpressionReflectionDelegateFactory.Instance.CreateDefaultConstructor(typeof(Type)); + + create(); + }); + } + + [Test] + public void CreatePropertySetter() + { + Action setter = ExpressionReflectionDelegateFactory.Instance.CreateSet(typeof(Movie).GetProperty("Name")); + + Movie m = new Movie(); + + setter(m, "OH HAI!"); + + Assert.AreEqual("OH HAI!", m.Name); + } + + [Test] + public void CreatePropertyGetter() + { + Func getter = ExpressionReflectionDelegateFactory.Instance.CreateGet(typeof(Movie).GetProperty("Name")); + + Movie m = new Movie(); + m.Name = "OH HAI!"; + + object value = getter(m); + + Assert.AreEqual("OH HAI!", value); + } + + [Test] + public void CreateMethodCall() + { + MethodCall method = ExpressionReflectionDelegateFactory.Instance.CreateMethodCall(typeof(Movie).GetMethod("ToString")); + + Movie m = new Movie(); + object result = method(m); + Assert.AreEqual("Newtonsoft.Json.Tests.TestObjects.Movie", result); + + method = ExpressionReflectionDelegateFactory.Instance.CreateMethodCall(typeof(Movie).GetMethod("Equals")); + + result = method(m, m); + Assert.AreEqual(true, result); + } + + [Test] + public void CreateMethodCall_Constructor() + { + MethodCall method = ExpressionReflectionDelegateFactory.Instance.CreateMethodCall(typeof(Movie).GetConstructor(new Type[0])); + + object result = method(null); + + Assert.IsTrue(result is Movie); + } + + public static class StaticTestClass + { + public static string StringField; + public static string StringProperty { get; set; } + } + + [Test] + public void GetStatic() + { + StaticTestClass.StringField = "Field!"; + StaticTestClass.StringProperty = "Property!"; + + Func getter = ExpressionReflectionDelegateFactory.Instance.CreateGet(typeof(StaticTestClass).GetProperty("StringProperty")); + + object v = getter(null); + Assert.AreEqual(StaticTestClass.StringProperty, v); + + getter = ExpressionReflectionDelegateFactory.Instance.CreateGet(typeof(StaticTestClass).GetField("StringField")); + + v = getter(null); + Assert.AreEqual(StaticTestClass.StringField, v); + } + + [Test] + public void SetStatic() + { + Action setter = ExpressionReflectionDelegateFactory.Instance.CreateSet(typeof(StaticTestClass).GetProperty("StringProperty")); + + setter(null, "New property!"); + Assert.AreEqual("New property!", StaticTestClass.StringProperty); + + setter = ExpressionReflectionDelegateFactory.Instance.CreateSet(typeof(StaticTestClass).GetField("StringField")); + + setter(null, "New field!"); + Assert.AreEqual("New field!", StaticTestClass.StringField); + } + + public class FieldsTestClass + { + public string StringField; + public bool BoolField; + + public readonly int IntReadOnlyField = int.MaxValue; + } + + [Test] + public void CreateGetField() + { + FieldsTestClass c = new FieldsTestClass + { + BoolField = true, + StringField = "String!" + }; + + Func getter = ExpressionReflectionDelegateFactory.Instance.CreateGet(typeof(FieldsTestClass).GetField("StringField")); + + object value = getter(c); + Assert.AreEqual("String!", value); + + getter = ExpressionReflectionDelegateFactory.Instance.CreateGet(typeof(FieldsTestClass).GetField("BoolField")); + + value = getter(c); + Assert.AreEqual(true, value); + } + + [Test] + public void CreateSetField_ReadOnly() + { + FieldsTestClass c = new FieldsTestClass(); + + Action setter = ExpressionReflectionDelegateFactory.Instance.CreateSet(typeof(FieldsTestClass).GetField("IntReadOnlyField")); + + setter(c, int.MinValue); + Assert.AreEqual(int.MinValue, c.IntReadOnlyField); + } + + [Test] + public void CreateSetField() + { + FieldsTestClass c = new FieldsTestClass(); + + Action setter = ExpressionReflectionDelegateFactory.Instance.CreateSet(typeof(FieldsTestClass).GetField("StringField")); + + setter(c, "String!"); + Assert.AreEqual("String!", c.StringField); + + setter = ExpressionReflectionDelegateFactory.Instance.CreateSet(typeof(FieldsTestClass).GetField("BoolField")); + + setter(c, true); + Assert.AreEqual(true, c.BoolField); + } + + [Test] + public void SetOnStruct() + { + object structTest = new StructTest(); + + Action setter = ExpressionReflectionDelegateFactory.Instance.CreateSet(typeof(StructTest).GetProperty("StringProperty")); + + setter(structTest, "Hi1"); + Assert.AreEqual("Hi1", ((StructTest)structTest).StringProperty); + + setter = ExpressionReflectionDelegateFactory.Instance.CreateSet(typeof(StructTest).GetField("StringField")); + + setter(structTest, "Hi2"); + Assert.AreEqual("Hi2", ((StructTest)structTest).StringField); + } + + [Test] + public void CreateGetWithBadObjectTarget() + { + ExceptionAssert.Throws("Unable to cast object of type 'Newtonsoft.Json.Tests.TestObjects.Person' to type 'Newtonsoft.Json.Tests.TestObjects.Movie'.", + () => + { + Person p = new Person(); + p.Name = "Hi"; + + Func setter = ExpressionReflectionDelegateFactory.Instance.CreateGet(typeof(Movie).GetProperty("Name")); + + setter(p); + }); + } + + [Test] + public void CreateSetWithBadObjectTarget() + { + ExceptionAssert.Throws("Unable to cast object of type 'Newtonsoft.Json.Tests.TestObjects.Person' to type 'Newtonsoft.Json.Tests.TestObjects.Movie'.", + () => + { + Person p = new Person(); + Movie m = new Movie(); + + Action setter = ExpressionReflectionDelegateFactory.Instance.CreateSet(typeof(Movie).GetProperty("Name")); + + setter(m, "Hi"); + + Assert.AreEqual(m.Name, "Hi"); + + setter(p, "Hi"); + + Assert.AreEqual(p.Name, "Hi"); + }); + } + + [Test] + public void CreateSetWithBadObjectValue() + { + ExceptionAssert.Throws("Unable to cast object of type 'System.Version' to type 'System.String'.", + () => + { + Movie m = new Movie(); + + Action setter = ExpressionReflectionDelegateFactory.Instance.CreateSet(typeof(Movie).GetProperty("Name")); + + setter(m, new Version("1.1.1.1")); + }); + } + + [Test] + public void CreateStaticMethodCall() + { + MethodInfo castMethodInfo = typeof(JsonSerializerTest.DictionaryKey).GetMethod("op_Implicit", new[] { typeof(string) }); + + Assert.IsNotNull(castMethodInfo); + + MethodCall call = ExpressionReflectionDelegateFactory.Instance.CreateMethodCall(castMethodInfo); + + object result = call(null, "First!"); + Assert.IsNotNull(result); + + JsonSerializerTest.DictionaryKey key = (JsonSerializerTest.DictionaryKey)result; + Assert.AreEqual("First!", key.Value); + } } - - [Test] - public void DefaultConstructor_Struct() - { - Func create = ExpressionReflectionDelegateFactory.Instance.CreateDefaultConstructor(typeof(StructTest)); - - StructTest m = (StructTest)create(); - Assert.IsNotNull(m); - } - - [Test] - public void DefaultConstructor_Abstract() - { - ExceptionAssert.Throws("Cannot create an abstract class.", - () => - { - Func create = ExpressionReflectionDelegateFactory.Instance.CreateDefaultConstructor(typeof(Type)); - - create(); - }); - } - - [Test] - public void CreatePropertySetter() - { - Action setter = ExpressionReflectionDelegateFactory.Instance.CreateSet(typeof(Movie).GetProperty("Name")); - - Movie m = new Movie(); - - setter(m, "OH HAI!"); - - Assert.AreEqual("OH HAI!", m.Name); - } - - [Test] - public void CreatePropertyGetter() - { - Func getter = ExpressionReflectionDelegateFactory.Instance.CreateGet(typeof(Movie).GetProperty("Name")); - - Movie m = new Movie(); - m.Name = "OH HAI!"; - - object value = getter(m); - - Assert.AreEqual("OH HAI!", value); - } - - [Test] - public void CreateMethodCall() - { - MethodCall method = ExpressionReflectionDelegateFactory.Instance.CreateMethodCall(typeof(Movie).GetMethod("ToString")); - - Movie m = new Movie(); - object result = method(m); - Assert.AreEqual("Newtonsoft.Json.Tests.TestObjects.Movie", result); - - method = ExpressionReflectionDelegateFactory.Instance.CreateMethodCall(typeof(Movie).GetMethod("Equals")); - - result = method(m, m); - Assert.AreEqual(true, result); - } - - [Test] - public void CreateMethodCall_Constructor() - { - MethodCall method = ExpressionReflectionDelegateFactory.Instance.CreateMethodCall(typeof(Movie).GetConstructor(new Type[0])); - - object result = method(null); - - Assert.IsTrue(result is Movie); - } - - public static class StaticTestClass - { - public static string StringField; - public static string StringProperty { get; set; } - } - - [Test] - public void GetStatic() - { - StaticTestClass.StringField = "Field!"; - StaticTestClass.StringProperty = "Property!"; - - Func getter = ExpressionReflectionDelegateFactory.Instance.CreateGet(typeof(StaticTestClass).GetProperty("StringProperty")); - - object v = getter(null); - Assert.AreEqual(StaticTestClass.StringProperty, v); - - getter = ExpressionReflectionDelegateFactory.Instance.CreateGet(typeof(StaticTestClass).GetField("StringField")); - - v = getter(null); - Assert.AreEqual(StaticTestClass.StringField, v); - } - - [Test] - public void SetStatic() - { - Action setter = ExpressionReflectionDelegateFactory.Instance.CreateSet(typeof(StaticTestClass).GetProperty("StringProperty")); - - setter(null, "New property!"); - Assert.AreEqual("New property!", StaticTestClass.StringProperty); - - setter = ExpressionReflectionDelegateFactory.Instance.CreateSet(typeof(StaticTestClass).GetField("StringField")); - - setter(null, "New field!"); - Assert.AreEqual("New field!", StaticTestClass.StringField); - } - - public class FieldsTestClass - { - public string StringField; - public bool BoolField; - - public readonly int IntReadOnlyField = int.MaxValue; - } - - [Test] - public void CreateGetField() - { - FieldsTestClass c = new FieldsTestClass - { - BoolField = true, - StringField = "String!" - }; - - Func getter = ExpressionReflectionDelegateFactory.Instance.CreateGet(typeof(FieldsTestClass).GetField("StringField")); - - object value = getter(c); - Assert.AreEqual("String!", value); - - getter = ExpressionReflectionDelegateFactory.Instance.CreateGet(typeof(FieldsTestClass).GetField("BoolField")); - - value = getter(c); - Assert.AreEqual(true, value); - } - - [Test] - public void CreateSetField_ReadOnly() - { - FieldsTestClass c = new FieldsTestClass(); - - Action setter = ExpressionReflectionDelegateFactory.Instance.CreateSet(typeof(FieldsTestClass).GetField("IntReadOnlyField")); - - setter(c, int.MinValue); - Assert.AreEqual(int.MinValue, c.IntReadOnlyField); - } - - [Test] - public void CreateSetField() - { - FieldsTestClass c = new FieldsTestClass(); - - Action setter = ExpressionReflectionDelegateFactory.Instance.CreateSet(typeof(FieldsTestClass).GetField("StringField")); - - setter(c, "String!"); - Assert.AreEqual("String!", c.StringField); - - setter = ExpressionReflectionDelegateFactory.Instance.CreateSet(typeof(FieldsTestClass).GetField("BoolField")); - - setter(c, true); - Assert.AreEqual(true, c.BoolField); - } - - [Test] - public void SetOnStruct() - { - object structTest = new StructTest(); - - Action setter = ExpressionReflectionDelegateFactory.Instance.CreateSet(typeof(StructTest).GetProperty("StringProperty")); - - setter(structTest, "Hi1"); - Assert.AreEqual("Hi1", ((StructTest)structTest).StringProperty); - - setter = ExpressionReflectionDelegateFactory.Instance.CreateSet(typeof(StructTest).GetField("StringField")); - - setter(structTest, "Hi2"); - Assert.AreEqual("Hi2", ((StructTest)structTest).StringField); - } - - [Test] - public void CreateGetWithBadObjectTarget() - { - ExceptionAssert.Throws("Unable to cast object of type 'Newtonsoft.Json.Tests.TestObjects.Person' to type 'Newtonsoft.Json.Tests.TestObjects.Movie'.", - () => - { - Person p = new Person(); - p.Name = "Hi"; - - Func setter = ExpressionReflectionDelegateFactory.Instance.CreateGet(typeof(Movie).GetProperty("Name")); - - setter(p); - }); - } - - [Test] - public void CreateSetWithBadObjectTarget() - { - ExceptionAssert.Throws("Unable to cast object of type 'Newtonsoft.Json.Tests.TestObjects.Person' to type 'Newtonsoft.Json.Tests.TestObjects.Movie'.", - () => - { - Person p = new Person(); - Movie m = new Movie(); - - Action setter = ExpressionReflectionDelegateFactory.Instance.CreateSet(typeof(Movie).GetProperty("Name")); - - setter(m, "Hi"); - - Assert.AreEqual(m.Name, "Hi"); - - setter(p, "Hi"); - - Assert.AreEqual(p.Name, "Hi"); - }); - } - - [Test] - public void CreateSetWithBadObjectValue() - { - ExceptionAssert.Throws("Unable to cast object of type 'System.Version' to type 'System.String'.", - () => - { - Movie m = new Movie(); - - Action setter = ExpressionReflectionDelegateFactory.Instance.CreateSet(typeof(Movie).GetProperty("Name")); - - setter(m, new Version("1.1.1.1")); - }); - } - - [Test] - public void CreateStaticMethodCall() - { - MethodInfo castMethodInfo = typeof(JsonSerializerTest.DictionaryKey).GetMethod("op_Implicit", new[] { typeof(string) }); - - Assert.IsNotNull(castMethodInfo); - - MethodCall call = ExpressionReflectionDelegateFactory.Instance.CreateMethodCall(castMethodInfo); - - object result = call(null, "First!"); - Assert.IsNotNull(result); - - JsonSerializerTest.DictionaryKey key = (JsonSerializerTest.DictionaryKey) result; - Assert.AreEqual("First!", key.Value); - } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Utilities/ReflectionUtilsTests.cs b/Src/Newtonsoft.Json.Tests/Utilities/ReflectionUtilsTests.cs index 6e723b02..7359335c 100644 --- a/Src/Newtonsoft.Json.Tests/Utilities/ReflectionUtilsTests.cs +++ b/Src/Newtonsoft.Json.Tests/Utilities/ReflectionUtilsTests.cs @@ -38,26 +38,27 @@ using global::Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Tests.Utilities { - [TestFixture] - public class ReflectionUtilsTests : TestFixtureBase - { - [Test] - public void GetTypeNameSimpleForGenericTypes() + [TestFixture] + public class ReflectionUtilsTests : TestFixtureBase { - string typeName; + [Test] + public void GetTypeNameSimpleForGenericTypes() + { + string typeName; - typeName = ReflectionUtils.GetTypeName(typeof(IList), FormatterAssemblyStyle.Simple, null); - Assert.AreEqual("System.Collections.Generic.IList`1[[System.Type, mscorlib]], mscorlib", typeName); + typeName = ReflectionUtils.GetTypeName(typeof(IList), FormatterAssemblyStyle.Simple, null); + Assert.AreEqual("System.Collections.Generic.IList`1[[System.Type, mscorlib]], mscorlib", typeName); - typeName = ReflectionUtils.GetTypeName(typeof(IDictionary, IList>), FormatterAssemblyStyle.Simple, null); - Assert.AreEqual("System.Collections.Generic.IDictionary`2[[System.Collections.Generic.IList`1[[System.Type, mscorlib]], mscorlib],[System.Collections.Generic.IList`1[[System.Type, mscorlib]], mscorlib]], mscorlib", typeName); + typeName = ReflectionUtils.GetTypeName(typeof(IDictionary, IList>), FormatterAssemblyStyle.Simple, null); + Assert.AreEqual("System.Collections.Generic.IDictionary`2[[System.Collections.Generic.IList`1[[System.Type, mscorlib]], mscorlib],[System.Collections.Generic.IList`1[[System.Type, mscorlib]], mscorlib]], mscorlib", typeName); - typeName = ReflectionUtils.GetTypeName(typeof(IList<>), FormatterAssemblyStyle.Simple, null); - Assert.AreEqual("System.Collections.Generic.IList`1, mscorlib", typeName); + typeName = ReflectionUtils.GetTypeName(typeof(IList<>), FormatterAssemblyStyle.Simple, null); + Assert.AreEqual("System.Collections.Generic.IList`1, mscorlib", typeName); - typeName = ReflectionUtils.GetTypeName(typeof(IDictionary<,>), FormatterAssemblyStyle.Simple, null); - Assert.AreEqual("System.Collections.Generic.IDictionary`2, mscorlib", typeName); + typeName = ReflectionUtils.GetTypeName(typeof(IDictionary<,>), FormatterAssemblyStyle.Simple, null); + Assert.AreEqual("System.Collections.Generic.IDictionary`2, mscorlib", typeName); + } } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Utilities/StringUtilsTests.cs b/Src/Newtonsoft.Json.Tests/Utilities/StringUtilsTests.cs index 0da96411..5f44fc4c 100644 --- a/Src/Newtonsoft.Json.Tests/Utilities/StringUtilsTests.cs +++ b/Src/Newtonsoft.Json.Tests/Utilities/StringUtilsTests.cs @@ -34,23 +34,23 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Tests.Utilities { - [TestFixture] - public class StringUtilsTests : TestFixtureBase - { - [Test] - public void ToCamelCaseTest() + [TestFixture] + public class StringUtilsTests : TestFixtureBase { - Assert.AreEqual("urlValue", StringUtils.ToCamelCase("URLValue")); - Assert.AreEqual("url", StringUtils.ToCamelCase("URL")); - Assert.AreEqual("id", StringUtils.ToCamelCase("ID")); - Assert.AreEqual("i", StringUtils.ToCamelCase("I")); - Assert.AreEqual("", StringUtils.ToCamelCase("")); - Assert.AreEqual(null, StringUtils.ToCamelCase(null)); - Assert.AreEqual("iPhone", StringUtils.ToCamelCase("iPhone")); - Assert.AreEqual("person", StringUtils.ToCamelCase("Person")); - Assert.AreEqual("iPhone", StringUtils.ToCamelCase("IPhone")); - Assert.AreEqual("i Phone", StringUtils.ToCamelCase("I Phone")); - Assert.AreEqual(" IPhone", StringUtils.ToCamelCase(" IPhone")); + [Test] + public void ToCamelCaseTest() + { + Assert.AreEqual("urlValue", StringUtils.ToCamelCase("URLValue")); + Assert.AreEqual("url", StringUtils.ToCamelCase("URL")); + Assert.AreEqual("id", StringUtils.ToCamelCase("ID")); + Assert.AreEqual("i", StringUtils.ToCamelCase("I")); + Assert.AreEqual("", StringUtils.ToCamelCase("")); + Assert.AreEqual(null, StringUtils.ToCamelCase(null)); + Assert.AreEqual("iPhone", StringUtils.ToCamelCase("iPhone")); + Assert.AreEqual("person", StringUtils.ToCamelCase("Person")); + Assert.AreEqual("iPhone", StringUtils.ToCamelCase("IPhone")); + Assert.AreEqual("i Phone", StringUtils.ToCamelCase("I Phone")); + Assert.AreEqual(" IPhone", StringUtils.ToCamelCase(" IPhone")); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Bson/BsonBinaryType.cs b/Src/Newtonsoft.Json/Bson/BsonBinaryType.cs index d4977ac5..638039fa 100644 --- a/Src/Newtonsoft.Json/Bson/BsonBinaryType.cs +++ b/Src/Newtonsoft.Json/Bson/BsonBinaryType.cs @@ -27,16 +27,18 @@ using System; namespace Newtonsoft.Json.Bson { - internal enum BsonBinaryType : byte - { - Binary = 0x00, - Function = 0x01, - [Obsolete("This type has been deprecated in the BSON specification. Use Binary instead.")] - BinaryOld = 0x02, - [Obsolete("This type has been deprecated in the BSON specification. Use Uuid instead.")] - UuidOld = 0x03, - Uuid = 0x04, - Md5 = 0x05, - UserDefined = 0x80 - } + internal enum BsonBinaryType : byte + { + Binary = 0x00, + Function = 0x01, + + [Obsolete("This type has been deprecated in the BSON specification. Use Binary instead.")] + BinaryOld = 0x02, + + [Obsolete("This type has been deprecated in the BSON specification. Use Uuid instead.")] + UuidOld = 0x03, + Uuid = 0x04, + Md5 = 0x05, + UserDefined = 0x80 + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Bson/BsonBinaryWriter.cs b/Src/Newtonsoft.Json/Bson/BsonBinaryWriter.cs index 60744b16..b0f40262 100644 --- a/Src/Newtonsoft.Json/Bson/BsonBinaryWriter.cs +++ b/Src/Newtonsoft.Json/Bson/BsonBinaryWriter.cs @@ -31,295 +31,295 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Bson { - internal class BsonBinaryWriter - { - private static readonly Encoding Encoding = new UTF8Encoding(false); - - private readonly BinaryWriter _writer; - - private byte[] _largeByteBuffer; - - public DateTimeKind DateTimeKindHandling { get; set; } - - public BsonBinaryWriter(BinaryWriter writer) + internal class BsonBinaryWriter { - DateTimeKindHandling = DateTimeKind.Utc; - _writer = writer; - } + private static readonly Encoding Encoding = new UTF8Encoding(false); - public void Flush() - { - _writer.Flush(); - } + private readonly BinaryWriter _writer; - public void Close() - { + private byte[] _largeByteBuffer; + + public DateTimeKind DateTimeKindHandling { get; set; } + + public BsonBinaryWriter(BinaryWriter writer) + { + DateTimeKindHandling = DateTimeKind.Utc; + _writer = writer; + } + + public void Flush() + { + _writer.Flush(); + } + + public void Close() + { #if !(NETFX_CORE || PORTABLE40 || PORTABLE) - _writer.Close(); + _writer.Close(); #else - _writer.Dispose(); + _writer.Dispose(); #endif - } + } - public void WriteToken(BsonToken t) - { - CalculateSize(t); - WriteTokenInternal(t); - } + public void WriteToken(BsonToken t) + { + CalculateSize(t); + WriteTokenInternal(t); + } - private void WriteTokenInternal(BsonToken t) - { - switch (t.Type) - { - case BsonType.Object: - { - BsonObject value = (BsonObject)t; - _writer.Write(value.CalculatedSize); - foreach (BsonProperty property in value) + private void WriteTokenInternal(BsonToken t) + { + switch (t.Type) { - _writer.Write((sbyte)property.Value.Type); - WriteString((string)property.Name.Value, property.Name.ByteCount, null); - WriteTokenInternal(property.Value); - } - _writer.Write((byte)0); - } - break; - case BsonType.Array: - { - BsonArray value = (BsonArray)t; - _writer.Write(value.CalculatedSize); - ulong index = 0; - foreach (BsonToken c in value) - { - _writer.Write((sbyte)c.Type); - WriteString(index.ToString(CultureInfo.InvariantCulture), MathUtils.IntLength(index), null); - WriteTokenInternal(c); - index++; - } - _writer.Write((byte)0); - } - break; - case BsonType.Integer: - { - BsonValue value = (BsonValue)t; - _writer.Write(Convert.ToInt32(value.Value, CultureInfo.InvariantCulture)); - } - break; - case BsonType.Long: - { - BsonValue value = (BsonValue)t; - _writer.Write(Convert.ToInt64(value.Value, CultureInfo.InvariantCulture)); - } - break; - case BsonType.Number: - { - BsonValue value = (BsonValue)t; - _writer.Write(Convert.ToDouble(value.Value, CultureInfo.InvariantCulture)); - } - break; - case BsonType.String: - { - BsonString value = (BsonString)t; - WriteString((string)value.Value, value.ByteCount, value.CalculatedSize - 4); - } - break; - case BsonType.Boolean: - { - BsonValue value = (BsonValue)t; - _writer.Write((bool)value.Value); - } - break; - case BsonType.Null: - case BsonType.Undefined: - break; - case BsonType.Date: - { - BsonValue value = (BsonValue)t; + case BsonType.Object: + { + BsonObject value = (BsonObject)t; + _writer.Write(value.CalculatedSize); + foreach (BsonProperty property in value) + { + _writer.Write((sbyte)property.Value.Type); + WriteString((string)property.Name.Value, property.Name.ByteCount, null); + WriteTokenInternal(property.Value); + } + _writer.Write((byte)0); + } + break; + case BsonType.Array: + { + BsonArray value = (BsonArray)t; + _writer.Write(value.CalculatedSize); + ulong index = 0; + foreach (BsonToken c in value) + { + _writer.Write((sbyte)c.Type); + WriteString(index.ToString(CultureInfo.InvariantCulture), MathUtils.IntLength(index), null); + WriteTokenInternal(c); + index++; + } + _writer.Write((byte)0); + } + break; + case BsonType.Integer: + { + BsonValue value = (BsonValue)t; + _writer.Write(Convert.ToInt32(value.Value, CultureInfo.InvariantCulture)); + } + break; + case BsonType.Long: + { + BsonValue value = (BsonValue)t; + _writer.Write(Convert.ToInt64(value.Value, CultureInfo.InvariantCulture)); + } + break; + case BsonType.Number: + { + BsonValue value = (BsonValue)t; + _writer.Write(Convert.ToDouble(value.Value, CultureInfo.InvariantCulture)); + } + break; + case BsonType.String: + { + BsonString value = (BsonString)t; + WriteString((string)value.Value, value.ByteCount, value.CalculatedSize - 4); + } + break; + case BsonType.Boolean: + { + BsonValue value = (BsonValue)t; + _writer.Write((bool)value.Value); + } + break; + case BsonType.Null: + case BsonType.Undefined: + break; + case BsonType.Date: + { + BsonValue value = (BsonValue)t; - long ticks = 0; + long ticks = 0; - if (value.Value is DateTime) - { - DateTime dateTime = (DateTime)value.Value; - if (DateTimeKindHandling == DateTimeKind.Utc) - dateTime = dateTime.ToUniversalTime(); - else if (DateTimeKindHandling == DateTimeKind.Local) - dateTime = dateTime.ToLocalTime(); + if (value.Value is DateTime) + { + DateTime dateTime = (DateTime)value.Value; + if (DateTimeKindHandling == DateTimeKind.Utc) + dateTime = dateTime.ToUniversalTime(); + else if (DateTimeKindHandling == DateTimeKind.Local) + dateTime = dateTime.ToLocalTime(); - ticks = DateTimeUtils.ConvertDateTimeToJavaScriptTicks(dateTime, false); - } + ticks = DateTimeUtils.ConvertDateTimeToJavaScriptTicks(dateTime, false); + } #if !NET20 - else - { - DateTimeOffset dateTimeOffset = (DateTimeOffset)value.Value; - ticks = DateTimeUtils.ConvertDateTimeToJavaScriptTicks(dateTimeOffset.UtcDateTime, dateTimeOffset.Offset); - } + else + { + DateTimeOffset dateTimeOffset = (DateTimeOffset)value.Value; + ticks = DateTimeUtils.ConvertDateTimeToJavaScriptTicks(dateTimeOffset.UtcDateTime, dateTimeOffset.Offset); + } #endif - _writer.Write(ticks); - } - break; - case BsonType.Binary: - { - BsonBinary value = (BsonBinary)t; + _writer.Write(ticks); + } + break; + case BsonType.Binary: + { + BsonBinary value = (BsonBinary)t; - byte[] data = (byte[])value.Value; - _writer.Write(data.Length); - _writer.Write((byte)value.BinaryType); - _writer.Write(data); - } - break; - case BsonType.Oid: - { - BsonValue value = (BsonValue)t; + byte[] data = (byte[])value.Value; + _writer.Write(data.Length); + _writer.Write((byte)value.BinaryType); + _writer.Write(data); + } + break; + case BsonType.Oid: + { + BsonValue value = (BsonValue)t; - byte[] data = (byte[])value.Value; - _writer.Write(data); - } - break; - case BsonType.Regex: - { - BsonRegex value = (BsonRegex)t; + byte[] data = (byte[])value.Value; + _writer.Write(data); + } + break; + case BsonType.Regex: + { + BsonRegex value = (BsonRegex)t; - WriteString((string)value.Pattern.Value, value.Pattern.ByteCount, null); - WriteString((string)value.Options.Value, value.Options.ByteCount, null); - } - break; - default: - throw new ArgumentOutOfRangeException("t", "Unexpected token when writing BSON: {0}".FormatWith(CultureInfo.InvariantCulture, t.Type)); - } - } - - private void WriteString(string s, int byteCount, int? calculatedlengthPrefix) - { - if (calculatedlengthPrefix != null) - _writer.Write(calculatedlengthPrefix.Value); - - WriteUtf8Bytes(s, byteCount); - - _writer.Write((byte)0); - } - - public void WriteUtf8Bytes(string s, int byteCount) - { - if (s != null) - { - if (_largeByteBuffer == null) - { - _largeByteBuffer = new byte[256]; - } - if (byteCount <= 256) - { - Encoding.GetBytes(s, 0, s.Length, _largeByteBuffer, 0); - _writer.Write(_largeByteBuffer, 0, byteCount); - } - else - { - byte[] bytes = Encoding.GetBytes(s); - _writer.Write(bytes); - } - } - } - - private int CalculateSize(int stringByteCount) - { - return stringByteCount + 1; - } - - private int CalculateSizeWithLength(int stringByteCount, bool includeSize) - { - int baseSize = (includeSize) - ? 5 // size bytes + terminator - : 1; // terminator - - return baseSize + stringByteCount; - } - - private int CalculateSize(BsonToken t) - { - switch (t.Type) - { - case BsonType.Object: - { - BsonObject value = (BsonObject)t; - - int bases = 4; - foreach (BsonProperty p in value) - { - int size = 1; - size += CalculateSize(p.Name); - size += CalculateSize(p.Value); - - bases += size; + WriteString((string)value.Pattern.Value, value.Pattern.ByteCount, null); + WriteString((string)value.Options.Value, value.Options.ByteCount, null); + } + break; + default: + throw new ArgumentOutOfRangeException("t", "Unexpected token when writing BSON: {0}".FormatWith(CultureInfo.InvariantCulture, t.Type)); } - bases += 1; - value.CalculatedSize = bases; - return bases; - } - case BsonType.Array: - { - BsonArray value = (BsonArray)t; + } - int size = 4; - ulong index = 0; - foreach (BsonToken c in value) + private void WriteString(string s, int byteCount, int? calculatedlengthPrefix) + { + if (calculatedlengthPrefix != null) + _writer.Write(calculatedlengthPrefix.Value); + + WriteUtf8Bytes(s, byteCount); + + _writer.Write((byte)0); + } + + public void WriteUtf8Bytes(string s, int byteCount) + { + if (s != null) { - size += 1; - size += CalculateSize(MathUtils.IntLength(index)); - size += CalculateSize(c); - index++; + if (_largeByteBuffer == null) + { + _largeByteBuffer = new byte[256]; + } + if (byteCount <= 256) + { + Encoding.GetBytes(s, 0, s.Length, _largeByteBuffer, 0); + _writer.Write(_largeByteBuffer, 0, byteCount); + } + else + { + byte[] bytes = Encoding.GetBytes(s); + _writer.Write(bytes); + } } - size += 1; - value.CalculatedSize = size; + } - return value.CalculatedSize; - } - case BsonType.Integer: - return 4; - case BsonType.Long: - return 8; - case BsonType.Number: - return 8; - case BsonType.String: - { - BsonString value = (BsonString)t; - string s = (string)value.Value; - value.ByteCount = (s != null) ? Encoding.GetByteCount(s) : 0; - value.CalculatedSize = CalculateSizeWithLength(value.ByteCount, value.IncludeLength); + private int CalculateSize(int stringByteCount) + { + return stringByteCount + 1; + } - return value.CalculatedSize; - } - case BsonType.Boolean: - return 1; - case BsonType.Null: - case BsonType.Undefined: - return 0; - case BsonType.Date: - return 8; - case BsonType.Binary: - { - BsonBinary value = (BsonBinary)t; + private int CalculateSizeWithLength(int stringByteCount, bool includeSize) + { + int baseSize = (includeSize) + ? 5 // size bytes + terminator + : 1; // terminator - byte[] data = (byte[])value.Value; - value.CalculatedSize = 4 + 1 + data.Length; + return baseSize + stringByteCount; + } - return value.CalculatedSize; - } - case BsonType.Oid: - return 12; - case BsonType.Regex: - { - BsonRegex value = (BsonRegex)t; - int size = 0; - size += CalculateSize(value.Pattern); - size += CalculateSize(value.Options); - value.CalculatedSize = size; + private int CalculateSize(BsonToken t) + { + switch (t.Type) + { + case BsonType.Object: + { + BsonObject value = (BsonObject)t; - return value.CalculatedSize; - } - default: - throw new ArgumentOutOfRangeException("t", "Unexpected token when writing BSON: {0}".FormatWith(CultureInfo.InvariantCulture, t.Type)); - } + int bases = 4; + foreach (BsonProperty p in value) + { + int size = 1; + size += CalculateSize(p.Name); + size += CalculateSize(p.Value); + + bases += size; + } + bases += 1; + value.CalculatedSize = bases; + return bases; + } + case BsonType.Array: + { + BsonArray value = (BsonArray)t; + + int size = 4; + ulong index = 0; + foreach (BsonToken c in value) + { + size += 1; + size += CalculateSize(MathUtils.IntLength(index)); + size += CalculateSize(c); + index++; + } + size += 1; + value.CalculatedSize = size; + + return value.CalculatedSize; + } + case BsonType.Integer: + return 4; + case BsonType.Long: + return 8; + case BsonType.Number: + return 8; + case BsonType.String: + { + BsonString value = (BsonString)t; + string s = (string)value.Value; + value.ByteCount = (s != null) ? Encoding.GetByteCount(s) : 0; + value.CalculatedSize = CalculateSizeWithLength(value.ByteCount, value.IncludeLength); + + return value.CalculatedSize; + } + case BsonType.Boolean: + return 1; + case BsonType.Null: + case BsonType.Undefined: + return 0; + case BsonType.Date: + return 8; + case BsonType.Binary: + { + BsonBinary value = (BsonBinary)t; + + byte[] data = (byte[])value.Value; + value.CalculatedSize = 4 + 1 + data.Length; + + return value.CalculatedSize; + } + case BsonType.Oid: + return 12; + case BsonType.Regex: + { + BsonRegex value = (BsonRegex)t; + int size = 0; + size += CalculateSize(value.Pattern); + size += CalculateSize(value.Options); + value.CalculatedSize = size; + + return value.CalculatedSize; + } + default: + throw new ArgumentOutOfRangeException("t", "Unexpected token when writing BSON: {0}".FormatWith(CultureInfo.InvariantCulture, t.Type)); + } + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Bson/BsonObjectId.cs b/Src/Newtonsoft.Json/Bson/BsonObjectId.cs index 85cea538..399e5f41 100644 --- a/Src/Newtonsoft.Json/Bson/BsonObjectId.cs +++ b/Src/Newtonsoft.Json/Bson/BsonObjectId.cs @@ -28,28 +28,28 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Bson { - /// - /// Represents a BSON Oid (object id). - /// - public class BsonObjectId - { /// - /// Gets or sets the value of the Oid. + /// Represents a BSON Oid (object id). /// - /// The value of the Oid. - public byte[] Value { get; private set; } - - /// - /// Initializes a new instance of the class. - /// - /// The Oid value. - public BsonObjectId(byte[] value) + public class BsonObjectId { - ValidationUtils.ArgumentNotNull(value, "value"); - if (value.Length != 12) - throw new ArgumentException("An ObjectId must be 12 bytes", "value"); + /// + /// Gets or sets the value of the Oid. + /// + /// The value of the Oid. + public byte[] Value { get; private set; } - Value = value; + /// + /// Initializes a new instance of the class. + /// + /// The Oid value. + public BsonObjectId(byte[] value) + { + ValidationUtils.ArgumentNotNull(value, "value"); + if (value.Length != 12) + throw new ArgumentException("An ObjectId must be 12 bytes", "value"); + + Value = value; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Bson/BsonReader.cs b/Src/Newtonsoft.Json/Bson/BsonReader.cs index 813b5de0..2f9923e9 100644 --- a/Src/Newtonsoft.Json/Bson/BsonReader.cs +++ b/Src/Newtonsoft.Json/Bson/BsonReader.cs @@ -33,816 +33,816 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Bson { - /// - /// Represents a reader that provides fast, non-cached, forward-only access to serialized Json data. - /// - public class BsonReader : JsonReader - { - private const int MaxCharBytesSize = 128; - private static readonly byte[] SeqRange1 = new byte[] {0, 127}; // range of 1-byte sequence - private static readonly byte[] SeqRange2 = new byte[] {194, 223}; // range of 2-byte sequence - private static readonly byte[] SeqRange3 = new byte[] {224, 239}; // range of 3-byte sequence - private static readonly byte[] SeqRange4 = new byte[] {240, 244}; // range of 4-byte sequence - - private readonly BinaryReader _reader; - private readonly List _stack; - - private byte[] _byteBuffer; - private char[] _charBuffer; - - private BsonType _currentElementType; - private BsonReaderState _bsonReaderState; - private ContainerContext _currentContext; - - private bool _readRootValueAsArray; - private bool _jsonNet35BinaryCompatibility; - private DateTimeKind _dateTimeKindHandling; - - private enum BsonReaderState - { - Normal, - ReferenceStart, - ReferenceRef, - ReferenceId, - CodeWScopeStart, - CodeWScopeCode, - CodeWScopeScope, - CodeWScopeScopeObject, - CodeWScopeScopeEnd - } - - private class ContainerContext - { - public readonly BsonType Type; - public int Length; - public int Position; - - public ContainerContext(BsonType type) - { - Type = type; - } - } - /// - /// Gets or sets a value indicating whether binary data reading should compatible with incorrect Json.NET 3.5 written binary. + /// Represents a reader that provides fast, non-cached, forward-only access to serialized Json data. /// - /// - /// true if binary data reading will be compatible with incorrect Json.NET 3.5 written binary; otherwise, false. - /// - [Obsolete("JsonNet35BinaryCompatibility will be removed in a future version of Json.NET.")] - public bool JsonNet35BinaryCompatibility + public class BsonReader : JsonReader { - get { return _jsonNet35BinaryCompatibility; } - set { _jsonNet35BinaryCompatibility = value; } - } + private const int MaxCharBytesSize = 128; + private static readonly byte[] SeqRange1 = new byte[] { 0, 127 }; // range of 1-byte sequence + private static readonly byte[] SeqRange2 = new byte[] { 194, 223 }; // range of 2-byte sequence + private static readonly byte[] SeqRange3 = new byte[] { 224, 239 }; // range of 3-byte sequence + private static readonly byte[] SeqRange4 = new byte[] { 240, 244 }; // range of 4-byte sequence - /// - /// Gets or sets a value indicating whether the root object will be read as a JSON array. - /// - /// - /// true if the root object will be read as a JSON array; otherwise, false. - /// - public bool ReadRootValueAsArray - { - get { return _readRootValueAsArray; } - set { _readRootValueAsArray = value; } - } + private readonly BinaryReader _reader; + private readonly List _stack; - /// - /// Gets or sets the used when reading values from BSON. - /// - /// The used when reading values from BSON. - public DateTimeKind DateTimeKindHandling - { - get { return _dateTimeKindHandling; } - set { _dateTimeKindHandling = value; } - } + private byte[] _byteBuffer; + private char[] _charBuffer; - /// - /// Initializes a new instance of the class. - /// - /// The stream. - public BsonReader(Stream stream) - : this(stream, false, DateTimeKind.Local) - { - } + private BsonType _currentElementType; + private BsonReaderState _bsonReaderState; + private ContainerContext _currentContext; - /// - /// Initializes a new instance of the class. - /// - /// The reader. - public BsonReader(BinaryReader reader) - : this(reader, false, DateTimeKind.Local) - { - } + private bool _readRootValueAsArray; + private bool _jsonNet35BinaryCompatibility; + private DateTimeKind _dateTimeKindHandling; - /// - /// Initializes a new instance of the class. - /// - /// The stream. - /// if set to true the root object will be read as a JSON array. - /// The used when reading values from BSON. - public BsonReader(Stream stream, bool readRootValueAsArray, DateTimeKind dateTimeKindHandling) - { - ValidationUtils.ArgumentNotNull(stream, "stream"); - _reader = new BinaryReader(stream); - _stack = new List(); - _readRootValueAsArray = readRootValueAsArray; - _dateTimeKindHandling = dateTimeKindHandling; - } + private enum BsonReaderState + { + Normal, + ReferenceStart, + ReferenceRef, + ReferenceId, + CodeWScopeStart, + CodeWScopeCode, + CodeWScopeScope, + CodeWScopeScopeObject, + CodeWScopeScopeEnd + } - /// - /// Initializes a new instance of the class. - /// - /// The reader. - /// if set to true the root object will be read as a JSON array. - /// The used when reading values from BSON. - public BsonReader(BinaryReader reader, bool readRootValueAsArray, DateTimeKind dateTimeKindHandling) - { - ValidationUtils.ArgumentNotNull(reader, "reader"); - _reader = reader; - _stack = new List(); - _readRootValueAsArray = readRootValueAsArray; - _dateTimeKindHandling = dateTimeKindHandling; - } + private class ContainerContext + { + public readonly BsonType Type; + public int Length; + public int Position; - private string ReadElement() - { - _currentElementType = ReadType(); - string elementName = ReadString(); - return elementName; - } + public ContainerContext(BsonType type) + { + Type = type; + } + } - /// - /// Reads the next JSON token from the stream as a . - /// - /// - /// A or a null reference if the next JSON token is null. This method will return null at the end of an array. - /// - public override byte[] ReadAsBytes() - { - return ReadAsBytesInternal(); - } + /// + /// Gets or sets a value indicating whether binary data reading should compatible with incorrect Json.NET 3.5 written binary. + /// + /// + /// true if binary data reading will be compatible with incorrect Json.NET 3.5 written binary; otherwise, false. + /// + [Obsolete("JsonNet35BinaryCompatibility will be removed in a future version of Json.NET.")] + public bool JsonNet35BinaryCompatibility + { + get { return _jsonNet35BinaryCompatibility; } + set { _jsonNet35BinaryCompatibility = value; } + } - /// - /// Reads the next JSON token from the stream as a . - /// - /// A . This method will return null at the end of an array. - public override decimal? ReadAsDecimal() - { - return ReadAsDecimalInternal(); - } + /// + /// Gets or sets a value indicating whether the root object will be read as a JSON array. + /// + /// + /// true if the root object will be read as a JSON array; otherwise, false. + /// + public bool ReadRootValueAsArray + { + get { return _readRootValueAsArray; } + set { _readRootValueAsArray = value; } + } - /// - /// Reads the next JSON token from the stream as a . - /// - /// A . This method will return null at the end of an array. - public override int? ReadAsInt32() - { - return ReadAsInt32Internal(); - } + /// + /// Gets or sets the used when reading values from BSON. + /// + /// The used when reading values from BSON. + public DateTimeKind DateTimeKindHandling + { + get { return _dateTimeKindHandling; } + set { _dateTimeKindHandling = value; } + } - /// - /// Reads the next JSON token from the stream as a . - /// - /// A . This method will return null at the end of an array. - public override string ReadAsString() - { - return ReadAsStringInternal(); - } + /// + /// Initializes a new instance of the class. + /// + /// The stream. + public BsonReader(Stream stream) + : this(stream, false, DateTimeKind.Local) + { + } - /// - /// Reads the next JSON token from the stream as a . - /// - /// A . This method will return null at the end of an array. - public override DateTime? ReadAsDateTime() - { - return ReadAsDateTimeInternal(); - } + /// + /// Initializes a new instance of the class. + /// + /// The reader. + public BsonReader(BinaryReader reader) + : this(reader, false, DateTimeKind.Local) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The stream. + /// if set to true the root object will be read as a JSON array. + /// The used when reading values from BSON. + public BsonReader(Stream stream, bool readRootValueAsArray, DateTimeKind dateTimeKindHandling) + { + ValidationUtils.ArgumentNotNull(stream, "stream"); + _reader = new BinaryReader(stream); + _stack = new List(); + _readRootValueAsArray = readRootValueAsArray; + _dateTimeKindHandling = dateTimeKindHandling; + } + + /// + /// Initializes a new instance of the class. + /// + /// The reader. + /// if set to true the root object will be read as a JSON array. + /// The used when reading values from BSON. + public BsonReader(BinaryReader reader, bool readRootValueAsArray, DateTimeKind dateTimeKindHandling) + { + ValidationUtils.ArgumentNotNull(reader, "reader"); + _reader = reader; + _stack = new List(); + _readRootValueAsArray = readRootValueAsArray; + _dateTimeKindHandling = dateTimeKindHandling; + } + + private string ReadElement() + { + _currentElementType = ReadType(); + string elementName = ReadString(); + return elementName; + } + + /// + /// Reads the next JSON token from the stream as a . + /// + /// + /// A or a null reference if the next JSON token is null. This method will return null at the end of an array. + /// + public override byte[] ReadAsBytes() + { + return ReadAsBytesInternal(); + } + + /// + /// Reads the next JSON token from the stream as a . + /// + /// A . This method will return null at the end of an array. + public override decimal? ReadAsDecimal() + { + return ReadAsDecimalInternal(); + } + + /// + /// Reads the next JSON token from the stream as a . + /// + /// A . This method will return null at the end of an array. + public override int? ReadAsInt32() + { + return ReadAsInt32Internal(); + } + + /// + /// Reads the next JSON token from the stream as a . + /// + /// A . This method will return null at the end of an array. + public override string ReadAsString() + { + return ReadAsStringInternal(); + } + + /// + /// Reads the next JSON token from the stream as a . + /// + /// A . This method will return null at the end of an array. + public override DateTime? ReadAsDateTime() + { + return ReadAsDateTimeInternal(); + } #if !NET20 - /// - /// Reads the next JSON token from the stream as a . - /// - /// - /// A . This method will return null at the end of an array. - /// - public override DateTimeOffset? ReadAsDateTimeOffset() - { - return ReadAsDateTimeOffsetInternal(); - } + /// + /// Reads the next JSON token from the stream as a . + /// + /// + /// A . This method will return null at the end of an array. + /// + public override DateTimeOffset? ReadAsDateTimeOffset() + { + return ReadAsDateTimeOffsetInternal(); + } #endif - /// - /// Reads the next JSON token from the stream. - /// - /// - /// true if the next token was read successfully; false if there are no more tokens to read. - /// - public override bool Read() - { - _readType = Json.ReadType.Read; - - return ReadInternal(); - } - - internal override bool ReadInternal() - { - try - { - bool success; - - switch (_bsonReaderState) + /// + /// Reads the next JSON token from the stream. + /// + /// + /// true if the next token was read successfully; false if there are no more tokens to read. + /// + public override bool Read() { - case BsonReaderState.Normal: - success = ReadNormal(); - break; - case BsonReaderState.ReferenceStart: - case BsonReaderState.ReferenceRef: - case BsonReaderState.ReferenceId: - success = ReadReference(); - break; - case BsonReaderState.CodeWScopeStart: - case BsonReaderState.CodeWScopeCode: - case BsonReaderState.CodeWScopeScope: - case BsonReaderState.CodeWScopeScopeObject: - case BsonReaderState.CodeWScopeScopeEnd: - success = ReadCodeWScope(); - break; - default: - throw JsonReaderException.Create(this, "Unexpected state: {0}".FormatWith(CultureInfo.InvariantCulture, _bsonReaderState)); + _readType = Json.ReadType.Read; + + return ReadInternal(); } - if (!success) + internal override bool ReadInternal() { - SetToken(JsonToken.None); - return false; + try + { + bool success; + + switch (_bsonReaderState) + { + case BsonReaderState.Normal: + success = ReadNormal(); + break; + case BsonReaderState.ReferenceStart: + case BsonReaderState.ReferenceRef: + case BsonReaderState.ReferenceId: + success = ReadReference(); + break; + case BsonReaderState.CodeWScopeStart: + case BsonReaderState.CodeWScopeCode: + case BsonReaderState.CodeWScopeScope: + case BsonReaderState.CodeWScopeScopeObject: + case BsonReaderState.CodeWScopeScopeEnd: + success = ReadCodeWScope(); + break; + default: + throw JsonReaderException.Create(this, "Unexpected state: {0}".FormatWith(CultureInfo.InvariantCulture, _bsonReaderState)); + } + + if (!success) + { + SetToken(JsonToken.None); + return false; + } + + return true; + } + catch (EndOfStreamException) + { + SetToken(JsonToken.None); + return false; + } } - return true; - } - catch (EndOfStreamException) - { - SetToken(JsonToken.None); - return false; - } - } + /// + /// Changes the to Closed. + /// + public override void Close() + { + base.Close(); - /// - /// Changes the to Closed. - /// - public override void Close() - { - base.Close(); - - if (CloseInput && _reader != null) + if (CloseInput && _reader != null) #if !(NETFX_CORE || PORTABLE40 || PORTABLE) - _reader.Close(); + _reader.Close(); #else - _reader.Dispose(); + _reader.Dispose(); #endif - } + } - private bool ReadCodeWScope() - { - switch (_bsonReaderState) - { - case BsonReaderState.CodeWScopeStart: - SetToken(JsonToken.PropertyName, "$code"); - _bsonReaderState = BsonReaderState.CodeWScopeCode; - return true; - case BsonReaderState.CodeWScopeCode: - // total CodeWScope size - not used - ReadInt32(); - - SetToken(JsonToken.String, ReadLengthString()); - _bsonReaderState = BsonReaderState.CodeWScopeScope; - return true; - case BsonReaderState.CodeWScopeScope: - if (CurrentState == State.PostValue) - { - SetToken(JsonToken.PropertyName, "$scope"); - return true; - } - else - { - SetToken(JsonToken.StartObject); - _bsonReaderState = BsonReaderState.CodeWScopeScopeObject; - - ContainerContext newContext = new ContainerContext(BsonType.Object); - PushContext(newContext); - newContext.Length = ReadInt32(); - - return true; - } - case BsonReaderState.CodeWScopeScopeObject: - bool result = ReadNormal(); - if (result && TokenType == JsonToken.EndObject) - _bsonReaderState = BsonReaderState.CodeWScopeScopeEnd; - - return result; - case BsonReaderState.CodeWScopeScopeEnd: - SetToken(JsonToken.EndObject); - _bsonReaderState = BsonReaderState.Normal; - return true; - default: - throw new ArgumentOutOfRangeException(); - } - } - - private bool ReadReference() - { - switch (CurrentState) - { - case State.ObjectStart: - { - SetToken(JsonToken.PropertyName, "$ref"); - _bsonReaderState = BsonReaderState.ReferenceRef; - return true; - } - case State.Property: - { - if (_bsonReaderState == BsonReaderState.ReferenceRef) + private bool ReadCodeWScope() + { + switch (_bsonReaderState) { - SetToken(JsonToken.String, ReadLengthString()); - return true; - } - else if (_bsonReaderState == BsonReaderState.ReferenceId) - { - SetToken(JsonToken.Bytes, ReadBytes(12)); - return true; - } - else - { - throw JsonReaderException.Create(this, "Unexpected state when reading BSON reference: " + _bsonReaderState); - } - } - case State.PostValue: - { - if (_bsonReaderState == BsonReaderState.ReferenceRef) - { - SetToken(JsonToken.PropertyName, "$id"); - _bsonReaderState = BsonReaderState.ReferenceId; - return true; - } - else if (_bsonReaderState == BsonReaderState.ReferenceId) - { - SetToken(JsonToken.EndObject); - _bsonReaderState = BsonReaderState.Normal; - return true; - } - else - { - throw JsonReaderException.Create(this, "Unexpected state when reading BSON reference: " + _bsonReaderState); - } - } - default: - throw JsonReaderException.Create(this, "Unexpected state when reading BSON reference: " + CurrentState); - } - } + case BsonReaderState.CodeWScopeStart: + SetToken(JsonToken.PropertyName, "$code"); + _bsonReaderState = BsonReaderState.CodeWScopeCode; + return true; + case BsonReaderState.CodeWScopeCode: + // total CodeWScope size - not used + ReadInt32(); - private bool ReadNormal() - { - switch (CurrentState) - { - case State.Start: - { - JsonToken token = (!_readRootValueAsArray) ? JsonToken.StartObject : JsonToken.StartArray; - BsonType type = (!_readRootValueAsArray) ? BsonType.Object : BsonType.Array; + SetToken(JsonToken.String, ReadLengthString()); + _bsonReaderState = BsonReaderState.CodeWScopeScope; + return true; + case BsonReaderState.CodeWScopeScope: + if (CurrentState == State.PostValue) + { + SetToken(JsonToken.PropertyName, "$scope"); + return true; + } + else + { + SetToken(JsonToken.StartObject); + _bsonReaderState = BsonReaderState.CodeWScopeScopeObject; + + ContainerContext newContext = new ContainerContext(BsonType.Object); + PushContext(newContext); + newContext.Length = ReadInt32(); + + return true; + } + case BsonReaderState.CodeWScopeScopeObject: + bool result = ReadNormal(); + if (result && TokenType == JsonToken.EndObject) + _bsonReaderState = BsonReaderState.CodeWScopeScopeEnd; + + return result; + case BsonReaderState.CodeWScopeScopeEnd: + SetToken(JsonToken.EndObject); + _bsonReaderState = BsonReaderState.Normal; + return true; + default: + throw new ArgumentOutOfRangeException(); + } + } + + private bool ReadReference() + { + switch (CurrentState) + { + case State.ObjectStart: + { + SetToken(JsonToken.PropertyName, "$ref"); + _bsonReaderState = BsonReaderState.ReferenceRef; + return true; + } + case State.Property: + { + if (_bsonReaderState == BsonReaderState.ReferenceRef) + { + SetToken(JsonToken.String, ReadLengthString()); + return true; + } + else if (_bsonReaderState == BsonReaderState.ReferenceId) + { + SetToken(JsonToken.Bytes, ReadBytes(12)); + return true; + } + else + { + throw JsonReaderException.Create(this, "Unexpected state when reading BSON reference: " + _bsonReaderState); + } + } + case State.PostValue: + { + if (_bsonReaderState == BsonReaderState.ReferenceRef) + { + SetToken(JsonToken.PropertyName, "$id"); + _bsonReaderState = BsonReaderState.ReferenceId; + return true; + } + else if (_bsonReaderState == BsonReaderState.ReferenceId) + { + SetToken(JsonToken.EndObject); + _bsonReaderState = BsonReaderState.Normal; + return true; + } + else + { + throw JsonReaderException.Create(this, "Unexpected state when reading BSON reference: " + _bsonReaderState); + } + } + default: + throw JsonReaderException.Create(this, "Unexpected state when reading BSON reference: " + CurrentState); + } + } + + private bool ReadNormal() + { + switch (CurrentState) + { + case State.Start: + { + JsonToken token = (!_readRootValueAsArray) ? JsonToken.StartObject : JsonToken.StartArray; + BsonType type = (!_readRootValueAsArray) ? BsonType.Object : BsonType.Array; + + SetToken(token); + ContainerContext newContext = new ContainerContext(type); + PushContext(newContext); + newContext.Length = ReadInt32(); + return true; + } + case State.Complete: + case State.Closed: + return false; + case State.Property: + { + ReadType(_currentElementType); + return true; + } + case State.ObjectStart: + case State.ArrayStart: + case State.PostValue: + ContainerContext context = _currentContext; + if (context == null) + return false; + + int lengthMinusEnd = context.Length - 1; + + if (context.Position < lengthMinusEnd) + { + if (context.Type == BsonType.Array) + { + ReadElement(); + ReadType(_currentElementType); + return true; + } + else + { + SetToken(JsonToken.PropertyName, ReadElement()); + return true; + } + } + else if (context.Position == lengthMinusEnd) + { + if (ReadByte() != 0) + throw JsonReaderException.Create(this, "Unexpected end of object byte value."); + + PopContext(); + if (_currentContext != null) + MovePosition(context.Length); + + JsonToken endToken = (context.Type == BsonType.Object) ? JsonToken.EndObject : JsonToken.EndArray; + SetToken(endToken); + return true; + } + else + { + throw JsonReaderException.Create(this, "Read past end of current container context."); + } + case State.ConstructorStart: + break; + case State.Constructor: + break; + case State.Error: + break; + case State.Finished: + break; + default: + throw new ArgumentOutOfRangeException(); + } - SetToken(token); - ContainerContext newContext = new ContainerContext(type); - PushContext(newContext); - newContext.Length = ReadInt32(); - return true; - } - case State.Complete: - case State.Closed: - return false; - case State.Property: - { - ReadType(_currentElementType); - return true; - } - case State.ObjectStart: - case State.ArrayStart: - case State.PostValue: - ContainerContext context = _currentContext; - if (context == null) return false; + } - int lengthMinusEnd = context.Length - 1; - - if (context.Position < lengthMinusEnd) - { - if (context.Type == BsonType.Array) - { - ReadElement(); - ReadType(_currentElementType); - return true; - } + private void PopContext() + { + _stack.RemoveAt(_stack.Count - 1); + if (_stack.Count == 0) + _currentContext = null; else + _currentContext = _stack[_stack.Count - 1]; + } + + private void PushContext(ContainerContext newContext) + { + _stack.Add(newContext); + _currentContext = newContext; + } + + private byte ReadByte() + { + MovePosition(1); + return _reader.ReadByte(); + } + + private void ReadType(BsonType type) + { + switch (type) { - SetToken(JsonToken.PropertyName, ReadElement()); - return true; + case BsonType.Number: + double d = ReadDouble(); + + if (_floatParseHandling == FloatParseHandling.Decimal) + SetToken(JsonToken.Float, Convert.ToDecimal(d, CultureInfo.InvariantCulture)); + else + SetToken(JsonToken.Float, d); + break; + case BsonType.String: + case BsonType.Symbol: + SetToken(JsonToken.String, ReadLengthString()); + break; + case BsonType.Object: + { + SetToken(JsonToken.StartObject); + + ContainerContext newContext = new ContainerContext(BsonType.Object); + PushContext(newContext); + newContext.Length = ReadInt32(); + break; + } + case BsonType.Array: + { + SetToken(JsonToken.StartArray); + + ContainerContext newContext = new ContainerContext(BsonType.Array); + PushContext(newContext); + newContext.Length = ReadInt32(); + break; + } + case BsonType.Binary: + SetToken(JsonToken.Bytes, ReadBinary()); + break; + case BsonType.Undefined: + SetToken(JsonToken.Undefined); + break; + case BsonType.Oid: + byte[] oid = ReadBytes(12); + SetToken(JsonToken.Bytes, oid); + break; + case BsonType.Boolean: + bool b = Convert.ToBoolean(ReadByte()); + SetToken(JsonToken.Boolean, b); + break; + case BsonType.Date: + long ticks = ReadInt64(); + DateTime utcDateTime = DateTimeUtils.ConvertJavaScriptTicksToDateTime(ticks); + + DateTime dateTime; + switch (DateTimeKindHandling) + { + case DateTimeKind.Unspecified: + dateTime = DateTime.SpecifyKind(utcDateTime, DateTimeKind.Unspecified); + break; + case DateTimeKind.Local: + dateTime = utcDateTime.ToLocalTime(); + break; + default: + dateTime = utcDateTime; + break; + } + + SetToken(JsonToken.Date, dateTime); + break; + case BsonType.Null: + SetToken(JsonToken.Null); + break; + case BsonType.Regex: + string expression = ReadString(); + string modifiers = ReadString(); + + string regex = @"/" + expression + @"/" + modifiers; + SetToken(JsonToken.String, regex); + break; + case BsonType.Reference: + SetToken(JsonToken.StartObject); + _bsonReaderState = BsonReaderState.ReferenceStart; + break; + case BsonType.Code: + SetToken(JsonToken.String, ReadLengthString()); + break; + case BsonType.CodeWScope: + SetToken(JsonToken.StartObject); + _bsonReaderState = BsonReaderState.CodeWScopeStart; + break; + case BsonType.Integer: + SetToken(JsonToken.Integer, (long)ReadInt32()); + break; + case BsonType.TimeStamp: + case BsonType.Long: + SetToken(JsonToken.Integer, ReadInt64()); + break; + default: + throw new ArgumentOutOfRangeException("type", "Unexpected BsonType value: " + type); } - } - else if (context.Position == lengthMinusEnd) - { - if (ReadByte() != 0) - throw JsonReaderException.Create(this, "Unexpected end of object byte value."); + } - PopContext(); - if (_currentContext != null) - MovePosition(context.Length); + private byte[] ReadBinary() + { + int dataLength = ReadInt32(); - JsonToken endToken = (context.Type == BsonType.Object) ? JsonToken.EndObject : JsonToken.EndArray; - SetToken(endToken); - return true; - } - else - { - throw JsonReaderException.Create(this, "Read past end of current container context."); - } - case State.ConstructorStart: - break; - case State.Constructor: - break; - case State.Error: - break; - case State.Finished: - break; - default: - throw new ArgumentOutOfRangeException(); - } - - return false; - } - - private void PopContext() - { - _stack.RemoveAt(_stack.Count - 1); - if (_stack.Count == 0) - _currentContext = null; - else - _currentContext = _stack[_stack.Count - 1]; - } - - private void PushContext(ContainerContext newContext) - { - _stack.Add(newContext); - _currentContext = newContext; - } - - private byte ReadByte() - { - MovePosition(1); - return _reader.ReadByte(); - } - - private void ReadType(BsonType type) - { - switch (type) - { - case BsonType.Number: - double d = ReadDouble(); - - if (_floatParseHandling == FloatParseHandling.Decimal) - SetToken(JsonToken.Float, Convert.ToDecimal(d, CultureInfo.InvariantCulture)); - else - SetToken(JsonToken.Float, d); - break; - case BsonType.String: - case BsonType.Symbol: - SetToken(JsonToken.String, ReadLengthString()); - break; - case BsonType.Object: - { - SetToken(JsonToken.StartObject); - - ContainerContext newContext = new ContainerContext(BsonType.Object); - PushContext(newContext); - newContext.Length = ReadInt32(); - break; - } - case BsonType.Array: - { - SetToken(JsonToken.StartArray); - - ContainerContext newContext = new ContainerContext(BsonType.Array); - PushContext(newContext); - newContext.Length = ReadInt32(); - break; - } - case BsonType.Binary: - SetToken(JsonToken.Bytes, ReadBinary()); - break; - case BsonType.Undefined: - SetToken(JsonToken.Undefined); - break; - case BsonType.Oid: - byte[] oid = ReadBytes(12); - SetToken(JsonToken.Bytes, oid); - break; - case BsonType.Boolean: - bool b = Convert.ToBoolean(ReadByte()); - SetToken(JsonToken.Boolean, b); - break; - case BsonType.Date: - long ticks = ReadInt64(); - DateTime utcDateTime = DateTimeUtils.ConvertJavaScriptTicksToDateTime(ticks); - - DateTime dateTime; - switch (DateTimeKindHandling) - { - case DateTimeKind.Unspecified: - dateTime = DateTime.SpecifyKind(utcDateTime, DateTimeKind.Unspecified); - break; - case DateTimeKind.Local: - dateTime = utcDateTime.ToLocalTime(); - break; - default: - dateTime = utcDateTime; - break; - } - - SetToken(JsonToken.Date, dateTime); - break; - case BsonType.Null: - SetToken(JsonToken.Null); - break; - case BsonType.Regex: - string expression = ReadString(); - string modifiers = ReadString(); - - string regex = @"/" + expression + @"/" + modifiers; - SetToken(JsonToken.String, regex); - break; - case BsonType.Reference: - SetToken(JsonToken.StartObject); - _bsonReaderState = BsonReaderState.ReferenceStart; - break; - case BsonType.Code: - SetToken(JsonToken.String, ReadLengthString()); - break; - case BsonType.CodeWScope: - SetToken(JsonToken.StartObject); - _bsonReaderState = BsonReaderState.CodeWScopeStart; - break; - case BsonType.Integer: - SetToken(JsonToken.Integer, (long) ReadInt32()); - break; - case BsonType.TimeStamp: - case BsonType.Long: - SetToken(JsonToken.Integer, ReadInt64()); - break; - default: - throw new ArgumentOutOfRangeException("type", "Unexpected BsonType value: " + type); - } - } - - private byte[] ReadBinary() - { - int dataLength = ReadInt32(); - - BsonBinaryType binaryType = (BsonBinaryType) ReadByte(); + BsonBinaryType binaryType = (BsonBinaryType)ReadByte(); #pragma warning disable 612,618 - // the old binary type has the data length repeated in the data for some reason - if (binaryType == BsonBinaryType.BinaryOld && !_jsonNet35BinaryCompatibility) - { - dataLength = ReadInt32(); - } + // the old binary type has the data length repeated in the data for some reason + if (binaryType == BsonBinaryType.BinaryOld && !_jsonNet35BinaryCompatibility) + { + dataLength = ReadInt32(); + } #pragma warning restore 612,618 - return ReadBytes(dataLength); - } - - private string ReadString() - { - EnsureBuffers(); - - StringBuilder builder = null; - - int totalBytesRead = 0; - // used in case of left over multibyte characters in the buffer - int offset = 0; - do - { - int count = offset; - byte b; - while (count < MaxCharBytesSize && (b = _reader.ReadByte()) > 0) - { - _byteBuffer[count++] = b; + return ReadBytes(dataLength); } - int byteCount = count - offset; - totalBytesRead += byteCount; - if (count < MaxCharBytesSize && builder == null) + private string ReadString() { - // pref optimization to avoid reading into a string builder - // if string is smaller than the buffer then return it directly - int length = Encoding.UTF8.GetChars(_byteBuffer, 0, byteCount, _charBuffer, 0); + EnsureBuffers(); - MovePosition(totalBytesRead + 1); - return new string(_charBuffer, 0, length); - } - else - { - // calculate the index of the end of the last full character in the buffer - int lastFullCharStop = GetLastFullCharStop(count - 1); + StringBuilder builder = null; - int charCount = Encoding.UTF8.GetChars(_byteBuffer, 0, lastFullCharStop + 1, _charBuffer, 0); - - if (builder == null) - builder = new StringBuilder(MaxCharBytesSize*2); - - builder.Append(_charBuffer, 0, charCount); - - if (lastFullCharStop < byteCount - 1) - { - offset = byteCount - lastFullCharStop - 1; - // copy left over multi byte characters to beginning of buffer for next iteration - Array.Copy(_byteBuffer, lastFullCharStop + 1, _byteBuffer, 0, offset); - } - else - { - // reached end of string - if (count < MaxCharBytesSize) + int totalBytesRead = 0; + // used in case of left over multibyte characters in the buffer + int offset = 0; + do { - MovePosition(totalBytesRead + 1); - return builder.ToString(); + int count = offset; + byte b; + while (count < MaxCharBytesSize && (b = _reader.ReadByte()) > 0) + { + _byteBuffer[count++] = b; + } + int byteCount = count - offset; + totalBytesRead += byteCount; + + if (count < MaxCharBytesSize && builder == null) + { + // pref optimization to avoid reading into a string builder + // if string is smaller than the buffer then return it directly + int length = Encoding.UTF8.GetChars(_byteBuffer, 0, byteCount, _charBuffer, 0); + + MovePosition(totalBytesRead + 1); + return new string(_charBuffer, 0, length); + } + else + { + // calculate the index of the end of the last full character in the buffer + int lastFullCharStop = GetLastFullCharStop(count - 1); + + int charCount = Encoding.UTF8.GetChars(_byteBuffer, 0, lastFullCharStop + 1, _charBuffer, 0); + + if (builder == null) + builder = new StringBuilder(MaxCharBytesSize * 2); + + builder.Append(_charBuffer, 0, charCount); + + if (lastFullCharStop < byteCount - 1) + { + offset = byteCount - lastFullCharStop - 1; + // copy left over multi byte characters to beginning of buffer for next iteration + Array.Copy(_byteBuffer, lastFullCharStop + 1, _byteBuffer, 0, offset); + } + else + { + // reached end of string + if (count < MaxCharBytesSize) + { + MovePosition(totalBytesRead + 1); + return builder.ToString(); + } + + offset = 0; + } + } + } while (true); + } + + private string ReadLengthString() + { + int length = ReadInt32(); + + MovePosition(length); + + string s = GetString(length - 1); + _reader.ReadByte(); + + return s; + } + + private string GetString(int length) + { + if (length == 0) + return string.Empty; + + EnsureBuffers(); + + StringBuilder builder = null; + + int totalBytesRead = 0; + + // used in case of left over multibyte characters in the buffer + int offset = 0; + do + { + int count = ((length - totalBytesRead) > MaxCharBytesSize - offset) + ? MaxCharBytesSize - offset + : length - totalBytesRead; + + int byteCount = _reader.Read(_byteBuffer, offset, count); + + if (byteCount == 0) + throw new EndOfStreamException("Unable to read beyond the end of the stream."); + + totalBytesRead += byteCount; + + // Above, byteCount is how many bytes we read this time. + // Below, byteCount is how many bytes are in the _byteBuffer. + byteCount += offset; + + if (byteCount == length) + { + // pref optimization to avoid reading into a string builder + // first iteration and all bytes read then return string directly + int charCount = Encoding.UTF8.GetChars(_byteBuffer, 0, byteCount, _charBuffer, 0); + return new string(_charBuffer, 0, charCount); + } + else + { + int lastFullCharStop = GetLastFullCharStop(byteCount - 1); + + if (builder == null) + builder = new StringBuilder(length); + + int charCount = Encoding.UTF8.GetChars(_byteBuffer, 0, lastFullCharStop + 1, _charBuffer, 0); + builder.Append(_charBuffer, 0, charCount); + + if (lastFullCharStop < byteCount - 1) + { + offset = byteCount - lastFullCharStop - 1; + // copy left over multi byte characters to beginning of buffer for next iteration + Array.Copy(_byteBuffer, lastFullCharStop + 1, _byteBuffer, 0, offset); + } + else + { + offset = 0; + } + } + } while (totalBytesRead < length); + + return builder.ToString(); + } + + private int GetLastFullCharStop(int start) + { + int lookbackPos = start; + int bis = 0; + while (lookbackPos >= 0) + { + bis = BytesInSequence(_byteBuffer[lookbackPos]); + if (bis == 0) + { + lookbackPos--; + continue; + } + else if (bis == 1) + { + break; + } + else + { + lookbackPos--; + break; + } + } + if (bis == start - lookbackPos) + { + //Full character. + return start; + } + else + { + return lookbackPos; } - - offset = 0; - } } - } while (true); - } - private string ReadLengthString() - { - int length = ReadInt32(); - - MovePosition(length); - - string s = GetString(length - 1); - _reader.ReadByte(); - - return s; - } - - private string GetString(int length) - { - if (length == 0) - return string.Empty; - - EnsureBuffers(); - - StringBuilder builder = null; - - int totalBytesRead = 0; - - // used in case of left over multibyte characters in the buffer - int offset = 0; - do - { - int count = ((length - totalBytesRead) > MaxCharBytesSize - offset) - ? MaxCharBytesSize - offset - : length - totalBytesRead; - - int byteCount = _reader.Read(_byteBuffer, offset, count); - - if (byteCount == 0) - throw new EndOfStreamException("Unable to read beyond the end of the stream."); - - totalBytesRead += byteCount; - - // Above, byteCount is how many bytes we read this time. - // Below, byteCount is how many bytes are in the _byteBuffer. - byteCount += offset; - - if (byteCount == length) + private int BytesInSequence(byte b) { - // pref optimization to avoid reading into a string builder - // first iteration and all bytes read then return string directly - int charCount = Encoding.UTF8.GetChars(_byteBuffer, 0, byteCount, _charBuffer, 0); - return new string(_charBuffer, 0, charCount); + if (b <= SeqRange1[1]) return 1; + if (b >= SeqRange2[0] && b <= SeqRange2[1]) return 2; + if (b >= SeqRange3[0] && b <= SeqRange3[1]) return 3; + if (b >= SeqRange4[0] && b <= SeqRange4[1]) return 4; + return 0; } - else + + private void EnsureBuffers() { - int lastFullCharStop = GetLastFullCharStop(byteCount - 1); - - if (builder == null) - builder = new StringBuilder(length); - - int charCount = Encoding.UTF8.GetChars(_byteBuffer, 0, lastFullCharStop + 1, _charBuffer, 0); - builder.Append(_charBuffer, 0, charCount); - - if (lastFullCharStop < byteCount - 1) - { - offset = byteCount - lastFullCharStop - 1; - // copy left over multi byte characters to beginning of buffer for next iteration - Array.Copy(_byteBuffer, lastFullCharStop + 1, _byteBuffer, 0, offset); - } - else - { - offset = 0; - } + if (_byteBuffer == null) + { + _byteBuffer = new byte[MaxCharBytesSize]; + } + if (_charBuffer == null) + { + int charBufferSize = Encoding.UTF8.GetMaxCharCount(MaxCharBytesSize); + _charBuffer = new char[charBufferSize]; + } } - } while (totalBytesRead < length); - return builder.ToString(); - } - - private int GetLastFullCharStop(int start) - { - int lookbackPos = start; - int bis = 0; - while (lookbackPos >= 0) - { - bis = BytesInSequence(_byteBuffer[lookbackPos]); - if (bis == 0) + private double ReadDouble() { - lookbackPos--; - continue; + MovePosition(8); + return _reader.ReadDouble(); } - else if (bis == 1) + + private int ReadInt32() { - break; + MovePosition(4); + return _reader.ReadInt32(); } - else + + private long ReadInt64() { - lookbackPos--; - break; + MovePosition(8); + return _reader.ReadInt64(); } - } - if (bis == start - lookbackPos) - { - //Full character. - return start; - } - else - { - return lookbackPos; - } - } - private int BytesInSequence(byte b) - { - if (b <= SeqRange1[1]) return 1; - if (b >= SeqRange2[0] && b <= SeqRange2[1]) return 2; - if (b >= SeqRange3[0] && b <= SeqRange3[1]) return 3; - if (b >= SeqRange4[0] && b <= SeqRange4[1]) return 4; - return 0; - } + private BsonType ReadType() + { + MovePosition(1); + return (BsonType)_reader.ReadSByte(); + } - private void EnsureBuffers() - { - if (_byteBuffer == null) - { - _byteBuffer = new byte[MaxCharBytesSize]; - } - if (_charBuffer == null) - { - int charBufferSize = Encoding.UTF8.GetMaxCharCount(MaxCharBytesSize); - _charBuffer = new char[charBufferSize]; - } - } + private void MovePosition(int count) + { + _currentContext.Position += count; + } - private double ReadDouble() - { - MovePosition(8); - return _reader.ReadDouble(); + private byte[] ReadBytes(int count) + { + MovePosition(count); + return _reader.ReadBytes(count); + } } - - private int ReadInt32() - { - MovePosition(4); - return _reader.ReadInt32(); - } - - private long ReadInt64() - { - MovePosition(8); - return _reader.ReadInt64(); - } - - private BsonType ReadType() - { - MovePosition(1); - return (BsonType) _reader.ReadSByte(); - } - - private void MovePosition(int count) - { - _currentContext.Position += count; - } - - private byte[] ReadBytes(int count) - { - MovePosition(count); - return _reader.ReadBytes(count); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Bson/BsonToken.cs b/Src/Newtonsoft.Json/Bson/BsonToken.cs index 601d0588..06927a47 100644 --- a/Src/Newtonsoft.Json/Bson/BsonToken.cs +++ b/Src/Newtonsoft.Json/Bson/BsonToken.cs @@ -28,130 +28,130 @@ using System.Collections.Generic; namespace Newtonsoft.Json.Bson { - internal abstract class BsonToken - { - public abstract BsonType Type { get; } - public BsonToken Parent { get; set; } - public int CalculatedSize { get; set; } - } - - internal class BsonObject : BsonToken, IEnumerable - { - private readonly List _children = new List(); - - public void Add(string name, BsonToken token) + internal abstract class BsonToken { - _children.Add(new BsonProperty { Name = new BsonString(name, false), Value = token }); - token.Parent = this; + public abstract BsonType Type { get; } + public BsonToken Parent { get; set; } + public int CalculatedSize { get; set; } } - public override BsonType Type + internal class BsonObject : BsonToken, IEnumerable { - get { return BsonType.Object; } + private readonly List _children = new List(); + + public void Add(string name, BsonToken token) + { + _children.Add(new BsonProperty { Name = new BsonString(name, false), Value = token }); + token.Parent = this; + } + + public override BsonType Type + { + get { return BsonType.Object; } + } + + public IEnumerator GetEnumerator() + { + return _children.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } } - public IEnumerator GetEnumerator() + internal class BsonArray : BsonToken, IEnumerable { - return _children.GetEnumerator(); + private readonly List _children = new List(); + + public void Add(BsonToken token) + { + _children.Add(token); + token.Parent = this; + } + + public override BsonType Type + { + get { return BsonType.Array; } + } + + public IEnumerator GetEnumerator() + { + return _children.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } } - IEnumerator IEnumerable.GetEnumerator() + internal class BsonValue : BsonToken { - return GetEnumerator(); - } - } + private readonly object _value; + private readonly BsonType _type; - internal class BsonArray : BsonToken, IEnumerable - { - private readonly List _children = new List(); + public BsonValue(object value, BsonType type) + { + _value = value; + _type = type; + } - public void Add(BsonToken token) - { - _children.Add(token); - token.Parent = this; + public object Value + { + get { return _value; } + } + + public override BsonType Type + { + get { return _type; } + } } - public override BsonType Type + internal class BsonString : BsonValue { - get { return BsonType.Array; } + public int ByteCount { get; set; } + public bool IncludeLength { get; set; } + + public BsonString(object value, bool includeLength) + : base(value, BsonType.String) + { + IncludeLength = includeLength; + } } - public IEnumerator GetEnumerator() + internal class BsonBinary : BsonValue { - return _children.GetEnumerator(); + public BsonBinaryType BinaryType { get; set; } + + public BsonBinary(byte[] value, BsonBinaryType binaryType) + : base(value, BsonType.Binary) + { + BinaryType = binaryType; + } } - IEnumerator IEnumerable.GetEnumerator() + internal class BsonRegex : BsonToken { - return GetEnumerator(); - } - } + public BsonString Pattern { get; set; } + public BsonString Options { get; set; } - internal class BsonValue : BsonToken - { - private readonly object _value; - private readonly BsonType _type; + public BsonRegex(string pattern, string options) + { + Pattern = new BsonString(pattern, false); + Options = new BsonString(options, false); + } - public BsonValue(object value, BsonType type) - { - _value = value; - _type = type; + public override BsonType Type + { + get { return BsonType.Regex; } + } } - public object Value + internal class BsonProperty { - get { return _value; } + public BsonString Name { get; set; } + public BsonToken Value { get; set; } } - - public override BsonType Type - { - get { return _type; } - } - } - - internal class BsonString : BsonValue - { - public int ByteCount { get; set; } - public bool IncludeLength { get; set; } - - public BsonString(object value, bool includeLength) - : base(value, BsonType.String) - { - IncludeLength = includeLength; - } - } - - internal class BsonBinary : BsonValue - { - public BsonBinaryType BinaryType { get; set; } - - public BsonBinary(byte[] value, BsonBinaryType binaryType) - : base(value, BsonType.Binary) - { - BinaryType = binaryType; - } - } - - internal class BsonRegex : BsonToken - { - public BsonString Pattern { get; set; } - public BsonString Options { get; set; } - - public BsonRegex(string pattern, string options) - { - Pattern = new BsonString(pattern, false); - Options = new BsonString(options, false); - } - - public override BsonType Type - { - get { return BsonType.Regex; } - } - } - - internal class BsonProperty - { - public BsonString Name { get; set; } - public BsonToken Value { get; set; } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Bson/BsonType.cs b/Src/Newtonsoft.Json/Bson/BsonType.cs index 73361e9d..e1192985 100644 --- a/Src/Newtonsoft.Json/Bson/BsonType.cs +++ b/Src/Newtonsoft.Json/Bson/BsonType.cs @@ -25,27 +25,27 @@ namespace Newtonsoft.Json.Bson { - internal enum BsonType : sbyte - { - Number = 1, - String = 2, - Object = 3, - Array = 4, - Binary = 5, - Undefined = 6, - Oid = 7, - Boolean = 8, - Date = 9, - Null = 10, - Regex = 11, - Reference = 12, - Code = 13, - Symbol = 14, - CodeWScope = 15, - Integer = 16, - TimeStamp = 17, - Long = 18, - MinKey = -1, - MaxKey = 127 - } + internal enum BsonType : sbyte + { + Number = 1, + String = 2, + Object = 3, + Array = 4, + Binary = 5, + Undefined = 6, + Oid = 7, + Boolean = 8, + Date = 9, + Null = 10, + Regex = 11, + Reference = 12, + Code = 13, + Symbol = 14, + CodeWScope = 15, + Integer = 16, + TimeStamp = 17, + Long = 18, + MinKey = -1, + MaxKey = 127 + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Bson/BsonWriter.cs b/Src/Newtonsoft.Json/Bson/BsonWriter.cs index 20d8374c..cfed08f7 100644 --- a/Src/Newtonsoft.Json/Bson/BsonWriter.cs +++ b/Src/Newtonsoft.Json/Bson/BsonWriter.cs @@ -37,481 +37,481 @@ using System.Globalization; namespace Newtonsoft.Json.Bson { - /// - /// Represents a writer that provides a fast, non-cached, forward-only way of generating JSON data. - /// - public class BsonWriter : JsonWriter - { - private readonly BsonBinaryWriter _writer; - - private BsonToken _root; - private BsonToken _parent; - private string _propertyName; - /// - /// Gets or sets the used when writing values to BSON. - /// When set to no conversion will occur. + /// Represents a writer that provides a fast, non-cached, forward-only way of generating JSON data. /// - /// The used when writing values to BSON. - public DateTimeKind DateTimeKindHandling + public class BsonWriter : JsonWriter { - get { return _writer.DateTimeKindHandling; } - set { _writer.DateTimeKindHandling = value; } - } + private readonly BsonBinaryWriter _writer; - /// - /// Initializes a new instance of the class. - /// - /// The stream. - public BsonWriter(Stream stream) - { - ValidationUtils.ArgumentNotNull(stream, "stream"); - _writer = new BsonBinaryWriter(new BinaryWriter(stream)); - } + private BsonToken _root; + private BsonToken _parent; + private string _propertyName; - /// - /// Initializes a new instance of the class. - /// - /// The writer. - public BsonWriter(BinaryWriter writer) - { - ValidationUtils.ArgumentNotNull(writer, "writer"); - _writer = new BsonBinaryWriter(writer); - } - - /// - /// Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. - /// - public override void Flush() - { - _writer.Flush(); - } - - /// - /// Writes the end. - /// - /// The token. - protected override void WriteEnd(JsonToken token) - { - base.WriteEnd(token); - RemoveParent(); - - if (Top == 0) - { - _writer.WriteToken(_root); - } - } - - /// - /// Writes out a comment /*...*/ containing the specified text. - /// - /// Text to place inside the comment. - public override void WriteComment(string text) - { - throw JsonWriterException.Create(this, "Cannot write JSON comment as BSON.", null); - } - - /// - /// Writes the start of a constructor with the given name. - /// - /// The name of the constructor. - public override void WriteStartConstructor(string name) - { - throw JsonWriterException.Create(this, "Cannot write JSON constructor as BSON.", null); - } - - /// - /// Writes raw JSON. - /// - /// The raw JSON to write. - public override void WriteRaw(string json) - { - throw JsonWriterException.Create(this, "Cannot write raw JSON as BSON.", null); - } - - /// - /// Writes raw JSON where a value is expected and updates the writer's state. - /// - /// The raw JSON to write. - public override void WriteRawValue(string json) - { - throw JsonWriterException.Create(this, "Cannot write raw JSON as BSON.", null); - } - - /// - /// Writes the beginning of a Json array. - /// - public override void WriteStartArray() - { - base.WriteStartArray(); - - AddParent(new BsonArray()); - } - - /// - /// Writes the beginning of a Json object. - /// - public override void WriteStartObject() - { - base.WriteStartObject(); - - AddParent(new BsonObject()); - } - - /// - /// Writes the property name of a name/value pair on a Json object. - /// - /// The name of the property. - public override void WritePropertyName(string name) - { - base.WritePropertyName(name); - - _propertyName = name; - } - - /// - /// Closes this stream and the underlying stream. - /// - public override void Close() - { - base.Close(); - - if (CloseOutput && _writer != null) - _writer.Close(); - } - - private void AddParent(BsonToken container) - { - AddToken(container); - _parent = container; - } - - private void RemoveParent() - { - _parent = _parent.Parent; - } - - private void AddValue(object value, BsonType type) - { - AddToken(new BsonValue(value, type)); - } - - internal void AddToken(BsonToken token) - { - if (_parent != null) - { - if (_parent is BsonObject) + /// + /// Gets or sets the used when writing values to BSON. + /// When set to no conversion will occur. + /// + /// The used when writing values to BSON. + public DateTimeKind DateTimeKindHandling { - ((BsonObject) _parent).Add(_propertyName, token); - _propertyName = null; + get { return _writer.DateTimeKindHandling; } + set { _writer.DateTimeKindHandling = value; } } - else + + /// + /// Initializes a new instance of the class. + /// + /// The stream. + public BsonWriter(Stream stream) { - ((BsonArray) _parent).Add(token); + ValidationUtils.ArgumentNotNull(stream, "stream"); + _writer = new BsonBinaryWriter(new BinaryWriter(stream)); } - } - else - { - if (token.Type != BsonType.Object && token.Type != BsonType.Array) - throw JsonWriterException.Create(this, "Error writing {0} value. BSON must start with an Object or Array.".FormatWith(CultureInfo.InvariantCulture, token.Type), null); - _parent = token; - _root = token; - } - } + /// + /// Initializes a new instance of the class. + /// + /// The writer. + public BsonWriter(BinaryWriter writer) + { + ValidationUtils.ArgumentNotNull(writer, "writer"); + _writer = new BsonBinaryWriter(writer); + } - #region WriteValue methods - /// - /// Writes a value. - /// An error will raised if the value cannot be written as a single JSON token. - /// - /// The value to write. - public override void WriteValue(object value) - { + /// + /// Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. + /// + public override void Flush() + { + _writer.Flush(); + } + + /// + /// Writes the end. + /// + /// The token. + protected override void WriteEnd(JsonToken token) + { + base.WriteEnd(token); + RemoveParent(); + + if (Top == 0) + { + _writer.WriteToken(_root); + } + } + + /// + /// Writes out a comment /*...*/ containing the specified text. + /// + /// Text to place inside the comment. + public override void WriteComment(string text) + { + throw JsonWriterException.Create(this, "Cannot write JSON comment as BSON.", null); + } + + /// + /// Writes the start of a constructor with the given name. + /// + /// The name of the constructor. + public override void WriteStartConstructor(string name) + { + throw JsonWriterException.Create(this, "Cannot write JSON constructor as BSON.", null); + } + + /// + /// Writes raw JSON. + /// + /// The raw JSON to write. + public override void WriteRaw(string json) + { + throw JsonWriterException.Create(this, "Cannot write raw JSON as BSON.", null); + } + + /// + /// Writes raw JSON where a value is expected and updates the writer's state. + /// + /// The raw JSON to write. + public override void WriteRawValue(string json) + { + throw JsonWriterException.Create(this, "Cannot write raw JSON as BSON.", null); + } + + /// + /// Writes the beginning of a Json array. + /// + public override void WriteStartArray() + { + base.WriteStartArray(); + + AddParent(new BsonArray()); + } + + /// + /// Writes the beginning of a Json object. + /// + public override void WriteStartObject() + { + base.WriteStartObject(); + + AddParent(new BsonObject()); + } + + /// + /// Writes the property name of a name/value pair on a Json object. + /// + /// The name of the property. + public override void WritePropertyName(string name) + { + base.WritePropertyName(name); + + _propertyName = name; + } + + /// + /// Closes this stream and the underlying stream. + /// + public override void Close() + { + base.Close(); + + if (CloseOutput && _writer != null) + _writer.Close(); + } + + private void AddParent(BsonToken container) + { + AddToken(container); + _parent = container; + } + + private void RemoveParent() + { + _parent = _parent.Parent; + } + + private void AddValue(object value, BsonType type) + { + AddToken(new BsonValue(value, type)); + } + + internal void AddToken(BsonToken token) + { + if (_parent != null) + { + if (_parent is BsonObject) + { + ((BsonObject)_parent).Add(_propertyName, token); + _propertyName = null; + } + else + { + ((BsonArray)_parent).Add(token); + } + } + else + { + if (token.Type != BsonType.Object && token.Type != BsonType.Array) + throw JsonWriterException.Create(this, "Error writing {0} value. BSON must start with an Object or Array.".FormatWith(CultureInfo.InvariantCulture, token.Type), null); + + _parent = token; + _root = token; + } + } + + #region WriteValue methods + /// + /// Writes a value. + /// An error will raised if the value cannot be written as a single JSON token. + /// + /// The value to write. + public override void WriteValue(object value) + { #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE || PORTABLE40) - if (value is BigInteger) - { - InternalWriteValue(JsonToken.Integer); - AddToken(new BsonBinary(((BigInteger)value).ToByteArray(), BsonBinaryType.Binary)); - } - else + if (value is BigInteger) + { + InternalWriteValue(JsonToken.Integer); + AddToken(new BsonBinary(((BigInteger)value).ToByteArray(), BsonBinaryType.Binary)); + } + else #endif - { - base.WriteValue(value); - } - } + { + base.WriteValue(value); + } + } - /// - /// Writes a null value. - /// - public override void WriteNull() - { - base.WriteNull(); - AddValue(null, BsonType.Null); - } + /// + /// Writes a null value. + /// + public override void WriteNull() + { + base.WriteNull(); + AddValue(null, BsonType.Null); + } - /// - /// Writes an undefined value. - /// - public override void WriteUndefined() - { - base.WriteUndefined(); - AddValue(null, BsonType.Undefined); - } + /// + /// Writes an undefined value. + /// + public override void WriteUndefined() + { + base.WriteUndefined(); + AddValue(null, BsonType.Undefined); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(string value) - { - base.WriteValue(value); - if (value == null) - AddValue(null, BsonType.Null); - else - AddToken(new BsonString(value, true)); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(string value) + { + base.WriteValue(value); + if (value == null) + AddValue(null, BsonType.Null); + else + AddToken(new BsonString(value, true)); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(int value) - { - base.WriteValue(value); - AddValue(value, BsonType.Integer); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(int value) + { + base.WriteValue(value); + AddValue(value, BsonType.Integer); + } - /// - /// Writes a value. - /// - /// The value to write. - [CLSCompliant(false)] - public override void WriteValue(uint value) - { - if (value > int.MaxValue) - throw JsonWriterException.Create(this, "Value is too large to fit in a signed 32 bit integer. BSON does not support unsigned values.", null); + /// + /// Writes a value. + /// + /// The value to write. + [CLSCompliant(false)] + public override void WriteValue(uint value) + { + if (value > int.MaxValue) + throw JsonWriterException.Create(this, "Value is too large to fit in a signed 32 bit integer. BSON does not support unsigned values.", null); - base.WriteValue(value); - AddValue(value, BsonType.Integer); - } + base.WriteValue(value); + AddValue(value, BsonType.Integer); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(long value) - { - base.WriteValue(value); - AddValue(value, BsonType.Long); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(long value) + { + base.WriteValue(value); + AddValue(value, BsonType.Long); + } - /// - /// Writes a value. - /// - /// The value to write. - [CLSCompliant(false)] - public override void WriteValue(ulong value) - { - if (value > long.MaxValue) - throw JsonWriterException.Create(this, "Value is too large to fit in a signed 64 bit integer. BSON does not support unsigned values.", null); + /// + /// Writes a value. + /// + /// The value to write. + [CLSCompliant(false)] + public override void WriteValue(ulong value) + { + if (value > long.MaxValue) + throw JsonWriterException.Create(this, "Value is too large to fit in a signed 64 bit integer. BSON does not support unsigned values.", null); - base.WriteValue(value); - AddValue(value, BsonType.Long); - } + base.WriteValue(value); + AddValue(value, BsonType.Long); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(float value) - { - base.WriteValue(value); - AddValue(value, BsonType.Number); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(float value) + { + base.WriteValue(value); + AddValue(value, BsonType.Number); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(double value) - { - base.WriteValue(value); - AddValue(value, BsonType.Number); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(double value) + { + base.WriteValue(value); + AddValue(value, BsonType.Number); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(bool value) - { - base.WriteValue(value); - AddValue(value, BsonType.Boolean); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(bool value) + { + base.WriteValue(value); + AddValue(value, BsonType.Boolean); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(short value) - { - base.WriteValue(value); - AddValue(value, BsonType.Integer); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(short value) + { + base.WriteValue(value); + AddValue(value, BsonType.Integer); + } - /// - /// Writes a value. - /// - /// The value to write. - [CLSCompliant(false)] - public override void WriteValue(ushort value) - { - base.WriteValue(value); - AddValue(value, BsonType.Integer); - } + /// + /// Writes a value. + /// + /// The value to write. + [CLSCompliant(false)] + public override void WriteValue(ushort value) + { + base.WriteValue(value); + AddValue(value, BsonType.Integer); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(char value) - { - base.WriteValue(value); - string s = null; + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(char value) + { + base.WriteValue(value); + string s = null; #if !(NETFX_CORE || PORTABLE40 || PORTABLE) - s = value.ToString(CultureInfo.InvariantCulture); + s = value.ToString(CultureInfo.InvariantCulture); #else - s = value.ToString(); + s = value.ToString(); #endif - AddToken(new BsonString(s, true)); - } + AddToken(new BsonString(s, true)); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(byte value) - { - base.WriteValue(value); - AddValue(value, BsonType.Integer); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(byte value) + { + base.WriteValue(value); + AddValue(value, BsonType.Integer); + } - /// - /// Writes a value. - /// - /// The value to write. - [CLSCompliant(false)] - public override void WriteValue(sbyte value) - { - base.WriteValue(value); - AddValue(value, BsonType.Integer); - } + /// + /// Writes a value. + /// + /// The value to write. + [CLSCompliant(false)] + public override void WriteValue(sbyte value) + { + base.WriteValue(value); + AddValue(value, BsonType.Integer); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(decimal value) - { - base.WriteValue(value); - AddValue(value, BsonType.Number); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(decimal value) + { + base.WriteValue(value); + AddValue(value, BsonType.Number); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(DateTime value) - { - base.WriteValue(value); - value = DateTimeUtils.EnsureDateTime(value, DateTimeZoneHandling); - AddValue(value, BsonType.Date); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(DateTime value) + { + base.WriteValue(value); + value = DateTimeUtils.EnsureDateTime(value, DateTimeZoneHandling); + AddValue(value, BsonType.Date); + } #if !NET20 - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(DateTimeOffset value) - { - base.WriteValue(value); - AddValue(value, BsonType.Date); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(DateTimeOffset value) + { + base.WriteValue(value); + AddValue(value, BsonType.Date); + } #endif - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(byte[] value) - { - base.WriteValue(value); - AddToken(new BsonBinary(value, BsonBinaryType.Binary)); + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(byte[] value) + { + base.WriteValue(value); + AddToken(new BsonBinary(value, BsonBinaryType.Binary)); + } + + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(Guid value) + { + base.WriteValue(value); + AddToken(new BsonBinary(value.ToByteArray(), BsonBinaryType.Uuid)); + } + + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(TimeSpan value) + { + base.WriteValue(value); + AddToken(new BsonString(value.ToString(), true)); + } + + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(Uri value) + { + base.WriteValue(value); + AddToken(new BsonString(value.ToString(), true)); + } + #endregion + + /// + /// Writes a value that represents a BSON object id. + /// + /// The Object ID value to write. + public void WriteObjectId(byte[] value) + { + ValidationUtils.ArgumentNotNull(value, "value"); + + if (value.Length != 12) + throw JsonWriterException.Create(this, "An object id must be 12 bytes", null); + + // hack to update the writer state + UpdateScopeWithFinishedValue(); + AutoComplete(JsonToken.Undefined); + AddValue(value, BsonType.Oid); + } + + /// + /// Writes a BSON regex. + /// + /// The regex pattern. + /// The regex options. + public void WriteRegex(string pattern, string options) + { + ValidationUtils.ArgumentNotNull(pattern, "pattern"); + + // hack to update the writer state + UpdateScopeWithFinishedValue(); + AutoComplete(JsonToken.Undefined); + AddToken(new BsonRegex(pattern, options)); + } } - - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(Guid value) - { - base.WriteValue(value); - AddToken(new BsonBinary(value.ToByteArray(), BsonBinaryType.Uuid)); - } - - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(TimeSpan value) - { - base.WriteValue(value); - AddToken(new BsonString(value.ToString(), true)); - } - - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(Uri value) - { - base.WriteValue(value); - AddToken(new BsonString(value.ToString(), true)); - } - #endregion - - /// - /// Writes a value that represents a BSON object id. - /// - /// The Object ID value to write. - public void WriteObjectId(byte[] value) - { - ValidationUtils.ArgumentNotNull(value, "value"); - - if (value.Length != 12) - throw JsonWriterException.Create(this, "An object id must be 12 bytes", null); - - // hack to update the writer state - UpdateScopeWithFinishedValue(); - AutoComplete(JsonToken.Undefined); - AddValue(value, BsonType.Oid); - } - - /// - /// Writes a BSON regex. - /// - /// The regex pattern. - /// The regex options. - public void WriteRegex(string pattern, string options) - { - ValidationUtils.ArgumentNotNull(pattern, "pattern"); - - // hack to update the writer state - UpdateScopeWithFinishedValue(); - AutoComplete(JsonToken.Undefined); - AddToken(new BsonRegex(pattern, options)); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/ConstructorHandling.cs b/Src/Newtonsoft.Json/ConstructorHandling.cs index 34b8487d..e403f1e4 100644 --- a/Src/Newtonsoft.Json/ConstructorHandling.cs +++ b/Src/Newtonsoft.Json/ConstructorHandling.cs @@ -25,18 +25,19 @@ namespace Newtonsoft.Json { - /// - /// Specifies how constructors are used when initializing objects during deserialization by the . - /// - public enum ConstructorHandling - { /// - /// First attempt to use the public default constructor, then fall back to single paramatized constructor, then the non-public default constructor. + /// Specifies how constructors are used when initializing objects during deserialization by the . /// - Default = 0, - /// - /// Json.NET will use a non-public default constructor before falling back to a paramatized constructor. - /// - AllowNonPublicDefaultConstructor = 1 - } + public enum ConstructorHandling + { + /// + /// First attempt to use the public default constructor, then fall back to single paramatized constructor, then the non-public default constructor. + /// + Default = 0, + + /// + /// Json.NET will use a non-public default constructor before falling back to a paramatized constructor. + /// + AllowNonPublicDefaultConstructor = 1 + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Converters/BinaryConverter.cs b/Src/Newtonsoft.Json/Converters/BinaryConverter.cs index 0da426d4..fc4939e8 100644 --- a/Src/Newtonsoft.Json/Converters/BinaryConverter.cs +++ b/Src/Newtonsoft.Json/Converters/BinaryConverter.cs @@ -33,150 +33,151 @@ using System.Collections.Generic; namespace Newtonsoft.Json.Converters { #if !NET20 - internal interface IBinary - { - byte[] ToArray(); - } -#endif - - /// - /// Converts a binary value to and from a base 64 string value. - /// - public class BinaryConverter : JsonConverter - { -#if !NET20 - private const string BinaryTypeName = "System.Data.Linq.Binary"; + internal interface IBinary + { + byte[] ToArray(); + } #endif /// - /// Writes the JSON representation of the object. + /// Converts a binary value to and from a base 64 string value. /// - /// The to write to. - /// The value. - /// The calling serializer. - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + public class BinaryConverter : JsonConverter { - if (value == null) - { - writer.WriteNull(); - return; - } - - byte[] data = GetByteArray(value); - - writer.WriteValue(data); - } - - private byte[] GetByteArray(object value) - { -#if !(NET20) - if (value.GetType().AssignableToTypeName(BinaryTypeName)) - { - IBinary binary = DynamicWrapper.CreateWrapper(value); - return binary.ToArray(); - } -#endif - if (value is SqlBinary) - return ((SqlBinary) value).Value; - - throw new JsonSerializationException("Unexpected value type when writing binary: {0}".FormatWith(CultureInfo.InvariantCulture, value.GetType())); - } - - /// - /// Reads the JSON representation of the object. - /// - /// The to read from. - /// Type of the object. - /// The existing value of object being read. - /// The calling serializer. - /// The object value. - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - Type t = (ReflectionUtils.IsNullableType(objectType)) - ? Nullable.GetUnderlyingType(objectType) - : objectType; - - if (reader.TokenType == JsonToken.Null) - { - if (!ReflectionUtils.IsNullable(objectType)) - throw JsonSerializationException.Create(reader, "Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType)); - - return null; - } - - byte[] data; - - if (reader.TokenType == JsonToken.StartArray) - { - data = ReadByteArray(reader); - } - else if (reader.TokenType == JsonToken.String) - { - // current token is already at base64 string - // unable to call ReadAsBytes so do it the old fashion way - string encodedData = reader.Value.ToString(); - data = Convert.FromBase64String(encodedData); - } - else - { - throw JsonSerializationException.Create(reader, "Unexpected token parsing binary. Expected String or StartArray, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); - } - - #if !NET20 - if (t.AssignableToTypeName(BinaryTypeName)) - return Activator.CreateInstance(t, data); + private const string BinaryTypeName = "System.Data.Linq.Binary"; #endif - if (t == typeof(SqlBinary)) - return new SqlBinary(data); - - throw JsonSerializationException.Create(reader, "Unexpected object type when writing binary: {0}".FormatWith(CultureInfo.InvariantCulture, objectType)); - } - - private byte[] ReadByteArray(JsonReader reader) - { - List byteList = new List(); - - while (reader.Read()) - { - switch (reader.TokenType) + /// + /// Writes the JSON representation of the object. + /// + /// The to write to. + /// The value. + /// The calling serializer. + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { - case JsonToken.Integer: - byteList.Add(Convert.ToByte(reader.Value, CultureInfo.InvariantCulture)); - break; - case JsonToken.EndArray: - return byteList.ToArray(); - case JsonToken.Comment: - // skip - break; - default: - throw JsonSerializationException.Create(reader, "Unexpected token when reading bytes: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); + if (value == null) + { + writer.WriteNull(); + return; + } + + byte[] data = GetByteArray(value); + + writer.WriteValue(data); } - } - throw JsonSerializationException.Create(reader, "Unexpected end when reading bytes."); - } + private byte[] GetByteArray(object value) + { +#if !(NET20) + if (value.GetType().AssignableToTypeName(BinaryTypeName)) + { + IBinary binary = DynamicWrapper.CreateWrapper(value); + return binary.ToArray(); + } +#endif + if (value is SqlBinary) + return ((SqlBinary)value).Value; + + throw new JsonSerializationException("Unexpected value type when writing binary: {0}".FormatWith(CultureInfo.InvariantCulture, value.GetType())); + } + + /// + /// Reads the JSON representation of the object. + /// + /// The to read from. + /// Type of the object. + /// The existing value of object being read. + /// The calling serializer. + /// The object value. + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + Type t = (ReflectionUtils.IsNullableType(objectType)) + ? Nullable.GetUnderlyingType(objectType) + : objectType; + + if (reader.TokenType == JsonToken.Null) + { + if (!ReflectionUtils.IsNullable(objectType)) + throw JsonSerializationException.Create(reader, "Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType)); + + return null; + } + + byte[] data; + + if (reader.TokenType == JsonToken.StartArray) + { + data = ReadByteArray(reader); + } + else if (reader.TokenType == JsonToken.String) + { + // current token is already at base64 string + // unable to call ReadAsBytes so do it the old fashion way + string encodedData = reader.Value.ToString(); + data = Convert.FromBase64String(encodedData); + } + else + { + throw JsonSerializationException.Create(reader, "Unexpected token parsing binary. Expected String or StartArray, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); + } + - /// - /// Determines whether this instance can convert the specified object type. - /// - /// Type of the object. - /// - /// true if this instance can convert the specified object type; otherwise, false. - /// - public override bool CanConvert(Type objectType) - { #if !NET20 - if (objectType.AssignableToTypeName(BinaryTypeName)) - return true; + if (t.AssignableToTypeName(BinaryTypeName)) + return Activator.CreateInstance(t, data); #endif - if (objectType == typeof(SqlBinary) || objectType == typeof(SqlBinary?)) - return true; + if (t == typeof(SqlBinary)) + return new SqlBinary(data); - return false; + throw JsonSerializationException.Create(reader, "Unexpected object type when writing binary: {0}".FormatWith(CultureInfo.InvariantCulture, objectType)); + } + + private byte[] ReadByteArray(JsonReader reader) + { + List byteList = new List(); + + while (reader.Read()) + { + switch (reader.TokenType) + { + case JsonToken.Integer: + byteList.Add(Convert.ToByte(reader.Value, CultureInfo.InvariantCulture)); + break; + case JsonToken.EndArray: + return byteList.ToArray(); + case JsonToken.Comment: + // skip + break; + default: + throw JsonSerializationException.Create(reader, "Unexpected token when reading bytes: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); + } + } + + throw JsonSerializationException.Create(reader, "Unexpected end when reading bytes."); + } + + /// + /// Determines whether this instance can convert the specified object type. + /// + /// Type of the object. + /// + /// true if this instance can convert the specified object type; otherwise, false. + /// + public override bool CanConvert(Type objectType) + { +#if !NET20 + if (objectType.AssignableToTypeName(BinaryTypeName)) + return true; +#endif + + if (objectType == typeof(SqlBinary) || objectType == typeof(SqlBinary?)) + return true; + + return false; + } } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Converters/BsonObjectIdConverter.cs b/Src/Newtonsoft.Json/Converters/BsonObjectIdConverter.cs index 38dd0e6d..8c5618d5 100644 --- a/Src/Newtonsoft.Json/Converters/BsonObjectIdConverter.cs +++ b/Src/Newtonsoft.Json/Converters/BsonObjectIdConverter.cs @@ -30,60 +30,60 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Converters { - /// - /// Converts a to and from JSON and BSON. - /// - public class BsonObjectIdConverter : JsonConverter - { /// - /// Writes the JSON representation of the object. + /// Converts a to and from JSON and BSON. /// - /// The to write to. - /// The value. - /// The calling serializer. - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + public class BsonObjectIdConverter : JsonConverter { - BsonObjectId objectId = (BsonObjectId) value; + /// + /// Writes the JSON representation of the object. + /// + /// The to write to. + /// The value. + /// The calling serializer. + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + BsonObjectId objectId = (BsonObjectId)value; - BsonWriter bsonWriter = writer as BsonWriter; - if (bsonWriter != null) - { - bsonWriter.WriteObjectId(objectId.Value); - } - else - { - writer.WriteValue(objectId.Value); - } + BsonWriter bsonWriter = writer as BsonWriter; + if (bsonWriter != null) + { + bsonWriter.WriteObjectId(objectId.Value); + } + else + { + writer.WriteValue(objectId.Value); + } + } + + /// + /// Reads the JSON representation of the object. + /// + /// The to read from. + /// Type of the object. + /// The existing value of object being read. + /// The calling serializer. + /// The object value. + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType != JsonToken.Bytes) + throw new JsonSerializationException("Expected Bytes but got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); + + byte[] value = (byte[])reader.Value; + + return new BsonObjectId(value); + } + + /// + /// Determines whether this instance can convert the specified object type. + /// + /// Type of the object. + /// + /// true if this instance can convert the specified object type; otherwise, false. + /// + public override bool CanConvert(Type objectType) + { + return (objectType == typeof(BsonObjectId)); + } } - - /// - /// Reads the JSON representation of the object. - /// - /// The to read from. - /// Type of the object. - /// The existing value of object being read. - /// The calling serializer. - /// The object value. - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - if (reader.TokenType != JsonToken.Bytes) - throw new JsonSerializationException("Expected Bytes but got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); - - byte[] value = (byte[])reader.Value; - - return new BsonObjectId(value); - } - - /// - /// Determines whether this instance can convert the specified object type. - /// - /// Type of the object. - /// - /// true if this instance can convert the specified object type; otherwise, false. - /// - public override bool CanConvert(Type objectType) - { - return (objectType == typeof (BsonObjectId)); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Converters/CustomCreationConverter.cs b/Src/Newtonsoft.Json/Converters/CustomCreationConverter.cs index 15347590..adf519b6 100644 --- a/Src/Newtonsoft.Json/Converters/CustomCreationConverter.cs +++ b/Src/Newtonsoft.Json/Converters/CustomCreationConverter.cs @@ -28,72 +28,72 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Converters { - /// - /// Create a custom object - /// - /// The object type to convert. - public abstract class CustomCreationConverter : JsonConverter - { /// - /// Writes the JSON representation of the object. + /// Create a custom object /// - /// The to write to. - /// The value. - /// The calling serializer. - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + /// The object type to convert. + public abstract class CustomCreationConverter : JsonConverter { - throw new NotSupportedException("CustomCreationConverter should only be used while deserializing."); + /// + /// Writes the JSON representation of the object. + /// + /// The to write to. + /// The value. + /// The calling serializer. + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + throw new NotSupportedException("CustomCreationConverter should only be used while deserializing."); + } + + /// + /// Reads the JSON representation of the object. + /// + /// The to read from. + /// Type of the object. + /// The existing value of object being read. + /// The calling serializer. + /// The object value. + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) + return null; + + T value = Create(objectType); + if (value == null) + throw new JsonSerializationException("No object created."); + + serializer.Populate(reader, value); + return value; + } + + /// + /// Creates an object which will then be populated by the serializer. + /// + /// Type of the object. + /// The created object. + public abstract T Create(Type objectType); + + /// + /// Determines whether this instance can convert the specified object type. + /// + /// Type of the object. + /// + /// true if this instance can convert the specified object type; otherwise, false. + /// + public override bool CanConvert(Type objectType) + { + return typeof(T).IsAssignableFrom(objectType); + } + + /// + /// Gets a value indicating whether this can write JSON. + /// + /// + /// true if this can write JSON; otherwise, false. + /// + public override bool CanWrite + { + get { return false; } + } } - - /// - /// Reads the JSON representation of the object. - /// - /// The to read from. - /// Type of the object. - /// The existing value of object being read. - /// The calling serializer. - /// The object value. - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - if (reader.TokenType == JsonToken.Null) - return null; - - T value = Create(objectType); - if (value == null) - throw new JsonSerializationException("No object created."); - - serializer.Populate(reader, value); - return value; - } - - /// - /// Creates an object which will then be populated by the serializer. - /// - /// Type of the object. - /// The created object. - public abstract T Create(Type objectType); - - /// - /// Determines whether this instance can convert the specified object type. - /// - /// Type of the object. - /// - /// true if this instance can convert the specified object type; otherwise, false. - /// - public override bool CanConvert(Type objectType) - { - return typeof (T).IsAssignableFrom(objectType); - } - - /// - /// Gets a value indicating whether this can write JSON. - /// - /// - /// true if this can write JSON; otherwise, false. - /// - public override bool CanWrite - { - get { return false; } - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Converters/DataSetConverter.cs b/Src/Newtonsoft.Json/Converters/DataSetConverter.cs index a14836f4..a9b25e48 100644 --- a/Src/Newtonsoft.Json/Converters/DataSetConverter.cs +++ b/Src/Newtonsoft.Json/Converters/DataSetConverter.cs @@ -30,82 +30,83 @@ using Newtonsoft.Json.Serialization; namespace Newtonsoft.Json.Converters { - /// - /// Converts a to and from JSON. - /// - public class DataSetConverter : JsonConverter - { /// - /// Writes the JSON representation of the object. + /// Converts a to and from JSON. /// - /// The to write to. - /// The value. - /// The calling serializer. - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + public class DataSetConverter : JsonConverter { - DataSet dataSet = (DataSet)value; - DefaultContractResolver resolver = serializer.ContractResolver as DefaultContractResolver; + /// + /// Writes the JSON representation of the object. + /// + /// The to write to. + /// The value. + /// The calling serializer. + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + DataSet dataSet = (DataSet)value; + DefaultContractResolver resolver = serializer.ContractResolver as DefaultContractResolver; - DataTableConverter converter = new DataTableConverter(); + DataTableConverter converter = new DataTableConverter(); - writer.WriteStartObject(); + writer.WriteStartObject(); - foreach (DataTable table in dataSet.Tables) - { - writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(table.TableName) : table.TableName); - - converter.WriteJson(writer, table, serializer); - } + foreach (DataTable table in dataSet.Tables) + { + writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(table.TableName) : table.TableName); - writer.WriteEndObject(); + converter.WriteJson(writer, table, serializer); + } + + writer.WriteEndObject(); + } + + /// + /// Reads the JSON representation of the object. + /// + /// The to read from. + /// Type of the object. + /// The existing value of object being read. + /// The calling serializer. + /// The object value. + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + // handle typed datasets + DataSet ds = (objectType == typeof(DataSet)) + ? new DataSet() + : (DataSet)Activator.CreateInstance(objectType); + + DataTableConverter converter = new DataTableConverter(); + + reader.Read(); + + while (reader.TokenType == JsonToken.PropertyName) + { + DataTable dt = ds.Tables[(string)reader.Value]; + bool exists = (dt != null); + + dt = (DataTable)converter.ReadJson(reader, typeof(DataTable), dt, serializer); + + if (!exists) + ds.Tables.Add(dt); + + reader.Read(); + } + + return ds; + } + + /// + /// Determines whether this instance can convert the specified value type. + /// + /// Type of the value. + /// + /// true if this instance can convert the specified value type; otherwise, false. + /// + public override bool CanConvert(Type valueType) + { + return typeof(DataSet).IsAssignableFrom(valueType); + } } - - /// - /// Reads the JSON representation of the object. - /// - /// The to read from. - /// Type of the object. - /// The existing value of object being read. - /// The calling serializer. - /// The object value. - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - // handle typed datasets - DataSet ds = (objectType == typeof(DataSet)) - ? new DataSet() - : (DataSet)Activator.CreateInstance(objectType); - - DataTableConverter converter = new DataTableConverter(); - - reader.Read(); - - while (reader.TokenType == JsonToken.PropertyName) - { - DataTable dt = ds.Tables[(string)reader.Value]; - bool exists = (dt != null); - - dt = (DataTable)converter.ReadJson(reader, typeof (DataTable), dt, serializer); - - if (!exists) - ds.Tables.Add(dt); - - reader.Read(); - } - - return ds; - } - - /// - /// Determines whether this instance can convert the specified value type. - /// - /// Type of the value. - /// - /// true if this instance can convert the specified value type; otherwise, false. - /// - public override bool CanConvert(Type valueType) - { - return typeof(DataSet).IsAssignableFrom(valueType); - } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Converters/DataTableConverter.cs b/Src/Newtonsoft.Json/Converters/DataTableConverter.cs index 4ddaea2e..f7ee8d8e 100644 --- a/Src/Newtonsoft.Json/Converters/DataTableConverter.cs +++ b/Src/Newtonsoft.Json/Converters/DataTableConverter.cs @@ -30,132 +30,133 @@ using Newtonsoft.Json.Serialization; namespace Newtonsoft.Json.Converters { - /// - /// Converts a to and from JSON. - /// - public class DataTableConverter : JsonConverter - { /// - /// Writes the JSON representation of the object. + /// Converts a to and from JSON. /// - /// The to write to. - /// The value. - /// The calling serializer. - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + public class DataTableConverter : JsonConverter { - DataTable table = (DataTable)value; - DefaultContractResolver resolver = serializer.ContractResolver as DefaultContractResolver; - - writer.WriteStartArray(); - - foreach (DataRow row in table.Rows) - { - writer.WriteStartObject(); - foreach (DataColumn column in row.Table.Columns) + /// + /// Writes the JSON representation of the object. + /// + /// The to write to. + /// The value. + /// The calling serializer. + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { - if (serializer.NullValueHandling == NullValueHandling.Ignore && (row[column] == null || row[column] == DBNull.Value)) - continue; + DataTable table = (DataTable)value; + DefaultContractResolver resolver = serializer.ContractResolver as DefaultContractResolver; - writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(column.ColumnName) : column.ColumnName); - serializer.Serialize(writer, row[column]); - } - writer.WriteEndObject(); - } + writer.WriteStartArray(); - writer.WriteEndArray(); - } + foreach (DataRow row in table.Rows) + { + writer.WriteStartObject(); + foreach (DataColumn column in row.Table.Columns) + { + if (serializer.NullValueHandling == NullValueHandling.Ignore && (row[column] == null || row[column] == DBNull.Value)) + continue; - /// - /// Reads the JSON representation of the object. - /// - /// The to read from. - /// Type of the object. - /// The existing value of object being read. - /// The calling serializer. - /// The object value. - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - DataTable dt = existingValue as DataTable; + writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(column.ColumnName) : column.ColumnName); + serializer.Serialize(writer, row[column]); + } + writer.WriteEndObject(); + } - if (dt == null) - { - // handle typed datasets - dt = (objectType == typeof(DataTable)) - ? new DataTable() - : (DataTable)Activator.CreateInstance(objectType); - } - - if (reader.TokenType == JsonToken.PropertyName) - { - dt.TableName = (string)reader.Value; - - reader.Read(); - } - - reader.Read(); - - while (reader.TokenType == JsonToken.StartObject) - { - DataRow dr = dt.NewRow(); - reader.Read(); - - while (reader.TokenType == JsonToken.PropertyName) - { - string columnName = (string)reader.Value; - - reader.Read(); - - if (!dt.Columns.Contains(columnName)) - { - Type columnType = GetColumnDataType(reader.TokenType); - dt.Columns.Add(new DataColumn(columnName, columnType)); - } - - dr[columnName] = reader.Value ?? DBNull.Value; - reader.Read(); + writer.WriteEndArray(); } - dr.EndEdit(); - dt.Rows.Add(dr); + /// + /// Reads the JSON representation of the object. + /// + /// The to read from. + /// Type of the object. + /// The existing value of object being read. + /// The calling serializer. + /// The object value. + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + DataTable dt = existingValue as DataTable; - reader.Read(); - } + if (dt == null) + { + // handle typed datasets + dt = (objectType == typeof(DataTable)) + ? new DataTable() + : (DataTable)Activator.CreateInstance(objectType); + } - return dt; + if (reader.TokenType == JsonToken.PropertyName) + { + dt.TableName = (string)reader.Value; + + reader.Read(); + } + + reader.Read(); + + while (reader.TokenType == JsonToken.StartObject) + { + DataRow dr = dt.NewRow(); + reader.Read(); + + while (reader.TokenType == JsonToken.PropertyName) + { + string columnName = (string)reader.Value; + + reader.Read(); + + if (!dt.Columns.Contains(columnName)) + { + Type columnType = GetColumnDataType(reader.TokenType); + dt.Columns.Add(new DataColumn(columnName, columnType)); + } + + dr[columnName] = reader.Value ?? DBNull.Value; + reader.Read(); + } + + dr.EndEdit(); + dt.Rows.Add(dr); + + reader.Read(); + } + + return dt; + } + + private static Type GetColumnDataType(JsonToken tokenType) + { + switch (tokenType) + { + case JsonToken.Integer: + return typeof(long); + case JsonToken.Float: + return typeof(double); + case JsonToken.String: + case JsonToken.Null: + case JsonToken.Undefined: + return typeof(string); + case JsonToken.Boolean: + return typeof(bool); + case JsonToken.Date: + return typeof(DateTime); + default: + throw new ArgumentOutOfRangeException(); + } + } + + /// + /// Determines whether this instance can convert the specified value type. + /// + /// Type of the value. + /// + /// true if this instance can convert the specified value type; otherwise, false. + /// + public override bool CanConvert(Type valueType) + { + return typeof(DataTable).IsAssignableFrom(valueType); + } } - - private static Type GetColumnDataType(JsonToken tokenType) - { - switch (tokenType) - { - case JsonToken.Integer: - return typeof (long); - case JsonToken.Float: - return typeof (double); - case JsonToken.String: - case JsonToken.Null: - case JsonToken.Undefined: - return typeof (string); - case JsonToken.Boolean: - return typeof (bool); - case JsonToken.Date: - return typeof (DateTime); - default: - throw new ArgumentOutOfRangeException(); - } - } - - /// - /// Determines whether this instance can convert the specified value type. - /// - /// Type of the value. - /// - /// true if this instance can convert the specified value type; otherwise, false. - /// - public override bool CanConvert(Type valueType) - { - return typeof(DataTable).IsAssignableFrom(valueType); - } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Converters/DateTimeConverterBase.cs b/Src/Newtonsoft.Json/Converters/DateTimeConverterBase.cs index d5bafe62..a928b13a 100644 --- a/Src/Newtonsoft.Json/Converters/DateTimeConverterBase.cs +++ b/Src/Newtonsoft.Json/Converters/DateTimeConverterBase.cs @@ -27,28 +27,28 @@ using System; namespace Newtonsoft.Json.Converters { - /// - /// Provides a base class for converting a to and from JSON. - /// - public abstract class DateTimeConverterBase : JsonConverter - { /// - /// Determines whether this instance can convert the specified object type. + /// Provides a base class for converting a to and from JSON. /// - /// Type of the object. - /// - /// true if this instance can convert the specified object type; otherwise, false. - /// - public override bool CanConvert(Type objectType) + public abstract class DateTimeConverterBase : JsonConverter { - if (objectType == typeof(DateTime) || objectType == typeof(DateTime?)) - return true; + /// + /// Determines whether this instance can convert the specified object type. + /// + /// Type of the object. + /// + /// true if this instance can convert the specified object type; otherwise, false. + /// + public override bool CanConvert(Type objectType) + { + if (objectType == typeof(DateTime) || objectType == typeof(DateTime?)) + return true; #if !NET20 - if (objectType == typeof(DateTimeOffset) || objectType == typeof(DateTimeOffset?)) - return true; + if (objectType == typeof(DateTimeOffset) || objectType == typeof(DateTimeOffset?)) + return true; #endif - return false; + return false; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Converters/EntityKeyMemberConverter.cs b/Src/Newtonsoft.Json/Converters/EntityKeyMemberConverter.cs index 44b92307..dc9dc8a8 100644 --- a/Src/Newtonsoft.Json/Converters/EntityKeyMemberConverter.cs +++ b/Src/Newtonsoft.Json/Converters/EntityKeyMemberConverter.cs @@ -31,110 +31,111 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Converters { - internal interface IEntityKeyMember - { - string Key { get; set; } - object Value { get; set; } - } - - /// - /// Converts an Entity Framework EntityKey to and from JSON. - /// - public class EntityKeyMemberConverter : JsonConverter - { - private const string EntityKeyMemberFullTypeName = "System.Data.EntityKeyMember"; - - /// - /// Writes the JSON representation of the object. - /// - /// The to write to. - /// The value. - /// The calling serializer. - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + internal interface IEntityKeyMember { - IEntityKeyMember entityKeyMember = DynamicWrapper.CreateWrapper(value); - Type keyType = (entityKeyMember.Value != null) ? entityKeyMember.Value.GetType() : null; - - writer.WriteStartObject(); - writer.WritePropertyName("Key"); - writer.WriteValue(entityKeyMember.Key); - writer.WritePropertyName("Type"); - writer.WriteValue((keyType != null) ? keyType.FullName : null); - - writer.WritePropertyName("Value"); - - if (keyType != null) - { - string valueJson; - if (JsonSerializerInternalWriter.TryConvertToString(entityKeyMember.Value, keyType, out valueJson)) - writer.WriteValue(valueJson); - else - writer.WriteValue(entityKeyMember.Value); - } - else - { - writer.WriteNull(); - } - - writer.WriteEndObject(); - } - - private static void ReadAndAssertProperty(JsonReader reader, string propertyName) - { - ReadAndAssert(reader); - - if (reader.TokenType != JsonToken.PropertyName || reader.Value.ToString() != propertyName) - throw new JsonSerializationException("Expected JSON property '{0}'.".FormatWith(CultureInfo.InvariantCulture, propertyName)); - } - - private static void ReadAndAssert(JsonReader reader) - { - if (!reader.Read()) - throw new JsonSerializationException("Unexpected end."); + string Key { get; set; } + object Value { get; set; } } /// - /// Reads the JSON representation of the object. + /// Converts an Entity Framework EntityKey to and from JSON. /// - /// The to read from. - /// Type of the object. - /// The existing value of object being read. - /// The calling serializer. - /// The object value. - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + public class EntityKeyMemberConverter : JsonConverter { - IEntityKeyMember entityKeyMember = DynamicWrapper.CreateWrapper(Activator.CreateInstance(objectType)); + private const string EntityKeyMemberFullTypeName = "System.Data.EntityKeyMember"; - ReadAndAssertProperty(reader, "Key"); - ReadAndAssert(reader); - entityKeyMember.Key = reader.Value.ToString(); + /// + /// Writes the JSON representation of the object. + /// + /// The to write to. + /// The value. + /// The calling serializer. + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + IEntityKeyMember entityKeyMember = DynamicWrapper.CreateWrapper(value); + Type keyType = (entityKeyMember.Value != null) ? entityKeyMember.Value.GetType() : null; - ReadAndAssertProperty(reader, "Type"); - ReadAndAssert(reader); - string type = reader.Value.ToString(); + writer.WriteStartObject(); + writer.WritePropertyName("Key"); + writer.WriteValue(entityKeyMember.Key); + writer.WritePropertyName("Type"); + writer.WriteValue((keyType != null) ? keyType.FullName : null); - Type t = Type.GetType(type); + writer.WritePropertyName("Value"); - ReadAndAssertProperty(reader, "Value"); - ReadAndAssert(reader); - entityKeyMember.Value = serializer.Deserialize(reader, t); + if (keyType != null) + { + string valueJson; + if (JsonSerializerInternalWriter.TryConvertToString(entityKeyMember.Value, keyType, out valueJson)) + writer.WriteValue(valueJson); + else + writer.WriteValue(entityKeyMember.Value); + } + else + { + writer.WriteNull(); + } - ReadAndAssert(reader); + writer.WriteEndObject(); + } - return DynamicWrapper.GetUnderlyingObject(entityKeyMember); + private static void ReadAndAssertProperty(JsonReader reader, string propertyName) + { + ReadAndAssert(reader); + + if (reader.TokenType != JsonToken.PropertyName || reader.Value.ToString() != propertyName) + throw new JsonSerializationException("Expected JSON property '{0}'.".FormatWith(CultureInfo.InvariantCulture, propertyName)); + } + + private static void ReadAndAssert(JsonReader reader) + { + if (!reader.Read()) + throw new JsonSerializationException("Unexpected end."); + } + + /// + /// Reads the JSON representation of the object. + /// + /// The to read from. + /// Type of the object. + /// The existing value of object being read. + /// The calling serializer. + /// The object value. + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + IEntityKeyMember entityKeyMember = DynamicWrapper.CreateWrapper(Activator.CreateInstance(objectType)); + + ReadAndAssertProperty(reader, "Key"); + ReadAndAssert(reader); + entityKeyMember.Key = reader.Value.ToString(); + + ReadAndAssertProperty(reader, "Type"); + ReadAndAssert(reader); + string type = reader.Value.ToString(); + + Type t = Type.GetType(type); + + ReadAndAssertProperty(reader, "Value"); + ReadAndAssert(reader); + entityKeyMember.Value = serializer.Deserialize(reader, t); + + ReadAndAssert(reader); + + return DynamicWrapper.GetUnderlyingObject(entityKeyMember); + } + + /// + /// Determines whether this instance can convert the specified object type. + /// + /// Type of the object. + /// + /// true if this instance can convert the specified object type; otherwise, false. + /// + public override bool CanConvert(Type objectType) + { + return (objectType.AssignableToTypeName(EntityKeyMemberFullTypeName)); + } } - - /// - /// Determines whether this instance can convert the specified object type. - /// - /// Type of the object. - /// - /// true if this instance can convert the specified object type; otherwise, false. - /// - public override bool CanConvert(Type objectType) - { - return (objectType.AssignableToTypeName(EntityKeyMemberFullTypeName)); - } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Converters/ExpandoObjectConverter.cs b/Src/Newtonsoft.Json/Converters/ExpandoObjectConverter.cs index 76754794..d07599d9 100644 --- a/Src/Newtonsoft.Json/Converters/ExpandoObjectConverter.cs +++ b/Src/Newtonsoft.Json/Converters/ExpandoObjectConverter.cs @@ -35,131 +35,131 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Converters { - /// - /// Converts an ExpandoObject to and from JSON. - /// - public class ExpandoObjectConverter : JsonConverter - { /// - /// Writes the JSON representation of the object. + /// Converts an ExpandoObject to and from JSON. /// - /// The to write to. - /// The value. - /// The calling serializer. - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + public class ExpandoObjectConverter : JsonConverter { - // can write is set to false - } - - /// - /// Reads the JSON representation of the object. - /// - /// The to read from. - /// Type of the object. - /// The existing value of object being read. - /// The calling serializer. - /// The object value. - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - return ReadValue(reader); - } - - private object ReadValue(JsonReader reader) - { - while (reader.TokenType == JsonToken.Comment) - { - if (!reader.Read()) - throw JsonSerializationException.Create(reader, "Unexpected end when reading ExpandoObject."); - } - - switch (reader.TokenType) - { - case JsonToken.StartObject: - return ReadObject(reader); - case JsonToken.StartArray: - return ReadList(reader); - default: - if (JsonReader.IsPrimitiveToken(reader.TokenType)) - return reader.Value; - - throw JsonSerializationException.Create(reader, "Unexpected token when converting ExpandoObject: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); - } - } - - private object ReadList(JsonReader reader) - { - IList list = new List(); - - while (reader.Read()) - { - switch (reader.TokenType) + /// + /// Writes the JSON representation of the object. + /// + /// The to write to. + /// The value. + /// The calling serializer. + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { - case JsonToken.Comment: - break; - default: - object v = ReadValue(reader); - - list.Add(v); - break; - case JsonToken.EndArray: - return list; + // can write is set to false } - } - throw JsonSerializationException.Create(reader, "Unexpected end when reading ExpandoObject."); - } - - private object ReadObject(JsonReader reader) - { - IDictionary expandoObject = new ExpandoObject(); - - while (reader.Read()) - { - switch (reader.TokenType) + /// + /// Reads the JSON representation of the object. + /// + /// The to read from. + /// Type of the object. + /// The existing value of object being read. + /// The calling serializer. + /// The object value. + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { - case JsonToken.PropertyName: - string propertyName = reader.Value.ToString(); - - if (!reader.Read()) - throw JsonSerializationException.Create(reader, "Unexpected end when reading ExpandoObject."); - - object v = ReadValue(reader); - - expandoObject[propertyName] = v; - break; - case JsonToken.Comment: - break; - case JsonToken.EndObject: - return expandoObject; + return ReadValue(reader); } - } - throw JsonSerializationException.Create(reader, "Unexpected end when reading ExpandoObject."); - } + private object ReadValue(JsonReader reader) + { + while (reader.TokenType == JsonToken.Comment) + { + if (!reader.Read()) + throw JsonSerializationException.Create(reader, "Unexpected end when reading ExpandoObject."); + } - /// - /// Determines whether this instance can convert the specified object type. - /// - /// Type of the object. - /// - /// true if this instance can convert the specified object type; otherwise, false. - /// - public override bool CanConvert(Type objectType) - { - return (objectType == typeof (ExpandoObject)); - } + switch (reader.TokenType) + { + case JsonToken.StartObject: + return ReadObject(reader); + case JsonToken.StartArray: + return ReadList(reader); + default: + if (JsonReader.IsPrimitiveToken(reader.TokenType)) + return reader.Value; - /// - /// Gets a value indicating whether this can write JSON. - /// - /// - /// true if this can write JSON; otherwise, false. - /// - public override bool CanWrite - { - get { return false; } + throw JsonSerializationException.Create(reader, "Unexpected token when converting ExpandoObject: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); + } + } + + private object ReadList(JsonReader reader) + { + IList list = new List(); + + while (reader.Read()) + { + switch (reader.TokenType) + { + case JsonToken.Comment: + break; + default: + object v = ReadValue(reader); + + list.Add(v); + break; + case JsonToken.EndArray: + return list; + } + } + + throw JsonSerializationException.Create(reader, "Unexpected end when reading ExpandoObject."); + } + + private object ReadObject(JsonReader reader) + { + IDictionary expandoObject = new ExpandoObject(); + + while (reader.Read()) + { + switch (reader.TokenType) + { + case JsonToken.PropertyName: + string propertyName = reader.Value.ToString(); + + if (!reader.Read()) + throw JsonSerializationException.Create(reader, "Unexpected end when reading ExpandoObject."); + + object v = ReadValue(reader); + + expandoObject[propertyName] = v; + break; + case JsonToken.Comment: + break; + case JsonToken.EndObject: + return expandoObject; + } + } + + throw JsonSerializationException.Create(reader, "Unexpected end when reading ExpandoObject."); + } + + /// + /// Determines whether this instance can convert the specified object type. + /// + /// Type of the object. + /// + /// true if this instance can convert the specified object type; otherwise, false. + /// + public override bool CanConvert(Type objectType) + { + return (objectType == typeof(ExpandoObject)); + } + + /// + /// Gets a value indicating whether this can write JSON. + /// + /// + /// true if this can write JSON; otherwise, false. + /// + public override bool CanWrite + { + get { return false; } + } } - } } #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Converters/IsoDateTimeConverter.cs b/Src/Newtonsoft.Json/Converters/IsoDateTimeConverter.cs index cca39b36..0f90b870 100644 --- a/Src/Newtonsoft.Json/Converters/IsoDateTimeConverter.cs +++ b/Src/Newtonsoft.Json/Converters/IsoDateTimeConverter.cs @@ -29,141 +29,141 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Converters { - /// - /// Converts a to and from the ISO 8601 date format (e.g. 2008-04-12T12:53Z). - /// - public class IsoDateTimeConverter : DateTimeConverterBase - { - private const string DefaultDateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK"; - - private DateTimeStyles _dateTimeStyles = DateTimeStyles.RoundtripKind; - private string _dateTimeFormat; - private CultureInfo _culture; - /// - /// Gets or sets the date time styles used when converting a date to and from JSON. + /// Converts a to and from the ISO 8601 date format (e.g. 2008-04-12T12:53Z). /// - /// The date time styles used when converting a date to and from JSON. - public DateTimeStyles DateTimeStyles + public class IsoDateTimeConverter : DateTimeConverterBase { - get { return _dateTimeStyles; } - set { _dateTimeStyles = value; } - } + private const string DefaultDateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK"; - /// - /// Gets or sets the date time format used when converting a date to and from JSON. - /// - /// The date time format used when converting a date to and from JSON. - public string DateTimeFormat - { - get { return _dateTimeFormat ?? string.Empty; } - set { _dateTimeFormat = StringUtils.NullEmptyString(value); } - } + private DateTimeStyles _dateTimeStyles = DateTimeStyles.RoundtripKind; + private string _dateTimeFormat; + private CultureInfo _culture; - /// - /// Gets or sets the culture used when converting a date to and from JSON. - /// - /// The culture used when converting a date to and from JSON. - public CultureInfo Culture - { - get { return _culture ?? CultureInfo.CurrentCulture; } - set { _culture = value; } - } + /// + /// Gets or sets the date time styles used when converting a date to and from JSON. + /// + /// The date time styles used when converting a date to and from JSON. + public DateTimeStyles DateTimeStyles + { + get { return _dateTimeStyles; } + set { _dateTimeStyles = value; } + } - /// - /// Writes the JSON representation of the object. - /// - /// The to write to. - /// The value. - /// The calling serializer. - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - string text; + /// + /// Gets or sets the date time format used when converting a date to and from JSON. + /// + /// The date time format used when converting a date to and from JSON. + public string DateTimeFormat + { + get { return _dateTimeFormat ?? string.Empty; } + set { _dateTimeFormat = StringUtils.NullEmptyString(value); } + } - if (value is DateTime) - { - DateTime dateTime = (DateTime)value; + /// + /// Gets or sets the culture used when converting a date to and from JSON. + /// + /// The culture used when converting a date to and from JSON. + public CultureInfo Culture + { + get { return _culture ?? CultureInfo.CurrentCulture; } + set { _culture = value; } + } - if ((_dateTimeStyles & DateTimeStyles.AdjustToUniversal) == DateTimeStyles.AdjustToUniversal - || (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal) - dateTime = dateTime.ToUniversalTime(); + /// + /// Writes the JSON representation of the object. + /// + /// The to write to. + /// The value. + /// The calling serializer. + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + string text; - text = dateTime.ToString(_dateTimeFormat ?? DefaultDateTimeFormat, Culture); - } + if (value is DateTime) + { + DateTime dateTime = (DateTime)value; + + if ((_dateTimeStyles & DateTimeStyles.AdjustToUniversal) == DateTimeStyles.AdjustToUniversal + || (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal) + dateTime = dateTime.ToUniversalTime(); + + text = dateTime.ToString(_dateTimeFormat ?? DefaultDateTimeFormat, Culture); + } #if !NET20 - else if (value is DateTimeOffset) - { - DateTimeOffset dateTimeOffset = (DateTimeOffset)value; - if ((_dateTimeStyles & DateTimeStyles.AdjustToUniversal) == DateTimeStyles.AdjustToUniversal - || (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal) - dateTimeOffset = dateTimeOffset.ToUniversalTime(); + else if (value is DateTimeOffset) + { + DateTimeOffset dateTimeOffset = (DateTimeOffset)value; + if ((_dateTimeStyles & DateTimeStyles.AdjustToUniversal) == DateTimeStyles.AdjustToUniversal + || (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal) + dateTimeOffset = dateTimeOffset.ToUniversalTime(); - text = dateTimeOffset.ToString(_dateTimeFormat ?? DefaultDateTimeFormat, Culture); - } + text = dateTimeOffset.ToString(_dateTimeFormat ?? DefaultDateTimeFormat, Culture); + } #endif - else - { - throw new JsonSerializationException("Unexpected value when converting date. Expected DateTime or DateTimeOffset, got {0}.".FormatWith(CultureInfo.InvariantCulture, ReflectionUtils.GetObjectType(value))); - } + else + { + throw new JsonSerializationException("Unexpected value when converting date. Expected DateTime or DateTimeOffset, got {0}.".FormatWith(CultureInfo.InvariantCulture, ReflectionUtils.GetObjectType(value))); + } - writer.WriteValue(text); - } + writer.WriteValue(text); + } - /// - /// Reads the JSON representation of the object. - /// - /// The to read from. - /// Type of the object. - /// The existing value of object being read. - /// The calling serializer. - /// The object value. - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - bool nullable = ReflectionUtils.IsNullableType(objectType); - Type t = (nullable) - ? Nullable.GetUnderlyingType(objectType) - : objectType; + /// + /// Reads the JSON representation of the object. + /// + /// The to read from. + /// Type of the object. + /// The existing value of object being read. + /// The calling serializer. + /// The object value. + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + bool nullable = ReflectionUtils.IsNullableType(objectType); + Type t = (nullable) + ? Nullable.GetUnderlyingType(objectType) + : objectType; - if (reader.TokenType == JsonToken.Null) - { - if (!ReflectionUtils.IsNullableType(objectType)) - throw JsonSerializationException.Create(reader, "Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType)); - - return null; - } + if (reader.TokenType == JsonToken.Null) + { + if (!ReflectionUtils.IsNullableType(objectType)) + throw JsonSerializationException.Create(reader, "Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType)); - if (reader.TokenType == JsonToken.Date) - { + return null; + } + + if (reader.TokenType == JsonToken.Date) + { #if !NET20 - if (t == typeof(DateTimeOffset)) - return new DateTimeOffset((DateTime)reader.Value); + if (t == typeof(DateTimeOffset)) + return new DateTimeOffset((DateTime)reader.Value); #endif - return reader.Value; - } + return reader.Value; + } - if (reader.TokenType != JsonToken.String) - throw JsonSerializationException.Create(reader, "Unexpected token parsing date. Expected String, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); + if (reader.TokenType != JsonToken.String) + throw JsonSerializationException.Create(reader, "Unexpected token parsing date. Expected String, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); - string dateText = reader.Value.ToString(); + string dateText = reader.Value.ToString(); - if (string.IsNullOrEmpty(dateText) && nullable) - return null; + if (string.IsNullOrEmpty(dateText) && nullable) + return null; #if !NET20 - if (t == typeof(DateTimeOffset)) - { - if (!string.IsNullOrEmpty(_dateTimeFormat)) - return DateTimeOffset.ParseExact(dateText, _dateTimeFormat, Culture, _dateTimeStyles); - else - return DateTimeOffset.Parse(dateText, Culture, _dateTimeStyles); - } + if (t == typeof(DateTimeOffset)) + { + if (!string.IsNullOrEmpty(_dateTimeFormat)) + return DateTimeOffset.ParseExact(dateText, _dateTimeFormat, Culture, _dateTimeStyles); + else + return DateTimeOffset.Parse(dateText, Culture, _dateTimeStyles); + } #endif - if (!string.IsNullOrEmpty(_dateTimeFormat)) - return DateTime.ParseExact(dateText, _dateTimeFormat, Culture, _dateTimeStyles); - else - return DateTime.Parse(dateText, Culture, _dateTimeStyles); + if (!string.IsNullOrEmpty(_dateTimeFormat)) + return DateTime.ParseExact(dateText, _dateTimeFormat, Culture, _dateTimeStyles); + else + return DateTime.Parse(dateText, Culture, _dateTimeStyles); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Converters/JavaScriptDateTimeConverter.cs b/Src/Newtonsoft.Json/Converters/JavaScriptDateTimeConverter.cs index 31fa7102..0e96a35e 100644 --- a/Src/Newtonsoft.Json/Converters/JavaScriptDateTimeConverter.cs +++ b/Src/Newtonsoft.Json/Converters/JavaScriptDateTimeConverter.cs @@ -29,90 +29,90 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Converters { - /// - /// Converts a to and from a JavaScript date constructor (e.g. new Date(52231943)). - /// - public class JavaScriptDateTimeConverter : DateTimeConverterBase - { /// - /// Writes the JSON representation of the object. + /// Converts a to and from a JavaScript date constructor (e.g. new Date(52231943)). /// - /// The to write to. - /// The value. - /// The calling serializer. - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + public class JavaScriptDateTimeConverter : DateTimeConverterBase { - long ticks; + /// + /// Writes the JSON representation of the object. + /// + /// The to write to. + /// The value. + /// The calling serializer. + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + long ticks; - if (value is DateTime) - { - DateTime dateTime = (DateTime)value; - DateTime utcDateTime = dateTime.ToUniversalTime(); - ticks = DateTimeUtils.ConvertDateTimeToJavaScriptTicks(utcDateTime); - } + if (value is DateTime) + { + DateTime dateTime = (DateTime)value; + DateTime utcDateTime = dateTime.ToUniversalTime(); + ticks = DateTimeUtils.ConvertDateTimeToJavaScriptTicks(utcDateTime); + } #if !NET20 - else if (value is DateTimeOffset) - { - DateTimeOffset dateTimeOffset = (DateTimeOffset)value; - DateTimeOffset utcDateTimeOffset = dateTimeOffset.ToUniversalTime(); - ticks = DateTimeUtils.ConvertDateTimeToJavaScriptTicks(utcDateTimeOffset.UtcDateTime); - } + else if (value is DateTimeOffset) + { + DateTimeOffset dateTimeOffset = (DateTimeOffset)value; + DateTimeOffset utcDateTimeOffset = dateTimeOffset.ToUniversalTime(); + ticks = DateTimeUtils.ConvertDateTimeToJavaScriptTicks(utcDateTimeOffset.UtcDateTime); + } #endif - else - { - throw new JsonSerializationException("Expected date object value."); - } + else + { + throw new JsonSerializationException("Expected date object value."); + } - writer.WriteStartConstructor("Date"); - writer.WriteValue(ticks); - writer.WriteEndConstructor(); - } + writer.WriteStartConstructor("Date"); + writer.WriteValue(ticks); + writer.WriteEndConstructor(); + } - /// - /// Reads the JSON representation of the object. - /// - /// The to read from. - /// Type of the object. - /// The existing property value of the JSON that is being converted. - /// The calling serializer. - /// The object value. - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - Type t = (ReflectionUtils.IsNullableType(objectType)) - ? Nullable.GetUnderlyingType(objectType) - : objectType; + /// + /// Reads the JSON representation of the object. + /// + /// The to read from. + /// Type of the object. + /// The existing property value of the JSON that is being converted. + /// The calling serializer. + /// The object value. + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + Type t = (ReflectionUtils.IsNullableType(objectType)) + ? Nullable.GetUnderlyingType(objectType) + : objectType; - if (reader.TokenType == JsonToken.Null) - { - if (!ReflectionUtils.IsNullable(objectType)) - throw JsonSerializationException.Create(reader, "Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType)); + if (reader.TokenType == JsonToken.Null) + { + if (!ReflectionUtils.IsNullable(objectType)) + throw JsonSerializationException.Create(reader, "Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType)); - return null; - } + return null; + } - if (reader.TokenType != JsonToken.StartConstructor || !string.Equals(reader.Value.ToString(), "Date", StringComparison.Ordinal)) - throw JsonSerializationException.Create(reader, "Unexpected token or value when parsing date. Token: {0}, Value: {1}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType, reader.Value)); + if (reader.TokenType != JsonToken.StartConstructor || !string.Equals(reader.Value.ToString(), "Date", StringComparison.Ordinal)) + throw JsonSerializationException.Create(reader, "Unexpected token or value when parsing date. Token: {0}, Value: {1}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType, reader.Value)); - reader.Read(); + reader.Read(); - if (reader.TokenType != JsonToken.Integer) - throw JsonSerializationException.Create(reader, "Unexpected token parsing date. Expected Integer, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); + if (reader.TokenType != JsonToken.Integer) + throw JsonSerializationException.Create(reader, "Unexpected token parsing date. Expected Integer, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); - long ticks = (long)reader.Value; + long ticks = (long)reader.Value; - DateTime d = DateTimeUtils.ConvertJavaScriptTicksToDateTime(ticks); + DateTime d = DateTimeUtils.ConvertJavaScriptTicksToDateTime(ticks); - reader.Read(); + reader.Read(); - if (reader.TokenType != JsonToken.EndConstructor) - throw JsonSerializationException.Create(reader, "Unexpected token parsing date. Expected EndConstructor, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); + if (reader.TokenType != JsonToken.EndConstructor) + throw JsonSerializationException.Create(reader, "Unexpected token parsing date. Expected EndConstructor, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); #if !NET20 - if (t == typeof(DateTimeOffset)) - return new DateTimeOffset(d); + if (t == typeof(DateTimeOffset)) + return new DateTimeOffset(d); #endif - return d; + return d; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Converters/JsonValueConverter.cs b/Src/Newtonsoft.Json/Converters/JsonValueConverter.cs index bea7b691..25f979fa 100644 --- a/Src/Newtonsoft.Json/Converters/JsonValueConverter.cs +++ b/Src/Newtonsoft.Json/Converters/JsonValueConverter.cs @@ -23,6 +23,7 @@ // OTHER DEALINGS IN THE SOFTWARE. #endregion + #if NETFX_CORE using System; using System.Collections.Generic; @@ -33,192 +34,192 @@ using Windows.Data.Json; namespace Newtonsoft.Json.Converters { - /// - /// Converts a to and from JSON. - /// - public class JsonValueConverter : JsonConverter - { /// - /// Writes the JSON representation of the object. + /// Converts a to and from JSON. /// - /// The to write to. - /// The value. - /// The calling serializer. - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + public class JsonValueConverter : JsonConverter { - WriteJsonValue(writer, (IJsonValue)value); - } + /// + /// Writes the JSON representation of the object. + /// + /// The to write to. + /// The value. + /// The calling serializer. + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + WriteJsonValue(writer, (IJsonValue)value); + } - private void WriteJsonValue(JsonWriter writer, IJsonValue value) - { - switch (value.ValueType) - { - case JsonValueType.Array: - { - JsonArray a = value.GetArray(); - writer.WriteStartArray(); - for (int i = 0; i < a.Count; i++) + private void WriteJsonValue(JsonWriter writer, IJsonValue value) + { + switch (value.ValueType) { - WriteJsonValue(writer, a[i]); + case JsonValueType.Array: + { + JsonArray a = value.GetArray(); + writer.WriteStartArray(); + for (int i = 0; i < a.Count; i++) + { + WriteJsonValue(writer, a[i]); + } + writer.WriteEndArray(); + } + break; + case JsonValueType.Boolean: + { + writer.WriteValue(value.GetBoolean()); + } + break; + case JsonValueType.Null: + { + writer.WriteNull(); + } + break; + case JsonValueType.Number: + { + // JsonValue doesn't support integers + // serialize whole numbers without a decimal point + double d = value.GetNumber(); + bool isInteger = (d % 1 == 0); + if (isInteger && d <= long.MaxValue && d >= long.MinValue) + writer.WriteValue(Convert.ToInt64(d)); + else + writer.WriteValue(d); + } + break; + case JsonValueType.Object: + { + JsonObject o = value.GetObject(); + writer.WriteStartObject(); + foreach (KeyValuePair v in o) + { + writer.WritePropertyName(v.Key); + WriteJsonValue(writer, v.Value); + } + writer.WriteEndObject(); + } + break; + case JsonValueType.String: + { + writer.WriteValue(value.GetString()); + } + break; + default: + throw new ArgumentOutOfRangeException("ValueType"); } - writer.WriteEndArray(); - } - break; - case JsonValueType.Boolean: - { - writer.WriteValue(value.GetBoolean()); - } - break; - case JsonValueType.Null: - { - writer.WriteNull(); - } - break; - case JsonValueType.Number: - { - // JsonValue doesn't support integers - // serialize whole numbers without a decimal point - double d = value.GetNumber(); - bool isInteger = (d % 1 == 0); - if (isInteger && d <= long.MaxValue && d >= long.MinValue) - writer.WriteValue(Convert.ToInt64(d)); - else - writer.WriteValue(d); - } - break; - case JsonValueType.Object: - { - JsonObject o = value.GetObject(); - writer.WriteStartObject(); - foreach (KeyValuePair v in o) + } + + /// + /// Reads the JSON representation of the object. + /// + /// The to read from. + /// Type of the object. + /// The existing value of object being read. + /// The calling serializer. + /// The object value. + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.None) + reader.Read(); + + IJsonValue value = CreateJsonValue(reader); + + if (!objectType.IsAssignableFrom(value.GetType())) + throw JsonSerializationException.Create(reader, "Could not convert '{0}' to '{1}'.".FormatWith(CultureInfo.InvariantCulture, value.GetType(), objectType)); + + return value; + } + + private IJsonValue CreateJsonValue(JsonReader reader) + { + while (reader.TokenType == JsonToken.Comment) { - writer.WritePropertyName(v.Key); - WriteJsonValue(writer, v.Value); + if (!reader.Read()) + throw JsonSerializationException.Create(reader, "Unexpected end."); } - writer.WriteEndObject(); - } - break; - case JsonValueType.String: - { - writer.WriteValue(value.GetString()); - } - break; - default: - throw new ArgumentOutOfRangeException("ValueType"); - } - } - /// - /// Reads the JSON representation of the object. - /// - /// The to read from. - /// Type of the object. - /// The existing value of object being read. - /// The calling serializer. - /// The object value. - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - if (reader.TokenType == JsonToken.None) - reader.Read(); + switch (reader.TokenType) + { + case JsonToken.StartObject: + { + return CreateJsonObject(reader); + } + case JsonToken.StartArray: + { + JsonArray a = new JsonArray(); - IJsonValue value = CreateJsonValue(reader); + while (reader.Read()) + { + switch (reader.TokenType) + { + case JsonToken.EndArray: + return a; + default: + IJsonValue value = CreateJsonValue(reader); + a.Add(value); + break; + } + } + } + break; + case JsonToken.Integer: + case JsonToken.Float: + return JsonValue.CreateNumberValue(Convert.ToDouble(reader.Value, CultureInfo.InvariantCulture)); + case JsonToken.String: + return JsonValue.CreateStringValue(reader.Value.ToString()); + case JsonToken.Boolean: + return JsonValue.CreateBooleanValue(Convert.ToBoolean(reader.Value, CultureInfo.InvariantCulture)); + case JsonToken.Null: + // surely there is a better way to create a null value than this? + return JsonValue.Parse("null"); + case JsonToken.Date: + return JsonValue.CreateStringValue(reader.Value.ToString()); + case JsonToken.Bytes: + return JsonValue.CreateStringValue(reader.Value.ToString()); + default: + throw JsonSerializationException.Create(reader, "Unexpected or unsupported token: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); + } - if (!objectType.IsAssignableFrom(value.GetType())) - throw JsonSerializationException.Create(reader, "Could not convert '{0}' to '{1}'.".FormatWith(CultureInfo.InvariantCulture, value.GetType(), objectType)); + throw JsonSerializationException.Create(reader, "Unexpected end."); + } - return value; - } - - private IJsonValue CreateJsonValue(JsonReader reader) - { - while (reader.TokenType == JsonToken.Comment) - { - if (!reader.Read()) - throw JsonSerializationException.Create(reader, "Unexpected end."); - } - - switch (reader.TokenType) - { - case JsonToken.StartObject: - { - return CreateJsonObject(reader); - } - case JsonToken.StartArray: - { - JsonArray a = new JsonArray(); + private JsonObject CreateJsonObject(JsonReader reader) + { + JsonObject o = new JsonObject(); + string propertyName = null; while (reader.Read()) { - switch (reader.TokenType) - { - case JsonToken.EndArray: - return a; - default: - IJsonValue value = CreateJsonValue(reader); - a.Add(value); - break; - } + switch (reader.TokenType) + { + case JsonToken.PropertyName: + propertyName = (string)reader.Value; + break; + case JsonToken.EndObject: + return o; + case JsonToken.Comment: + break; + default: + IJsonValue propertyValue = CreateJsonValue(reader); + o.Add(propertyName, propertyValue); + break; + } } - } - break; - case JsonToken.Integer: - case JsonToken.Float: - return JsonValue.CreateNumberValue(Convert.ToDouble(reader.Value, CultureInfo.InvariantCulture)); - case JsonToken.String: - return JsonValue.CreateStringValue(reader.Value.ToString()); - case JsonToken.Boolean: - return JsonValue.CreateBooleanValue(Convert.ToBoolean(reader.Value, CultureInfo.InvariantCulture)); - case JsonToken.Null: - // surely there is a better way to create a null value than this? - return JsonValue.Parse("null"); - case JsonToken.Date: - return JsonValue.CreateStringValue(reader.Value.ToString()); - case JsonToken.Bytes: - return JsonValue.CreateStringValue(reader.Value.ToString()); - default: - throw JsonSerializationException.Create(reader, "Unexpected or unsupported token: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); - } - throw JsonSerializationException.Create(reader, "Unexpected end."); - } - - private JsonObject CreateJsonObject(JsonReader reader) - { - JsonObject o = new JsonObject(); - string propertyName = null; - - while (reader.Read()) - { - switch (reader.TokenType) - { - case JsonToken.PropertyName: - propertyName = (string)reader.Value; - break; - case JsonToken.EndObject: - return o; - case JsonToken.Comment: - break; - default: - IJsonValue propertyValue = CreateJsonValue(reader); - o.Add(propertyName, propertyValue); - break; + throw JsonSerializationException.Create(reader, "Unexpected end."); } - } - throw JsonSerializationException.Create(reader, "Unexpected end."); + /// + /// Determines whether this instance can convert the specified object type. + /// + /// Type of the object. + /// + /// true if this instance can convert the specified object type; otherwise, false. + /// + public override bool CanConvert(Type objectType) + { + return typeof(IJsonValue).IsAssignableFrom(objectType); + } } - - /// - /// Determines whether this instance can convert the specified object type. - /// - /// Type of the object. - /// - /// true if this instance can convert the specified object type; otherwise, false. - /// - public override bool CanConvert(Type objectType) - { - return typeof(IJsonValue).IsAssignableFrom(objectType); - } - } } #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Converters/KeyValuePairConverter.cs b/Src/Newtonsoft.Json/Converters/KeyValuePairConverter.cs index bb41ff27..d76c05ef 100644 --- a/Src/Newtonsoft.Json/Converters/KeyValuePairConverter.cs +++ b/Src/Newtonsoft.Json/Converters/KeyValuePairConverter.cs @@ -31,111 +31,111 @@ using System.Reflection; namespace Newtonsoft.Json.Converters { - /// - /// Converts a to and from JSON. - /// - public class KeyValuePairConverter : JsonConverter - { - private const string KeyName = "Key"; - private const string ValueName = "Value"; - /// - /// Writes the JSON representation of the object. + /// Converts a to and from JSON. /// - /// The to write to. - /// The value. - /// The calling serializer. - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + public class KeyValuePairConverter : JsonConverter { - Type t = value.GetType(); - PropertyInfo keyProperty = t.GetProperty(KeyName); - PropertyInfo valueProperty = t.GetProperty(ValueName); + private const string KeyName = "Key"; + private const string ValueName = "Value"; - DefaultContractResolver resolver = serializer.ContractResolver as DefaultContractResolver; - - writer.WriteStartObject(); - - writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(KeyName) : KeyName); - serializer.Serialize(writer, ReflectionUtils.GetMemberValue(keyProperty, value)); - writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(ValueName) : ValueName); - serializer.Serialize(writer, ReflectionUtils.GetMemberValue(valueProperty, value)); - writer.WriteEndObject(); - } - - /// - /// Reads the JSON representation of the object. - /// - /// The to read from. - /// Type of the object. - /// The existing value of object being read. - /// The calling serializer. - /// The object value. - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - bool isNullable = ReflectionUtils.IsNullableType(objectType); - - if (reader.TokenType == JsonToken.Null) - { - if (!isNullable) - throw JsonSerializationException.Create(reader, "Cannot convert null value to KeyValuePair."); - - return null; - } - - Type t = (isNullable) - ? Nullable.GetUnderlyingType(objectType) - : objectType; - - IList genericArguments = t.GetGenericArguments(); - Type keyType = genericArguments[0]; - Type valueType = genericArguments[1]; - - object key = null; - object value = null; - - reader.Read(); - - while (reader.TokenType == JsonToken.PropertyName) - { - string propertyName = reader.Value.ToString(); - if (string.Equals(propertyName, KeyName, StringComparison.OrdinalIgnoreCase)) + /// + /// Writes the JSON representation of the object. + /// + /// The to write to. + /// The value. + /// The calling serializer. + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { - reader.Read(); - key = serializer.Deserialize(reader, keyType); - } - else if (string.Equals(propertyName, ValueName, StringComparison.OrdinalIgnoreCase)) - { - reader.Read(); - value = serializer.Deserialize(reader, valueType); - } - else - { - reader.Skip(); + Type t = value.GetType(); + PropertyInfo keyProperty = t.GetProperty(KeyName); + PropertyInfo valueProperty = t.GetProperty(ValueName); + + DefaultContractResolver resolver = serializer.ContractResolver as DefaultContractResolver; + + writer.WriteStartObject(); + + writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(KeyName) : KeyName); + serializer.Serialize(writer, ReflectionUtils.GetMemberValue(keyProperty, value)); + writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(ValueName) : ValueName); + serializer.Serialize(writer, ReflectionUtils.GetMemberValue(valueProperty, value)); + writer.WriteEndObject(); } - reader.Read(); - } + /// + /// Reads the JSON representation of the object. + /// + /// The to read from. + /// Type of the object. + /// The existing value of object being read. + /// The calling serializer. + /// The object value. + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + bool isNullable = ReflectionUtils.IsNullableType(objectType); - return Activator.CreateInstance(t, key, value); + if (reader.TokenType == JsonToken.Null) + { + if (!isNullable) + throw JsonSerializationException.Create(reader, "Cannot convert null value to KeyValuePair."); + + return null; + } + + Type t = (isNullable) + ? Nullable.GetUnderlyingType(objectType) + : objectType; + + IList genericArguments = t.GetGenericArguments(); + Type keyType = genericArguments[0]; + Type valueType = genericArguments[1]; + + object key = null; + object value = null; + + reader.Read(); + + while (reader.TokenType == JsonToken.PropertyName) + { + string propertyName = reader.Value.ToString(); + if (string.Equals(propertyName, KeyName, StringComparison.OrdinalIgnoreCase)) + { + reader.Read(); + key = serializer.Deserialize(reader, keyType); + } + else if (string.Equals(propertyName, ValueName, StringComparison.OrdinalIgnoreCase)) + { + reader.Read(); + value = serializer.Deserialize(reader, valueType); + } + else + { + reader.Skip(); + } + + reader.Read(); + } + + return Activator.CreateInstance(t, key, value); + } + + /// + /// Determines whether this instance can convert the specified object type. + /// + /// Type of the object. + /// + /// true if this instance can convert the specified object type; otherwise, false. + /// + public override bool CanConvert(Type objectType) + { + Type t = (ReflectionUtils.IsNullableType(objectType)) + ? Nullable.GetUnderlyingType(objectType) + : objectType; + + if (t.IsValueType() && t.IsGenericType()) + return (t.GetGenericTypeDefinition() == typeof(KeyValuePair<,>)); + + return false; + } } - - /// - /// Determines whether this instance can convert the specified object type. - /// - /// Type of the object. - /// - /// true if this instance can convert the specified object type; otherwise, false. - /// - public override bool CanConvert(Type objectType) - { - Type t = (ReflectionUtils.IsNullableType(objectType)) - ? Nullable.GetUnderlyingType(objectType) - : objectType; - - if (t.IsValueType() && t.IsGenericType()) - return (t.GetGenericTypeDefinition() == typeof(KeyValuePair<,>)); - - return false; - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Converters/RegexConverter.cs b/Src/Newtonsoft.Json/Converters/RegexConverter.cs index d11423d7..e5898332 100644 --- a/Src/Newtonsoft.Json/Converters/RegexConverter.cs +++ b/Src/Newtonsoft.Json/Converters/RegexConverter.cs @@ -31,171 +31,171 @@ using Newtonsoft.Json.Serialization; namespace Newtonsoft.Json.Converters { - /// - /// Converts a to and from JSON and BSON. - /// - public class RegexConverter : JsonConverter - { - private const string PatternName = "Pattern"; - private const string OptionsName = "Options"; - /// - /// Writes the JSON representation of the object. + /// Converts a to and from JSON and BSON. /// - /// The to write to. - /// The value. - /// The calling serializer. - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + public class RegexConverter : JsonConverter { - Regex regex = (Regex) value; + private const string PatternName = "Pattern"; + private const string OptionsName = "Options"; - BsonWriter bsonWriter = writer as BsonWriter; - if (bsonWriter != null) - WriteBson(bsonWriter, regex); - else - WriteJson(writer, regex, serializer); - } - - private bool HasFlag(RegexOptions options, RegexOptions flag) - { - return ((options & flag) == flag); - } - - private void WriteBson(BsonWriter writer, Regex regex) - { - // Regular expression - The first cstring is the regex pattern, the second - // is the regex options string. Options are identified by characters, which - // must be stored in alphabetical order. Valid options are 'i' for case - // insensitive matching, 'm' for multiline matching, 'x' for verbose mode, - // 'l' to make \w, \W, etc. locale dependent, 's' for dotall mode - // ('.' matches everything), and 'u' to make \w, \W, etc. match unicode. - - string options = null; - - if (HasFlag(regex.Options, RegexOptions.IgnoreCase)) - options += "i"; - - if (HasFlag(regex.Options, RegexOptions.Multiline)) - options += "m"; - - if (HasFlag(regex.Options, RegexOptions.Singleline)) - options += "s"; - - options += "u"; - - if (HasFlag(regex.Options, RegexOptions.ExplicitCapture)) - options += "x"; - - writer.WriteRegex(regex.ToString(), options); - } - - private void WriteJson(JsonWriter writer, Regex regex, JsonSerializer serializer) - { - DefaultContractResolver resolver = serializer.ContractResolver as DefaultContractResolver; - - writer.WriteStartObject(); - writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(PatternName) : PatternName); - writer.WriteValue(regex.ToString()); - writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(OptionsName) : OptionsName); - serializer.Serialize(writer, regex.Options); - writer.WriteEndObject(); - } - - /// - /// Reads the JSON representation of the object. - /// - /// The to read from. - /// Type of the object. - /// The existing value of object being read. - /// The calling serializer. - /// The object value. - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - if (reader.TokenType == JsonToken.StartObject) - return ReadRegexObject(reader, serializer); - - if (reader.TokenType == JsonToken.String) - return ReadRegexString(reader); - - throw JsonSerializationException.Create(reader, "Unexpected token when reading Regex."); - } - - private object ReadRegexString(JsonReader reader) - { - string regexText = (string)reader.Value; - int patternOptionDelimiterIndex = regexText.LastIndexOf('/'); - - string patternText = regexText.Substring(1, patternOptionDelimiterIndex - 1); - string optionsText = regexText.Substring(patternOptionDelimiterIndex + 1); - - RegexOptions options = RegexOptions.None; - foreach (char c in optionsText) - { - switch (c) + /// + /// Writes the JSON representation of the object. + /// + /// The to write to. + /// The value. + /// The calling serializer. + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { - case 'i': - options |= RegexOptions.IgnoreCase; - break; - case 'm': - options |= RegexOptions.Multiline; - break; - case 's': - options |= RegexOptions.Singleline; - break; - case 'x': - options |= RegexOptions.ExplicitCapture; - break; - } - } + Regex regex = (Regex)value; - return new Regex(patternText, options); - } - - private Regex ReadRegexObject(JsonReader reader, JsonSerializer serializer) - { - string pattern = null; - RegexOptions? options = null; - - while (reader.Read()) - { - switch (reader.TokenType) - { - case JsonToken.PropertyName: - string propertyName = reader.Value.ToString(); - - if (!reader.Read()) - throw JsonSerializationException.Create(reader, "Unexpected end when reading Regex."); - - if (string.Equals(propertyName, PatternName, StringComparison.OrdinalIgnoreCase)) - pattern = (string)reader.Value; - else if (string.Equals(propertyName, OptionsName, StringComparison.OrdinalIgnoreCase)) - options = serializer.Deserialize(reader); + BsonWriter bsonWriter = writer as BsonWriter; + if (bsonWriter != null) + WriteBson(bsonWriter, regex); else - reader.Skip(); - break; - case JsonToken.Comment: - break; - case JsonToken.EndObject: - if (pattern == null) - throw JsonSerializationException.Create(reader, "Error deserializing Regex. No pattern found."); - - return new Regex(pattern, options ?? RegexOptions.None); + WriteJson(writer, regex, serializer); } - } - throw JsonSerializationException.Create(reader, "Unexpected end when reading Regex."); - } + private bool HasFlag(RegexOptions options, RegexOptions flag) + { + return ((options & flag) == flag); + } - /// - /// Determines whether this instance can convert the specified object type. - /// - /// Type of the object. - /// - /// true if this instance can convert the specified object type; otherwise, false. - /// - public override bool CanConvert(Type objectType) - { - return (objectType == typeof (Regex)); + private void WriteBson(BsonWriter writer, Regex regex) + { + // Regular expression - The first cstring is the regex pattern, the second + // is the regex options string. Options are identified by characters, which + // must be stored in alphabetical order. Valid options are 'i' for case + // insensitive matching, 'm' for multiline matching, 'x' for verbose mode, + // 'l' to make \w, \W, etc. locale dependent, 's' for dotall mode + // ('.' matches everything), and 'u' to make \w, \W, etc. match unicode. + + string options = null; + + if (HasFlag(regex.Options, RegexOptions.IgnoreCase)) + options += "i"; + + if (HasFlag(regex.Options, RegexOptions.Multiline)) + options += "m"; + + if (HasFlag(regex.Options, RegexOptions.Singleline)) + options += "s"; + + options += "u"; + + if (HasFlag(regex.Options, RegexOptions.ExplicitCapture)) + options += "x"; + + writer.WriteRegex(regex.ToString(), options); + } + + private void WriteJson(JsonWriter writer, Regex regex, JsonSerializer serializer) + { + DefaultContractResolver resolver = serializer.ContractResolver as DefaultContractResolver; + + writer.WriteStartObject(); + writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(PatternName) : PatternName); + writer.WriteValue(regex.ToString()); + writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(OptionsName) : OptionsName); + serializer.Serialize(writer, regex.Options); + writer.WriteEndObject(); + } + + /// + /// Reads the JSON representation of the object. + /// + /// The to read from. + /// Type of the object. + /// The existing value of object being read. + /// The calling serializer. + /// The object value. + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.StartObject) + return ReadRegexObject(reader, serializer); + + if (reader.TokenType == JsonToken.String) + return ReadRegexString(reader); + + throw JsonSerializationException.Create(reader, "Unexpected token when reading Regex."); + } + + private object ReadRegexString(JsonReader reader) + { + string regexText = (string)reader.Value; + int patternOptionDelimiterIndex = regexText.LastIndexOf('/'); + + string patternText = regexText.Substring(1, patternOptionDelimiterIndex - 1); + string optionsText = regexText.Substring(patternOptionDelimiterIndex + 1); + + RegexOptions options = RegexOptions.None; + foreach (char c in optionsText) + { + switch (c) + { + case 'i': + options |= RegexOptions.IgnoreCase; + break; + case 'm': + options |= RegexOptions.Multiline; + break; + case 's': + options |= RegexOptions.Singleline; + break; + case 'x': + options |= RegexOptions.ExplicitCapture; + break; + } + } + + return new Regex(patternText, options); + } + + private Regex ReadRegexObject(JsonReader reader, JsonSerializer serializer) + { + string pattern = null; + RegexOptions? options = null; + + while (reader.Read()) + { + switch (reader.TokenType) + { + case JsonToken.PropertyName: + string propertyName = reader.Value.ToString(); + + if (!reader.Read()) + throw JsonSerializationException.Create(reader, "Unexpected end when reading Regex."); + + if (string.Equals(propertyName, PatternName, StringComparison.OrdinalIgnoreCase)) + pattern = (string)reader.Value; + else if (string.Equals(propertyName, OptionsName, StringComparison.OrdinalIgnoreCase)) + options = serializer.Deserialize(reader); + else + reader.Skip(); + break; + case JsonToken.Comment: + break; + case JsonToken.EndObject: + if (pattern == null) + throw JsonSerializationException.Create(reader, "Error deserializing Regex. No pattern found."); + + return new Regex(pattern, options ?? RegexOptions.None); + } + } + + throw JsonSerializationException.Create(reader, "Unexpected end when reading Regex."); + } + + /// + /// Determines whether this instance can convert the specified object type. + /// + /// Type of the object. + /// + /// true if this instance can convert the specified object type; otherwise, false. + /// + public override bool CanConvert(Type objectType) + { + return (objectType == typeof(Regex)); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Converters/StringEnumConverter.cs b/Src/Newtonsoft.Json/Converters/StringEnumConverter.cs index cdbf21d3..6499ce70 100644 --- a/Src/Newtonsoft.Json/Converters/StringEnumConverter.cs +++ b/Src/Newtonsoft.Json/Converters/StringEnumConverter.cs @@ -33,203 +33,204 @@ using Newtonsoft.Json.Utilities; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json.Converters { - /// - /// Converts an to and from its name string value. - /// - public class StringEnumConverter : JsonConverter - { - private readonly Dictionary> _enumMemberNamesPerType = new Dictionary>(); - /// - /// Gets or sets a value indicating whether the written enum text should be camel case. + /// Converts an to and from its name string value. /// - /// true if the written enum text will be camel case; otherwise, false. - public bool CamelCaseText { get; set; } - - /// - /// Writes the JSON representation of the object. - /// - /// The to write to. - /// The value. - /// The calling serializer. - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + public class StringEnumConverter : JsonConverter { - if (value == null) - { - writer.WriteNull(); - return; - } + private readonly Dictionary> _enumMemberNamesPerType = new Dictionary>(); - Enum e = (Enum)value; + /// + /// Gets or sets a value indicating whether the written enum text should be camel case. + /// + /// true if the written enum text will be camel case; otherwise, false. + public bool CamelCaseText { get; set; } - string enumName = e.ToString("G"); - - if (char.IsNumber(enumName[0]) || enumName[0] == '-') - { - // enum value has no name so write number - writer.WriteValue(value); - } - else - { - BidirectionalDictionary map = GetEnumNameMap(e.GetType()); - - string[] names = enumName.Split(','); - for (int i = 0; i < names.Length; i++) + /// + /// Writes the JSON representation of the object. + /// + /// The to write to. + /// The value. + /// The calling serializer. + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { - string name = names[i].Trim(); - - string resolvedEnumName; - map.TryGetByFirst(name, out resolvedEnumName); - resolvedEnumName = resolvedEnumName ?? name; - - if (CamelCaseText) - resolvedEnumName = StringUtils.ToCamelCase(resolvedEnumName); - - names[i] = resolvedEnumName; - } - - string finalName = string.Join(", ", names); - - writer.WriteValue(finalName); - } - } - - /// - /// Reads the JSON representation of the object. - /// - /// The to read from. - /// Type of the object. - /// The existing value of object being read. - /// The calling serializer. - /// The object value. - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - bool isNullable = ReflectionUtils.IsNullableType(objectType); - Type t = isNullable ? Nullable.GetUnderlyingType(objectType) : objectType; - - if (reader.TokenType == JsonToken.Null) - { - if (!ReflectionUtils.IsNullableType(objectType)) - throw JsonSerializationException.Create(reader, "Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType)); - - return null; - } - - try - { - if (reader.TokenType == JsonToken.String) - { - string enumText = reader.Value.ToString(); - if (enumText == string.Empty && isNullable) - return null; - - string finalEnumText; - - BidirectionalDictionary map = GetEnumNameMap(t); - if (enumText.IndexOf(',') != -1) - { - string[] names = enumText.Split(','); - for (int i = 0; i < names.Length; i++) + if (value == null) { - string name = names[i].Trim(); - - names[i] = ResolvedEnumName(map, name); + writer.WriteNull(); + return; } - finalEnumText = string.Join(", ", names); - } - else - { - finalEnumText = ResolvedEnumName(map, enumText); - } + Enum e = (Enum)value; - return Enum.Parse(t, finalEnumText, true); + string enumName = e.ToString("G"); + + if (char.IsNumber(enumName[0]) || enumName[0] == '-') + { + // enum value has no name so write number + writer.WriteValue(value); + } + else + { + BidirectionalDictionary map = GetEnumNameMap(e.GetType()); + + string[] names = enumName.Split(','); + for (int i = 0; i < names.Length; i++) + { + string name = names[i].Trim(); + + string resolvedEnumName; + map.TryGetByFirst(name, out resolvedEnumName); + resolvedEnumName = resolvedEnumName ?? name; + + if (CamelCaseText) + resolvedEnumName = StringUtils.ToCamelCase(resolvedEnumName); + + names[i] = resolvedEnumName; + } + + string finalName = string.Join(", ", names); + + writer.WriteValue(finalName); + } } - if (reader.TokenType == JsonToken.Integer) - return ConvertUtils.ConvertOrCast(reader.Value, CultureInfo.InvariantCulture, t); - } - catch (Exception ex) - { - throw JsonSerializationException.Create(reader, "Error converting value {0} to type '{1}'.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.FormatValueForPrint(reader.Value), objectType), ex); - } - - - throw JsonSerializationException.Create(reader, "Unexpected token when parsing enum. Expected String or Integer, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); - } - - private static string ResolvedEnumName(BidirectionalDictionary map, string enumText) - { - string resolvedEnumName; - map.TryGetBySecond(enumText, out resolvedEnumName); - resolvedEnumName = resolvedEnumName ?? enumText; - return resolvedEnumName; - } - - private BidirectionalDictionary GetEnumNameMap(Type t) - { - BidirectionalDictionary map; - - if (!_enumMemberNamesPerType.TryGetValue(t, out map)) - { - lock (_enumMemberNamesPerType) + /// + /// Reads the JSON representation of the object. + /// + /// The to read from. + /// Type of the object. + /// The existing value of object being read. + /// The calling serializer. + /// The object value. + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { - if (_enumMemberNamesPerType.TryGetValue(t, out map)) - return map; + bool isNullable = ReflectionUtils.IsNullableType(objectType); + Type t = isNullable ? Nullable.GetUnderlyingType(objectType) : objectType; - map = new BidirectionalDictionary( - StringComparer.OrdinalIgnoreCase, - StringComparer.OrdinalIgnoreCase); + if (reader.TokenType == JsonToken.Null) + { + if (!ReflectionUtils.IsNullableType(objectType)) + throw JsonSerializationException.Create(reader, "Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType)); + + return null; + } + + try + { + if (reader.TokenType == JsonToken.String) + { + string enumText = reader.Value.ToString(); + if (enumText == string.Empty && isNullable) + return null; + + string finalEnumText; + + BidirectionalDictionary map = GetEnumNameMap(t); + if (enumText.IndexOf(',') != -1) + { + string[] names = enumText.Split(','); + for (int i = 0; i < names.Length; i++) + { + string name = names[i].Trim(); + + names[i] = ResolvedEnumName(map, name); + } + + finalEnumText = string.Join(", ", names); + } + else + { + finalEnumText = ResolvedEnumName(map, enumText); + } + + return Enum.Parse(t, finalEnumText, true); + } + + if (reader.TokenType == JsonToken.Integer) + return ConvertUtils.ConvertOrCast(reader.Value, CultureInfo.InvariantCulture, t); + } + catch (Exception ex) + { + throw JsonSerializationException.Create(reader, "Error converting value {0} to type '{1}'.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.FormatValueForPrint(reader.Value), objectType), ex); + } + + + throw JsonSerializationException.Create(reader, "Unexpected token when parsing enum. Expected String or Integer, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); + } + + private static string ResolvedEnumName(BidirectionalDictionary map, string enumText) + { + string resolvedEnumName; + map.TryGetBySecond(enumText, out resolvedEnumName); + resolvedEnumName = resolvedEnumName ?? enumText; + return resolvedEnumName; + } + + private BidirectionalDictionary GetEnumNameMap(Type t) + { + BidirectionalDictionary map; + + if (!_enumMemberNamesPerType.TryGetValue(t, out map)) + { + lock (_enumMemberNamesPerType) + { + if (_enumMemberNamesPerType.TryGetValue(t, out map)) + return map; + + map = new BidirectionalDictionary( + StringComparer.OrdinalIgnoreCase, + StringComparer.OrdinalIgnoreCase); + + foreach (FieldInfo f in t.GetFields()) + { + string n1 = f.Name; + string n2; - foreach (FieldInfo f in t.GetFields()) - { - string n1 = f.Name; - string n2; - #if !NET20 - n2 = f.GetCustomAttributes(typeof (EnumMemberAttribute), true) - .Cast() - .Select(a => a.Value) - .SingleOrDefault() ?? f.Name; + n2 = f.GetCustomAttributes(typeof(EnumMemberAttribute), true) + .Cast() + .Select(a => a.Value) + .SingleOrDefault() ?? f.Name; #else n2 = f.Name; #endif - string s; - if (map.TryGetBySecond(n2, out s)) - { - throw new InvalidOperationException("Enum name '{0}' already exists on enum '{1}'." - .FormatWith(CultureInfo.InvariantCulture, n2, t.Name)); + string s; + if (map.TryGetBySecond(n2, out s)) + { + throw new InvalidOperationException("Enum name '{0}' already exists on enum '{1}'." + .FormatWith(CultureInfo.InvariantCulture, n2, t.Name)); + } + + map.Set(n1, n2); + } + + _enumMemberNamesPerType[t] = map; + } } - map.Set(n1, n2); - } - - _enumMemberNamesPerType[t] = map; + return map; } - } - return map; + /// + /// Determines whether this instance can convert the specified object type. + /// + /// Type of the object. + /// + /// true if this instance can convert the specified object type; otherwise, false. + /// + public override bool CanConvert(Type objectType) + { + Type t = (ReflectionUtils.IsNullableType(objectType)) + ? Nullable.GetUnderlyingType(objectType) + : objectType; + + return t.IsEnum(); + } } - - /// - /// Determines whether this instance can convert the specified object type. - /// - /// Type of the object. - /// - /// true if this instance can convert the specified object type; otherwise, false. - /// - public override bool CanConvert(Type objectType) - { - Type t = (ReflectionUtils.IsNullableType(objectType)) - ? Nullable.GetUnderlyingType(objectType) - : objectType; - - return t.IsEnum(); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Converters/VersionConverter.cs b/Src/Newtonsoft.Json/Converters/VersionConverter.cs index f4a5b43b..3f512e44 100644 --- a/Src/Newtonsoft.Json/Converters/VersionConverter.cs +++ b/Src/Newtonsoft.Json/Converters/VersionConverter.cs @@ -29,78 +29,78 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Converters { - /// - /// Converts a to and from a string (e.g. "1.2.3.4"). - /// - public class VersionConverter : JsonConverter - { /// - /// Writes the JSON representation of the object. + /// Converts a to and from a string (e.g. "1.2.3.4"). /// - /// The to write to. - /// The value. - /// The calling serializer. - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + public class VersionConverter : JsonConverter { - if (value == null) - { - writer.WriteNull(); - } - else if (value is Version) - { - writer.WriteValue(value.ToString()); - } - else - { - throw new JsonSerializationException("Expected Version object value"); - } - } - - /// - /// Reads the JSON representation of the object. - /// - /// The to read from. - /// Type of the object. - /// The existing property value of the JSON that is being converted. - /// The calling serializer. - /// The object value. - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - if (reader.TokenType == JsonToken.Null) - { - return null; - } - else - { - if (reader.TokenType == JsonToken.String) + /// + /// Writes the JSON representation of the object. + /// + /// The to write to. + /// The value. + /// The calling serializer. + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { - try - { - Version v = new Version((string) reader.Value); - return v; - } - catch (Exception ex) - { - throw JsonSerializationException.Create(reader, "Error parsing version string: {0}".FormatWith(CultureInfo.InvariantCulture, reader.Value), ex); - } + if (value == null) + { + writer.WriteNull(); + } + else if (value is Version) + { + writer.WriteValue(value.ToString()); + } + else + { + throw new JsonSerializationException("Expected Version object value"); + } } - else - { - throw JsonSerializationException.Create(reader, "Unexpected token or value when parsing version. Token: {0}, Value: {1}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType, reader.Value)); - } - } - } - /// - /// Determines whether this instance can convert the specified object type. - /// - /// Type of the object. - /// - /// true if this instance can convert the specified object type; otherwise, false. - /// - public override bool CanConvert(Type objectType) - { - return objectType == typeof (Version); + /// + /// Reads the JSON representation of the object. + /// + /// The to read from. + /// Type of the object. + /// The existing property value of the JSON that is being converted. + /// The calling serializer. + /// The object value. + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) + { + return null; + } + else + { + if (reader.TokenType == JsonToken.String) + { + try + { + Version v = new Version((string)reader.Value); + return v; + } + catch (Exception ex) + { + throw JsonSerializationException.Create(reader, "Error parsing version string: {0}".FormatWith(CultureInfo.InvariantCulture, reader.Value), ex); + } + } + else + { + throw JsonSerializationException.Create(reader, "Unexpected token or value when parsing version. Token: {0}, Value: {1}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType, reader.Value)); + } + } + } + + /// + /// Determines whether this instance can convert the specified object type. + /// + /// Type of the object. + /// + /// true if this instance can convert the specified object type; otherwise, false. + /// + public override bool CanConvert(Type objectType) + { + return objectType == typeof(Version); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs b/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs index 38878409..519963ec 100644 --- a/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs +++ b/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs @@ -36,1530 +36,1533 @@ using Newtonsoft.Json.Utilities; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json.Converters { - #region XmlNodeWrappers + + #region XmlNodeWrappers #if !SILVERLIGHT && !NETFX_CORE && !PORTABLE && !PORTABLE40 - internal class XmlDocumentWrapper : XmlNodeWrapper, IXmlDocument - { - private readonly XmlDocument _document; - - public XmlDocumentWrapper(XmlDocument document) - : base(document) + internal class XmlDocumentWrapper : XmlNodeWrapper, IXmlDocument { - _document = document; + private readonly XmlDocument _document; + + public XmlDocumentWrapper(XmlDocument document) + : base(document) + { + _document = document; + } + + public IXmlNode CreateComment(string data) + { + return new XmlNodeWrapper(_document.CreateComment(data)); + } + + public IXmlNode CreateTextNode(string text) + { + return new XmlNodeWrapper(_document.CreateTextNode(text)); + } + + public IXmlNode CreateCDataSection(string data) + { + return new XmlNodeWrapper(_document.CreateCDataSection(data)); + } + + public IXmlNode CreateWhitespace(string text) + { + return new XmlNodeWrapper(_document.CreateWhitespace(text)); + } + + public IXmlNode CreateSignificantWhitespace(string text) + { + return new XmlNodeWrapper(_document.CreateSignificantWhitespace(text)); + } + + public IXmlNode CreateXmlDeclaration(string version, string encoding, string standalone) + { + return new XmlNodeWrapper(_document.CreateXmlDeclaration(version, encoding, standalone)); + } + + public IXmlNode CreateProcessingInstruction(string target, string data) + { + return new XmlNodeWrapper(_document.CreateProcessingInstruction(target, data)); + } + + public IXmlElement CreateElement(string elementName) + { + return new XmlElementWrapper(_document.CreateElement(elementName)); + } + + public IXmlElement CreateElement(string qualifiedName, string namespaceUri) + { + return new XmlElementWrapper(_document.CreateElement(qualifiedName, namespaceUri)); + } + + public IXmlNode CreateAttribute(string name, string value) + { + XmlNodeWrapper attribute = new XmlNodeWrapper(_document.CreateAttribute(name)); + attribute.Value = value; + + return attribute; + } + + public IXmlNode CreateAttribute(string qualifiedName, string namespaceUri, string value) + { + XmlNodeWrapper attribute = new XmlNodeWrapper(_document.CreateAttribute(qualifiedName, namespaceUri)); + attribute.Value = value; + + return attribute; + } + + public IXmlElement DocumentElement + { + get + { + if (_document.DocumentElement == null) + return null; + + return new XmlElementWrapper(_document.DocumentElement); + } + } } - public IXmlNode CreateComment(string data) + internal class XmlElementWrapper : XmlNodeWrapper, IXmlElement { - return new XmlNodeWrapper(_document.CreateComment(data)); + private readonly XmlElement _element; + + public XmlElementWrapper(XmlElement element) + : base(element) + { + _element = element; + } + + public void SetAttributeNode(IXmlNode attribute) + { + XmlNodeWrapper xmlAttributeWrapper = (XmlNodeWrapper)attribute; + + _element.SetAttributeNode((XmlAttribute)xmlAttributeWrapper.WrappedNode); + } + + public string GetPrefixOfNamespace(string namespaceUri) + { + return _element.GetPrefixOfNamespace(namespaceUri); + } } - public IXmlNode CreateTextNode(string text) + internal class XmlDeclarationWrapper : XmlNodeWrapper, IXmlDeclaration { - return new XmlNodeWrapper(_document.CreateTextNode(text)); + private readonly XmlDeclaration _declaration; + + public XmlDeclarationWrapper(XmlDeclaration declaration) + : base(declaration) + { + _declaration = declaration; + } + + public string Version + { + get { return _declaration.Version; } + } + + public string Encoding + { + get { return _declaration.Encoding; } + set { _declaration.Encoding = value; } + } + + public string Standalone + { + get { return _declaration.Standalone; } + set { _declaration.Standalone = value; } + } } - public IXmlNode CreateCDataSection(string data) + internal class XmlNodeWrapper : IXmlNode { - return new XmlNodeWrapper(_document.CreateCDataSection(data)); + private readonly XmlNode _node; + + public XmlNodeWrapper(XmlNode node) + { + _node = node; + } + + public object WrappedNode + { + get { return _node; } + } + + public XmlNodeType NodeType + { + get { return _node.NodeType; } + } + + public string LocalName + { + get { return _node.LocalName; } + } + + public IList ChildNodes + { + get { return _node.ChildNodes.Cast().Select(n => WrapNode(n)).ToList(); } + } + + private IXmlNode WrapNode(XmlNode node) + { + switch (node.NodeType) + { + case XmlNodeType.Element: + return new XmlElementWrapper((XmlElement)node); + case XmlNodeType.XmlDeclaration: + return new XmlDeclarationWrapper((XmlDeclaration)node); + default: + return new XmlNodeWrapper(node); + } + } + + public IList Attributes + { + get + { + if (_node.Attributes == null) + return null; + + return _node.Attributes.Cast().Select(a => WrapNode(a)).ToList(); + } + } + + public IXmlNode ParentNode + { + get + { + XmlNode node = (_node is XmlAttribute) + ? ((XmlAttribute)_node).OwnerElement + : _node.ParentNode; + + if (node == null) + return null; + + return WrapNode(node); + } + } + + public string Value + { + get { return _node.Value; } + set { _node.Value = value; } + } + + public IXmlNode AppendChild(IXmlNode newChild) + { + XmlNodeWrapper xmlNodeWrapper = (XmlNodeWrapper)newChild; + _node.AppendChild(xmlNodeWrapper._node); + + return newChild; + } + + public string NamespaceUri + { + get { return _node.NamespaceURI; } + } } - - public IXmlNode CreateWhitespace(string text) - { - return new XmlNodeWrapper(_document.CreateWhitespace(text)); - } - - public IXmlNode CreateSignificantWhitespace(string text) - { - return new XmlNodeWrapper(_document.CreateSignificantWhitespace(text)); - } - - public IXmlNode CreateXmlDeclaration(string version, string encoding, string standalone) - { - return new XmlNodeWrapper(_document.CreateXmlDeclaration(version, encoding, standalone)); - } - - public IXmlNode CreateProcessingInstruction(string target, string data) - { - return new XmlNodeWrapper(_document.CreateProcessingInstruction(target, data)); - } - - public IXmlElement CreateElement(string elementName) - { - return new XmlElementWrapper(_document.CreateElement(elementName)); - } - - public IXmlElement CreateElement(string qualifiedName, string namespaceUri) - { - return new XmlElementWrapper(_document.CreateElement(qualifiedName, namespaceUri)); - } - - public IXmlNode CreateAttribute(string name, string value) - { - XmlNodeWrapper attribute = new XmlNodeWrapper(_document.CreateAttribute(name)); - attribute.Value = value; - - return attribute; - } - - public IXmlNode CreateAttribute(string qualifiedName, string namespaceUri, string value) - { - XmlNodeWrapper attribute = new XmlNodeWrapper(_document.CreateAttribute(qualifiedName, namespaceUri)); - attribute.Value = value; - - return attribute; - } - - public IXmlElement DocumentElement - { - get - { - if (_document.DocumentElement == null) - return null; - - return new XmlElementWrapper(_document.DocumentElement); - } - } - } - - internal class XmlElementWrapper : XmlNodeWrapper, IXmlElement - { - private readonly XmlElement _element; - - public XmlElementWrapper(XmlElement element) - : base(element) - { - _element = element; - } - - public void SetAttributeNode(IXmlNode attribute) - { - XmlNodeWrapper xmlAttributeWrapper = (XmlNodeWrapper)attribute; - - _element.SetAttributeNode((XmlAttribute) xmlAttributeWrapper.WrappedNode); - } - - public string GetPrefixOfNamespace(string namespaceUri) - { - return _element.GetPrefixOfNamespace(namespaceUri); - } - } - - internal class XmlDeclarationWrapper : XmlNodeWrapper, IXmlDeclaration - { - private readonly XmlDeclaration _declaration; - - public XmlDeclarationWrapper(XmlDeclaration declaration) - : base(declaration) - { - _declaration = declaration; - } - - public string Version - { - get { return _declaration.Version; } - } - - public string Encoding - { - get { return _declaration.Encoding; } - set { _declaration.Encoding = value; } - } - - public string Standalone - { - get { return _declaration.Standalone; } - set { _declaration.Standalone = value; } - } - } - - internal class XmlNodeWrapper : IXmlNode - { - private readonly XmlNode _node; - - public XmlNodeWrapper(XmlNode node) - { - _node = node; - } - - public object WrappedNode - { - get { return _node; } - } - - public XmlNodeType NodeType - { - get { return _node.NodeType; } - } - - public string LocalName - { - get { return _node.LocalName; } - } - - public IList ChildNodes - { - get { return _node.ChildNodes.Cast().Select(n => WrapNode(n)).ToList(); } - } - - private IXmlNode WrapNode(XmlNode node) - { - switch (node.NodeType) - { - case XmlNodeType.Element: - return new XmlElementWrapper((XmlElement) node); - case XmlNodeType.XmlDeclaration: - return new XmlDeclarationWrapper((XmlDeclaration) node); - default: - return new XmlNodeWrapper(node); - } - } - - public IList Attributes - { - get - { - if (_node.Attributes == null) - return null; - - return _node.Attributes.Cast().Select(a => WrapNode(a)).ToList(); - } - } - - public IXmlNode ParentNode - { - get - { - XmlNode node = (_node is XmlAttribute) - ? ((XmlAttribute) _node).OwnerElement - : _node.ParentNode; - - if (node == null) - return null; - - return WrapNode(node); - } - } - - public string Value - { - get { return _node.Value; } - set { _node.Value = value; } - } - - public IXmlNode AppendChild(IXmlNode newChild) - { - XmlNodeWrapper xmlNodeWrapper = (XmlNodeWrapper) newChild; - _node.AppendChild(xmlNodeWrapper._node); - - return newChild; - } - - public string NamespaceUri - { - get { return _node.NamespaceURI; } - } - } #endif - #endregion + #endregion - #region Interfaces - internal interface IXmlDocument : IXmlNode - { - IXmlNode CreateComment(string text); - IXmlNode CreateTextNode(string text); - IXmlNode CreateCDataSection(string data); - IXmlNode CreateWhitespace(string text); - IXmlNode CreateSignificantWhitespace(string text); - IXmlNode CreateXmlDeclaration(string version, string encoding, string standalone); - IXmlNode CreateProcessingInstruction(string target, string data); - IXmlElement CreateElement(string elementName); - IXmlElement CreateElement(string qualifiedName, string namespaceUri); - IXmlNode CreateAttribute(string name, string value); - IXmlNode CreateAttribute(string qualifiedName, string namespaceUri, string value); + #region Interfaces + internal interface IXmlDocument : IXmlNode + { + IXmlNode CreateComment(string text); + IXmlNode CreateTextNode(string text); + IXmlNode CreateCDataSection(string data); + IXmlNode CreateWhitespace(string text); + IXmlNode CreateSignificantWhitespace(string text); + IXmlNode CreateXmlDeclaration(string version, string encoding, string standalone); + IXmlNode CreateProcessingInstruction(string target, string data); + IXmlElement CreateElement(string elementName); + IXmlElement CreateElement(string qualifiedName, string namespaceUri); + IXmlNode CreateAttribute(string name, string value); + IXmlNode CreateAttribute(string qualifiedName, string namespaceUri, string value); - IXmlElement DocumentElement { get; } - } + IXmlElement DocumentElement { get; } + } - internal interface IXmlDeclaration : IXmlNode - { - string Version { get; } - string Encoding { get; set; } - string Standalone { get; set; } - } + internal interface IXmlDeclaration : IXmlNode + { + string Version { get; } + string Encoding { get; set; } + string Standalone { get; set; } + } - internal interface IXmlElement : IXmlNode - { - void SetAttributeNode(IXmlNode attribute); - string GetPrefixOfNamespace(string namespaceUri); - } + internal interface IXmlElement : IXmlNode + { + void SetAttributeNode(IXmlNode attribute); + string GetPrefixOfNamespace(string namespaceUri); + } - internal interface IXmlNode - { - XmlNodeType NodeType { get; } - string LocalName { get; } - IList ChildNodes { get; } - IList Attributes { get; } - IXmlNode ParentNode { get; } - string Value { get; set; } - IXmlNode AppendChild(IXmlNode newChild); - string NamespaceUri { get; } - object WrappedNode { get; } - } - #endregion + internal interface IXmlNode + { + XmlNodeType NodeType { get; } + string LocalName { get; } + IList ChildNodes { get; } + IList Attributes { get; } + IXmlNode ParentNode { get; } + string Value { get; set; } + IXmlNode AppendChild(IXmlNode newChild); + string NamespaceUri { get; } + object WrappedNode { get; } + } + #endregion - #region XNodeWrappers + #region XNodeWrappers #if !NET20 - internal class XDeclarationWrapper : XObjectWrapper, IXmlDeclaration - { - internal XDeclaration Declaration { get; private set; } - - public XDeclarationWrapper(XDeclaration declaration) - : base(null) + internal class XDeclarationWrapper : XObjectWrapper, IXmlDeclaration { - Declaration = declaration; + internal XDeclaration Declaration { get; private set; } + + public XDeclarationWrapper(XDeclaration declaration) + : base(null) + { + Declaration = declaration; + } + + public override XmlNodeType NodeType + { + get { return XmlNodeType.XmlDeclaration; } + } + + public string Version + { + get { return Declaration.Version; } + } + + public string Encoding + { + get { return Declaration.Encoding; } + set { Declaration.Encoding = value; } + } + + public string Standalone + { + get { return Declaration.Standalone; } + set { Declaration.Standalone = value; } + } } - public override XmlNodeType NodeType + internal class XDocumentWrapper : XContainerWrapper, IXmlDocument { - get { return XmlNodeType.XmlDeclaration; } + private XDocument Document + { + get { return (XDocument)WrappedNode; } + } + + public XDocumentWrapper(XDocument document) + : base(document) + { + } + + public override IList ChildNodes + { + get + { + IList childNodes = base.ChildNodes; + + if (Document.Declaration != null) + childNodes.Insert(0, new XDeclarationWrapper(Document.Declaration)); + + return childNodes; + } + } + + public IXmlNode CreateComment(string text) + { + return new XObjectWrapper(new XComment(text)); + } + + public IXmlNode CreateTextNode(string text) + { + return new XObjectWrapper(new XText(text)); + } + + public IXmlNode CreateCDataSection(string data) + { + return new XObjectWrapper(new XCData(data)); + } + + public IXmlNode CreateWhitespace(string text) + { + return new XObjectWrapper(new XText(text)); + } + + public IXmlNode CreateSignificantWhitespace(string text) + { + return new XObjectWrapper(new XText(text)); + } + + public IXmlNode CreateXmlDeclaration(string version, string encoding, string standalone) + { + return new XDeclarationWrapper(new XDeclaration(version, encoding, standalone)); + } + + public IXmlNode CreateProcessingInstruction(string target, string data) + { + return new XProcessingInstructionWrapper(new XProcessingInstruction(target, data)); + } + + public IXmlElement CreateElement(string elementName) + { + return new XElementWrapper(new XElement(elementName)); + } + + public IXmlElement CreateElement(string qualifiedName, string namespaceUri) + { + string localName = MiscellaneousUtils.GetLocalName(qualifiedName); + return new XElementWrapper(new XElement(XName.Get(localName, namespaceUri))); + } + + public IXmlNode CreateAttribute(string name, string value) + { + return new XAttributeWrapper(new XAttribute(name, value)); + } + + public IXmlNode CreateAttribute(string qualifiedName, string namespaceUri, string value) + { + string localName = MiscellaneousUtils.GetLocalName(qualifiedName); + return new XAttributeWrapper(new XAttribute(XName.Get(localName, namespaceUri), value)); + } + + public IXmlElement DocumentElement + { + get + { + if (Document.Root == null) + return null; + + return new XElementWrapper(Document.Root); + } + } + + public override IXmlNode AppendChild(IXmlNode newChild) + { + XDeclarationWrapper declarationWrapper = newChild as XDeclarationWrapper; + if (declarationWrapper != null) + { + Document.Declaration = declarationWrapper.Declaration; + return declarationWrapper; + } + else + { + return base.AppendChild(newChild); + } + } } - public string Version + internal class XTextWrapper : XObjectWrapper { - get { return Declaration.Version; } + private XText Text + { + get { return (XText)WrappedNode; } + } + + public XTextWrapper(XText text) + : base(text) + { + } + + public override string Value + { + get { return Text.Value; } + set { Text.Value = value; } + } + + public override IXmlNode ParentNode + { + get + { + if (Text.Parent == null) + return null; + + return XContainerWrapper.WrapNode(Text.Parent); + } + } } - public string Encoding + internal class XCommentWrapper : XObjectWrapper { - get { return Declaration.Encoding; } - set { Declaration.Encoding = value; } + private XComment Text + { + get { return (XComment)WrappedNode; } + } + + public XCommentWrapper(XComment text) + : base(text) + { + } + + public override string Value + { + get { return Text.Value; } + set { Text.Value = value; } + } + + public override IXmlNode ParentNode + { + get + { + if (Text.Parent == null) + return null; + + return XContainerWrapper.WrapNode(Text.Parent); + } + } } - public string Standalone + internal class XProcessingInstructionWrapper : XObjectWrapper { - get { return Declaration.Standalone; } - set { Declaration.Standalone = value; } - } - } + private XProcessingInstruction ProcessingInstruction + { + get { return (XProcessingInstruction)WrappedNode; } + } - internal class XDocumentWrapper : XContainerWrapper, IXmlDocument - { - private XDocument Document - { - get { return (XDocument)WrappedNode; } + public XProcessingInstructionWrapper(XProcessingInstruction processingInstruction) + : base(processingInstruction) + { + } + + public override string LocalName + { + get { return ProcessingInstruction.Target; } + } + + public override string Value + { + get { return ProcessingInstruction.Data; } + set { ProcessingInstruction.Data = value; } + } } - public XDocumentWrapper(XDocument document) - : base(document) + internal class XContainerWrapper : XObjectWrapper { + private XContainer Container + { + get { return (XContainer)WrappedNode; } + } + + public XContainerWrapper(XContainer container) + : base(container) + { + } + + public override IList ChildNodes + { + get { return Container.Nodes().Select(n => WrapNode(n)).ToList(); } + } + + public override IXmlNode ParentNode + { + get + { + if (Container.Parent == null) + return null; + + return WrapNode(Container.Parent); + } + } + + internal static IXmlNode WrapNode(XObject node) + { + if (node is XDocument) + return new XDocumentWrapper((XDocument)node); + else if (node is XElement) + return new XElementWrapper((XElement)node); + else if (node is XContainer) + return new XContainerWrapper((XContainer)node); + else if (node is XProcessingInstruction) + return new XProcessingInstructionWrapper((XProcessingInstruction)node); + else if (node is XText) + return new XTextWrapper((XText)node); + else if (node is XComment) + return new XCommentWrapper((XComment)node); + else if (node is XAttribute) + return new XAttributeWrapper((XAttribute)node); + else + return new XObjectWrapper(node); + } + + public override IXmlNode AppendChild(IXmlNode newChild) + { + Container.Add(newChild.WrappedNode); + return newChild; + } } - public override IList ChildNodes + internal class XObjectWrapper : IXmlNode { - get - { - IList childNodes = base.ChildNodes; + private readonly XObject _xmlObject; - if (Document.Declaration != null) - childNodes.Insert(0, new XDeclarationWrapper(Document.Declaration)); + public XObjectWrapper(XObject xmlObject) + { + _xmlObject = xmlObject; + } - return childNodes; - } + public object WrappedNode + { + get { return _xmlObject; } + } + + public virtual XmlNodeType NodeType + { + get { return _xmlObject.NodeType; } + } + + public virtual string LocalName + { + get { return null; } + } + + public virtual IList ChildNodes + { + get { return new List(); } + } + + public virtual IList Attributes + { + get { return null; } + } + + public virtual IXmlNode ParentNode + { + get { return null; } + } + + public virtual string Value + { + get { return null; } + set { throw new InvalidOperationException(); } + } + + public virtual IXmlNode AppendChild(IXmlNode newChild) + { + throw new InvalidOperationException(); + } + + public virtual string NamespaceUri + { + get { return null; } + } } - public IXmlNode CreateComment(string text) + internal class XAttributeWrapper : XObjectWrapper { - return new XObjectWrapper(new XComment(text)); + private XAttribute Attribute + { + get { return (XAttribute)WrappedNode; } + } + + public XAttributeWrapper(XAttribute attribute) + : base(attribute) + { + } + + public override string Value + { + get { return Attribute.Value; } + set { Attribute.Value = value; } + } + + public override string LocalName + { + get { return Attribute.Name.LocalName; } + } + + public override string NamespaceUri + { + get { return Attribute.Name.NamespaceName; } + } + + public override IXmlNode ParentNode + { + get + { + if (Attribute.Parent == null) + return null; + + return XContainerWrapper.WrapNode(Attribute.Parent); + } + } } - public IXmlNode CreateTextNode(string text) + internal class XElementWrapper : XContainerWrapper, IXmlElement { - return new XObjectWrapper(new XText(text)); + private XElement Element + { + get { return (XElement)WrappedNode; } + } + + public XElementWrapper(XElement element) + : base(element) + { + } + + public void SetAttributeNode(IXmlNode attribute) + { + XObjectWrapper wrapper = (XObjectWrapper)attribute; + Element.Add(wrapper.WrappedNode); + } + + public override IList Attributes + { + get { return Element.Attributes().Select(a => new XAttributeWrapper(a)).Cast().ToList(); } + } + + public override string Value + { + get { return Element.Value; } + set { Element.Value = value; } + } + + public override string LocalName + { + get { return Element.Name.LocalName; } + } + + public override string NamespaceUri + { + get { return Element.Name.NamespaceName; } + } + + public string GetPrefixOfNamespace(string namespaceUri) + { + return Element.GetPrefixOfNamespace(namespaceUri); + } } - - public IXmlNode CreateCDataSection(string data) - { - return new XObjectWrapper(new XCData(data)); - } - - public IXmlNode CreateWhitespace(string text) - { - return new XObjectWrapper(new XText(text)); - } - - public IXmlNode CreateSignificantWhitespace(string text) - { - return new XObjectWrapper(new XText(text)); - } - - public IXmlNode CreateXmlDeclaration(string version, string encoding, string standalone) - { - return new XDeclarationWrapper(new XDeclaration(version, encoding, standalone)); - } - - public IXmlNode CreateProcessingInstruction(string target, string data) - { - return new XProcessingInstructionWrapper(new XProcessingInstruction(target, data)); - } - - public IXmlElement CreateElement(string elementName) - { - return new XElementWrapper(new XElement(elementName)); - } - - public IXmlElement CreateElement(string qualifiedName, string namespaceUri) - { - string localName = MiscellaneousUtils.GetLocalName(qualifiedName); - return new XElementWrapper(new XElement(XName.Get(localName, namespaceUri))); - } - - public IXmlNode CreateAttribute(string name, string value) - { - return new XAttributeWrapper(new XAttribute(name, value)); - } - - public IXmlNode CreateAttribute(string qualifiedName, string namespaceUri, string value) - { - string localName = MiscellaneousUtils.GetLocalName(qualifiedName); - return new XAttributeWrapper(new XAttribute(XName.Get(localName, namespaceUri), value)); - } - - public IXmlElement DocumentElement - { - get - { - if (Document.Root == null) - return null; - - return new XElementWrapper(Document.Root); - } - } - - public override IXmlNode AppendChild(IXmlNode newChild) - { - XDeclarationWrapper declarationWrapper = newChild as XDeclarationWrapper; - if (declarationWrapper != null) - { - Document.Declaration = declarationWrapper.Declaration; - return declarationWrapper; - } - else - { - return base.AppendChild(newChild); - } - } - } - - internal class XTextWrapper : XObjectWrapper - { - private XText Text - { - get { return (XText)WrappedNode; } - } - - public XTextWrapper(XText text) - : base(text) - { - } - - public override string Value - { - get { return Text.Value; } - set { Text.Value = value; } - } - - public override IXmlNode ParentNode - { - get - { - if (Text.Parent == null) - return null; - - return XContainerWrapper.WrapNode(Text.Parent); - } - } - } - - internal class XCommentWrapper : XObjectWrapper - { - private XComment Text - { - get { return (XComment)WrappedNode; } - } - - public XCommentWrapper(XComment text) - : base(text) - { - } - - public override string Value - { - get { return Text.Value; } - set { Text.Value = value; } - } - - public override IXmlNode ParentNode - { - get - { - if (Text.Parent == null) - return null; - - return XContainerWrapper.WrapNode(Text.Parent); - } - } - } - - internal class XProcessingInstructionWrapper : XObjectWrapper - { - private XProcessingInstruction ProcessingInstruction - { - get { return (XProcessingInstruction)WrappedNode; } - } - - public XProcessingInstructionWrapper(XProcessingInstruction processingInstruction) - : base(processingInstruction) - { - } - - public override string LocalName - { - get { return ProcessingInstruction.Target; } - } - - public override string Value - { - get { return ProcessingInstruction.Data; } - set { ProcessingInstruction.Data = value; } - } - } - - internal class XContainerWrapper : XObjectWrapper - { - private XContainer Container - { - get { return (XContainer)WrappedNode; } - } - - public XContainerWrapper(XContainer container) - : base(container) - { - } - - public override IList ChildNodes - { - get { return Container.Nodes().Select(n => WrapNode(n)).ToList(); } - } - - public override IXmlNode ParentNode - { - get - { - if (Container.Parent == null) - return null; - - return WrapNode(Container.Parent); - } - } - - internal static IXmlNode WrapNode(XObject node) - { - if (node is XDocument) - return new XDocumentWrapper((XDocument)node); - else if (node is XElement) - return new XElementWrapper((XElement)node); - else if (node is XContainer) - return new XContainerWrapper((XContainer)node); - else if (node is XProcessingInstruction) - return new XProcessingInstructionWrapper((XProcessingInstruction)node); - else if (node is XText) - return new XTextWrapper((XText)node); - else if (node is XComment) - return new XCommentWrapper((XComment)node); - else if (node is XAttribute) - return new XAttributeWrapper((XAttribute) node); - else - return new XObjectWrapper(node); - } - - public override IXmlNode AppendChild(IXmlNode newChild) - { - Container.Add(newChild.WrappedNode); - return newChild; - } - } - - internal class XObjectWrapper : IXmlNode - { - private readonly XObject _xmlObject; - - public XObjectWrapper(XObject xmlObject) - { - _xmlObject = xmlObject; - } - - public object WrappedNode - { - get { return _xmlObject; } - } - - public virtual XmlNodeType NodeType - { - get { return _xmlObject.NodeType; } - } - - public virtual string LocalName - { - get { return null; } - } - - public virtual IList ChildNodes - { - get { return new List(); } - } - - public virtual IList Attributes - { - get { return null; } - } - - public virtual IXmlNode ParentNode - { - get { return null; } - } - - public virtual string Value - { - get { return null; } - set { throw new InvalidOperationException(); } - } - - public virtual IXmlNode AppendChild(IXmlNode newChild) - { - throw new InvalidOperationException(); - } - - public virtual string NamespaceUri - { - get { return null; } - } - } - - internal class XAttributeWrapper : XObjectWrapper - { - private XAttribute Attribute - { - get { return (XAttribute)WrappedNode; } - } - - public XAttributeWrapper(XAttribute attribute) - : base(attribute) - { - } - - public override string Value - { - get { return Attribute.Value; } - set { Attribute.Value = value; } - } - - public override string LocalName - { - get { return Attribute.Name.LocalName; } - } - - public override string NamespaceUri - { - get { return Attribute.Name.NamespaceName; } - } - - public override IXmlNode ParentNode - { - get - { - if (Attribute.Parent == null) - return null; - - return XContainerWrapper.WrapNode(Attribute.Parent); - } - } - } - - internal class XElementWrapper : XContainerWrapper, IXmlElement - { - private XElement Element - { - get { return (XElement) WrappedNode; } - } - - public XElementWrapper(XElement element) - : base(element) - { - } - - public void SetAttributeNode(IXmlNode attribute) - { - XObjectWrapper wrapper = (XObjectWrapper)attribute; - Element.Add(wrapper.WrappedNode); - } - - public override IList Attributes - { - get { return Element.Attributes().Select(a => new XAttributeWrapper(a)).Cast().ToList(); } - } - - public override string Value - { - get { return Element.Value; } - set { Element.Value = value; } - } - - public override string LocalName - { - get { return Element.Name.LocalName; } - } - - public override string NamespaceUri - { - get { return Element.Name.NamespaceName; } - } - - public string GetPrefixOfNamespace(string namespaceUri) - { - return Element.GetPrefixOfNamespace(namespaceUri); - } - } #endif - #endregion - - /// - /// Converts XML to and from JSON. - /// - public class XmlNodeConverter : JsonConverter - { - private const string TextName = "#text"; - private const string CommentName = "#comment"; - private const string CDataName = "#cdata-section"; - private const string WhitespaceName = "#whitespace"; - private const string SignificantWhitespaceName = "#significant-whitespace"; - private const string DeclarationName = "?xml"; - private const string JsonNamespaceUri = "http://james.newtonking.com/projects/json"; + #endregion /// - /// Gets or sets the name of the root element to insert when deserializing to XML if the JSON structure has produces multiple root elements. + /// Converts XML to and from JSON. /// - /// The name of the deserialize root element. - public string DeserializeRootElementName { get; set; } - - /// - /// Gets or sets a flag to indicate whether to write the Json.NET array attribute. - /// This attribute helps preserve arrays when converting the written XML back to JSON. - /// - /// true if the array attibute is written to the XML; otherwise, false. - public bool WriteArrayAttribute { get; set; } - - /// - /// Gets or sets a value indicating whether to write the root JSON object. - /// - /// true if the JSON root object is omitted; otherwise, false. - public bool OmitRootObject { get; set; } - - #region Writing - /// - /// Writes the JSON representation of the object. - /// - /// The to write to. - /// The calling serializer. - /// The value. - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + public class XmlNodeConverter : JsonConverter { - IXmlNode node = WrapXml(value); + private const string TextName = "#text"; + private const string CommentName = "#comment"; + private const string CDataName = "#cdata-section"; + private const string WhitespaceName = "#whitespace"; + private const string SignificantWhitespaceName = "#significant-whitespace"; + private const string DeclarationName = "?xml"; + private const string JsonNamespaceUri = "http://james.newtonking.com/projects/json"; - XmlNamespaceManager manager = new XmlNamespaceManager(new NameTable()); - PushParentNamespaces(node, manager); + /// + /// Gets or sets the name of the root element to insert when deserializing to XML if the JSON structure has produces multiple root elements. + /// + /// The name of the deserialize root element. + public string DeserializeRootElementName { get; set; } - if (!OmitRootObject) - writer.WriteStartObject(); + /// + /// Gets or sets a flag to indicate whether to write the Json.NET array attribute. + /// This attribute helps preserve arrays when converting the written XML back to JSON. + /// + /// true if the array attibute is written to the XML; otherwise, false. + public bool WriteArrayAttribute { get; set; } - SerializeNode(writer, node, manager, !OmitRootObject); - - if (!OmitRootObject) - writer.WriteEndObject(); - } + /// + /// Gets or sets a value indicating whether to write the root JSON object. + /// + /// true if the JSON root object is omitted; otherwise, false. + public bool OmitRootObject { get; set; } - private IXmlNode WrapXml(object value) - { + #region Writing + /// + /// Writes the JSON representation of the object. + /// + /// The to write to. + /// The calling serializer. + /// The value. + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + IXmlNode node = WrapXml(value); + + XmlNamespaceManager manager = new XmlNamespaceManager(new NameTable()); + PushParentNamespaces(node, manager); + + if (!OmitRootObject) + writer.WriteStartObject(); + + SerializeNode(writer, node, manager, !OmitRootObject); + + if (!OmitRootObject) + writer.WriteEndObject(); + } + + private IXmlNode WrapXml(object value) + { #if !NET20 - if (value is XObject) - return XContainerWrapper.WrapNode((XObject)value); + if (value is XObject) + return XContainerWrapper.WrapNode((XObject)value); #endif #if !(SILVERLIGHT || NETFX_CORE || PORTABLE) - if (value is XmlNode) - return new XmlNodeWrapper((XmlNode)value); + if (value is XmlNode) + return new XmlNodeWrapper((XmlNode)value); #endif - - throw new ArgumentException("Value must be an XML object.", "value"); - } - private void PushParentNamespaces(IXmlNode node, XmlNamespaceManager manager) - { - List parentElements = null; - - IXmlNode parent = node; - while ((parent = parent.ParentNode) != null) - { - if (parent.NodeType == XmlNodeType.Element) - { - if (parentElements == null) - parentElements = new List(); - - parentElements.Add(parent); - } - } - - if (parentElements != null) - { - parentElements.Reverse(); - - foreach (IXmlNode parentElement in parentElements) - { - manager.PushScope(); - foreach (IXmlNode attribute in parentElement.Attributes) - { - if (attribute.NamespaceUri == "http://www.w3.org/2000/xmlns/" && attribute.LocalName != "xmlns") - manager.AddNamespace(attribute.LocalName, attribute.Value); - } - } - } - } - - private string ResolveFullName(IXmlNode node, XmlNamespaceManager manager) - { - string prefix = (node.NamespaceUri == null || (node.LocalName == "xmlns" && node.NamespaceUri == "http://www.w3.org/2000/xmlns/")) - ? null - : manager.LookupPrefix(node.NamespaceUri); - - if (!string.IsNullOrEmpty(prefix)) - return prefix + ":" + node.LocalName; - else - return node.LocalName; - } - - private string GetPropertyName(IXmlNode node, XmlNamespaceManager manager) - { - switch (node.NodeType) - { - case XmlNodeType.Attribute: - if (node.NamespaceUri == JsonNamespaceUri) - return "$" + node.LocalName; - else - return "@" + ResolveFullName(node, manager); - case XmlNodeType.CDATA: - return CDataName; - case XmlNodeType.Comment: - return CommentName; - case XmlNodeType.Element: - return ResolveFullName(node, manager); - case XmlNodeType.ProcessingInstruction: - return "?" + ResolveFullName(node, manager); - case XmlNodeType.XmlDeclaration: - return DeclarationName; - case XmlNodeType.SignificantWhitespace: - return SignificantWhitespaceName; - case XmlNodeType.Text: - return TextName; - case XmlNodeType.Whitespace: - return WhitespaceName; - default: - throw new JsonSerializationException("Unexpected XmlNodeType when getting node name: " + node.NodeType); - } - } - - private bool IsArray(IXmlNode node) - { - IXmlNode jsonArrayAttribute = (node.Attributes != null) - ? node.Attributes.SingleOrDefault(a => a.LocalName == "Array" && a.NamespaceUri == JsonNamespaceUri) - : null; - - return (jsonArrayAttribute != null && XmlConvert.ToBoolean(jsonArrayAttribute.Value)); - } - - private void SerializeGroupedNodes(JsonWriter writer, IXmlNode node, XmlNamespaceManager manager, bool writePropertyName) - { - // group nodes together by name - Dictionary> nodesGroupedByName = new Dictionary>(); - - for (int i = 0; i < node.ChildNodes.Count; i++) - { - IXmlNode childNode = node.ChildNodes[i]; - string nodeName = GetPropertyName(childNode, manager); - - List nodes; - if (!nodesGroupedByName.TryGetValue(nodeName, out nodes)) - { - nodes = new List(); - nodesGroupedByName.Add(nodeName, nodes); + throw new ArgumentException("Value must be an XML object.", "value"); } - nodes.Add(childNode); - } - - // loop through grouped nodes. write single name instances as normal, - // write multiple names together in an array - foreach (KeyValuePair> nodeNameGroup in nodesGroupedByName) - { - List groupedNodes = nodeNameGroup.Value; - bool writeArray; - - if (groupedNodes.Count == 1) + private void PushParentNamespaces(IXmlNode node, XmlNamespaceManager manager) { - writeArray = IsArray(groupedNodes[0]); - } - else - { - writeArray = true; - } + List parentElements = null; - if (!writeArray) - { - SerializeNode(writer, groupedNodes[0], manager, writePropertyName); - } - else - { - string elementNames = nodeNameGroup.Key; - - if (writePropertyName) - writer.WritePropertyName(elementNames); - - writer.WriteStartArray(); - - for (int i = 0; i < groupedNodes.Count; i++) - { - SerializeNode(writer, groupedNodes[i], manager, false); - } - - writer.WriteEndArray(); - } - } - } - - private void SerializeNode(JsonWriter writer, IXmlNode node, XmlNamespaceManager manager, bool writePropertyName) - { - switch (node.NodeType) - { - case XmlNodeType.Document: - case XmlNodeType.DocumentFragment: - SerializeGroupedNodes(writer, node, manager, writePropertyName); - break; - case XmlNodeType.Element: - if (IsArray(node) && node.ChildNodes.All(n => n.LocalName == node.LocalName) && node.ChildNodes.Count > 0) - { - SerializeGroupedNodes(writer, node, manager, false); - } - else - { - manager.PushScope(); - - foreach (IXmlNode attribute in node.Attributes) + IXmlNode parent = node; + while ((parent = parent.ParentNode) != null) { - if (attribute.NamespaceUri == "http://www.w3.org/2000/xmlns/") - { - string namespacePrefix = (attribute.LocalName != "xmlns") + if (parent.NodeType == XmlNodeType.Element) + { + if (parentElements == null) + parentElements = new List(); + + parentElements.Add(parent); + } + } + + if (parentElements != null) + { + parentElements.Reverse(); + + foreach (IXmlNode parentElement in parentElements) + { + manager.PushScope(); + foreach (IXmlNode attribute in parentElement.Attributes) + { + if (attribute.NamespaceUri == "http://www.w3.org/2000/xmlns/" && attribute.LocalName != "xmlns") + manager.AddNamespace(attribute.LocalName, attribute.Value); + } + } + } + } + + private string ResolveFullName(IXmlNode node, XmlNamespaceManager manager) + { + string prefix = (node.NamespaceUri == null || (node.LocalName == "xmlns" && node.NamespaceUri == "http://www.w3.org/2000/xmlns/")) + ? null + : manager.LookupPrefix(node.NamespaceUri); + + if (!string.IsNullOrEmpty(prefix)) + return prefix + ":" + node.LocalName; + else + return node.LocalName; + } + + private string GetPropertyName(IXmlNode node, XmlNamespaceManager manager) + { + switch (node.NodeType) + { + case XmlNodeType.Attribute: + if (node.NamespaceUri == JsonNamespaceUri) + return "$" + node.LocalName; + else + return "@" + ResolveFullName(node, manager); + case XmlNodeType.CDATA: + return CDataName; + case XmlNodeType.Comment: + return CommentName; + case XmlNodeType.Element: + return ResolveFullName(node, manager); + case XmlNodeType.ProcessingInstruction: + return "?" + ResolveFullName(node, manager); + case XmlNodeType.XmlDeclaration: + return DeclarationName; + case XmlNodeType.SignificantWhitespace: + return SignificantWhitespaceName; + case XmlNodeType.Text: + return TextName; + case XmlNodeType.Whitespace: + return WhitespaceName; + default: + throw new JsonSerializationException("Unexpected XmlNodeType when getting node name: " + node.NodeType); + } + } + + private bool IsArray(IXmlNode node) + { + IXmlNode jsonArrayAttribute = (node.Attributes != null) + ? node.Attributes.SingleOrDefault(a => a.LocalName == "Array" && a.NamespaceUri == JsonNamespaceUri) + : null; + + return (jsonArrayAttribute != null && XmlConvert.ToBoolean(jsonArrayAttribute.Value)); + } + + private void SerializeGroupedNodes(JsonWriter writer, IXmlNode node, XmlNamespaceManager manager, bool writePropertyName) + { + // group nodes together by name + Dictionary> nodesGroupedByName = new Dictionary>(); + + for (int i = 0; i < node.ChildNodes.Count; i++) + { + IXmlNode childNode = node.ChildNodes[i]; + string nodeName = GetPropertyName(childNode, manager); + + List nodes; + if (!nodesGroupedByName.TryGetValue(nodeName, out nodes)) + { + nodes = new List(); + nodesGroupedByName.Add(nodeName, nodes); + } + + nodes.Add(childNode); + } + + // loop through grouped nodes. write single name instances as normal, + // write multiple names together in an array + foreach (KeyValuePair> nodeNameGroup in nodesGroupedByName) + { + List groupedNodes = nodeNameGroup.Value; + bool writeArray; + + if (groupedNodes.Count == 1) + { + writeArray = IsArray(groupedNodes[0]); + } + else + { + writeArray = true; + } + + if (!writeArray) + { + SerializeNode(writer, groupedNodes[0], manager, writePropertyName); + } + else + { + string elementNames = nodeNameGroup.Key; + + if (writePropertyName) + writer.WritePropertyName(elementNames); + + writer.WriteStartArray(); + + for (int i = 0; i < groupedNodes.Count; i++) + { + SerializeNode(writer, groupedNodes[i], manager, false); + } + + writer.WriteEndArray(); + } + } + } + + private void SerializeNode(JsonWriter writer, IXmlNode node, XmlNamespaceManager manager, bool writePropertyName) + { + switch (node.NodeType) + { + case XmlNodeType.Document: + case XmlNodeType.DocumentFragment: + SerializeGroupedNodes(writer, node, manager, writePropertyName); + break; + case XmlNodeType.Element: + if (IsArray(node) && node.ChildNodes.All(n => n.LocalName == node.LocalName) && node.ChildNodes.Count > 0) + { + SerializeGroupedNodes(writer, node, manager, false); + } + else + { + manager.PushScope(); + + foreach (IXmlNode attribute in node.Attributes) + { + if (attribute.NamespaceUri == "http://www.w3.org/2000/xmlns/") + { + string namespacePrefix = (attribute.LocalName != "xmlns") ? attribute.LocalName : string.Empty; - string namespaceUri = attribute.Value; + string namespaceUri = attribute.Value; - manager.AddNamespace(namespacePrefix, namespaceUri); - } + manager.AddNamespace(namespacePrefix, namespaceUri); + } + } + + if (writePropertyName) + writer.WritePropertyName(GetPropertyName(node, manager)); + + if (!ValueAttributes(node.Attributes).Any() && node.ChildNodes.Count == 1 + && node.ChildNodes[0].NodeType == XmlNodeType.Text) + { + // write elements with a single text child as a name value pair + writer.WriteValue(node.ChildNodes[0].Value); + } + else if (node.ChildNodes.Count == 0 && CollectionUtils.IsNullOrEmpty(node.Attributes)) + { + // empty element + writer.WriteNull(); + } + else + { + writer.WriteStartObject(); + + for (int i = 0; i < node.Attributes.Count; i++) + { + SerializeNode(writer, node.Attributes[i], manager, true); + } + + SerializeGroupedNodes(writer, node, manager, true); + + writer.WriteEndObject(); + } + + manager.PopScope(); + } + + break; + case XmlNodeType.Comment: + if (writePropertyName) + writer.WriteComment(node.Value); + break; + case XmlNodeType.Attribute: + case XmlNodeType.Text: + case XmlNodeType.CDATA: + case XmlNodeType.ProcessingInstruction: + case XmlNodeType.Whitespace: + case XmlNodeType.SignificantWhitespace: + if (node.NamespaceUri == "http://www.w3.org/2000/xmlns/" && node.Value == JsonNamespaceUri) + return; + + if (node.NamespaceUri == JsonNamespaceUri) + { + if (node.LocalName == "Array") + return; + } + + if (writePropertyName) + writer.WritePropertyName(GetPropertyName(node, manager)); + writer.WriteValue(node.Value); + break; + case XmlNodeType.XmlDeclaration: + IXmlDeclaration declaration = (IXmlDeclaration)node; + writer.WritePropertyName(GetPropertyName(node, manager)); + writer.WriteStartObject(); + + if (!string.IsNullOrEmpty(declaration.Version)) + { + writer.WritePropertyName("@version"); + writer.WriteValue(declaration.Version); + } + if (!string.IsNullOrEmpty(declaration.Encoding)) + { + writer.WritePropertyName("@encoding"); + writer.WriteValue(declaration.Encoding); + } + if (!string.IsNullOrEmpty(declaration.Standalone)) + { + writer.WritePropertyName("@standalone"); + writer.WriteValue(declaration.Standalone); + } + + writer.WriteEndObject(); + break; + default: + throw new JsonSerializationException("Unexpected XmlNodeType when serializing nodes: " + node.NodeType); } + } + #endregion - if (writePropertyName) - writer.WritePropertyName(GetPropertyName(node, manager)); + #region Reading + /// + /// Reads the JSON representation of the object. + /// + /// The to read from. + /// Type of the object. + /// The existing value of object being read. + /// The calling serializer. + /// The object value. + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.Null) + return null; - if (!ValueAttributes(node.Attributes).Any() && node.ChildNodes.Count == 1 - && node.ChildNodes[0].NodeType == XmlNodeType.Text) + XmlNamespaceManager manager = new XmlNamespaceManager(new NameTable()); + IXmlDocument document = null; + IXmlNode rootNode = null; + +#if !NET20 + if (typeof(XObject).IsAssignableFrom(objectType)) { - // write elements with a single text child as a name value pair - writer.WriteValue(node.ChildNodes[0].Value); + if (objectType != typeof(XDocument) && objectType != typeof(XElement)) + throw new JsonSerializationException("XmlNodeConverter only supports deserializing XDocument or XElement."); + + XDocument d = new XDocument(); + document = new XDocumentWrapper(d); + rootNode = document; } - else if (node.ChildNodes.Count == 0 && CollectionUtils.IsNullOrEmpty(node.Attributes)) +#endif +#if !(SILVERLIGHT || NETFX_CORE || PORTABLE) + if (typeof(XmlNode).IsAssignableFrom(objectType)) { - // empty element - writer.WriteNull(); + if (objectType != typeof(XmlDocument)) + throw new JsonSerializationException("XmlNodeConverter only supports deserializing XmlDocuments"); + + XmlDocument d = new XmlDocument(); + document = new XmlDocumentWrapper(d); + rootNode = document; + } +#endif + + if (document == null || rootNode == null) + throw new JsonSerializationException("Unexpected type when converting XML: " + objectType); + + if (reader.TokenType != JsonToken.StartObject) + throw new JsonSerializationException("XmlNodeConverter can only convert JSON that begins with an object."); + + if (!string.IsNullOrEmpty(DeserializeRootElementName)) + { + //rootNode = document.CreateElement(DeserializeRootElementName); + //document.AppendChild(rootNode); + ReadElement(reader, document, rootNode, DeserializeRootElementName, manager); } else { - writer.WriteStartObject(); - - for (int i = 0; i < node.Attributes.Count; i++) - { - SerializeNode(writer, node.Attributes[i], manager, true); - } - - SerializeGroupedNodes(writer, node, manager, true); - - writer.WriteEndObject(); + reader.Read(); + DeserializeNode(reader, document, manager, rootNode); } - manager.PopScope(); - } - - break; - case XmlNodeType.Comment: - if (writePropertyName) - writer.WriteComment(node.Value); - break; - case XmlNodeType.Attribute: - case XmlNodeType.Text: - case XmlNodeType.CDATA: - case XmlNodeType.ProcessingInstruction: - case XmlNodeType.Whitespace: - case XmlNodeType.SignificantWhitespace: - if (node.NamespaceUri == "http://www.w3.org/2000/xmlns/" && node.Value == JsonNamespaceUri) - return; - - if (node.NamespaceUri == JsonNamespaceUri) - { - if (node.LocalName == "Array") - return; - } - - if (writePropertyName) - writer.WritePropertyName(GetPropertyName(node, manager)); - writer.WriteValue(node.Value); - break; - case XmlNodeType.XmlDeclaration: - IXmlDeclaration declaration = (IXmlDeclaration)node; - writer.WritePropertyName(GetPropertyName(node, manager)); - writer.WriteStartObject(); - - if (!string.IsNullOrEmpty(declaration.Version)) - { - writer.WritePropertyName("@version"); - writer.WriteValue(declaration.Version); - } - if (!string.IsNullOrEmpty(declaration.Encoding)) - { - writer.WritePropertyName("@encoding"); - writer.WriteValue(declaration.Encoding); - } - if (!string.IsNullOrEmpty(declaration.Standalone)) - { - writer.WritePropertyName("@standalone"); - writer.WriteValue(declaration.Standalone); - } - - writer.WriteEndObject(); - break; - default: - throw new JsonSerializationException("Unexpected XmlNodeType when serializing nodes: " + node.NodeType); - } - } - #endregion - - #region Reading - /// - /// Reads the JSON representation of the object. - /// - /// The to read from. - /// Type of the object. - /// The existing value of object being read. - /// The calling serializer. - /// The object value. - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - if (reader.TokenType == JsonToken.Null) - return null; - - XmlNamespaceManager manager = new XmlNamespaceManager(new NameTable()); - IXmlDocument document = null; - IXmlNode rootNode = null; - #if !NET20 - if (typeof(XObject).IsAssignableFrom(objectType)) - { - if (objectType != typeof (XDocument) && objectType != typeof (XElement)) - throw new JsonSerializationException("XmlNodeConverter only supports deserializing XDocument or XElement."); - - XDocument d = new XDocument(); - document = new XDocumentWrapper(d); - rootNode = document; - } -#endif -#if !(SILVERLIGHT || NETFX_CORE || PORTABLE) - if (typeof(XmlNode).IsAssignableFrom(objectType)) - { - if (objectType != typeof (XmlDocument)) - throw new JsonSerializationException("XmlNodeConverter only supports deserializing XmlDocuments"); - - XmlDocument d = new XmlDocument(); - document = new XmlDocumentWrapper(d); - rootNode = document; - } -#endif - - if (document == null || rootNode == null) - throw new JsonSerializationException("Unexpected type when converting XML: " + objectType); - - if (reader.TokenType != JsonToken.StartObject) - throw new JsonSerializationException("XmlNodeConverter can only convert JSON that begins with an object."); - - if (!string.IsNullOrEmpty(DeserializeRootElementName)) - { - //rootNode = document.CreateElement(DeserializeRootElementName); - //document.AppendChild(rootNode); - ReadElement(reader, document, rootNode, DeserializeRootElementName, manager); - } - else - { - reader.Read(); - DeserializeNode(reader, document, manager, rootNode); - } - -#if !NET20 - if (objectType == typeof(XElement)) - { - XElement element = (XElement)document.DocumentElement.WrappedNode; - element.Remove(); - - return element; - } -#endif - - return document.WrappedNode; - } - - private void DeserializeValue(JsonReader reader, IXmlDocument document, XmlNamespaceManager manager, string propertyName, IXmlNode currentNode) - { - switch (propertyName) - { - case TextName: - currentNode.AppendChild(document.CreateTextNode(reader.Value.ToString())); - break; - case CDataName: - currentNode.AppendChild(document.CreateCDataSection(reader.Value.ToString())); - break; - case WhitespaceName: - currentNode.AppendChild(document.CreateWhitespace(reader.Value.ToString())); - break; - case SignificantWhitespaceName: - currentNode.AppendChild(document.CreateSignificantWhitespace(reader.Value.ToString())); - break; - default: - // processing instructions and the xml declaration start with ? - if (!string.IsNullOrEmpty(propertyName) && propertyName[0] == '?') - { - CreateInstruction(reader, document, currentNode, propertyName); - } - else - { - if (reader.TokenType == JsonToken.StartArray) + if (objectType == typeof(XElement)) { - // handle nested arrays - ReadArrayElements(reader, document, propertyName, currentNode, manager); - return; + XElement element = (XElement)document.DocumentElement.WrappedNode; + element.Remove(); + + return element; } +#endif - // have to wait until attributes have been parsed before creating element - // attributes may contain namespace info used by the element - ReadElement(reader, document, currentNode, propertyName, manager); - } - break; - } - } - - private void ReadElement(JsonReader reader, IXmlDocument document, IXmlNode currentNode, string propertyName, XmlNamespaceManager manager) - { - if (string.IsNullOrEmpty(propertyName)) - throw new JsonSerializationException("XmlNodeConverter cannot convert JSON with an empty property name to XML."); - - Dictionary attributeNameValues = ReadAttributeElements(reader, manager); - - string elementPrefix = MiscellaneousUtils.GetPrefix(propertyName); - - if (propertyName.StartsWith("@")) - { - var attributeName = propertyName.Substring(1); - var attributeValue = reader.Value.ToString(); - - var attributePrefix = MiscellaneousUtils.GetPrefix(attributeName); - - var attribute = (!string.IsNullOrEmpty(attributePrefix)) - ? document.CreateAttribute(attributeName, manager.LookupNamespace(attributePrefix), attributeValue) - : document.CreateAttribute(attributeName, attributeValue); - - ((IXmlElement)currentNode).SetAttributeNode(attribute); - } - else - { - IXmlElement element = CreateElement(propertyName, document, elementPrefix, manager); - - currentNode.AppendChild(element); - - // add attributes to newly created element - foreach (KeyValuePair nameValue in attributeNameValues) - { - string attributePrefix = MiscellaneousUtils.GetPrefix(nameValue.Key); - - IXmlNode attribute = (!string.IsNullOrEmpty(attributePrefix)) - ? document.CreateAttribute(nameValue.Key, manager.LookupNamespace(attributePrefix), nameValue.Value) - : document.CreateAttribute(nameValue.Key, nameValue.Value); - - element.SetAttributeNode(attribute); + return document.WrappedNode; } - if (reader.TokenType == JsonToken.String - || reader.TokenType == JsonToken.Integer - || reader.TokenType == JsonToken.Float - || reader.TokenType == JsonToken.Boolean - || reader.TokenType == JsonToken.Date) + private void DeserializeValue(JsonReader reader, IXmlDocument document, XmlNamespaceManager manager, string propertyName, IXmlNode currentNode) { - element.AppendChild(document.CreateTextNode(ConvertTokenToXmlValue(reader))); + switch (propertyName) + { + case TextName: + currentNode.AppendChild(document.CreateTextNode(reader.Value.ToString())); + break; + case CDataName: + currentNode.AppendChild(document.CreateCDataSection(reader.Value.ToString())); + break; + case WhitespaceName: + currentNode.AppendChild(document.CreateWhitespace(reader.Value.ToString())); + break; + case SignificantWhitespaceName: + currentNode.AppendChild(document.CreateSignificantWhitespace(reader.Value.ToString())); + break; + default: + // processing instructions and the xml declaration start with ? + if (!string.IsNullOrEmpty(propertyName) && propertyName[0] == '?') + { + CreateInstruction(reader, document, currentNode, propertyName); + } + else + { + if (reader.TokenType == JsonToken.StartArray) + { + // handle nested arrays + ReadArrayElements(reader, document, propertyName, currentNode, manager); + return; + } + + // have to wait until attributes have been parsed before creating element + // attributes may contain namespace info used by the element + ReadElement(reader, document, currentNode, propertyName, manager); + } + break; + } } - else if (reader.TokenType == JsonToken.Null) + + private void ReadElement(JsonReader reader, IXmlDocument document, IXmlNode currentNode, string propertyName, XmlNamespaceManager manager) { - // empty element. do nothing + if (string.IsNullOrEmpty(propertyName)) + throw new JsonSerializationException("XmlNodeConverter cannot convert JSON with an empty property name to XML."); + + Dictionary attributeNameValues = ReadAttributeElements(reader, manager); + + string elementPrefix = MiscellaneousUtils.GetPrefix(propertyName); + + if (propertyName.StartsWith("@")) + { + var attributeName = propertyName.Substring(1); + var attributeValue = reader.Value.ToString(); + + var attributePrefix = MiscellaneousUtils.GetPrefix(attributeName); + + var attribute = (!string.IsNullOrEmpty(attributePrefix)) + ? document.CreateAttribute(attributeName, manager.LookupNamespace(attributePrefix), attributeValue) + : document.CreateAttribute(attributeName, attributeValue); + + ((IXmlElement)currentNode).SetAttributeNode(attribute); + } + else + { + IXmlElement element = CreateElement(propertyName, document, elementPrefix, manager); + + currentNode.AppendChild(element); + + // add attributes to newly created element + foreach (KeyValuePair nameValue in attributeNameValues) + { + string attributePrefix = MiscellaneousUtils.GetPrefix(nameValue.Key); + + IXmlNode attribute = (!string.IsNullOrEmpty(attributePrefix)) + ? document.CreateAttribute(nameValue.Key, manager.LookupNamespace(attributePrefix), nameValue.Value) + : document.CreateAttribute(nameValue.Key, nameValue.Value); + + element.SetAttributeNode(attribute); + } + + if (reader.TokenType == JsonToken.String + || reader.TokenType == JsonToken.Integer + || reader.TokenType == JsonToken.Float + || reader.TokenType == JsonToken.Boolean + || reader.TokenType == JsonToken.Date) + { + element.AppendChild(document.CreateTextNode(ConvertTokenToXmlValue(reader))); + } + else if (reader.TokenType == JsonToken.Null) + { + // empty element. do nothing + } + else + { + // finished element will have no children to deserialize + if (reader.TokenType != JsonToken.EndObject) + { + manager.PushScope(); + + DeserializeNode(reader, document, manager, element); + + manager.PopScope(); + } + } + } } - else + + private string ConvertTokenToXmlValue(JsonReader reader) { - // finished element will have no children to deserialize - if (reader.TokenType != JsonToken.EndObject) - { - manager.PushScope(); - - DeserializeNode(reader, document, manager, element); - - manager.PopScope(); - } - } - } - } - - private string ConvertTokenToXmlValue(JsonReader reader) - { - if (reader.TokenType == JsonToken.String) - { - return reader.Value.ToString(); - } - else if (reader.TokenType == JsonToken.Integer) - { - return XmlConvert.ToString(Convert.ToInt64(reader.Value, CultureInfo.InvariantCulture)); - } - else if (reader.TokenType == JsonToken.Float) - { - return XmlConvert.ToString(Convert.ToDouble(reader.Value, CultureInfo.InvariantCulture)); - } - else if (reader.TokenType == JsonToken.Boolean) - { - return XmlConvert.ToString(Convert.ToBoolean(reader.Value, CultureInfo.InvariantCulture)); - } - else if (reader.TokenType == JsonToken.Date) - { - DateTime d = Convert.ToDateTime(reader.Value, CultureInfo.InvariantCulture); + if (reader.TokenType == JsonToken.String) + { + return reader.Value.ToString(); + } + else if (reader.TokenType == JsonToken.Integer) + { + return XmlConvert.ToString(Convert.ToInt64(reader.Value, CultureInfo.InvariantCulture)); + } + else if (reader.TokenType == JsonToken.Float) + { + return XmlConvert.ToString(Convert.ToDouble(reader.Value, CultureInfo.InvariantCulture)); + } + else if (reader.TokenType == JsonToken.Boolean) + { + return XmlConvert.ToString(Convert.ToBoolean(reader.Value, CultureInfo.InvariantCulture)); + } + else if (reader.TokenType == JsonToken.Date) + { + DateTime d = Convert.ToDateTime(reader.Value, CultureInfo.InvariantCulture); #if !(NETFX_CORE || PORTABLE) - return XmlConvert.ToString(d, DateTimeUtils.ToSerializationMode(d.Kind)); + return XmlConvert.ToString(d, DateTimeUtils.ToSerializationMode(d.Kind)); #else return XmlConvert.ToString(d); -#endif - } - else if (reader.TokenType == JsonToken.Null) - { - return null; - } - else - { - throw JsonSerializationException.Create(reader, "Cannot get an XML string value from token type '{0}'.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); - } - } - - private void ReadArrayElements(JsonReader reader, IXmlDocument document, string propertyName, IXmlNode currentNode, XmlNamespaceManager manager) - { - string elementPrefix = MiscellaneousUtils.GetPrefix(propertyName); - - IXmlElement nestedArrayElement = CreateElement(propertyName, document, elementPrefix, manager); - - currentNode.AppendChild(nestedArrayElement); - - int count = 0; - while (reader.Read() && reader.TokenType != JsonToken.EndArray) - { - DeserializeValue(reader, document, manager, propertyName, nestedArrayElement); - count++; - } - - if (WriteArrayAttribute) - { - AddJsonArrayAttribute(nestedArrayElement, document); - } - - if (count == 1 && WriteArrayAttribute) - { - IXmlElement arrayElement = nestedArrayElement.ChildNodes.OfType().Single(n => n.LocalName == propertyName); - AddJsonArrayAttribute(arrayElement, document); - } - } - - private void AddJsonArrayAttribute(IXmlElement element, IXmlDocument document) - { - element.SetAttributeNode(document.CreateAttribute("json:Array", JsonNamespaceUri, "true")); - -#if !NET20 - // linq to xml doesn't automatically include prefixes via the namespace manager - if (element is XElementWrapper) - { - if (element.GetPrefixOfNamespace(JsonNamespaceUri) == null) - { - element.SetAttributeNode(document.CreateAttribute("xmlns:json", "http://www.w3.org/2000/xmlns/", JsonNamespaceUri)); - } - } #endif - } - - private Dictionary ReadAttributeElements(JsonReader reader, XmlNamespaceManager manager) - { - Dictionary attributeNameValues = new Dictionary(); - bool finishedAttributes = false; - bool finishedElement = false; - - // a string token means the element only has a single text child - if (reader.TokenType != JsonToken.String - && reader.TokenType != JsonToken.Null - && reader.TokenType != JsonToken.Boolean - && reader.TokenType != JsonToken.Integer - && reader.TokenType != JsonToken.Float - && reader.TokenType != JsonToken.Date - && reader.TokenType != JsonToken.StartConstructor) - { - // read properties until first non-attribute is encountered - while (!finishedAttributes && !finishedElement && reader.Read()) - { - switch (reader.TokenType) - { - case JsonToken.PropertyName: - string attributeName = reader.Value.ToString(); - - if (!string.IsNullOrEmpty(attributeName)) - { - char firstChar = attributeName[0]; - string attributeValue; - - switch (firstChar) - { - case '@': - attributeName = attributeName.Substring(1); - reader.Read(); - attributeValue = ConvertTokenToXmlValue(reader); - attributeNameValues.Add(attributeName, attributeValue); - - string namespacePrefix; - if (IsNamespaceAttribute(attributeName, out namespacePrefix)) - { - manager.AddNamespace(namespacePrefix, attributeValue); - } - break; - case '$': - attributeName = attributeName.Substring(1); - reader.Read(); - attributeValue = reader.Value.ToString(); - - // check that JsonNamespaceUri is in scope - // if it isn't then add it to document and namespace manager - string jsonPrefix = manager.LookupPrefix(JsonNamespaceUri); - if (jsonPrefix == null) - { - // ensure that the prefix used is free - int? i = null; - while (manager.LookupNamespace("json" + i) != null) - { - i = i.GetValueOrDefault() + 1; - } - jsonPrefix = "json" + i; - - attributeNameValues.Add("xmlns:" + jsonPrefix, JsonNamespaceUri); - manager.AddNamespace(jsonPrefix, JsonNamespaceUri); - } - - attributeNameValues.Add(jsonPrefix + ":" + attributeName, attributeValue); - break; - default: - finishedAttributes = true; - break; - } - } - else - { - finishedAttributes = true; - } - - break; - case JsonToken.EndObject: - finishedElement = true; - break; - default: - throw new JsonSerializationException("Unexpected JsonToken: " + reader.TokenType); - } - } - } - - return attributeNameValues; - } - - private void CreateInstruction(JsonReader reader, IXmlDocument document, IXmlNode currentNode, string propertyName) - { - if (propertyName == DeclarationName) - { - string version = null; - string encoding = null; - string standalone = null; - while (reader.Read() && reader.TokenType != JsonToken.EndObject) - { - switch (reader.Value.ToString()) - { - case "@version": - reader.Read(); - version = reader.Value.ToString(); - break; - case "@encoding": - reader.Read(); - encoding = reader.Value.ToString(); - break; - case "@standalone": - reader.Read(); - standalone = reader.Value.ToString(); - break; - default: - throw new JsonSerializationException("Unexpected property name encountered while deserializing XmlDeclaration: " + reader.Value); - } - } - - IXmlNode declaration = document.CreateXmlDeclaration(version, encoding, standalone); - currentNode.AppendChild(declaration); - } - else - { - IXmlNode instruction = document.CreateProcessingInstruction(propertyName.Substring(1), reader.Value.ToString()); - currentNode.AppendChild(instruction); - } - } - - private IXmlElement CreateElement(string elementName, IXmlDocument document, string elementPrefix, XmlNamespaceManager manager) - { - string ns = string.IsNullOrEmpty(elementPrefix) ? manager.DefaultNamespace : manager.LookupNamespace(elementPrefix); - - IXmlElement element = (!string.IsNullOrEmpty(ns)) ? document.CreateElement(elementName, ns) : document.CreateElement(elementName); - - return element; - } - - private void DeserializeNode(JsonReader reader, IXmlDocument document, XmlNamespaceManager manager, IXmlNode currentNode) - { - do - { - switch (reader.TokenType) - { - case JsonToken.PropertyName: - if (currentNode.NodeType == XmlNodeType.Document && document.DocumentElement != null) - throw new JsonSerializationException("JSON root object has multiple properties. The root object must have a single property in order to create a valid XML document. Consider specifing a DeserializeRootElementName."); - - string propertyName = reader.Value.ToString(); - reader.Read(); - - if (reader.TokenType == JsonToken.StartArray) + } + else if (reader.TokenType == JsonToken.Null) { - int count = 0; - while (reader.Read() && reader.TokenType != JsonToken.EndArray) - { - DeserializeValue(reader, document, manager, propertyName, currentNode); - count++; - } - - if (count == 1 && WriteArrayAttribute) - { - IXmlElement arrayElement = currentNode.ChildNodes.OfType().Single(n => n.LocalName == propertyName); - AddJsonArrayAttribute(arrayElement, document); - } + return null; } else { - DeserializeValue(reader, document, manager, propertyName, currentNode); + throw JsonSerializationException.Create(reader, "Cannot get an XML string value from token type '{0}'.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); } - break; - case JsonToken.StartConstructor: - string constructorName = reader.Value.ToString(); + } - while (reader.Read() && reader.TokenType != JsonToken.EndConstructor) + private void ReadArrayElements(JsonReader reader, IXmlDocument document, string propertyName, IXmlNode currentNode, XmlNamespaceManager manager) + { + string elementPrefix = MiscellaneousUtils.GetPrefix(propertyName); + + IXmlElement nestedArrayElement = CreateElement(propertyName, document, elementPrefix, manager); + + currentNode.AppendChild(nestedArrayElement); + + int count = 0; + while (reader.Read() && reader.TokenType != JsonToken.EndArray) { - DeserializeValue(reader, document, manager, constructorName, currentNode); + DeserializeValue(reader, document, manager, propertyName, nestedArrayElement); + count++; } - break; - case JsonToken.Comment: - currentNode.AppendChild(document.CreateComment((string)reader.Value)); - break; - case JsonToken.EndObject: - case JsonToken.EndArray: - return; - default: - throw new JsonSerializationException("Unexpected JsonToken when deserializing node: " + reader.TokenType); - } - } while (reader.TokenType == JsonToken.PropertyName || reader.Read()); - // don't read if current token is a property. token was already read when parsing element attributes - } - /// - /// Checks if the attributeName is a namespace attribute. - /// - /// Attribute name to test. - /// The attribute name prefix if it has one, otherwise an empty string. - /// True if attribute name is for a namespace attribute, otherwise false. - private bool IsNamespaceAttribute(string attributeName, out string prefix) - { - if (attributeName.StartsWith("xmlns", StringComparison.Ordinal)) - { - if (attributeName.Length == 5) + if (WriteArrayAttribute) + { + AddJsonArrayAttribute(nestedArrayElement, document); + } + + if (count == 1 && WriteArrayAttribute) + { + IXmlElement arrayElement = nestedArrayElement.ChildNodes.OfType().Single(n => n.LocalName == propertyName); + AddJsonArrayAttribute(arrayElement, document); + } + } + + private void AddJsonArrayAttribute(IXmlElement element, IXmlDocument document) { - prefix = string.Empty; - return true; - } - else if (attributeName[5] == ':') - { - prefix = attributeName.Substring(6, attributeName.Length - 6); - return true; - } - } - prefix = null; - return false; - } + element.SetAttributeNode(document.CreateAttribute("json:Array", JsonNamespaceUri, "true")); - private IEnumerable ValueAttributes(IEnumerable c) - { - return c.Where(a => a.NamespaceUri != JsonNamespaceUri); - } - #endregion - - /// - /// Determines whether this instance can convert the specified value type. - /// - /// Type of the value. - /// - /// true if this instance can convert the specified value type; otherwise, false. - /// - public override bool CanConvert(Type valueType) - { #if !NET20 - if (typeof(XObject).IsAssignableFrom(valueType)) - return true; + // linq to xml doesn't automatically include prefixes via the namespace manager + if (element is XElementWrapper) + { + if (element.GetPrefixOfNamespace(JsonNamespaceUri) == null) + { + element.SetAttributeNode(document.CreateAttribute("xmlns:json", "http://www.w3.org/2000/xmlns/", JsonNamespaceUri)); + } + } +#endif + } + + private Dictionary ReadAttributeElements(JsonReader reader, XmlNamespaceManager manager) + { + Dictionary attributeNameValues = new Dictionary(); + bool finishedAttributes = false; + bool finishedElement = false; + + // a string token means the element only has a single text child + if (reader.TokenType != JsonToken.String + && reader.TokenType != JsonToken.Null + && reader.TokenType != JsonToken.Boolean + && reader.TokenType != JsonToken.Integer + && reader.TokenType != JsonToken.Float + && reader.TokenType != JsonToken.Date + && reader.TokenType != JsonToken.StartConstructor) + { + // read properties until first non-attribute is encountered + while (!finishedAttributes && !finishedElement && reader.Read()) + { + switch (reader.TokenType) + { + case JsonToken.PropertyName: + string attributeName = reader.Value.ToString(); + + if (!string.IsNullOrEmpty(attributeName)) + { + char firstChar = attributeName[0]; + string attributeValue; + + switch (firstChar) + { + case '@': + attributeName = attributeName.Substring(1); + reader.Read(); + attributeValue = ConvertTokenToXmlValue(reader); + attributeNameValues.Add(attributeName, attributeValue); + + string namespacePrefix; + if (IsNamespaceAttribute(attributeName, out namespacePrefix)) + { + manager.AddNamespace(namespacePrefix, attributeValue); + } + break; + case '$': + attributeName = attributeName.Substring(1); + reader.Read(); + attributeValue = reader.Value.ToString(); + + // check that JsonNamespaceUri is in scope + // if it isn't then add it to document and namespace manager + string jsonPrefix = manager.LookupPrefix(JsonNamespaceUri); + if (jsonPrefix == null) + { + // ensure that the prefix used is free + int? i = null; + while (manager.LookupNamespace("json" + i) != null) + { + i = i.GetValueOrDefault() + 1; + } + jsonPrefix = "json" + i; + + attributeNameValues.Add("xmlns:" + jsonPrefix, JsonNamespaceUri); + manager.AddNamespace(jsonPrefix, JsonNamespaceUri); + } + + attributeNameValues.Add(jsonPrefix + ":" + attributeName, attributeValue); + break; + default: + finishedAttributes = true; + break; + } + } + else + { + finishedAttributes = true; + } + + break; + case JsonToken.EndObject: + finishedElement = true; + break; + default: + throw new JsonSerializationException("Unexpected JsonToken: " + reader.TokenType); + } + } + } + + return attributeNameValues; + } + + private void CreateInstruction(JsonReader reader, IXmlDocument document, IXmlNode currentNode, string propertyName) + { + if (propertyName == DeclarationName) + { + string version = null; + string encoding = null; + string standalone = null; + while (reader.Read() && reader.TokenType != JsonToken.EndObject) + { + switch (reader.Value.ToString()) + { + case "@version": + reader.Read(); + version = reader.Value.ToString(); + break; + case "@encoding": + reader.Read(); + encoding = reader.Value.ToString(); + break; + case "@standalone": + reader.Read(); + standalone = reader.Value.ToString(); + break; + default: + throw new JsonSerializationException("Unexpected property name encountered while deserializing XmlDeclaration: " + reader.Value); + } + } + + IXmlNode declaration = document.CreateXmlDeclaration(version, encoding, standalone); + currentNode.AppendChild(declaration); + } + else + { + IXmlNode instruction = document.CreateProcessingInstruction(propertyName.Substring(1), reader.Value.ToString()); + currentNode.AppendChild(instruction); + } + } + + private IXmlElement CreateElement(string elementName, IXmlDocument document, string elementPrefix, XmlNamespaceManager manager) + { + string ns = string.IsNullOrEmpty(elementPrefix) ? manager.DefaultNamespace : manager.LookupNamespace(elementPrefix); + + IXmlElement element = (!string.IsNullOrEmpty(ns)) ? document.CreateElement(elementName, ns) : document.CreateElement(elementName); + + return element; + } + + private void DeserializeNode(JsonReader reader, IXmlDocument document, XmlNamespaceManager manager, IXmlNode currentNode) + { + do + { + switch (reader.TokenType) + { + case JsonToken.PropertyName: + if (currentNode.NodeType == XmlNodeType.Document && document.DocumentElement != null) + throw new JsonSerializationException("JSON root object has multiple properties. The root object must have a single property in order to create a valid XML document. Consider specifing a DeserializeRootElementName."); + + string propertyName = reader.Value.ToString(); + reader.Read(); + + if (reader.TokenType == JsonToken.StartArray) + { + int count = 0; + while (reader.Read() && reader.TokenType != JsonToken.EndArray) + { + DeserializeValue(reader, document, manager, propertyName, currentNode); + count++; + } + + if (count == 1 && WriteArrayAttribute) + { + IXmlElement arrayElement = currentNode.ChildNodes.OfType().Single(n => n.LocalName == propertyName); + AddJsonArrayAttribute(arrayElement, document); + } + } + else + { + DeserializeValue(reader, document, manager, propertyName, currentNode); + } + break; + case JsonToken.StartConstructor: + string constructorName = reader.Value.ToString(); + + while (reader.Read() && reader.TokenType != JsonToken.EndConstructor) + { + DeserializeValue(reader, document, manager, constructorName, currentNode); + } + break; + case JsonToken.Comment: + currentNode.AppendChild(document.CreateComment((string)reader.Value)); + break; + case JsonToken.EndObject: + case JsonToken.EndArray: + return; + default: + throw new JsonSerializationException("Unexpected JsonToken when deserializing node: " + reader.TokenType); + } + } while (reader.TokenType == JsonToken.PropertyName || reader.Read()); + // don't read if current token is a property. token was already read when parsing element attributes + } + + /// + /// Checks if the attributeName is a namespace attribute. + /// + /// Attribute name to test. + /// The attribute name prefix if it has one, otherwise an empty string. + /// True if attribute name is for a namespace attribute, otherwise false. + private bool IsNamespaceAttribute(string attributeName, out string prefix) + { + if (attributeName.StartsWith("xmlns", StringComparison.Ordinal)) + { + if (attributeName.Length == 5) + { + prefix = string.Empty; + return true; + } + else if (attributeName[5] == ':') + { + prefix = attributeName.Substring(6, attributeName.Length - 6); + return true; + } + } + prefix = null; + return false; + } + + private IEnumerable ValueAttributes(IEnumerable c) + { + return c.Where(a => a.NamespaceUri != JsonNamespaceUri); + } + #endregion + + /// + /// Determines whether this instance can convert the specified value type. + /// + /// Type of the value. + /// + /// true if this instance can convert the specified value type; otherwise, false. + /// + public override bool CanConvert(Type valueType) + { +#if !NET20 + if (typeof(XObject).IsAssignableFrom(valueType)) + return true; #endif #if !(SILVERLIGHT || NETFX_CORE || PORTABLE) - if (typeof(XmlNode).IsAssignableFrom(valueType)) - return true; + if (typeof(XmlNode).IsAssignableFrom(valueType)) + return true; #endif - return false; + return false; + } } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json/DateFormatHandling.cs b/Src/Newtonsoft.Json/DateFormatHandling.cs index 428dcac1..e26feec3 100644 --- a/Src/Newtonsoft.Json/DateFormatHandling.cs +++ b/Src/Newtonsoft.Json/DateFormatHandling.cs @@ -25,18 +25,19 @@ namespace Newtonsoft.Json { - /// - /// Specifies how dates are formatted when writing JSON text. - /// - public enum DateFormatHandling - { /// - /// Dates are written in the ISO 8601 format, e.g. "2012-03-21T05:40Z". + /// Specifies how dates are formatted when writing JSON text. /// - IsoDateFormat, - /// - /// Dates are written in the Microsoft JSON format, e.g. "\/Date(1198908717056)\/". - /// - MicrosoftDateFormat - } + public enum DateFormatHandling + { + /// + /// Dates are written in the ISO 8601 format, e.g. "2012-03-21T05:40Z". + /// + IsoDateFormat, + + /// + /// Dates are written in the Microsoft JSON format, e.g. "\/Date(1198908717056)\/". + /// + MicrosoftDateFormat + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/DateParseHandling.cs b/Src/Newtonsoft.Json/DateParseHandling.cs index 225ff372..84abaf56 100644 --- a/Src/Newtonsoft.Json/DateParseHandling.cs +++ b/Src/Newtonsoft.Json/DateParseHandling.cs @@ -25,24 +25,25 @@ namespace Newtonsoft.Json { - /// - /// Specifies how date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed when reading JSON text. - /// - public enum DateParseHandling - { /// - /// Date formatted strings are not parsed to a date type and are read as strings. + /// Specifies how date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed when reading JSON text. /// - None, - /// - /// Date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed to . - /// - DateTime, + public enum DateParseHandling + { + /// + /// Date formatted strings are not parsed to a date type and are read as strings. + /// + None, + + /// + /// Date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed to . + /// + DateTime, #if !NET20 - /// - /// Date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed to . - /// - DateTimeOffset + /// + /// Date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed to . + /// + DateTimeOffset #endif - } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/DateTimeZoneHandling.cs b/Src/Newtonsoft.Json/DateTimeZoneHandling.cs index 79ec22b3..df889089 100644 --- a/Src/Newtonsoft.Json/DateTimeZoneHandling.cs +++ b/Src/Newtonsoft.Json/DateTimeZoneHandling.cs @@ -27,27 +27,30 @@ using System; namespace Newtonsoft.Json { - /// - /// Specifies how to treat the time value when converting between string and . - /// - public enum DateTimeZoneHandling - { /// - /// Treat as local time. If the object represents a Coordinated Universal Time (UTC), it is converted to the local time. + /// Specifies how to treat the time value when converting between string and . /// - Local, - /// - /// Treat as a UTC. If the object represents a local time, it is converted to a UTC. - /// - Utc, - /// - /// Treat as a local time if a is being converted to a string. - /// If a string is being converted to , convert to a local time if a time zone is specified. - /// - Unspecified, - /// - /// Time zone information should be preserved when converting. - /// - RoundtripKind - } + public enum DateTimeZoneHandling + { + /// + /// Treat as local time. If the object represents a Coordinated Universal Time (UTC), it is converted to the local time. + /// + Local, + + /// + /// Treat as a UTC. If the object represents a local time, it is converted to a UTC. + /// + Utc, + + /// + /// Treat as a local time if a is being converted to a string. + /// If a string is being converted to , convert to a local time if a time zone is specified. + /// + Unspecified, + + /// + /// Time zone information should be preserved when converting. + /// + RoundtripKind + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/DefaultValueHandling.cs b/Src/Newtonsoft.Json/DefaultValueHandling.cs index e427ed27..8060964f 100644 --- a/Src/Newtonsoft.Json/DefaultValueHandling.cs +++ b/Src/Newtonsoft.Json/DefaultValueHandling.cs @@ -28,37 +28,40 @@ using System.ComponentModel; namespace Newtonsoft.Json { - /// - /// Specifies default value handling options for the . - /// - /// - /// - /// - /// - [Flags] - public enum DefaultValueHandling - { /// - /// Include members where the member value is the same as the member's default value when serializing objects. - /// Included members are written to JSON. Has no effect when deserializing. + /// Specifies default value handling options for the . /// - Include = 0, - /// - /// Ignore members where the member value is the same as the member's default value when serializing objects - /// so that is is not written to JSON. - /// This option will ignore all default values (e.g. null for objects and nullable typesl; 0 for integers, - /// decimals and floating point numbers; and false for booleans). The default value ignored can be changed by - /// placing the on the property. - /// - Ignore = 1, - /// - /// Members with a default value but no JSON will be set to their default value when deserializing. - /// - Populate = 2, - /// - /// Ignore members where the member value is the same as the member's default value when serializing objects - /// and sets members to their default value when deserializing. - /// - IgnoreAndPopulate = Ignore | Populate - } + /// + /// + /// + /// + [Flags] + public enum DefaultValueHandling + { + /// + /// Include members where the member value is the same as the member's default value when serializing objects. + /// Included members are written to JSON. Has no effect when deserializing. + /// + Include = 0, + + /// + /// Ignore members where the member value is the same as the member's default value when serializing objects + /// so that is is not written to JSON. + /// This option will ignore all default values (e.g. null for objects and nullable typesl; 0 for integers, + /// decimals and floating point numbers; and false for booleans). The default value ignored can be changed by + /// placing the on the property. + /// + Ignore = 1, + + /// + /// Members with a default value but no JSON will be set to their default value when deserializing. + /// + Populate = 2, + + /// + /// Ignore members where the member value is the same as the member's default value when serializing objects + /// and sets members to their default value when deserializing. + /// + IgnoreAndPopulate = Ignore | Populate + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/FloatFormatHandling.cs b/Src/Newtonsoft.Json/FloatFormatHandling.cs index 29959482..f39f7cc4 100644 --- a/Src/Newtonsoft.Json/FloatFormatHandling.cs +++ b/Src/Newtonsoft.Json/FloatFormatHandling.cs @@ -25,24 +25,26 @@ namespace Newtonsoft.Json { - /// - /// Specifies float format handling options when writing special floating point numbers, e.g. , - /// and with . - /// - public enum FloatFormatHandling - { /// - /// Write special floating point values as strings in JSON, e.g. "NaN", "Infinity", "-Infinity". + /// Specifies float format handling options when writing special floating point numbers, e.g. , + /// and with . /// - String, - /// - /// Write special floating point values as symbols in JSON, e.g. NaN, Infinity, -Infinity. - /// Note that this will produce non-valid JSON. - /// - Symbol, - /// - /// Write special floating point values as the property's default value in JSON, e.g. 0.0 for a property, null for a property. - /// - DefaultValue - } + public enum FloatFormatHandling + { + /// + /// Write special floating point values as strings in JSON, e.g. "NaN", "Infinity", "-Infinity". + /// + String, + + /// + /// Write special floating point values as symbols in JSON, e.g. NaN, Infinity, -Infinity. + /// Note that this will produce non-valid JSON. + /// + Symbol, + + /// + /// Write special floating point values as the property's default value in JSON, e.g. 0.0 for a property, null for a property. + /// + DefaultValue + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/FloatParseHandling.cs b/Src/Newtonsoft.Json/FloatParseHandling.cs index 72303745..093d6e98 100644 --- a/Src/Newtonsoft.Json/FloatParseHandling.cs +++ b/Src/Newtonsoft.Json/FloatParseHandling.cs @@ -25,18 +25,19 @@ namespace Newtonsoft.Json { - /// - /// Specifies how floating point numbers, e.g. 1.0 and 9.9, are parsed when reading JSON text. - /// - public enum FloatParseHandling - { /// - /// Floating point numbers are parsed to . + /// Specifies how floating point numbers, e.g. 1.0 and 9.9, are parsed when reading JSON text. /// - Double, - /// - /// Floating point numbers are parsed to . - /// - Decimal - } + public enum FloatParseHandling + { + /// + /// Floating point numbers are parsed to . + /// + Double, + + /// + /// Floating point numbers are parsed to . + /// + Decimal + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/FormatterAssemblyStyle.cs b/Src/Newtonsoft.Json/FormatterAssemblyStyle.cs index c2c3e443..541c0a4f 100644 --- a/Src/Newtonsoft.Json/FormatterAssemblyStyle.cs +++ b/Src/Newtonsoft.Json/FormatterAssemblyStyle.cs @@ -1,19 +1,23 @@ -#if SILVERLIGHT || PocketPC || NETFX_CORE || PORTABLE40 || PORTABLE + +#if SILVERLIGHT || PocketPC || NETFX_CORE || PORTABLE40 || PORTABLE + namespace System.Runtime.Serialization.Formatters { - /// - /// Indicates the method that will be used during deserialization for locating and loading assemblies. - /// - public enum FormatterAssemblyStyle - { /// - /// In simple mode, the assembly used during deserialization need not match exactly the assembly used during serialization. Specifically, the version numbers need not match as the LoadWithPartialName method is used to load the assembly. + /// Indicates the method that will be used during deserialization for locating and loading assemblies. /// - Simple, - /// - /// In full mode, the assembly used during deserialization must match exactly the assembly used during serialization. The Load method of the Assembly class is used to load the assembly. - /// - Full - } + public enum FormatterAssemblyStyle + { + /// + /// In simple mode, the assembly used during deserialization need not match exactly the assembly used during serialization. Specifically, the version numbers need not match as the LoadWithPartialName method is used to load the assembly. + /// + Simple, + + /// + /// In full mode, the assembly used during deserialization must match exactly the assembly used during serialization. The Load method of the Assembly class is used to load the assembly. + /// + Full + } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Formatting.cs b/Src/Newtonsoft.Json/Formatting.cs index c3121aac..55043b52 100644 --- a/Src/Newtonsoft.Json/Formatting.cs +++ b/Src/Newtonsoft.Json/Formatting.cs @@ -25,18 +25,19 @@ namespace Newtonsoft.Json { - /// - /// Specifies formatting options for the . - /// - public enum Formatting - { /// - /// No special formatting is applied. This is the default. + /// Specifies formatting options for the . /// - None, - /// - /// Causes child objects to be indented according to the and settings. - /// - Indented - } + public enum Formatting + { + /// + /// No special formatting is applied. This is the default. + /// + None, + + /// + /// Causes child objects to be indented according to the and settings. + /// + Indented + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/IJsonLineInfo.cs b/Src/Newtonsoft.Json/IJsonLineInfo.cs index f863e30f..b71aedf7 100644 --- a/Src/Newtonsoft.Json/IJsonLineInfo.cs +++ b/Src/Newtonsoft.Json/IJsonLineInfo.cs @@ -25,28 +25,29 @@ namespace Newtonsoft.Json { - /// - /// Provides an interface to enable a class to return line and position information. - /// - public interface IJsonLineInfo - { /// - /// Gets a value indicating whether the class can return line information. + /// Provides an interface to enable a class to return line and position information. /// - /// - /// true if LineNumber and LinePosition can be provided; otherwise, false. - /// - bool HasLineInfo(); + public interface IJsonLineInfo + { + /// + /// Gets a value indicating whether the class can return line information. + /// + /// + /// true if LineNumber and LinePosition can be provided; otherwise, false. + /// + bool HasLineInfo(); - /// - /// Gets the current line number. - /// - /// The current line number or 0 if no line information is available (for example, HasLineInfo returns false). - int LineNumber { get; } - /// - /// Gets the current line position. - /// - /// The current line position or 0 if no line information is available (for example, HasLineInfo returns false). - int LinePosition { get; } - } + /// + /// Gets the current line number. + /// + /// The current line number or 0 if no line information is available (for example, HasLineInfo returns false). + int LineNumber { get; } + + /// + /// Gets the current line position. + /// + /// The current line position or 0 if no line information is available (for example, HasLineInfo returns false). + int LinePosition { get; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/JsonArrayAttribute.cs b/Src/Newtonsoft.Json/JsonArrayAttribute.cs index 440c1a9e..bbfc90d9 100644 --- a/Src/Newtonsoft.Json/JsonArrayAttribute.cs +++ b/Src/Newtonsoft.Json/JsonArrayAttribute.cs @@ -27,47 +27,47 @@ using System; namespace Newtonsoft.Json { - /// - /// Instructs the how to serialize the collection. - /// - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)] - public sealed class JsonArrayAttribute : JsonContainerAttribute - { - private bool _allowNullItems; - /// - /// Gets or sets a value indicating whether null items are allowed in the collection. + /// Instructs the how to serialize the collection. /// - /// true if null items are allowed in the collection; otherwise, false. - public bool AllowNullItems + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)] + public sealed class JsonArrayAttribute : JsonContainerAttribute { - get { return _allowNullItems; } - set { _allowNullItems = value; } - } + private bool _allowNullItems; - /// - /// Initializes a new instance of the class. - /// - public JsonArrayAttribute() - { - } + /// + /// Gets or sets a value indicating whether null items are allowed in the collection. + /// + /// true if null items are allowed in the collection; otherwise, false. + public bool AllowNullItems + { + get { return _allowNullItems; } + set { _allowNullItems = value; } + } - /// - /// Initializes a new instance of the class with a flag indicating whether the array can contain null items - /// - /// A flag indicating whether the array can contain null items. - public JsonArrayAttribute(bool allowNullItems) - { - _allowNullItems = allowNullItems; - } + /// + /// Initializes a new instance of the class. + /// + public JsonArrayAttribute() + { + } - /// - /// Initializes a new instance of the class with the specified container Id. - /// - /// The container Id. - public JsonArrayAttribute(string id) - : base(id) - { + /// + /// Initializes a new instance of the class with a flag indicating whether the array can contain null items + /// + /// A flag indicating whether the array can contain null items. + public JsonArrayAttribute(bool allowNullItems) + { + _allowNullItems = allowNullItems; + } + + /// + /// Initializes a new instance of the class with the specified container Id. + /// + /// The container Id. + public JsonArrayAttribute(string id) + : base(id) + { + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/JsonConstructorAttribute.cs b/Src/Newtonsoft.Json/JsonConstructorAttribute.cs index 3ea20c96..cd5d1bb8 100644 --- a/Src/Newtonsoft.Json/JsonConstructorAttribute.cs +++ b/Src/Newtonsoft.Json/JsonConstructorAttribute.cs @@ -27,11 +27,11 @@ using System; namespace Newtonsoft.Json { - /// - /// Instructs the to use the specified constructor when deserializing that object. - /// - [AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false)] - public sealed class JsonConstructorAttribute : Attribute - { - } + /// + /// Instructs the to use the specified constructor when deserializing that object. + /// + [AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false)] + public sealed class JsonConstructorAttribute : Attribute + { + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/JsonContainerAttribute.cs b/Src/Newtonsoft.Json/JsonContainerAttribute.cs index ce2674e6..d444189a 100644 --- a/Src/Newtonsoft.Json/JsonContainerAttribute.cs +++ b/Src/Newtonsoft.Json/JsonContainerAttribute.cs @@ -27,99 +27,101 @@ using System; namespace Newtonsoft.Json { - /// - /// Instructs the how to serialize the object. - /// - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)] - public abstract class JsonContainerAttribute : Attribute - { /// - /// Gets or sets the id. + /// Instructs the how to serialize the object. /// - /// The id. - public string Id { get; set; } - /// - /// Gets or sets the title. - /// - /// The title. - public string Title { get; set; } - /// - /// Gets or sets the description. - /// - /// The description. - public string Description { get; set; } - - /// - /// Gets the collection's items converter. - /// - /// The collection's items converter. - public Type ItemConverterType { get; set; } - - // yuck. can't set nullable properties on an attribute in C# - // have to use this approach to get an unset default state - internal bool? _isReference; - internal bool? _itemIsReference; - internal ReferenceLoopHandling? _itemReferenceLoopHandling; - internal TypeNameHandling? _itemTypeNameHandling; - - /// - /// Gets or sets a value that indicates whether to preserve object references. - /// - /// - /// true to keep object reference; otherwise, false. The default is false. - /// - public bool IsReference + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)] + public abstract class JsonContainerAttribute : Attribute { - get { return _isReference ?? default(bool); } - set { _isReference = value; } - } + /// + /// Gets or sets the id. + /// + /// The id. + public string Id { get; set; } - /// - /// Gets or sets a value that indicates whether to preserve collection's items references. - /// - /// - /// true to keep collection's items object references; otherwise, false. The default is false. - /// - public bool ItemIsReference - { - get { return _itemIsReference ?? default(bool); } - set { _itemIsReference = value; } - } + /// + /// Gets or sets the title. + /// + /// The title. + public string Title { get; set; } - /// - /// Gets or sets the reference loop handling used when serializing the collection's items. - /// - /// The reference loop handling. - public ReferenceLoopHandling ItemReferenceLoopHandling - { - get { return _itemReferenceLoopHandling ?? default(ReferenceLoopHandling); } - set { _itemReferenceLoopHandling = value; } - } + /// + /// Gets or sets the description. + /// + /// The description. + public string Description { get; set; } - /// - /// Gets or sets the type name handling used when serializing the collection's items. - /// - /// The type name handling. - public TypeNameHandling ItemTypeNameHandling - { - get { return _itemTypeNameHandling ?? default(TypeNameHandling); } - set { _itemTypeNameHandling = value; } - } + /// + /// Gets the collection's items converter. + /// + /// The collection's items converter. + public Type ItemConverterType { get; set; } - /// - /// Initializes a new instance of the class. - /// - protected JsonContainerAttribute() - { - } + // yuck. can't set nullable properties on an attribute in C# + // have to use this approach to get an unset default state + internal bool? _isReference; + internal bool? _itemIsReference; + internal ReferenceLoopHandling? _itemReferenceLoopHandling; + internal TypeNameHandling? _itemTypeNameHandling; - /// - /// Initializes a new instance of the class with the specified container Id. - /// - /// The container Id. - protected JsonContainerAttribute(string id) - { - Id = id; + /// + /// Gets or sets a value that indicates whether to preserve object references. + /// + /// + /// true to keep object reference; otherwise, false. The default is false. + /// + public bool IsReference + { + get { return _isReference ?? default(bool); } + set { _isReference = value; } + } + + /// + /// Gets or sets a value that indicates whether to preserve collection's items references. + /// + /// + /// true to keep collection's items object references; otherwise, false. The default is false. + /// + public bool ItemIsReference + { + get { return _itemIsReference ?? default(bool); } + set { _itemIsReference = value; } + } + + /// + /// Gets or sets the reference loop handling used when serializing the collection's items. + /// + /// The reference loop handling. + public ReferenceLoopHandling ItemReferenceLoopHandling + { + get { return _itemReferenceLoopHandling ?? default(ReferenceLoopHandling); } + set { _itemReferenceLoopHandling = value; } + } + + /// + /// Gets or sets the type name handling used when serializing the collection's items. + /// + /// The type name handling. + public TypeNameHandling ItemTypeNameHandling + { + get { return _itemTypeNameHandling ?? default(TypeNameHandling); } + set { _itemTypeNameHandling = value; } + } + + /// + /// Initializes a new instance of the class. + /// + protected JsonContainerAttribute() + { + } + + /// + /// Initializes a new instance of the class with the specified container Id. + /// + /// The container Id. + protected JsonContainerAttribute(string id) + { + Id = id; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/JsonConvert.cs b/Src/Newtonsoft.Json/JsonConvert.cs index 5fa341c9..e5a22f5b 100644 --- a/Src/Newtonsoft.Json/JsonConvert.cs +++ b/Src/Newtonsoft.Json/JsonConvert.cs @@ -40,1037 +40,1038 @@ using Newtonsoft.Json.Serialization; using System.Text; #if !NET20 && (!SILVERLIGHT || WINDOWS_PHONE) && !PORTABLE40 using System.Xml.Linq; + #endif namespace Newtonsoft.Json { - /// - /// Provides methods for converting between common language runtime types and JSON types. - /// - /// - /// - /// - public static class JsonConvert - { /// - /// Gets or sets a function that creates default . - /// Default settings are automatically used by serialization methods on , - /// and and on . - /// To serialize without using any default settings create a with - /// . + /// Provides methods for converting between common language runtime types and JSON types. /// - public static Func DefaultSettings { get; set; } - - /// - /// Represents JavaScript's boolean value true as a string. This field is read-only. - /// - public static readonly string True = "true"; - - /// - /// Represents JavaScript's boolean value false as a string. This field is read-only. - /// - public static readonly string False = "false"; - - /// - /// Represents JavaScript's null as a string. This field is read-only. - /// - public static readonly string Null = "null"; - - /// - /// Represents JavaScript's undefined as a string. This field is read-only. - /// - public static readonly string Undefined = "undefined"; - - /// - /// Represents JavaScript's positive infinity as a string. This field is read-only. - /// - public static readonly string PositiveInfinity = "Infinity"; - - /// - /// Represents JavaScript's negative infinity as a string. This field is read-only. - /// - public static readonly string NegativeInfinity = "-Infinity"; - - /// - /// Represents JavaScript's NaN as a string. This field is read-only. - /// - public static readonly string NaN = "NaN"; - - /// - /// Converts the to its JSON string representation. - /// - /// The value to convert. - /// A JSON string representation of the . - public static string ToString(DateTime value) + /// + /// + /// + public static class JsonConvert { - return ToString(value, DateFormatHandling.IsoDateFormat, DateTimeZoneHandling.RoundtripKind); - } + /// + /// Gets or sets a function that creates default . + /// Default settings are automatically used by serialization methods on , + /// and and on . + /// To serialize without using any default settings create a with + /// . + /// + public static Func DefaultSettings { get; set; } - /// - /// Converts the to its JSON string representation using the specified. - /// - /// The value to convert. - /// The format the date will be converted to. - /// The time zone handling when the date is converted to a string. - /// A JSON string representation of the . - public static string ToString(DateTime value, DateFormatHandling format, DateTimeZoneHandling timeZoneHandling) - { - DateTime updatedDateTime = DateTimeUtils.EnsureDateTime(value, timeZoneHandling); + /// + /// Represents JavaScript's boolean value true as a string. This field is read-only. + /// + public static readonly string True = "true"; - using (StringWriter writer = StringUtils.CreateStringWriter(64)) - { - writer.Write('"'); - DateTimeUtils.WriteDateTimeString(writer, updatedDateTime, format, null, CultureInfo.InvariantCulture); - writer.Write('"'); - return writer.ToString(); - } - } + /// + /// Represents JavaScript's boolean value false as a string. This field is read-only. + /// + public static readonly string False = "false"; + + /// + /// Represents JavaScript's null as a string. This field is read-only. + /// + public static readonly string Null = "null"; + + /// + /// Represents JavaScript's undefined as a string. This field is read-only. + /// + public static readonly string Undefined = "undefined"; + + /// + /// Represents JavaScript's positive infinity as a string. This field is read-only. + /// + public static readonly string PositiveInfinity = "Infinity"; + + /// + /// Represents JavaScript's negative infinity as a string. This field is read-only. + /// + public static readonly string NegativeInfinity = "-Infinity"; + + /// + /// Represents JavaScript's NaN as a string. This field is read-only. + /// + public static readonly string NaN = "NaN"; + + /// + /// Converts the to its JSON string representation. + /// + /// The value to convert. + /// A JSON string representation of the . + public static string ToString(DateTime value) + { + return ToString(value, DateFormatHandling.IsoDateFormat, DateTimeZoneHandling.RoundtripKind); + } + + /// + /// Converts the to its JSON string representation using the specified. + /// + /// The value to convert. + /// The format the date will be converted to. + /// The time zone handling when the date is converted to a string. + /// A JSON string representation of the . + public static string ToString(DateTime value, DateFormatHandling format, DateTimeZoneHandling timeZoneHandling) + { + DateTime updatedDateTime = DateTimeUtils.EnsureDateTime(value, timeZoneHandling); + + using (StringWriter writer = StringUtils.CreateStringWriter(64)) + { + writer.Write('"'); + DateTimeUtils.WriteDateTimeString(writer, updatedDateTime, format, null, CultureInfo.InvariantCulture); + writer.Write('"'); + return writer.ToString(); + } + } #if !NET20 - /// - /// Converts the to its JSON string representation. - /// - /// The value to convert. - /// A JSON string representation of the . - public static string ToString(DateTimeOffset value) - { - return ToString(value, DateFormatHandling.IsoDateFormat); - } + /// + /// Converts the to its JSON string representation. + /// + /// The value to convert. + /// A JSON string representation of the . + public static string ToString(DateTimeOffset value) + { + return ToString(value, DateFormatHandling.IsoDateFormat); + } - /// - /// Converts the to its JSON string representation using the specified. - /// - /// The value to convert. - /// The format the date will be converted to. - /// A JSON string representation of the . - public static string ToString(DateTimeOffset value, DateFormatHandling format) - { - using (StringWriter writer = StringUtils.CreateStringWriter(64)) - { - writer.Write('"'); - DateTimeUtils.WriteDateTimeOffsetString(writer, value, format, null, CultureInfo.InvariantCulture); - writer.Write('"'); - return writer.ToString(); - } - } + /// + /// Converts the to its JSON string representation using the specified. + /// + /// The value to convert. + /// The format the date will be converted to. + /// A JSON string representation of the . + public static string ToString(DateTimeOffset value, DateFormatHandling format) + { + using (StringWriter writer = StringUtils.CreateStringWriter(64)) + { + writer.Write('"'); + DateTimeUtils.WriteDateTimeOffsetString(writer, value, format, null, CultureInfo.InvariantCulture); + writer.Write('"'); + return writer.ToString(); + } + } #endif - /// - /// Converts the to its JSON string representation. - /// - /// The value to convert. - /// A JSON string representation of the . - public static string ToString(bool value) - { - return (value) ? True : False; - } + /// + /// Converts the to its JSON string representation. + /// + /// The value to convert. + /// A JSON string representation of the . + public static string ToString(bool value) + { + return (value) ? True : False; + } - /// - /// Converts the to its JSON string representation. - /// - /// The value to convert. - /// A JSON string representation of the . - public static string ToString(char value) - { - return ToString(char.ToString(value)); - } + /// + /// Converts the to its JSON string representation. + /// + /// The value to convert. + /// A JSON string representation of the . + public static string ToString(char value) + { + return ToString(char.ToString(value)); + } - /// - /// Converts the to its JSON string representation. - /// - /// The value to convert. - /// A JSON string representation of the . - public static string ToString(Enum value) - { - return value.ToString("D"); - } + /// + /// Converts the to its JSON string representation. + /// + /// The value to convert. + /// A JSON string representation of the . + public static string ToString(Enum value) + { + return value.ToString("D"); + } - /// - /// Converts the to its JSON string representation. - /// - /// The value to convert. - /// A JSON string representation of the . - public static string ToString(int value) - { - return value.ToString(null, CultureInfo.InvariantCulture); - } + /// + /// Converts the to its JSON string representation. + /// + /// The value to convert. + /// A JSON string representation of the . + public static string ToString(int value) + { + return value.ToString(null, CultureInfo.InvariantCulture); + } - /// - /// Converts the to its JSON string representation. - /// - /// The value to convert. - /// A JSON string representation of the . - public static string ToString(short value) - { - return value.ToString(null, CultureInfo.InvariantCulture); - } + /// + /// Converts the to its JSON string representation. + /// + /// The value to convert. + /// A JSON string representation of the . + public static string ToString(short value) + { + return value.ToString(null, CultureInfo.InvariantCulture); + } - /// - /// Converts the to its JSON string representation. - /// - /// The value to convert. - /// A JSON string representation of the . - [CLSCompliant(false)] - public static string ToString(ushort value) - { - return value.ToString(null, CultureInfo.InvariantCulture); - } + /// + /// Converts the to its JSON string representation. + /// + /// The value to convert. + /// A JSON string representation of the . + [CLSCompliant(false)] + public static string ToString(ushort value) + { + return value.ToString(null, CultureInfo.InvariantCulture); + } - /// - /// Converts the to its JSON string representation. - /// - /// The value to convert. - /// A JSON string representation of the . - [CLSCompliant(false)] - public static string ToString(uint value) - { - return value.ToString(null, CultureInfo.InvariantCulture); - } + /// + /// Converts the to its JSON string representation. + /// + /// The value to convert. + /// A JSON string representation of the . + [CLSCompliant(false)] + public static string ToString(uint value) + { + return value.ToString(null, CultureInfo.InvariantCulture); + } - /// - /// Converts the to its JSON string representation. - /// - /// The value to convert. - /// A JSON string representation of the . - public static string ToString(long value) - { - return value.ToString(null, CultureInfo.InvariantCulture); - } + /// + /// Converts the to its JSON string representation. + /// + /// The value to convert. + /// A JSON string representation of the . + public static string ToString(long value) + { + return value.ToString(null, CultureInfo.InvariantCulture); + } #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - private static string ToStringInternal(BigInteger value) - { - return value.ToString(null, CultureInfo.InvariantCulture); - } + private static string ToStringInternal(BigInteger value) + { + return value.ToString(null, CultureInfo.InvariantCulture); + } #endif - /// - /// Converts the to its JSON string representation. - /// - /// The value to convert. - /// A JSON string representation of the . - [CLSCompliant(false)] - public static string ToString(ulong value) - { - return value.ToString(null, CultureInfo.InvariantCulture); - } + /// + /// Converts the to its JSON string representation. + /// + /// The value to convert. + /// A JSON string representation of the . + [CLSCompliant(false)] + public static string ToString(ulong value) + { + return value.ToString(null, CultureInfo.InvariantCulture); + } - /// - /// Converts the to its JSON string representation. - /// - /// The value to convert. - /// A JSON string representation of the . - public static string ToString(float value) - { - return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)); - } + /// + /// Converts the to its JSON string representation. + /// + /// The value to convert. + /// A JSON string representation of the . + public static string ToString(float value) + { + return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)); + } - internal static string ToString(float value, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable) - { - return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar, nullable); - } + internal static string ToString(float value, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable) + { + return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar, nullable); + } - private static string EnsureFloatFormat(double value, string text, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable) - { - if (floatFormatHandling == FloatFormatHandling.Symbol || !(double.IsInfinity(value) || double.IsNaN(value))) - return text; + private static string EnsureFloatFormat(double value, string text, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable) + { + if (floatFormatHandling == FloatFormatHandling.Symbol || !(double.IsInfinity(value) || double.IsNaN(value))) + return text; - if (floatFormatHandling == FloatFormatHandling.DefaultValue) - return (!nullable) ? "0.0" : Null; - - return quoteChar + text + quoteChar; - } + if (floatFormatHandling == FloatFormatHandling.DefaultValue) + return (!nullable) ? "0.0" : Null; - /// - /// Converts the to its JSON string representation. - /// - /// The value to convert. - /// A JSON string representation of the . - public static string ToString(double value) - { - return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)); - } + return quoteChar + text + quoteChar; + } - internal static string ToString(double value, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable) - { - return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar, nullable); - } + /// + /// Converts the to its JSON string representation. + /// + /// The value to convert. + /// A JSON string representation of the . + public static string ToString(double value) + { + return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)); + } - private static string EnsureDecimalPlace(double value, string text) - { - if (double.IsNaN(value) || double.IsInfinity(value) || text.IndexOf('.') != -1 || text.IndexOf('E') != -1 || text.IndexOf('e') != -1) - return text; + internal static string ToString(double value, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable) + { + return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar, nullable); + } - return text + ".0"; - } + private static string EnsureDecimalPlace(double value, string text) + { + if (double.IsNaN(value) || double.IsInfinity(value) || text.IndexOf('.') != -1 || text.IndexOf('E') != -1 || text.IndexOf('e') != -1) + return text; - private static string EnsureDecimalPlace(string text) - { - if (text.IndexOf('.') != -1) - return text; + return text + ".0"; + } - return text + ".0"; - } + private static string EnsureDecimalPlace(string text) + { + if (text.IndexOf('.') != -1) + return text; - /// - /// Converts the to its JSON string representation. - /// - /// The value to convert. - /// A JSON string representation of the . - public static string ToString(byte value) - { - return value.ToString(null, CultureInfo.InvariantCulture); - } + return text + ".0"; + } - /// - /// Converts the to its JSON string representation. - /// - /// The value to convert. - /// A JSON string representation of the . - [CLSCompliant(false)] - public static string ToString(sbyte value) - { - return value.ToString(null, CultureInfo.InvariantCulture); - } + /// + /// Converts the to its JSON string representation. + /// + /// The value to convert. + /// A JSON string representation of the . + public static string ToString(byte value) + { + return value.ToString(null, CultureInfo.InvariantCulture); + } - /// - /// Converts the to its JSON string representation. - /// - /// The value to convert. - /// A JSON string representation of the . - public static string ToString(decimal value) - { - return EnsureDecimalPlace(value.ToString(null, CultureInfo.InvariantCulture)); - } + /// + /// Converts the to its JSON string representation. + /// + /// The value to convert. + /// A JSON string representation of the . + [CLSCompliant(false)] + public static string ToString(sbyte value) + { + return value.ToString(null, CultureInfo.InvariantCulture); + } - /// - /// Converts the to its JSON string representation. - /// - /// The value to convert. - /// A JSON string representation of the . - public static string ToString(Guid value) - { - return ToString(value, '"'); - } + /// + /// Converts the to its JSON string representation. + /// + /// The value to convert. + /// A JSON string representation of the . + public static string ToString(decimal value) + { + return EnsureDecimalPlace(value.ToString(null, CultureInfo.InvariantCulture)); + } - internal static string ToString(Guid value, char quoteChar) - { - string text = null; + /// + /// Converts the to its JSON string representation. + /// + /// The value to convert. + /// A JSON string representation of the . + public static string ToString(Guid value) + { + return ToString(value, '"'); + } + + internal static string ToString(Guid value, char quoteChar) + { + string text = null; #if !(NETFX_CORE || PORTABLE40 || PORTABLE) - text = value.ToString("D", CultureInfo.InvariantCulture); + text = value.ToString("D", CultureInfo.InvariantCulture); #else - text = value.ToString("D"); + text = value.ToString("D"); #endif - return quoteChar + text + quoteChar; - } + return quoteChar + text + quoteChar; + } - /// - /// Converts the to its JSON string representation. - /// - /// The value to convert. - /// A JSON string representation of the . - public static string ToString(TimeSpan value) - { - return ToString(value, '"'); - } + /// + /// Converts the to its JSON string representation. + /// + /// The value to convert. + /// A JSON string representation of the . + public static string ToString(TimeSpan value) + { + return ToString(value, '"'); + } - internal static string ToString(TimeSpan value, char quoteChar) - { - return ToString(value.ToString(), quoteChar); - } + internal static string ToString(TimeSpan value, char quoteChar) + { + return ToString(value.ToString(), quoteChar); + } - /// - /// Converts the to its JSON string representation. - /// - /// The value to convert. - /// A JSON string representation of the . - public static string ToString(Uri value) - { - if (value == null) - return Null; + /// + /// Converts the to its JSON string representation. + /// + /// The value to convert. + /// A JSON string representation of the . + public static string ToString(Uri value) + { + if (value == null) + return Null; - return ToString(value, '"'); - } + return ToString(value, '"'); + } - internal static string ToString(Uri value, char quoteChar) - { - return ToString(value.ToString(), quoteChar); - } + internal static string ToString(Uri value, char quoteChar) + { + return ToString(value.ToString(), quoteChar); + } - /// - /// Converts the to its JSON string representation. - /// - /// The value to convert. - /// A JSON string representation of the . - public static string ToString(string value) - { - return ToString(value, '"'); - } + /// + /// Converts the to its JSON string representation. + /// + /// The value to convert. + /// A JSON string representation of the . + public static string ToString(string value) + { + return ToString(value, '"'); + } - /// - /// Converts the to its JSON string representation. - /// - /// The value to convert. - /// The string delimiter character. - /// A JSON string representation of the . - public static string ToString(string value, char delimiter) - { - if (delimiter != '"' && delimiter != '\'') - throw new ArgumentException("Delimiter must be a single or double quote.", "delimiter"); + /// + /// Converts the to its JSON string representation. + /// + /// The value to convert. + /// The string delimiter character. + /// A JSON string representation of the . + public static string ToString(string value, char delimiter) + { + if (delimiter != '"' && delimiter != '\'') + throw new ArgumentException("Delimiter must be a single or double quote.", "delimiter"); - return JavaScriptUtils.ToEscapedJavaScriptString(value, delimiter, true); - } + return JavaScriptUtils.ToEscapedJavaScriptString(value, delimiter, true); + } - /// - /// Converts the to its JSON string representation. - /// - /// The value to convert. - /// A JSON string representation of the . - public static string ToString(object value) - { - if (value == null) - return Null; + /// + /// Converts the to its JSON string representation. + /// + /// The value to convert. + /// A JSON string representation of the . + public static string ToString(object value) + { + if (value == null) + return Null; - PrimitiveTypeCode typeCode = ConvertUtils.GetTypeCode(value); + PrimitiveTypeCode typeCode = ConvertUtils.GetTypeCode(value); - switch (typeCode) - { - case PrimitiveTypeCode.String: - return ToString((string) value); - case PrimitiveTypeCode.Char: - return ToString((char) value); - case PrimitiveTypeCode.Boolean: - return ToString((bool) value); - case PrimitiveTypeCode.SByte: - return ToString((sbyte) value); - case PrimitiveTypeCode.Int16: - return ToString((short) value); - case PrimitiveTypeCode.UInt16: - return ToString((ushort) value); - case PrimitiveTypeCode.Int32: - return ToString((int) value); - case PrimitiveTypeCode.Byte: - return ToString((byte) value); - case PrimitiveTypeCode.UInt32: - return ToString((uint) value); - case PrimitiveTypeCode.Int64: - return ToString((long) value); - case PrimitiveTypeCode.UInt64: - return ToString((ulong) value); - case PrimitiveTypeCode.Single: - return ToString((float) value); - case PrimitiveTypeCode.Double: - return ToString((double) value); - case PrimitiveTypeCode.DateTime: - return ToString((DateTime) value); - case PrimitiveTypeCode.Decimal: - return ToString((decimal) value); + switch (typeCode) + { + case PrimitiveTypeCode.String: + return ToString((string)value); + case PrimitiveTypeCode.Char: + return ToString((char)value); + case PrimitiveTypeCode.Boolean: + return ToString((bool)value); + case PrimitiveTypeCode.SByte: + return ToString((sbyte)value); + case PrimitiveTypeCode.Int16: + return ToString((short)value); + case PrimitiveTypeCode.UInt16: + return ToString((ushort)value); + case PrimitiveTypeCode.Int32: + return ToString((int)value); + case PrimitiveTypeCode.Byte: + return ToString((byte)value); + case PrimitiveTypeCode.UInt32: + return ToString((uint)value); + case PrimitiveTypeCode.Int64: + return ToString((long)value); + case PrimitiveTypeCode.UInt64: + return ToString((ulong)value); + case PrimitiveTypeCode.Single: + return ToString((float)value); + case PrimitiveTypeCode.Double: + return ToString((double)value); + case PrimitiveTypeCode.DateTime: + return ToString((DateTime)value); + case PrimitiveTypeCode.Decimal: + return ToString((decimal)value); #if !(NETFX_CORE || PORTABLE) - case PrimitiveTypeCode.DBNull: - return Null; + case PrimitiveTypeCode.DBNull: + return Null; #endif #if !NET20 - case PrimitiveTypeCode.DateTimeOffset: - return ToString((DateTimeOffset) value); + case PrimitiveTypeCode.DateTimeOffset: + return ToString((DateTimeOffset)value); #endif - case PrimitiveTypeCode.Guid: - return ToString((Guid) value); - case PrimitiveTypeCode.Uri: - return ToString((Uri) value); - case PrimitiveTypeCode.TimeSpan: - return ToString((TimeSpan) value); + case PrimitiveTypeCode.Guid: + return ToString((Guid)value); + case PrimitiveTypeCode.Uri: + return ToString((Uri)value); + case PrimitiveTypeCode.TimeSpan: + return ToString((TimeSpan)value); #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - case PrimitiveTypeCode.BigInteger: - return ToStringInternal((BigInteger)value); + case PrimitiveTypeCode.BigInteger: + return ToStringInternal((BigInteger)value); #endif - } + } - throw new ArgumentException("Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType())); - } + throw new ArgumentException("Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType())); + } - #region Serialize - /// - /// Serializes the specified object to a JSON string. - /// - /// The object to serialize. - /// A JSON string representation of the object. - public static string SerializeObject(object value) - { - return SerializeObject(value, Formatting.None, (JsonSerializerSettings) null); - } + #region Serialize + /// + /// Serializes the specified object to a JSON string. + /// + /// The object to serialize. + /// A JSON string representation of the object. + public static string SerializeObject(object value) + { + return SerializeObject(value, Formatting.None, (JsonSerializerSettings)null); + } - /// - /// Serializes the specified object to a JSON string using formatting. - /// - /// The object to serialize. - /// Indicates how the output is formatted. - /// - /// A JSON string representation of the object. - /// - public static string SerializeObject(object value, Formatting formatting) - { - return SerializeObject(value, formatting, (JsonSerializerSettings) null); - } + /// + /// Serializes the specified object to a JSON string using formatting. + /// + /// The object to serialize. + /// Indicates how the output is formatted. + /// + /// A JSON string representation of the object. + /// + public static string SerializeObject(object value, Formatting formatting) + { + return SerializeObject(value, formatting, (JsonSerializerSettings)null); + } - /// - /// Serializes the specified object to a JSON string using a collection of . - /// - /// The object to serialize. - /// A collection converters used while serializing. - /// A JSON string representation of the object. - public static string SerializeObject(object value, params JsonConverter[] converters) - { - return SerializeObject(value, Formatting.None, converters); - } + /// + /// Serializes the specified object to a JSON string using a collection of . + /// + /// The object to serialize. + /// A collection converters used while serializing. + /// A JSON string representation of the object. + public static string SerializeObject(object value, params JsonConverter[] converters) + { + return SerializeObject(value, Formatting.None, converters); + } - /// - /// Serializes the specified object to a JSON string using formatting and a collection of . - /// - /// The object to serialize. - /// Indicates how the output is formatted. - /// A collection converters used while serializing. - /// A JSON string representation of the object. - public static string SerializeObject(object value, Formatting formatting, params JsonConverter[] converters) - { - JsonSerializerSettings settings = (converters != null && converters.Length > 0) - ? new JsonSerializerSettings {Converters = converters} - : null; + /// + /// Serializes the specified object to a JSON string using formatting and a collection of . + /// + /// The object to serialize. + /// Indicates how the output is formatted. + /// A collection converters used while serializing. + /// A JSON string representation of the object. + public static string SerializeObject(object value, Formatting formatting, params JsonConverter[] converters) + { + JsonSerializerSettings settings = (converters != null && converters.Length > 0) + ? new JsonSerializerSettings { Converters = converters } + : null; - return SerializeObject(value, formatting, settings); - } + return SerializeObject(value, formatting, settings); + } - /// - /// Serializes the specified object to a JSON string using . - /// - /// The object to serialize. - /// The used to serialize the object. - /// If this is null, default serialization settings will be is used. - /// - /// A JSON string representation of the object. - /// - public static string SerializeObject(object value, JsonSerializerSettings settings) - { - return SerializeObject(value, Formatting.None, settings); - } + /// + /// Serializes the specified object to a JSON string using . + /// + /// The object to serialize. + /// The used to serialize the object. + /// If this is null, default serialization settings will be is used. + /// + /// A JSON string representation of the object. + /// + public static string SerializeObject(object value, JsonSerializerSettings settings) + { + return SerializeObject(value, Formatting.None, settings); + } - /// - /// Serializes the specified object to a JSON string using formatting and . - /// - /// The object to serialize. - /// Indicates how the output is formatted. - /// The used to serialize the object. - /// If this is null, default serialization settings will be is used. - /// - /// A JSON string representation of the object. - /// - public static string SerializeObject(object value, Formatting formatting, JsonSerializerSettings settings) - { - return SerializeObject(value, null, formatting, settings); - } + /// + /// Serializes the specified object to a JSON string using formatting and . + /// + /// The object to serialize. + /// Indicates how the output is formatted. + /// The used to serialize the object. + /// If this is null, default serialization settings will be is used. + /// + /// A JSON string representation of the object. + /// + public static string SerializeObject(object value, Formatting formatting, JsonSerializerSettings settings) + { + return SerializeObject(value, null, formatting, settings); + } - /// - /// Serializes the specified object to a JSON string using a type, formatting and . - /// - /// The object to serialize. - /// Indicates how the output is formatted. - /// The used to serialize the object. - /// If this is null, default serialization settings will be is used. - /// - /// The type of the value being serialized. - /// This parameter is used when is Auto to write out the type name if the type of the value does not match. - /// Specifing the type is optional. - /// - /// - /// A JSON string representation of the object. - /// - public static string SerializeObject(object value, Type type, Formatting formatting, JsonSerializerSettings settings) - { - JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings); + /// + /// Serializes the specified object to a JSON string using a type, formatting and . + /// + /// The object to serialize. + /// Indicates how the output is formatted. + /// The used to serialize the object. + /// If this is null, default serialization settings will be is used. + /// + /// The type of the value being serialized. + /// This parameter is used when is Auto to write out the type name if the type of the value does not match. + /// Specifing the type is optional. + /// + /// + /// A JSON string representation of the object. + /// + public static string SerializeObject(object value, Type type, Formatting formatting, JsonSerializerSettings settings) + { + JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings); - StringBuilder sb = new StringBuilder(256); - StringWriter sw = new StringWriter(sb, CultureInfo.InvariantCulture); - using (JsonTextWriter jsonWriter = new JsonTextWriter(sw)) - { - jsonWriter.Formatting = formatting; + StringBuilder sb = new StringBuilder(256); + StringWriter sw = new StringWriter(sb, CultureInfo.InvariantCulture); + using (JsonTextWriter jsonWriter = new JsonTextWriter(sw)) + { + jsonWriter.Formatting = formatting; - jsonSerializer.Serialize(jsonWriter, value, type); - } + jsonSerializer.Serialize(jsonWriter, value, type); + } - return sw.ToString(); - } + return sw.ToString(); + } #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40) - /// - /// Asynchronously serializes the specified object to a JSON string. - /// Serialization will happen on a new thread. - /// - /// The object to serialize. - /// - /// A task that represents the asynchronous serialize operation. The value of the TResult parameter contains a JSON string representation of the object. - /// - public static Task SerializeObjectAsync(object value) - { - return SerializeObjectAsync(value, Formatting.None, null); - } + /// + /// Asynchronously serializes the specified object to a JSON string. + /// Serialization will happen on a new thread. + /// + /// The object to serialize. + /// + /// A task that represents the asynchronous serialize operation. The value of the TResult parameter contains a JSON string representation of the object. + /// + public static Task SerializeObjectAsync(object value) + { + return SerializeObjectAsync(value, Formatting.None, null); + } - /// - /// Asynchronously serializes the specified object to a JSON string using formatting. - /// Serialization will happen on a new thread. - /// - /// The object to serialize. - /// Indicates how the output is formatted. - /// - /// A task that represents the asynchronous serialize operation. The value of the TResult parameter contains a JSON string representation of the object. - /// - public static Task SerializeObjectAsync(object value, Formatting formatting) - { - return SerializeObjectAsync(value, formatting, null); - } + /// + /// Asynchronously serializes the specified object to a JSON string using formatting. + /// Serialization will happen on a new thread. + /// + /// The object to serialize. + /// Indicates how the output is formatted. + /// + /// A task that represents the asynchronous serialize operation. The value of the TResult parameter contains a JSON string representation of the object. + /// + public static Task SerializeObjectAsync(object value, Formatting formatting) + { + return SerializeObjectAsync(value, formatting, null); + } - /// - /// Asynchronously serializes the specified object to a JSON string using formatting and a collection of . - /// Serialization will happen on a new thread. - /// - /// The object to serialize. - /// Indicates how the output is formatted. - /// The used to serialize the object. - /// If this is null, default serialization settings will be is used. - /// - /// A task that represents the asynchronous serialize operation. The value of the TResult parameter contains a JSON string representation of the object. - /// - public static Task SerializeObjectAsync(object value, Formatting formatting, JsonSerializerSettings settings) - { - return Task.Factory.StartNew(() => SerializeObject(value, formatting, settings)); - } + /// + /// Asynchronously serializes the specified object to a JSON string using formatting and a collection of . + /// Serialization will happen on a new thread. + /// + /// The object to serialize. + /// Indicates how the output is formatted. + /// The used to serialize the object. + /// If this is null, default serialization settings will be is used. + /// + /// A task that represents the asynchronous serialize operation. The value of the TResult parameter contains a JSON string representation of the object. + /// + public static Task SerializeObjectAsync(object value, Formatting formatting, JsonSerializerSettings settings) + { + return Task.Factory.StartNew(() => SerializeObject(value, formatting, settings)); + } #endif - #endregion + #endregion - #region Deserialize - /// - /// Deserializes the JSON to a .NET object. - /// - /// The JSON to deserialize. - /// The deserialized object from the Json string. - public static object DeserializeObject(string value) - { - return DeserializeObject(value, null, (JsonSerializerSettings) null); - } + #region Deserialize + /// + /// Deserializes the JSON to a .NET object. + /// + /// The JSON to deserialize. + /// The deserialized object from the Json string. + public static object DeserializeObject(string value) + { + return DeserializeObject(value, null, (JsonSerializerSettings)null); + } - /// - /// Deserializes the JSON to a .NET object using . - /// - /// The JSON to deserialize. - /// - /// The used to deserialize the object. - /// If this is null, default serialization settings will be is used. - /// - /// The deserialized object from the JSON string. - public static object DeserializeObject(string value, JsonSerializerSettings settings) - { - return DeserializeObject(value, null, settings); - } + /// + /// Deserializes the JSON to a .NET object using . + /// + /// The JSON to deserialize. + /// + /// The used to deserialize the object. + /// If this is null, default serialization settings will be is used. + /// + /// The deserialized object from the JSON string. + public static object DeserializeObject(string value, JsonSerializerSettings settings) + { + return DeserializeObject(value, null, settings); + } - /// - /// Deserializes the JSON to the specified .NET type. - /// - /// The JSON to deserialize. - /// The of object being deserialized. - /// The deserialized object from the Json string. - public static object DeserializeObject(string value, Type type) - { - return DeserializeObject(value, type, (JsonSerializerSettings) null); - } + /// + /// Deserializes the JSON to the specified .NET type. + /// + /// The JSON to deserialize. + /// The of object being deserialized. + /// The deserialized object from the Json string. + public static object DeserializeObject(string value, Type type) + { + return DeserializeObject(value, type, (JsonSerializerSettings)null); + } - /// - /// Deserializes the JSON to the specified .NET type. - /// - /// The type of the object to deserialize to. - /// The JSON to deserialize. - /// The deserialized object from the Json string. - public static T DeserializeObject(string value) - { - return DeserializeObject(value, (JsonSerializerSettings) null); - } + /// + /// Deserializes the JSON to the specified .NET type. + /// + /// The type of the object to deserialize to. + /// The JSON to deserialize. + /// The deserialized object from the Json string. + public static T DeserializeObject(string value) + { + return DeserializeObject(value, (JsonSerializerSettings)null); + } - /// - /// Deserializes the JSON to the given anonymous type. - /// - /// - /// The anonymous type to deserialize to. This can't be specified - /// traditionally and must be infered from the anonymous type passed - /// as a parameter. - /// - /// The JSON to deserialize. - /// The anonymous type object. - /// The deserialized anonymous type from the JSON string. - public static T DeserializeAnonymousType(string value, T anonymousTypeObject) - { - return DeserializeObject(value); - } + /// + /// Deserializes the JSON to the given anonymous type. + /// + /// + /// The anonymous type to deserialize to. This can't be specified + /// traditionally and must be infered from the anonymous type passed + /// as a parameter. + /// + /// The JSON to deserialize. + /// The anonymous type object. + /// The deserialized anonymous type from the JSON string. + public static T DeserializeAnonymousType(string value, T anonymousTypeObject) + { + return DeserializeObject(value); + } - /// - /// Deserializes the JSON to the given anonymous type using . - /// - /// - /// The anonymous type to deserialize to. This can't be specified - /// traditionally and must be infered from the anonymous type passed - /// as a parameter. - /// - /// The JSON to deserialize. - /// The anonymous type object. - /// - /// The used to deserialize the object. - /// If this is null, default serialization settings will be is used. - /// - /// The deserialized anonymous type from the JSON string. - public static T DeserializeAnonymousType(string value, T anonymousTypeObject, JsonSerializerSettings settings) - { - return DeserializeObject(value, settings); - } + /// + /// Deserializes the JSON to the given anonymous type using . + /// + /// + /// The anonymous type to deserialize to. This can't be specified + /// traditionally and must be infered from the anonymous type passed + /// as a parameter. + /// + /// The JSON to deserialize. + /// The anonymous type object. + /// + /// The used to deserialize the object. + /// If this is null, default serialization settings will be is used. + /// + /// The deserialized anonymous type from the JSON string. + public static T DeserializeAnonymousType(string value, T anonymousTypeObject, JsonSerializerSettings settings) + { + return DeserializeObject(value, settings); + } - /// - /// Deserializes the JSON to the specified .NET type using a collection of . - /// - /// The type of the object to deserialize to. - /// The JSON to deserialize. - /// Converters to use while deserializing. - /// The deserialized object from the JSON string. - public static T DeserializeObject(string value, params JsonConverter[] converters) - { - return (T) DeserializeObject(value, typeof (T), converters); - } + /// + /// Deserializes the JSON to the specified .NET type using a collection of . + /// + /// The type of the object to deserialize to. + /// The JSON to deserialize. + /// Converters to use while deserializing. + /// The deserialized object from the JSON string. + public static T DeserializeObject(string value, params JsonConverter[] converters) + { + return (T)DeserializeObject(value, typeof(T), converters); + } - /// - /// Deserializes the JSON to the specified .NET type using . - /// - /// The type of the object to deserialize to. - /// The object to deserialize. - /// - /// The used to deserialize the object. - /// If this is null, default serialization settings will be is used. - /// - /// The deserialized object from the JSON string. - public static T DeserializeObject(string value, JsonSerializerSettings settings) - { - return (T) DeserializeObject(value, typeof (T), settings); - } + /// + /// Deserializes the JSON to the specified .NET type using . + /// + /// The type of the object to deserialize to. + /// The object to deserialize. + /// + /// The used to deserialize the object. + /// If this is null, default serialization settings will be is used. + /// + /// The deserialized object from the JSON string. + public static T DeserializeObject(string value, JsonSerializerSettings settings) + { + return (T)DeserializeObject(value, typeof(T), settings); + } - /// - /// Deserializes the JSON to the specified .NET type using a collection of . - /// - /// The JSON to deserialize. - /// The type of the object to deserialize. - /// Converters to use while deserializing. - /// The deserialized object from the JSON string. - public static object DeserializeObject(string value, Type type, params JsonConverter[] converters) - { - JsonSerializerSettings settings = (converters != null && converters.Length > 0) - ? new JsonSerializerSettings {Converters = converters} - : null; + /// + /// Deserializes the JSON to the specified .NET type using a collection of . + /// + /// The JSON to deserialize. + /// The type of the object to deserialize. + /// Converters to use while deserializing. + /// The deserialized object from the JSON string. + public static object DeserializeObject(string value, Type type, params JsonConverter[] converters) + { + JsonSerializerSettings settings = (converters != null && converters.Length > 0) + ? new JsonSerializerSettings { Converters = converters } + : null; - return DeserializeObject(value, type, settings); - } + return DeserializeObject(value, type, settings); + } - /// - /// Deserializes the JSON to the specified .NET type using . - /// - /// The JSON to deserialize. - /// The type of the object to deserialize to. - /// - /// The used to deserialize the object. - /// If this is null, default serialization settings will be is used. - /// - /// The deserialized object from the JSON string. - public static object DeserializeObject(string value, Type type, JsonSerializerSettings settings) - { - ValidationUtils.ArgumentNotNull(value, "value"); + /// + /// Deserializes the JSON to the specified .NET type using . + /// + /// The JSON to deserialize. + /// The type of the object to deserialize to. + /// + /// The used to deserialize the object. + /// If this is null, default serialization settings will be is used. + /// + /// The deserialized object from the JSON string. + public static object DeserializeObject(string value, Type type, JsonSerializerSettings settings) + { + ValidationUtils.ArgumentNotNull(value, "value"); - StringReader sr = new StringReader(value); - JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings); + StringReader sr = new StringReader(value); + JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings); - // by default DeserializeObject should check for additional content - if (!jsonSerializer.IsCheckAdditionalContentSet()) - jsonSerializer.CheckAdditionalContent = true; + // by default DeserializeObject should check for additional content + if (!jsonSerializer.IsCheckAdditionalContentSet()) + jsonSerializer.CheckAdditionalContent = true; - return jsonSerializer.Deserialize(new JsonTextReader(sr), type); - } + return jsonSerializer.Deserialize(new JsonTextReader(sr), type); + } #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40) - /// - /// Asynchronously deserializes the JSON to the specified .NET type. - /// Deserialization will happen on a new thread. - /// - /// The type of the object to deserialize to. - /// The JSON to deserialize. - /// - /// A task that represents the asynchronous deserialize operation. The value of the TResult parameter contains the deserialized object from the JSON string. - /// - public static Task DeserializeObjectAsync(string value) - { - return DeserializeObjectAsync(value, null); - } + /// + /// Asynchronously deserializes the JSON to the specified .NET type. + /// Deserialization will happen on a new thread. + /// + /// The type of the object to deserialize to. + /// The JSON to deserialize. + /// + /// A task that represents the asynchronous deserialize operation. The value of the TResult parameter contains the deserialized object from the JSON string. + /// + public static Task DeserializeObjectAsync(string value) + { + return DeserializeObjectAsync(value, null); + } - /// - /// Asynchronously deserializes the JSON to the specified .NET type using . - /// Deserialization will happen on a new thread. - /// - /// The type of the object to deserialize to. - /// The JSON to deserialize. - /// - /// The used to deserialize the object. - /// If this is null, default serialization settings will be is used. - /// - /// - /// A task that represents the asynchronous deserialize operation. The value of the TResult parameter contains the deserialized object from the JSON string. - /// - public static Task DeserializeObjectAsync(string value, JsonSerializerSettings settings) - { - return Task.Factory.StartNew(() => DeserializeObject(value, settings)); - } + /// + /// Asynchronously deserializes the JSON to the specified .NET type using . + /// Deserialization will happen on a new thread. + /// + /// The type of the object to deserialize to. + /// The JSON to deserialize. + /// + /// The used to deserialize the object. + /// If this is null, default serialization settings will be is used. + /// + /// + /// A task that represents the asynchronous deserialize operation. The value of the TResult parameter contains the deserialized object from the JSON string. + /// + public static Task DeserializeObjectAsync(string value, JsonSerializerSettings settings) + { + return Task.Factory.StartNew(() => DeserializeObject(value, settings)); + } - /// - /// Asynchronously deserializes the JSON to the specified .NET type. - /// Deserialization will happen on a new thread. - /// - /// The JSON to deserialize. - /// - /// A task that represents the asynchronous deserialize operation. The value of the TResult parameter contains the deserialized object from the JSON string. - /// - public static Task DeserializeObjectAsync(string value) - { - return DeserializeObjectAsync(value, null, null); - } + /// + /// Asynchronously deserializes the JSON to the specified .NET type. + /// Deserialization will happen on a new thread. + /// + /// The JSON to deserialize. + /// + /// A task that represents the asynchronous deserialize operation. The value of the TResult parameter contains the deserialized object from the JSON string. + /// + public static Task DeserializeObjectAsync(string value) + { + return DeserializeObjectAsync(value, null, null); + } - /// - /// Asynchronously deserializes the JSON to the specified .NET type using . - /// Deserialization will happen on a new thread. - /// - /// The JSON to deserialize. - /// The type of the object to deserialize to. - /// - /// The used to deserialize the object. - /// If this is null, default serialization settings will be is used. - /// - /// - /// A task that represents the asynchronous deserialize operation. The value of the TResult parameter contains the deserialized object from the JSON string. - /// - public static Task DeserializeObjectAsync(string value, Type type, JsonSerializerSettings settings) - { - return Task.Factory.StartNew(() => DeserializeObject(value, type, settings)); - } + /// + /// Asynchronously deserializes the JSON to the specified .NET type using . + /// Deserialization will happen on a new thread. + /// + /// The JSON to deserialize. + /// The type of the object to deserialize to. + /// + /// The used to deserialize the object. + /// If this is null, default serialization settings will be is used. + /// + /// + /// A task that represents the asynchronous deserialize operation. The value of the TResult parameter contains the deserialized object from the JSON string. + /// + public static Task DeserializeObjectAsync(string value, Type type, JsonSerializerSettings settings) + { + return Task.Factory.StartNew(() => DeserializeObject(value, type, settings)); + } #endif - #endregion + #endregion - /// - /// Populates the object with values from the JSON string. - /// - /// The JSON to populate values from. - /// The target object to populate values onto. - public static void PopulateObject(string value, object target) - { - PopulateObject(value, target, null); - } + /// + /// Populates the object with values from the JSON string. + /// + /// The JSON to populate values from. + /// The target object to populate values onto. + public static void PopulateObject(string value, object target) + { + PopulateObject(value, target, null); + } - /// - /// Populates the object with values from the JSON string using . - /// - /// The JSON to populate values from. - /// The target object to populate values onto. - /// - /// The used to deserialize the object. - /// If this is null, default serialization settings will be is used. - /// - public static void PopulateObject(string value, object target, JsonSerializerSettings settings) - { - StringReader sr = new StringReader(value); - JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings); + /// + /// Populates the object with values from the JSON string using . + /// + /// The JSON to populate values from. + /// The target object to populate values onto. + /// + /// The used to deserialize the object. + /// If this is null, default serialization settings will be is used. + /// + public static void PopulateObject(string value, object target, JsonSerializerSettings settings) + { + StringReader sr = new StringReader(value); + JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings); - using (JsonReader jsonReader = new JsonTextReader(sr)) - { - jsonSerializer.Populate(jsonReader, target); + using (JsonReader jsonReader = new JsonTextReader(sr)) + { + jsonSerializer.Populate(jsonReader, target); - if (jsonReader.Read() && jsonReader.TokenType != JsonToken.Comment) - throw new JsonSerializationException("Additional text found in JSON string after finishing deserializing object."); - } - } + if (jsonReader.Read() && jsonReader.TokenType != JsonToken.Comment) + throw new JsonSerializationException("Additional text found in JSON string after finishing deserializing object."); + } + } #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40) - /// - /// Asynchronously populates the object with values from the JSON string using . - /// - /// The JSON to populate values from. - /// The target object to populate values onto. - /// - /// The used to deserialize the object. - /// If this is null, default serialization settings will be is used. - /// - /// - /// A task that represents the asynchronous populate operation. - /// - public static Task PopulateObjectAsync(string value, object target, JsonSerializerSettings settings) - { - return Task.Factory.StartNew(() => PopulateObject(value, target, settings)); - } + /// + /// Asynchronously populates the object with values from the JSON string using . + /// + /// The JSON to populate values from. + /// The target object to populate values onto. + /// + /// The used to deserialize the object. + /// If this is null, default serialization settings will be is used. + /// + /// + /// A task that represents the asynchronous populate operation. + /// + public static Task PopulateObjectAsync(string value, object target, JsonSerializerSettings settings) + { + return Task.Factory.StartNew(() => PopulateObject(value, target, settings)); + } #endif #if !(SILVERLIGHT || PORTABLE40 || PORTABLE || NETFX_CORE) - /// - /// Serializes the XML node to a JSON string. - /// - /// The node to serialize. - /// A JSON string of the XmlNode. - public static string SerializeXmlNode(XmlNode node) - { - return SerializeXmlNode(node, Formatting.None); - } + /// + /// Serializes the XML node to a JSON string. + /// + /// The node to serialize. + /// A JSON string of the XmlNode. + public static string SerializeXmlNode(XmlNode node) + { + return SerializeXmlNode(node, Formatting.None); + } - /// - /// Serializes the XML node to a JSON string using formatting. - /// - /// The node to serialize. - /// Indicates how the output is formatted. - /// A JSON string of the XmlNode. - public static string SerializeXmlNode(XmlNode node, Formatting formatting) - { - XmlNodeConverter converter = new XmlNodeConverter(); + /// + /// Serializes the XML node to a JSON string using formatting. + /// + /// The node to serialize. + /// Indicates how the output is formatted. + /// A JSON string of the XmlNode. + public static string SerializeXmlNode(XmlNode node, Formatting formatting) + { + XmlNodeConverter converter = new XmlNodeConverter(); - return SerializeObject(node, formatting, converter); - } + return SerializeObject(node, formatting, converter); + } - /// - /// Serializes the XML node to a JSON string using formatting and omits the root object if is true. - /// - /// The node to serialize. - /// Indicates how the output is formatted. - /// Omits writing the root object. - /// A JSON string of the XmlNode. - public static string SerializeXmlNode(XmlNode node, Formatting formatting, bool omitRootObject) - { - XmlNodeConverter converter = new XmlNodeConverter {OmitRootObject = omitRootObject}; + /// + /// Serializes the XML node to a JSON string using formatting and omits the root object if is true. + /// + /// The node to serialize. + /// Indicates how the output is formatted. + /// Omits writing the root object. + /// A JSON string of the XmlNode. + public static string SerializeXmlNode(XmlNode node, Formatting formatting, bool omitRootObject) + { + XmlNodeConverter converter = new XmlNodeConverter { OmitRootObject = omitRootObject }; - return SerializeObject(node, formatting, converter); - } + return SerializeObject(node, formatting, converter); + } - /// - /// Deserializes the XmlNode from a JSON string. - /// - /// The JSON string. - /// The deserialized XmlNode - public static XmlDocument DeserializeXmlNode(string value) - { - return DeserializeXmlNode(value, null); - } + /// + /// Deserializes the XmlNode from a JSON string. + /// + /// The JSON string. + /// The deserialized XmlNode + public static XmlDocument DeserializeXmlNode(string value) + { + return DeserializeXmlNode(value, null); + } - /// - /// Deserializes the XmlNode from a JSON string nested in a root elment specified by . - /// - /// The JSON string. - /// The name of the root element to append when deserializing. - /// The deserialized XmlNode - public static XmlDocument DeserializeXmlNode(string value, string deserializeRootElementName) - { - return DeserializeXmlNode(value, deserializeRootElementName, false); - } + /// + /// Deserializes the XmlNode from a JSON string nested in a root elment specified by . + /// + /// The JSON string. + /// The name of the root element to append when deserializing. + /// The deserialized XmlNode + public static XmlDocument DeserializeXmlNode(string value, string deserializeRootElementName) + { + return DeserializeXmlNode(value, deserializeRootElementName, false); + } - /// - /// Deserializes the XmlNode from a JSON string nested in a root elment specified by - /// and writes a .NET array attribute for collections. - /// - /// The JSON string. - /// The name of the root element to append when deserializing. - /// - /// A flag to indicate whether to write the Json.NET array attribute. - /// This attribute helps preserve arrays when converting the written XML back to JSON. - /// - /// The deserialized XmlNode - public static XmlDocument DeserializeXmlNode(string value, string deserializeRootElementName, bool writeArrayAttribute) - { - XmlNodeConverter converter = new XmlNodeConverter(); - converter.DeserializeRootElementName = deserializeRootElementName; - converter.WriteArrayAttribute = writeArrayAttribute; + /// + /// Deserializes the XmlNode from a JSON string nested in a root elment specified by + /// and writes a .NET array attribute for collections. + /// + /// The JSON string. + /// The name of the root element to append when deserializing. + /// + /// A flag to indicate whether to write the Json.NET array attribute. + /// This attribute helps preserve arrays when converting the written XML back to JSON. + /// + /// The deserialized XmlNode + public static XmlDocument DeserializeXmlNode(string value, string deserializeRootElementName, bool writeArrayAttribute) + { + XmlNodeConverter converter = new XmlNodeConverter(); + converter.DeserializeRootElementName = deserializeRootElementName; + converter.WriteArrayAttribute = writeArrayAttribute; - return (XmlDocument) DeserializeObject(value, typeof (XmlDocument), converter); - } + return (XmlDocument)DeserializeObject(value, typeof(XmlDocument), converter); + } #endif #if !NET20 && (!(SILVERLIGHT) || WINDOWS_PHONE) && !PORTABLE40 - /// - /// Serializes the to a JSON string. - /// - /// The node to convert to JSON. - /// A JSON string of the XNode. - public static string SerializeXNode(XObject node) - { - return SerializeXNode(node, Formatting.None); - } + /// + /// Serializes the to a JSON string. + /// + /// The node to convert to JSON. + /// A JSON string of the XNode. + public static string SerializeXNode(XObject node) + { + return SerializeXNode(node, Formatting.None); + } - /// - /// Serializes the to a JSON string using formatting. - /// - /// The node to convert to JSON. - /// Indicates how the output is formatted. - /// A JSON string of the XNode. - public static string SerializeXNode(XObject node, Formatting formatting) - { - return SerializeXNode(node, formatting, false); - } + /// + /// Serializes the to a JSON string using formatting. + /// + /// The node to convert to JSON. + /// Indicates how the output is formatted. + /// A JSON string of the XNode. + public static string SerializeXNode(XObject node, Formatting formatting) + { + return SerializeXNode(node, formatting, false); + } - /// - /// Serializes the to a JSON string using formatting and omits the root object if is true. - /// - /// The node to serialize. - /// Indicates how the output is formatted. - /// Omits writing the root object. - /// A JSON string of the XNode. - public static string SerializeXNode(XObject node, Formatting formatting, bool omitRootObject) - { - XmlNodeConverter converter = new XmlNodeConverter {OmitRootObject = omitRootObject}; + /// + /// Serializes the to a JSON string using formatting and omits the root object if is true. + /// + /// The node to serialize. + /// Indicates how the output is formatted. + /// Omits writing the root object. + /// A JSON string of the XNode. + public static string SerializeXNode(XObject node, Formatting formatting, bool omitRootObject) + { + XmlNodeConverter converter = new XmlNodeConverter { OmitRootObject = omitRootObject }; - return SerializeObject(node, formatting, converter); - } + return SerializeObject(node, formatting, converter); + } - /// - /// Deserializes the from a JSON string. - /// - /// The JSON string. - /// The deserialized XNode - public static XDocument DeserializeXNode(string value) - { - return DeserializeXNode(value, null); - } + /// + /// Deserializes the from a JSON string. + /// + /// The JSON string. + /// The deserialized XNode + public static XDocument DeserializeXNode(string value) + { + return DeserializeXNode(value, null); + } - /// - /// Deserializes the from a JSON string nested in a root elment specified by . - /// - /// The JSON string. - /// The name of the root element to append when deserializing. - /// The deserialized XNode - public static XDocument DeserializeXNode(string value, string deserializeRootElementName) - { - return DeserializeXNode(value, deserializeRootElementName, false); - } + /// + /// Deserializes the from a JSON string nested in a root elment specified by . + /// + /// The JSON string. + /// The name of the root element to append when deserializing. + /// The deserialized XNode + public static XDocument DeserializeXNode(string value, string deserializeRootElementName) + { + return DeserializeXNode(value, deserializeRootElementName, false); + } - /// - /// Deserializes the from a JSON string nested in a root elment specified by - /// and writes a .NET array attribute for collections. - /// - /// The JSON string. - /// The name of the root element to append when deserializing. - /// - /// A flag to indicate whether to write the Json.NET array attribute. - /// This attribute helps preserve arrays when converting the written XML back to JSON. - /// - /// The deserialized XNode - public static XDocument DeserializeXNode(string value, string deserializeRootElementName, bool writeArrayAttribute) - { - XmlNodeConverter converter = new XmlNodeConverter(); - converter.DeserializeRootElementName = deserializeRootElementName; - converter.WriteArrayAttribute = writeArrayAttribute; + /// + /// Deserializes the from a JSON string nested in a root elment specified by + /// and writes a .NET array attribute for collections. + /// + /// The JSON string. + /// The name of the root element to append when deserializing. + /// + /// A flag to indicate whether to write the Json.NET array attribute. + /// This attribute helps preserve arrays when converting the written XML back to JSON. + /// + /// The deserialized XNode + public static XDocument DeserializeXNode(string value, string deserializeRootElementName, bool writeArrayAttribute) + { + XmlNodeConverter converter = new XmlNodeConverter(); + converter.DeserializeRootElementName = deserializeRootElementName; + converter.WriteArrayAttribute = writeArrayAttribute; - return (XDocument) DeserializeObject(value, typeof (XDocument), converter); - } + return (XDocument)DeserializeObject(value, typeof(XDocument), converter); + } #endif - } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/JsonConverter.cs b/Src/Newtonsoft.Json/JsonConverter.cs index dd619f2c..424b7eeb 100644 --- a/Src/Newtonsoft.Json/JsonConverter.cs +++ b/Src/Newtonsoft.Json/JsonConverter.cs @@ -31,63 +31,63 @@ using Newtonsoft.Json.Schema; namespace Newtonsoft.Json { - /// - /// Converts an object to and from JSON. - /// - public abstract class JsonConverter - { /// - /// Writes the JSON representation of the object. + /// Converts an object to and from JSON. /// - /// The to write to. - /// The value. - /// The calling serializer. - public abstract void WriteJson(JsonWriter writer, object value, JsonSerializer serializer); - - /// - /// Reads the JSON representation of the object. - /// - /// The to read from. - /// Type of the object. - /// The existing value of object being read. - /// The calling serializer. - /// The object value. - public abstract object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer); - - /// - /// Determines whether this instance can convert the specified object type. - /// - /// Type of the object. - /// - /// true if this instance can convert the specified object type; otherwise, false. - /// - public abstract bool CanConvert(Type objectType); - - /// - /// Gets the of the JSON produced by the JsonConverter. - /// - /// The of the JSON produced by the JsonConverter. - public virtual JsonSchema GetSchema() + public abstract class JsonConverter { - return null; - } + /// + /// Writes the JSON representation of the object. + /// + /// The to write to. + /// The value. + /// The calling serializer. + public abstract void WriteJson(JsonWriter writer, object value, JsonSerializer serializer); - /// - /// Gets a value indicating whether this can read JSON. - /// - /// true if this can read JSON; otherwise, false. - public virtual bool CanRead - { - get { return true; } - } + /// + /// Reads the JSON representation of the object. + /// + /// The to read from. + /// Type of the object. + /// The existing value of object being read. + /// The calling serializer. + /// The object value. + public abstract object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer); - /// - /// Gets a value indicating whether this can write JSON. - /// - /// true if this can write JSON; otherwise, false. - public virtual bool CanWrite - { - get { return true; } + /// + /// Determines whether this instance can convert the specified object type. + /// + /// Type of the object. + /// + /// true if this instance can convert the specified object type; otherwise, false. + /// + public abstract bool CanConvert(Type objectType); + + /// + /// Gets the of the JSON produced by the JsonConverter. + /// + /// The of the JSON produced by the JsonConverter. + public virtual JsonSchema GetSchema() + { + return null; + } + + /// + /// Gets a value indicating whether this can read JSON. + /// + /// true if this can read JSON; otherwise, false. + public virtual bool CanRead + { + get { return true; } + } + + /// + /// Gets a value indicating whether this can write JSON. + /// + /// true if this can write JSON; otherwise, false. + public virtual bool CanWrite + { + get { return true; } + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/JsonConverterAttribute.cs b/Src/Newtonsoft.Json/JsonConverterAttribute.cs index 3fd46bde..f1ab0d55 100644 --- a/Src/Newtonsoft.Json/JsonConverterAttribute.cs +++ b/Src/Newtonsoft.Json/JsonConverterAttribute.cs @@ -29,45 +29,45 @@ using System.Globalization; namespace Newtonsoft.Json { - /// - /// Instructs the to use the specified when serializing the member or class. - /// - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface | AttributeTargets.Enum | AttributeTargets.Parameter, AllowMultiple = false)] - public sealed class JsonConverterAttribute : Attribute - { - private readonly Type _converterType; - /// - /// Gets the type of the converter. + /// Instructs the to use the specified when serializing the member or class. /// - /// The type of the converter. - public Type ConverterType + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface | AttributeTargets.Enum | AttributeTargets.Parameter, AllowMultiple = false)] + public sealed class JsonConverterAttribute : Attribute { - get { return _converterType; } - } + private readonly Type _converterType; - /// - /// Initializes a new instance of the class. - /// - /// Type of the converter. - public JsonConverterAttribute(Type converterType) - { - if (converterType == null) - throw new ArgumentNullException("converterType"); + /// + /// Gets the type of the converter. + /// + /// The type of the converter. + public Type ConverterType + { + get { return _converterType; } + } - _converterType = converterType; - } + /// + /// Initializes a new instance of the class. + /// + /// Type of the converter. + public JsonConverterAttribute(Type converterType) + { + if (converterType == null) + throw new ArgumentNullException("converterType"); - internal static JsonConverter CreateJsonConverterInstance(Type converterType) - { - try - { - return (JsonConverter)Activator.CreateInstance(converterType); - } - catch (Exception ex) - { - throw new JsonException("Error creating {0}".FormatWith(CultureInfo.InvariantCulture, converterType), ex); - } + _converterType = converterType; + } + + internal static JsonConverter CreateJsonConverterInstance(Type converterType) + { + try + { + return (JsonConverter)Activator.CreateInstance(converterType); + } + catch (Exception ex) + { + throw new JsonException("Error creating {0}".FormatWith(CultureInfo.InvariantCulture, converterType), ex); + } + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/JsonConverterCollection.cs b/Src/Newtonsoft.Json/JsonConverterCollection.cs index 50f70c51..b2c04927 100644 --- a/Src/Newtonsoft.Json/JsonConverterCollection.cs +++ b/Src/Newtonsoft.Json/JsonConverterCollection.cs @@ -30,10 +30,10 @@ using System.Collections.ObjectModel; namespace Newtonsoft.Json { - /// - /// Represents a collection of . - /// - public class JsonConverterCollection : Collection - { - } -} + /// + /// Represents a collection of . + /// + public class JsonConverterCollection : Collection + { + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json/JsonDictionaryAttribute.cs b/Src/Newtonsoft.Json/JsonDictionaryAttribute.cs index 6ef4011e..7ddf4118 100644 --- a/Src/Newtonsoft.Json/JsonDictionaryAttribute.cs +++ b/Src/Newtonsoft.Json/JsonDictionaryAttribute.cs @@ -27,26 +27,26 @@ using System; namespace Newtonsoft.Json { - /// - /// Instructs the how to serialize the collection. - /// - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)] - public sealed class JsonDictionaryAttribute : JsonContainerAttribute - { /// - /// Initializes a new instance of the class. + /// Instructs the how to serialize the collection. /// - public JsonDictionaryAttribute() + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)] + public sealed class JsonDictionaryAttribute : JsonContainerAttribute { - } + /// + /// Initializes a new instance of the class. + /// + public JsonDictionaryAttribute() + { + } - /// - /// Initializes a new instance of the class with the specified container Id. - /// - /// The container Id. - public JsonDictionaryAttribute(string id) - : base(id) - { + /// + /// Initializes a new instance of the class with the specified container Id. + /// + /// The container Id. + public JsonDictionaryAttribute(string id) + : base(id) + { + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/JsonException.cs b/Src/Newtonsoft.Json/JsonException.cs index ad4cdf15..299b2655 100644 --- a/Src/Newtonsoft.Json/JsonException.cs +++ b/Src/Newtonsoft.Json/JsonException.cs @@ -32,61 +32,61 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json { - /// - /// The exception thrown when an error occurs during Json serialization or deserialization. - /// + /// + /// The exception thrown when an error occurs during Json serialization or deserialization. + /// #if !(SILVERLIGHT || WINDOWS_PHONE || NETFX_CORE || PORTABLE40 || PORTABLE) - [Serializable] + [Serializable] #endif - public class JsonException : Exception - { - /// - /// Initializes a new instance of the class. - /// - public JsonException() + public class JsonException : Exception { - } + /// + /// Initializes a new instance of the class. + /// + public JsonException() + { + } - /// - /// Initializes a new instance of the class - /// with a specified error message. - /// - /// The error message that explains the reason for the exception. - public JsonException(string message) - : base(message) - { - } + /// + /// Initializes a new instance of the class + /// with a specified error message. + /// + /// The error message that explains the reason for the exception. + public JsonException(string message) + : base(message) + { + } - /// - /// Initializes a new instance of the class - /// with a specified error message and a reference to the inner exception that is the cause of this exception. - /// - /// The error message that explains the reason for the exception. - /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - public JsonException(string message, Exception innerException) - : base(message, innerException) - { - } + /// + /// Initializes a new instance of the class + /// with a specified error message and a reference to the inner exception that is the cause of this exception. + /// + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + public JsonException(string message, Exception innerException) + : base(message, innerException) + { + } #if !(WINDOWS_PHONE || SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) - /// - /// Initializes a new instance of the class. - /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. - /// The parameter is null. - /// The class name is null or is zero (0). - public JsonException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } + /// + /// Initializes a new instance of the class. + /// + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. + /// The parameter is null. + /// The class name is null or is zero (0). + public JsonException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } #endif - internal static JsonException Create(IJsonLineInfo lineInfo, string path, string message) - { - message = JsonPosition.FormatMessage(lineInfo, path, message); + internal static JsonException Create(IJsonLineInfo lineInfo, string path, string message) + { + message = JsonPosition.FormatMessage(lineInfo, path, message); - return new JsonException(message); + return new JsonException(message); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/JsonExtensionDataAttribute.cs b/Src/Newtonsoft.Json/JsonExtensionDataAttribute.cs index c6b25c95..6bc15b7f 100644 --- a/Src/Newtonsoft.Json/JsonExtensionDataAttribute.cs +++ b/Src/Newtonsoft.Json/JsonExtensionDataAttribute.cs @@ -2,36 +2,36 @@ namespace Newtonsoft.Json { - /// - /// Instructs the to deserialize properties with no matching class member into the specified collection - /// and write values during serialization. - /// - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)] - public class JsonExtensionDataAttribute : Attribute - { /// - /// Gets or sets a value that indicates whether to write extension data when serializing the object. + /// Instructs the to deserialize properties with no matching class member into the specified collection + /// and write values during serialization. /// - /// - /// true to write extension data when serializing the object; otherwise, false. The default is true. - /// - public bool WriteData { get; set; } - - /// - /// Gets or sets a value that indicates whether to read extension data when deserializing the object. - /// - /// - /// true to read extension data when deserializing the object; otherwise, false. The default is true. - /// - public bool ReadData { get; set; } - - /// - /// Initializes a new instance of the class. - /// - public JsonExtensionDataAttribute() + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)] + public class JsonExtensionDataAttribute : Attribute { - WriteData = true; - ReadData = true; + /// + /// Gets or sets a value that indicates whether to write extension data when serializing the object. + /// + /// + /// true to write extension data when serializing the object; otherwise, false. The default is true. + /// + public bool WriteData { get; set; } + + /// + /// Gets or sets a value that indicates whether to read extension data when deserializing the object. + /// + /// + /// true to read extension data when deserializing the object; otherwise, false. The default is true. + /// + public bool ReadData { get; set; } + + /// + /// Initializes a new instance of the class. + /// + public JsonExtensionDataAttribute() + { + WriteData = true; + ReadData = true; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/JsonIgnoreAttribute.cs b/Src/Newtonsoft.Json/JsonIgnoreAttribute.cs index e7511a02..8229299f 100644 --- a/Src/Newtonsoft.Json/JsonIgnoreAttribute.cs +++ b/Src/Newtonsoft.Json/JsonIgnoreAttribute.cs @@ -29,11 +29,11 @@ using System.Text; namespace Newtonsoft.Json { - /// - /// Instructs the not to serialize the public field or public read/write property value. - /// - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)] - public sealed class JsonIgnoreAttribute : Attribute - { - } + /// + /// Instructs the not to serialize the public field or public read/write property value. + /// + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)] + public sealed class JsonIgnoreAttribute : Attribute + { + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/JsonObjectAttribute.cs b/Src/Newtonsoft.Json/JsonObjectAttribute.cs index 862db6bd..61fad921 100644 --- a/Src/Newtonsoft.Json/JsonObjectAttribute.cs +++ b/Src/Newtonsoft.Json/JsonObjectAttribute.cs @@ -27,63 +27,63 @@ using System; namespace Newtonsoft.Json { - /// - /// Instructs the how to serialize the object. - /// - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false)] - public sealed class JsonObjectAttribute : JsonContainerAttribute - { - private MemberSerialization _memberSerialization = MemberSerialization.OptOut; - - // yuck. can't set nullable properties on an attribute in C# - // have to use this approach to get an unset default state - internal Required? _itemRequired; - /// - /// Gets or sets the member serialization. + /// Instructs the how to serialize the object. /// - /// The member serialization. - public MemberSerialization MemberSerialization + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false)] + public sealed class JsonObjectAttribute : JsonContainerAttribute { - get { return _memberSerialization; } - set { _memberSerialization = value; } - } + private MemberSerialization _memberSerialization = MemberSerialization.OptOut; - /// - /// Gets or sets a value that indicates whether the object's properties are required. - /// - /// - /// A value indicating whether the object's properties are required. - /// - public Required ItemRequired - { - get { return _itemRequired ?? default(Required); } - set { _itemRequired = value; } - } + // yuck. can't set nullable properties on an attribute in C# + // have to use this approach to get an unset default state + internal Required? _itemRequired; - /// - /// Initializes a new instance of the class. - /// - public JsonObjectAttribute() - { - } + /// + /// Gets or sets the member serialization. + /// + /// The member serialization. + public MemberSerialization MemberSerialization + { + get { return _memberSerialization; } + set { _memberSerialization = value; } + } - /// - /// Initializes a new instance of the class with the specified member serialization. - /// - /// The member serialization. - public JsonObjectAttribute(MemberSerialization memberSerialization) - { - MemberSerialization = memberSerialization; - } + /// + /// Gets or sets a value that indicates whether the object's properties are required. + /// + /// + /// A value indicating whether the object's properties are required. + /// + public Required ItemRequired + { + get { return _itemRequired ?? default(Required); } + set { _itemRequired = value; } + } - /// - /// Initializes a new instance of the class with the specified container Id. - /// - /// The container Id. - public JsonObjectAttribute(string id) - : base(id) - { + /// + /// Initializes a new instance of the class. + /// + public JsonObjectAttribute() + { + } + + /// + /// Initializes a new instance of the class with the specified member serialization. + /// + /// The member serialization. + public JsonObjectAttribute(MemberSerialization memberSerialization) + { + MemberSerialization = memberSerialization; + } + + /// + /// Initializes a new instance of the class with the specified container Id. + /// + /// The container Id. + public JsonObjectAttribute(string id) + : base(id) + { + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/JsonPosition.cs b/Src/Newtonsoft.Json/JsonPosition.cs index 784f825e..cbd32f92 100644 --- a/Src/Newtonsoft.Json/JsonPosition.cs +++ b/Src/Newtonsoft.Json/JsonPosition.cs @@ -31,85 +31,85 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json { - internal enum JsonContainerType - { - None, - Object, - Array, - Constructor - } - - internal struct JsonPosition - { - internal JsonContainerType Type; - internal int Position; - internal string PropertyName; - internal bool HasIndex; - - public JsonPosition(JsonContainerType type) + internal enum JsonContainerType { - Type = type; - HasIndex = TypeHasIndex(type); - Position = -1; - PropertyName = null; + None, + Object, + Array, + Constructor } - internal void WriteTo(StringBuilder sb) + internal struct JsonPosition { - switch (Type) - { - case JsonContainerType.Object: - if (sb.Length > 0) - sb.Append("."); - sb.Append(PropertyName); - break; - case JsonContainerType.Array: - case JsonContainerType.Constructor: - sb.Append("["); - sb.Append(Position); - sb.Append("]"); - break; - } + internal JsonContainerType Type; + internal int Position; + internal string PropertyName; + internal bool HasIndex; + + public JsonPosition(JsonContainerType type) + { + Type = type; + HasIndex = TypeHasIndex(type); + Position = -1; + PropertyName = null; + } + + internal void WriteTo(StringBuilder sb) + { + switch (Type) + { + case JsonContainerType.Object: + if (sb.Length > 0) + sb.Append("."); + sb.Append(PropertyName); + break; + case JsonContainerType.Array: + case JsonContainerType.Constructor: + sb.Append("["); + sb.Append(Position); + sb.Append("]"); + break; + } + } + + internal static bool TypeHasIndex(JsonContainerType type) + { + return (type == JsonContainerType.Array || type == JsonContainerType.Constructor); + } + + internal static string BuildPath(IEnumerable positions) + { + StringBuilder sb = new StringBuilder(); + + foreach (JsonPosition state in positions) + { + state.WriteTo(sb); + } + + return sb.ToString(); + } + + internal static string FormatMessage(IJsonLineInfo lineInfo, string path, string message) + { + // don't add a fullstop and space when message ends with a new line + if (!message.EndsWith(Environment.NewLine)) + { + message = message.Trim(); + + if (!message.EndsWith(".")) + message += "."; + + message += " "; + } + + message += "Path '{0}'".FormatWith(CultureInfo.InvariantCulture, path); + + if (lineInfo != null && lineInfo.HasLineInfo()) + message += ", line {0}, position {1}".FormatWith(CultureInfo.InvariantCulture, lineInfo.LineNumber, lineInfo.LinePosition); + + message += "."; + + return message; + } } - - internal static bool TypeHasIndex(JsonContainerType type) - { - return (type == JsonContainerType.Array || type == JsonContainerType.Constructor); - } - - internal static string BuildPath(IEnumerable positions) - { - StringBuilder sb = new StringBuilder(); - - foreach (JsonPosition state in positions) - { - state.WriteTo(sb); - } - - return sb.ToString(); - } - - internal static string FormatMessage(IJsonLineInfo lineInfo, string path, string message) - { - // don't add a fullstop and space when message ends with a new line - if (!message.EndsWith(Environment.NewLine)) - { - message = message.Trim(); - - if (!message.EndsWith(".")) - message += "."; - - message += " "; - } - - message += "Path '{0}'".FormatWith(CultureInfo.InvariantCulture, path); - - if (lineInfo != null && lineInfo.HasLineInfo()) - message += ", line {0}, position {1}".FormatWith(CultureInfo.InvariantCulture, lineInfo.LineNumber, lineInfo.LinePosition); - - message += "."; - - return message; - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/JsonPropertyAttribute.cs b/Src/Newtonsoft.Json/JsonPropertyAttribute.cs index 8d197c05..6ed7c5bf 100644 --- a/Src/Newtonsoft.Json/JsonPropertyAttribute.cs +++ b/Src/Newtonsoft.Json/JsonPropertyAttribute.cs @@ -27,164 +27,164 @@ using System; namespace Newtonsoft.Json { - /// - /// Instructs the to always serialize the member with the specified name. - /// - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false)] - public sealed class JsonPropertyAttribute : Attribute - { - // yuck. can't set nullable properties on an attribute in C# - // have to use this approach to get an unset default state - internal NullValueHandling? _nullValueHandling; - internal DefaultValueHandling? _defaultValueHandling; - internal ReferenceLoopHandling? _referenceLoopHandling; - internal ObjectCreationHandling? _objectCreationHandling; - internal TypeNameHandling? _typeNameHandling; - internal bool? _isReference; - internal int? _order; - internal Required? _required; - internal bool? _itemIsReference; - internal ReferenceLoopHandling? _itemReferenceLoopHandling; - internal TypeNameHandling? _itemTypeNameHandling; - /// - /// Gets or sets the converter used when serializing the property's collection items. + /// Instructs the to always serialize the member with the specified name. /// - /// The collection's items converter. - public Type ItemConverterType { get; set; } - - /// - /// Gets or sets the null value handling used when serializing this property. - /// - /// The null value handling. - public NullValueHandling NullValueHandling + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false)] + public sealed class JsonPropertyAttribute : Attribute { - get { return _nullValueHandling ?? default(NullValueHandling); } - set { _nullValueHandling = value; } - } + // yuck. can't set nullable properties on an attribute in C# + // have to use this approach to get an unset default state + internal NullValueHandling? _nullValueHandling; + internal DefaultValueHandling? _defaultValueHandling; + internal ReferenceLoopHandling? _referenceLoopHandling; + internal ObjectCreationHandling? _objectCreationHandling; + internal TypeNameHandling? _typeNameHandling; + internal bool? _isReference; + internal int? _order; + internal Required? _required; + internal bool? _itemIsReference; + internal ReferenceLoopHandling? _itemReferenceLoopHandling; + internal TypeNameHandling? _itemTypeNameHandling; - /// - /// Gets or sets the default value handling used when serializing this property. - /// - /// The default value handling. - public DefaultValueHandling DefaultValueHandling - { - get { return _defaultValueHandling ?? default(DefaultValueHandling); } - set { _defaultValueHandling = value; } - } + /// + /// Gets or sets the converter used when serializing the property's collection items. + /// + /// The collection's items converter. + public Type ItemConverterType { get; set; } - /// - /// Gets or sets the reference loop handling used when serializing this property. - /// - /// The reference loop handling. - public ReferenceLoopHandling ReferenceLoopHandling - { - get { return _referenceLoopHandling ?? default(ReferenceLoopHandling); } - set { _referenceLoopHandling = value; } - } + /// + /// Gets or sets the null value handling used when serializing this property. + /// + /// The null value handling. + public NullValueHandling NullValueHandling + { + get { return _nullValueHandling ?? default(NullValueHandling); } + set { _nullValueHandling = value; } + } - /// - /// Gets or sets the object creation handling used when deserializing this property. - /// - /// The object creation handling. - public ObjectCreationHandling ObjectCreationHandling - { - get { return _objectCreationHandling ?? default(ObjectCreationHandling); } - set { _objectCreationHandling = value; } - } + /// + /// Gets or sets the default value handling used when serializing this property. + /// + /// The default value handling. + public DefaultValueHandling DefaultValueHandling + { + get { return _defaultValueHandling ?? default(DefaultValueHandling); } + set { _defaultValueHandling = value; } + } - /// - /// Gets or sets the type name handling used when serializing this property. - /// - /// The type name handling. - public TypeNameHandling TypeNameHandling - { - get { return _typeNameHandling ?? default(TypeNameHandling); } - set { _typeNameHandling = value; } - } + /// + /// Gets or sets the reference loop handling used when serializing this property. + /// + /// The reference loop handling. + public ReferenceLoopHandling ReferenceLoopHandling + { + get { return _referenceLoopHandling ?? default(ReferenceLoopHandling); } + set { _referenceLoopHandling = value; } + } - /// - /// Gets or sets whether this property's value is serialized as a reference. - /// - /// Whether this property's value is serialized as a reference. - public bool IsReference - { - get { return _isReference ?? default(bool); } - set { _isReference = value; } - } + /// + /// Gets or sets the object creation handling used when deserializing this property. + /// + /// The object creation handling. + public ObjectCreationHandling ObjectCreationHandling + { + get { return _objectCreationHandling ?? default(ObjectCreationHandling); } + set { _objectCreationHandling = value; } + } - /// - /// Gets or sets the order of serialization and deserialization of a member. - /// - /// The numeric order of serialization or deserialization. - public int Order - { - get { return _order ?? default(int); } - set { _order = value; } - } + /// + /// Gets or sets the type name handling used when serializing this property. + /// + /// The type name handling. + public TypeNameHandling TypeNameHandling + { + get { return _typeNameHandling ?? default(TypeNameHandling); } + set { _typeNameHandling = value; } + } - /// - /// Gets or sets a value indicating whether this property is required. - /// - /// - /// A value indicating whether this property is required. - /// - public Required Required - { - get { return _required ?? Required.Default; } - set { _required = value; } - } + /// + /// Gets or sets whether this property's value is serialized as a reference. + /// + /// Whether this property's value is serialized as a reference. + public bool IsReference + { + get { return _isReference ?? default(bool); } + set { _isReference = value; } + } - /// - /// Gets or sets the name of the property. - /// - /// The name of the property. - public string PropertyName { get; set; } + /// + /// Gets or sets the order of serialization and deserialization of a member. + /// + /// The numeric order of serialization or deserialization. + public int Order + { + get { return _order ?? default(int); } + set { _order = value; } + } - /// - /// Gets or sets the the reference loop handling used when serializing the property's collection items. - /// - /// The collection's items reference loop handling. - public ReferenceLoopHandling ItemReferenceLoopHandling - { - get { return _itemReferenceLoopHandling ?? default(ReferenceLoopHandling); } - set { _itemReferenceLoopHandling = value; } - } + /// + /// Gets or sets a value indicating whether this property is required. + /// + /// + /// A value indicating whether this property is required. + /// + public Required Required + { + get { return _required ?? Required.Default; } + set { _required = value; } + } - /// - /// Gets or sets the the type name handling used when serializing the property's collection items. - /// - /// The collection's items type name handling. - public TypeNameHandling ItemTypeNameHandling - { - get { return _itemTypeNameHandling ?? default(TypeNameHandling); } - set { _itemTypeNameHandling = value; } - } + /// + /// Gets or sets the name of the property. + /// + /// The name of the property. + public string PropertyName { get; set; } - /// - /// Gets or sets whether this property's collection items are serialized as a reference. - /// - /// Whether this property's collection items are serialized as a reference. - public bool ItemIsReference - { - get { return _itemIsReference ?? default(bool); } - set { _itemIsReference = value; } - } + /// + /// Gets or sets the the reference loop handling used when serializing the property's collection items. + /// + /// The collection's items reference loop handling. + public ReferenceLoopHandling ItemReferenceLoopHandling + { + get { return _itemReferenceLoopHandling ?? default(ReferenceLoopHandling); } + set { _itemReferenceLoopHandling = value; } + } - /// - /// Initializes a new instance of the class. - /// - public JsonPropertyAttribute() - { - } + /// + /// Gets or sets the the type name handling used when serializing the property's collection items. + /// + /// The collection's items type name handling. + public TypeNameHandling ItemTypeNameHandling + { + get { return _itemTypeNameHandling ?? default(TypeNameHandling); } + set { _itemTypeNameHandling = value; } + } - /// - /// Initializes a new instance of the class with the specified name. - /// - /// Name of the property. - public JsonPropertyAttribute(string propertyName) - { - PropertyName = propertyName; + /// + /// Gets or sets whether this property's collection items are serialized as a reference. + /// + /// Whether this property's collection items are serialized as a reference. + public bool ItemIsReference + { + get { return _itemIsReference ?? default(bool); } + set { _itemIsReference = value; } + } + + /// + /// Initializes a new instance of the class. + /// + public JsonPropertyAttribute() + { + } + + /// + /// Initializes a new instance of the class with the specified name. + /// + /// Name of the property. + public JsonPropertyAttribute(string propertyName) + { + PropertyName = propertyName; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/JsonReader.cs b/Src/Newtonsoft.Json/JsonReader.cs index c7990325..d5f29e93 100644 --- a/Src/Newtonsoft.Json/JsonReader.cs +++ b/Src/Newtonsoft.Json/JsonReader.cs @@ -32,913 +32,926 @@ using Newtonsoft.Json.Utilities; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json { - /// - /// Represents a reader that provides fast, non-cached, forward-only access to serialized Json data. - /// - public abstract class JsonReader : IDisposable - { /// - /// Specifies the state of the reader. + /// Represents a reader that provides fast, non-cached, forward-only access to serialized Json data. /// - protected internal enum State + public abstract class JsonReader : IDisposable { - /// - /// The Read method has not been called. - /// - Start, - /// - /// The end of the file has been reached successfully. - /// - Complete, - /// - /// Reader is at a property. - /// - Property, - /// - /// Reader is at the start of an object. - /// - ObjectStart, - /// - /// Reader is in an object. - /// - Object, - /// - /// Reader is at the start of an array. - /// - ArrayStart, - /// - /// Reader is in an array. - /// - Array, - /// - /// The Close method has been called. - /// - Closed, - /// - /// Reader has just read a value. - /// - PostValue, - /// - /// Reader is at the start of a constructor. - /// - ConstructorStart, - /// - /// Reader in a constructor. - /// - Constructor, - /// - /// An error occurred that prevents the read operation from continuing. - /// - Error, - /// - /// The end of the file has been reached successfully. - /// - Finished - } - - // current Token data - private JsonToken _tokenType; - private object _value; - internal char _quoteChar; - internal State _currentState; - internal ReadType _readType; - private JsonPosition _currentPosition; - private CultureInfo _culture; - private DateTimeZoneHandling _dateTimeZoneHandling; - private int? _maxDepth; - private bool _hasExceededMaxDepth; - internal DateParseHandling _dateParseHandling; - internal FloatParseHandling _floatParseHandling; - private readonly List _stack; - - /// - /// Gets the current reader state. - /// - /// The current reader state. - protected State CurrentState - { - get { return _currentState; } - } - - /// - /// Gets or sets a value indicating whether the underlying stream or - /// should be closed when the reader is closed. - /// - /// - /// true to close the underlying stream or when - /// the reader is closed; otherwise false. The default is true. - /// - public bool CloseInput { get; set; } - - /// - /// Gets the quotation mark character used to enclose the value of a string. - /// - public virtual char QuoteChar - { - get { return _quoteChar; } - protected internal set { _quoteChar = value; } - } - - /// - /// Get or set how time zones are handling when reading JSON. - /// - public DateTimeZoneHandling DateTimeZoneHandling - { - get { return _dateTimeZoneHandling; } - set { _dateTimeZoneHandling = value; } - } - - /// - /// Get or set how date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed when reading JSON. - /// - public DateParseHandling DateParseHandling - { - get { return _dateParseHandling; } - set { _dateParseHandling = value; } - } - - /// - /// Get or set how floating point numbers, e.g. 1.0 and 9.9, are parsed when reading JSON text. - /// - public FloatParseHandling FloatParseHandling - { - get { return _floatParseHandling; } - set { _floatParseHandling = value; } - } - - /// - /// Gets or sets the maximum depth allowed when reading JSON. Reading past this depth will throw a . - /// - public int? MaxDepth - { - get { return _maxDepth; } - set - { - if (value <= 0) - throw new ArgumentException("Value must be positive.", "value"); - - _maxDepth = value; - } - } - - /// - /// Gets the type of the current JSON token. - /// - public virtual JsonToken TokenType - { - get { return _tokenType; } - } - - /// - /// Gets the text value of the current JSON token. - /// - public virtual object Value - { - get { return _value; } - } - - /// - /// Gets The Common Language Runtime (CLR) type for the current JSON token. - /// - public virtual Type ValueType - { - get { return (_value != null) ? _value.GetType() : null; } - } - - /// - /// Gets the depth of the current token in the JSON document. - /// - /// The depth of the current token in the JSON document. - public virtual int Depth - { - get - { - int depth = _stack.Count; - if (IsStartToken(TokenType) || _currentPosition.Type == JsonContainerType.None) - return depth; - else - return depth + 1; - } - } - - /// - /// Gets the path of the current JSON token. - /// - public virtual string Path - { - get - { - if (_currentPosition.Type == JsonContainerType.None) - return string.Empty; - - bool insideContainer = (_currentState != State.ArrayStart - && _currentState != State.ConstructorStart - && _currentState != State.ObjectStart); - - IEnumerable positions = (!insideContainer) - ? _stack - : _stack.Concat(new[] {_currentPosition}); - - return JsonPosition.BuildPath(positions); - } - } - - /// - /// Gets or sets the culture used when reading JSON. Defaults to . - /// - public CultureInfo Culture - { - get { return _culture ?? CultureInfo.InvariantCulture; } - set { _culture = value; } - } - - internal JsonPosition GetPosition(int depth) - { - if (depth < _stack.Count) - return _stack[depth]; - - return _currentPosition; - } - - /// - /// Initializes a new instance of the class with the specified . - /// - protected JsonReader() - { - _currentState = State.Start; - _stack = new List(4); - _dateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind; - _dateParseHandling = DateParseHandling.DateTime; - _floatParseHandling = FloatParseHandling.Double; - - CloseInput = true; - } - - private void Push(JsonContainerType value) - { - UpdateScopeWithFinishedValue(); - - if (_currentPosition.Type == JsonContainerType.None) - { - _currentPosition = new JsonPosition(value); - } - else - { - _stack.Add(_currentPosition); - _currentPosition = new JsonPosition(value); - - // this is a little hacky because Depth increases when first property/value is written but only testing here is faster/simpler - if (_maxDepth != null && Depth + 1 > _maxDepth && !_hasExceededMaxDepth) + /// + /// Specifies the state of the reader. + /// + protected internal enum State { - _hasExceededMaxDepth = true; - throw JsonReaderException.Create(this, "The reader's MaxDepth of {0} has been exceeded.".FormatWith(CultureInfo.InvariantCulture, _maxDepth)); - } - } - } + /// + /// The Read method has not been called. + /// + Start, - private JsonContainerType Pop() - { - JsonPosition oldPosition; - if (_stack.Count > 0) - { - oldPosition = _currentPosition; - _currentPosition = _stack[_stack.Count - 1]; - _stack.RemoveAt(_stack.Count - 1); - } - else - { - oldPosition = _currentPosition; - _currentPosition = new JsonPosition(); - } + /// + /// The end of the file has been reached successfully. + /// + Complete, - if (_maxDepth != null && Depth <= _maxDepth) - _hasExceededMaxDepth = false; + /// + /// Reader is at a property. + /// + Property, - return oldPosition.Type; - } + /// + /// Reader is at the start of an object. + /// + ObjectStart, - private JsonContainerType Peek() - { - return _currentPosition.Type; - } + /// + /// Reader is in an object. + /// + Object, - /// - /// Reads the next JSON token from the stream. - /// - /// true if the next token was read successfully; false if there are no more tokens to read. - public abstract bool Read(); + /// + /// Reader is at the start of an array. + /// + ArrayStart, - /// - /// Reads the next JSON token from the stream as a . - /// - /// A . This method will return null at the end of an array. - public abstract int? ReadAsInt32(); + /// + /// Reader is in an array. + /// + Array, - /// - /// Reads the next JSON token from the stream as a . - /// - /// A . This method will return null at the end of an array. - public abstract string ReadAsString(); + /// + /// The Close method has been called. + /// + Closed, - /// - /// Reads the next JSON token from the stream as a . - /// - /// A or a null reference if the next JSON token is null. This method will return null at the end of an array. - public abstract byte[] ReadAsBytes(); + /// + /// Reader has just read a value. + /// + PostValue, - /// - /// Reads the next JSON token from the stream as a . - /// - /// A . This method will return null at the end of an array. - public abstract decimal? ReadAsDecimal(); + /// + /// Reader is at the start of a constructor. + /// + ConstructorStart, - /// - /// Reads the next JSON token from the stream as a . - /// - /// A . This method will return null at the end of an array. - public abstract DateTime? ReadAsDateTime(); + /// + /// Reader in a constructor. + /// + Constructor, -#if !NET20 - /// - /// Reads the next JSON token from the stream as a . - /// - /// A . This method will return null at the end of an array. - public abstract DateTimeOffset? ReadAsDateTimeOffset(); -#endif + /// + /// An error occurred that prevents the read operation from continuing. + /// + Error, - internal virtual bool ReadInternal() - { - throw new NotImplementedException(); - } - -#if !NET20 - internal DateTimeOffset? ReadAsDateTimeOffsetInternal() - { - _readType = ReadType.ReadAsDateTimeOffset; - - JsonToken t; - - do - { - if (!ReadInternal()) - { - SetToken(JsonToken.None); - return null; - } - else - { - t = TokenType; - } - } while (t == JsonToken.Comment); - - if (t == JsonToken.Date) - { - if (Value is DateTime) - SetToken(JsonToken.Date, new DateTimeOffset((DateTime)Value)); - - return (DateTimeOffset)Value; - } - - if (t == JsonToken.Null) - return null; - - DateTimeOffset dt; - if (t == JsonToken.String) - { - string s = (string)Value; - if (string.IsNullOrEmpty(s)) - { - SetToken(JsonToken.Null); - return null; + /// + /// The end of the file has been reached successfully. + /// + Finished } - if (DateTimeOffset.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt)) + // current Token data + private JsonToken _tokenType; + private object _value; + internal char _quoteChar; + internal State _currentState; + internal ReadType _readType; + private JsonPosition _currentPosition; + private CultureInfo _culture; + private DateTimeZoneHandling _dateTimeZoneHandling; + private int? _maxDepth; + private bool _hasExceededMaxDepth; + internal DateParseHandling _dateParseHandling; + internal FloatParseHandling _floatParseHandling; + private readonly List _stack; + + /// + /// Gets the current reader state. + /// + /// The current reader state. + protected State CurrentState { - SetToken(JsonToken.Date, dt); - return dt; - } - else - { - throw JsonReaderException.Create(this, "Could not convert string to DateTimeOffset: {0}.".FormatWith(CultureInfo.InvariantCulture, Value)); - } - } - - if (t == JsonToken.EndArray) - return null; - - throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, t)); - } -#endif - - internal byte[] ReadAsBytesInternal() - { - _readType = ReadType.ReadAsBytes; - - JsonToken t; - - do - { - if (!ReadInternal()) - { - SetToken(JsonToken.None); - return null; - } - else - { - t = TokenType; - } - } while (t == JsonToken.Comment); - - if (IsWrappedInTypeObject()) - { - byte[] data = ReadAsBytes(); - ReadInternal(); - SetToken(JsonToken.Bytes, data); - return data; - } - - // attempt to convert possible base 64 string to bytes - if (t == JsonToken.String) - { - string s = (string)Value; - byte[] data = (s.Length == 0) ? new byte[0] : Convert.FromBase64String(s); - SetToken(JsonToken.Bytes, data); - return data; - } - - if (t == JsonToken.Null) - return null; - - if (t == JsonToken.Bytes) - return (byte[])Value; - - if (t == JsonToken.StartArray) - { - List data = new List(); - - while (ReadInternal()) - { - t = TokenType; - switch (t) - { - case JsonToken.Integer: - data.Add(Convert.ToByte(Value, CultureInfo.InvariantCulture)); - break; - case JsonToken.EndArray: - byte[] d = data.ToArray(); - SetToken(JsonToken.Bytes, d); - return d; - case JsonToken.Comment: - // skip - break; - default: - throw JsonReaderException.Create(this, "Unexpected token when reading bytes: {0}.".FormatWith(CultureInfo.InvariantCulture, t)); - } + get { return _currentState; } } - throw JsonReaderException.Create(this, "Unexpected end when reading bytes."); - } + /// + /// Gets or sets a value indicating whether the underlying stream or + /// should be closed when the reader is closed. + /// + /// + /// true to close the underlying stream or when + /// the reader is closed; otherwise false. The default is true. + /// + public bool CloseInput { get; set; } - if (t == JsonToken.EndArray) - return null; - - throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, t)); - } - - internal decimal? ReadAsDecimalInternal() - { - _readType = ReadType.ReadAsDecimal; - - JsonToken t; - - do - { - if (!ReadInternal()) + /// + /// Gets the quotation mark character used to enclose the value of a string. + /// + public virtual char QuoteChar { - SetToken(JsonToken.None); - return null; - } - else - { - t = TokenType; - } - } while (t == JsonToken.Comment); - - if (t == JsonToken.Integer || t == JsonToken.Float) - { - if (!(Value is decimal)) - SetToken(JsonToken.Float, Convert.ToDecimal(Value, CultureInfo.InvariantCulture)); - - return (decimal)Value; - } - - if (t == JsonToken.Null) - return null; - - decimal d; - if (t == JsonToken.String) - { - string s = (string)Value; - if (string.IsNullOrEmpty(s)) - { - SetToken(JsonToken.Null); - return null; + get { return _quoteChar; } + protected internal set { _quoteChar = value; } } - if (decimal.TryParse(s, NumberStyles.Number, Culture, out d)) + /// + /// Get or set how time zones are handling when reading JSON. + /// + public DateTimeZoneHandling DateTimeZoneHandling { - SetToken(JsonToken.Float, d); - return d; - } - else - { - throw JsonReaderException.Create(this, "Could not convert string to decimal: {0}.".FormatWith(CultureInfo.InvariantCulture, Value)); - } - } - - if (t == JsonToken.EndArray) - return null; - - throw JsonReaderException.Create(this, "Error reading decimal. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, t)); - } - - internal int? ReadAsInt32Internal() - { - _readType = ReadType.ReadAsInt32; - - JsonToken t; - - do - { - if (!ReadInternal()) - { - SetToken(JsonToken.None); - return null; - } - else - { - t = TokenType; - } - } while (t == JsonToken.Comment); - - if (t == JsonToken.Integer || t == JsonToken.Float) - { - if (!(Value is int)) - SetToken(JsonToken.Integer, Convert.ToInt32(Value, CultureInfo.InvariantCulture)); - - return (int)Value; - } - - if (t == JsonToken.Null) - return null; - - int i; - if (t == JsonToken.String) - { - string s = (string)Value; - if (string.IsNullOrEmpty(s)) - { - SetToken(JsonToken.Null); - return null; + get { return _dateTimeZoneHandling; } + set { _dateTimeZoneHandling = value; } } - if (int.TryParse(s, NumberStyles.Integer, Culture, out i)) + /// + /// Get or set how date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed when reading JSON. + /// + public DateParseHandling DateParseHandling { - SetToken(JsonToken.Integer, i); - return i; - } - else - { - throw JsonReaderException.Create(this, "Could not convert string to integer: {0}.".FormatWith(CultureInfo.InvariantCulture, Value)); - } - } - - if (t == JsonToken.EndArray) - return null; - - throw JsonReaderException.Create(this, "Error reading integer. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType)); - } - - internal string ReadAsStringInternal() - { - _readType = ReadType.ReadAsString; - - JsonToken t; - - do - { - if (!ReadInternal()) - { - SetToken(JsonToken.None); - return null; - } - else - { - t = TokenType; - } - } while (t == JsonToken.Comment); - - if (t == JsonToken.String) - return (string)Value; - - if (t == JsonToken.Null) - return null; - - if (IsPrimitiveToken(t)) - { - if (Value != null) - { - string s; - if (Value is IFormattable) - s = ((IFormattable)Value).ToString(null, Culture); - else - s = Value.ToString(); - - SetToken(JsonToken.String, s); - return s; - } - } - - if (t == JsonToken.EndArray) - return null; - - throw JsonReaderException.Create(this, "Error reading string. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, t)); - } - - internal DateTime? ReadAsDateTimeInternal() - { - _readType = ReadType.ReadAsDateTime; - - do - { - if (!ReadInternal()) - { - SetToken(JsonToken.None); - return null; - } - } while (TokenType == JsonToken.Comment); - - if (TokenType == JsonToken.Date) - return (DateTime)Value; - - if (TokenType == JsonToken.Null) - return null; - - DateTime dt; - if (TokenType == JsonToken.String) - { - string s = (string)Value; - if (string.IsNullOrEmpty(s)) - { - SetToken(JsonToken.Null); - return null; + get { return _dateParseHandling; } + set { _dateParseHandling = value; } } - if (DateTime.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt)) + /// + /// Get or set how floating point numbers, e.g. 1.0 and 9.9, are parsed when reading JSON text. + /// + public FloatParseHandling FloatParseHandling { - dt = DateTimeUtils.EnsureDateTime(dt, DateTimeZoneHandling); - SetToken(JsonToken.Date, dt); - return dt; + get { return _floatParseHandling; } + set { _floatParseHandling = value; } } - else + + /// + /// Gets or sets the maximum depth allowed when reading JSON. Reading past this depth will throw a . + /// + public int? MaxDepth { - throw JsonReaderException.Create(this, "Could not convert string to DateTime: {0}.".FormatWith(CultureInfo.InvariantCulture, Value)); - } - } - - if (TokenType == JsonToken.EndArray) - return null; - - throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType)); - } - - private bool IsWrappedInTypeObject() - { - _readType = ReadType.Read; - - if (TokenType == JsonToken.StartObject) - { - if (!ReadInternal()) - throw JsonReaderException.Create(this, "Unexpected end when reading bytes."); - - if (Value.ToString() == "$type") - { - ReadInternal(); - if (Value != null && Value.ToString().StartsWith("System.Byte[]")) - { - ReadInternal(); - if (Value.ToString() == "$value") + get { return _maxDepth; } + set { - return true; + if (value <= 0) + throw new ArgumentException("Value must be positive.", "value"); + + _maxDepth = value; } - } } - throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, JsonToken.StartObject)); - } - - return false; - } - - /// - /// Skips the children of the current token. - /// - public void Skip() - { - if (TokenType == JsonToken.PropertyName) - Read(); - - if (IsStartToken(TokenType)) - { - int depth = Depth; - - while (Read() && (depth < Depth)) + /// + /// Gets the type of the current JSON token. + /// + public virtual JsonToken TokenType { + get { return _tokenType; } + } + + /// + /// Gets the text value of the current JSON token. + /// + public virtual object Value + { + get { return _value; } + } + + /// + /// Gets The Common Language Runtime (CLR) type for the current JSON token. + /// + public virtual Type ValueType + { + get { return (_value != null) ? _value.GetType() : null; } + } + + /// + /// Gets the depth of the current token in the JSON document. + /// + /// The depth of the current token in the JSON document. + public virtual int Depth + { + get + { + int depth = _stack.Count; + if (IsStartToken(TokenType) || _currentPosition.Type == JsonContainerType.None) + return depth; + else + return depth + 1; + } + } + + /// + /// Gets the path of the current JSON token. + /// + public virtual string Path + { + get + { + if (_currentPosition.Type == JsonContainerType.None) + return string.Empty; + + bool insideContainer = (_currentState != State.ArrayStart + && _currentState != State.ConstructorStart + && _currentState != State.ObjectStart); + + IEnumerable positions = (!insideContainer) + ? _stack + : _stack.Concat(new[] { _currentPosition }); + + return JsonPosition.BuildPath(positions); + } + } + + /// + /// Gets or sets the culture used when reading JSON. Defaults to . + /// + public CultureInfo Culture + { + get { return _culture ?? CultureInfo.InvariantCulture; } + set { _culture = value; } + } + + internal JsonPosition GetPosition(int depth) + { + if (depth < _stack.Count) + return _stack[depth]; + + return _currentPosition; + } + + /// + /// Initializes a new instance of the class with the specified . + /// + protected JsonReader() + { + _currentState = State.Start; + _stack = new List(4); + _dateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind; + _dateParseHandling = DateParseHandling.DateTime; + _floatParseHandling = FloatParseHandling.Double; + + CloseInput = true; + } + + private void Push(JsonContainerType value) + { + UpdateScopeWithFinishedValue(); + + if (_currentPosition.Type == JsonContainerType.None) + { + _currentPosition = new JsonPosition(value); + } + else + { + _stack.Add(_currentPosition); + _currentPosition = new JsonPosition(value); + + // this is a little hacky because Depth increases when first property/value is written but only testing here is faster/simpler + if (_maxDepth != null && Depth + 1 > _maxDepth && !_hasExceededMaxDepth) + { + _hasExceededMaxDepth = true; + throw JsonReaderException.Create(this, "The reader's MaxDepth of {0} has been exceeded.".FormatWith(CultureInfo.InvariantCulture, _maxDepth)); + } + } + } + + private JsonContainerType Pop() + { + JsonPosition oldPosition; + if (_stack.Count > 0) + { + oldPosition = _currentPosition; + _currentPosition = _stack[_stack.Count - 1]; + _stack.RemoveAt(_stack.Count - 1); + } + else + { + oldPosition = _currentPosition; + _currentPosition = new JsonPosition(); + } + + if (_maxDepth != null && Depth <= _maxDepth) + _hasExceededMaxDepth = false; + + return oldPosition.Type; + } + + private JsonContainerType Peek() + { + return _currentPosition.Type; + } + + /// + /// Reads the next JSON token from the stream. + /// + /// true if the next token was read successfully; false if there are no more tokens to read. + public abstract bool Read(); + + /// + /// Reads the next JSON token from the stream as a . + /// + /// A . This method will return null at the end of an array. + public abstract int? ReadAsInt32(); + + /// + /// Reads the next JSON token from the stream as a . + /// + /// A . This method will return null at the end of an array. + public abstract string ReadAsString(); + + /// + /// Reads the next JSON token from the stream as a . + /// + /// A or a null reference if the next JSON token is null. This method will return null at the end of an array. + public abstract byte[] ReadAsBytes(); + + /// + /// Reads the next JSON token from the stream as a . + /// + /// A . This method will return null at the end of an array. + public abstract decimal? ReadAsDecimal(); + + /// + /// Reads the next JSON token from the stream as a . + /// + /// A . This method will return null at the end of an array. + public abstract DateTime? ReadAsDateTime(); + +#if !NET20 + /// + /// Reads the next JSON token from the stream as a . + /// + /// A . This method will return null at the end of an array. + public abstract DateTimeOffset? ReadAsDateTimeOffset(); +#endif + + internal virtual bool ReadInternal() + { + throw new NotImplementedException(); + } + +#if !NET20 + internal DateTimeOffset? ReadAsDateTimeOffsetInternal() + { + _readType = ReadType.ReadAsDateTimeOffset; + + JsonToken t; + + do + { + if (!ReadInternal()) + { + SetToken(JsonToken.None); + return null; + } + else + { + t = TokenType; + } + } while (t == JsonToken.Comment); + + if (t == JsonToken.Date) + { + if (Value is DateTime) + SetToken(JsonToken.Date, new DateTimeOffset((DateTime)Value)); + + return (DateTimeOffset)Value; + } + + if (t == JsonToken.Null) + return null; + + DateTimeOffset dt; + if (t == JsonToken.String) + { + string s = (string)Value; + if (string.IsNullOrEmpty(s)) + { + SetToken(JsonToken.Null); + return null; + } + + if (DateTimeOffset.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt)) + { + SetToken(JsonToken.Date, dt); + return dt; + } + else + { + throw JsonReaderException.Create(this, "Could not convert string to DateTimeOffset: {0}.".FormatWith(CultureInfo.InvariantCulture, Value)); + } + } + + if (t == JsonToken.EndArray) + return null; + + throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, t)); + } +#endif + + internal byte[] ReadAsBytesInternal() + { + _readType = ReadType.ReadAsBytes; + + JsonToken t; + + do + { + if (!ReadInternal()) + { + SetToken(JsonToken.None); + return null; + } + else + { + t = TokenType; + } + } while (t == JsonToken.Comment); + + if (IsWrappedInTypeObject()) + { + byte[] data = ReadAsBytes(); + ReadInternal(); + SetToken(JsonToken.Bytes, data); + return data; + } + + // attempt to convert possible base 64 string to bytes + if (t == JsonToken.String) + { + string s = (string)Value; + byte[] data = (s.Length == 0) ? new byte[0] : Convert.FromBase64String(s); + SetToken(JsonToken.Bytes, data); + return data; + } + + if (t == JsonToken.Null) + return null; + + if (t == JsonToken.Bytes) + return (byte[])Value; + + if (t == JsonToken.StartArray) + { + List data = new List(); + + while (ReadInternal()) + { + t = TokenType; + switch (t) + { + case JsonToken.Integer: + data.Add(Convert.ToByte(Value, CultureInfo.InvariantCulture)); + break; + case JsonToken.EndArray: + byte[] d = data.ToArray(); + SetToken(JsonToken.Bytes, d); + return d; + case JsonToken.Comment: + // skip + break; + default: + throw JsonReaderException.Create(this, "Unexpected token when reading bytes: {0}.".FormatWith(CultureInfo.InvariantCulture, t)); + } + } + + throw JsonReaderException.Create(this, "Unexpected end when reading bytes."); + } + + if (t == JsonToken.EndArray) + return null; + + throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, t)); + } + + internal decimal? ReadAsDecimalInternal() + { + _readType = ReadType.ReadAsDecimal; + + JsonToken t; + + do + { + if (!ReadInternal()) + { + SetToken(JsonToken.None); + return null; + } + else + { + t = TokenType; + } + } while (t == JsonToken.Comment); + + if (t == JsonToken.Integer || t == JsonToken.Float) + { + if (!(Value is decimal)) + SetToken(JsonToken.Float, Convert.ToDecimal(Value, CultureInfo.InvariantCulture)); + + return (decimal)Value; + } + + if (t == JsonToken.Null) + return null; + + decimal d; + if (t == JsonToken.String) + { + string s = (string)Value; + if (string.IsNullOrEmpty(s)) + { + SetToken(JsonToken.Null); + return null; + } + + if (decimal.TryParse(s, NumberStyles.Number, Culture, out d)) + { + SetToken(JsonToken.Float, d); + return d; + } + else + { + throw JsonReaderException.Create(this, "Could not convert string to decimal: {0}.".FormatWith(CultureInfo.InvariantCulture, Value)); + } + } + + if (t == JsonToken.EndArray) + return null; + + throw JsonReaderException.Create(this, "Error reading decimal. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, t)); + } + + internal int? ReadAsInt32Internal() + { + _readType = ReadType.ReadAsInt32; + + JsonToken t; + + do + { + if (!ReadInternal()) + { + SetToken(JsonToken.None); + return null; + } + else + { + t = TokenType; + } + } while (t == JsonToken.Comment); + + if (t == JsonToken.Integer || t == JsonToken.Float) + { + if (!(Value is int)) + SetToken(JsonToken.Integer, Convert.ToInt32(Value, CultureInfo.InvariantCulture)); + + return (int)Value; + } + + if (t == JsonToken.Null) + return null; + + int i; + if (t == JsonToken.String) + { + string s = (string)Value; + if (string.IsNullOrEmpty(s)) + { + SetToken(JsonToken.Null); + return null; + } + + if (int.TryParse(s, NumberStyles.Integer, Culture, out i)) + { + SetToken(JsonToken.Integer, i); + return i; + } + else + { + throw JsonReaderException.Create(this, "Could not convert string to integer: {0}.".FormatWith(CultureInfo.InvariantCulture, Value)); + } + } + + if (t == JsonToken.EndArray) + return null; + + throw JsonReaderException.Create(this, "Error reading integer. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType)); + } + + internal string ReadAsStringInternal() + { + _readType = ReadType.ReadAsString; + + JsonToken t; + + do + { + if (!ReadInternal()) + { + SetToken(JsonToken.None); + return null; + } + else + { + t = TokenType; + } + } while (t == JsonToken.Comment); + + if (t == JsonToken.String) + return (string)Value; + + if (t == JsonToken.Null) + return null; + + if (IsPrimitiveToken(t)) + { + if (Value != null) + { + string s; + if (Value is IFormattable) + s = ((IFormattable)Value).ToString(null, Culture); + else + s = Value.ToString(); + + SetToken(JsonToken.String, s); + return s; + } + } + + if (t == JsonToken.EndArray) + return null; + + throw JsonReaderException.Create(this, "Error reading string. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, t)); + } + + internal DateTime? ReadAsDateTimeInternal() + { + _readType = ReadType.ReadAsDateTime; + + do + { + if (!ReadInternal()) + { + SetToken(JsonToken.None); + return null; + } + } while (TokenType == JsonToken.Comment); + + if (TokenType == JsonToken.Date) + return (DateTime)Value; + + if (TokenType == JsonToken.Null) + return null; + + DateTime dt; + if (TokenType == JsonToken.String) + { + string s = (string)Value; + if (string.IsNullOrEmpty(s)) + { + SetToken(JsonToken.Null); + return null; + } + + if (DateTime.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt)) + { + dt = DateTimeUtils.EnsureDateTime(dt, DateTimeZoneHandling); + SetToken(JsonToken.Date, dt); + return dt; + } + else + { + throw JsonReaderException.Create(this, "Could not convert string to DateTime: {0}.".FormatWith(CultureInfo.InvariantCulture, Value)); + } + } + + if (TokenType == JsonToken.EndArray) + return null; + + throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType)); + } + + private bool IsWrappedInTypeObject() + { + _readType = ReadType.Read; + + if (TokenType == JsonToken.StartObject) + { + if (!ReadInternal()) + throw JsonReaderException.Create(this, "Unexpected end when reading bytes."); + + if (Value.ToString() == "$type") + { + ReadInternal(); + if (Value != null && Value.ToString().StartsWith("System.Byte[]")) + { + ReadInternal(); + if (Value.ToString() == "$value") + { + return true; + } + } + } + + throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, JsonToken.StartObject)); + } + + return false; + } + + /// + /// Skips the children of the current token. + /// + public void Skip() + { + if (TokenType == JsonToken.PropertyName) + Read(); + + if (IsStartToken(TokenType)) + { + int depth = Depth; + + while (Read() && (depth < Depth)) + { + } + } + } + + /// + /// Sets the current token. + /// + /// The new token. + protected void SetToken(JsonToken newToken) + { + SetToken(newToken, null); + } + + /// + /// Sets the current token and value. + /// + /// The new token. + /// The value. + protected void SetToken(JsonToken newToken, object value) + { + _tokenType = newToken; + _value = value; + + switch (newToken) + { + case JsonToken.StartObject: + _currentState = State.ObjectStart; + Push(JsonContainerType.Object); + break; + case JsonToken.StartArray: + _currentState = State.ArrayStart; + Push(JsonContainerType.Array); + break; + case JsonToken.StartConstructor: + _currentState = State.ConstructorStart; + Push(JsonContainerType.Constructor); + break; + case JsonToken.EndObject: + ValidateEnd(JsonToken.EndObject); + break; + case JsonToken.EndArray: + ValidateEnd(JsonToken.EndArray); + break; + case JsonToken.EndConstructor: + ValidateEnd(JsonToken.EndConstructor); + break; + case JsonToken.PropertyName: + _currentState = State.Property; + + _currentPosition.PropertyName = (string)value; + break; + case JsonToken.Undefined: + case JsonToken.Integer: + case JsonToken.Float: + case JsonToken.Boolean: + case JsonToken.Null: + case JsonToken.Date: + case JsonToken.String: + case JsonToken.Raw: + case JsonToken.Bytes: + _currentState = (Peek() != JsonContainerType.None) ? State.PostValue : State.Finished; + + UpdateScopeWithFinishedValue(); + break; + } + } + + private void UpdateScopeWithFinishedValue() + { + if (_currentPosition.HasIndex) + _currentPosition.Position++; + } + + private void ValidateEnd(JsonToken endToken) + { + JsonContainerType currentObject = Pop(); + + if (GetTypeForCloseToken(endToken) != currentObject) + throw JsonReaderException.Create(this, "JsonToken {0} is not valid for closing JsonType {1}.".FormatWith(CultureInfo.InvariantCulture, endToken, currentObject)); + + _currentState = (Peek() != JsonContainerType.None) ? State.PostValue : State.Finished; + } + + /// + /// Sets the state based on current token type. + /// + protected void SetStateBasedOnCurrent() + { + JsonContainerType currentObject = Peek(); + + switch (currentObject) + { + case JsonContainerType.Object: + _currentState = State.Object; + break; + case JsonContainerType.Array: + _currentState = State.Array; + break; + case JsonContainerType.Constructor: + _currentState = State.Constructor; + break; + case JsonContainerType.None: + _currentState = State.Finished; + break; + default: + throw JsonReaderException.Create(this, "While setting the reader state back to current object an unexpected JsonType was encountered: {0}".FormatWith(CultureInfo.InvariantCulture, currentObject)); + } + } + + internal static bool IsPrimitiveToken(JsonToken token) + { + switch (token) + { + case JsonToken.Integer: + case JsonToken.Float: + case JsonToken.String: + case JsonToken.Boolean: + case JsonToken.Undefined: + case JsonToken.Null: + case JsonToken.Date: + case JsonToken.Bytes: + return true; + default: + return false; + } + } + + internal static bool IsStartToken(JsonToken token) + { + switch (token) + { + case JsonToken.StartObject: + case JsonToken.StartArray: + case JsonToken.StartConstructor: + return true; + default: + return false; + } + } + + private JsonContainerType GetTypeForCloseToken(JsonToken token) + { + switch (token) + { + case JsonToken.EndObject: + return JsonContainerType.Object; + case JsonToken.EndArray: + return JsonContainerType.Array; + case JsonToken.EndConstructor: + return JsonContainerType.Constructor; + default: + throw JsonReaderException.Create(this, "Not a valid close JsonToken: {0}".FormatWith(CultureInfo.InvariantCulture, token)); + } + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + void IDisposable.Dispose() + { + Dispose(true); + } + + /// + /// Releases unmanaged and - optionally - managed resources + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool disposing) + { + if (_currentState != State.Closed && disposing) + Close(); + } + + /// + /// Changes the to Closed. + /// + public virtual void Close() + { + _currentState = State.Closed; + _tokenType = JsonToken.None; + _value = null; } - } } - - /// - /// Sets the current token. - /// - /// The new token. - protected void SetToken(JsonToken newToken) - { - SetToken(newToken, null); - } - - /// - /// Sets the current token and value. - /// - /// The new token. - /// The value. - protected void SetToken(JsonToken newToken, object value) - { - _tokenType = newToken; - _value = value; - - switch (newToken) - { - case JsonToken.StartObject: - _currentState = State.ObjectStart; - Push(JsonContainerType.Object); - break; - case JsonToken.StartArray: - _currentState = State.ArrayStart; - Push(JsonContainerType.Array); - break; - case JsonToken.StartConstructor: - _currentState = State.ConstructorStart; - Push(JsonContainerType.Constructor); - break; - case JsonToken.EndObject: - ValidateEnd(JsonToken.EndObject); - break; - case JsonToken.EndArray: - ValidateEnd(JsonToken.EndArray); - break; - case JsonToken.EndConstructor: - ValidateEnd(JsonToken.EndConstructor); - break; - case JsonToken.PropertyName: - _currentState = State.Property; - - _currentPosition.PropertyName = (string) value; - break; - case JsonToken.Undefined: - case JsonToken.Integer: - case JsonToken.Float: - case JsonToken.Boolean: - case JsonToken.Null: - case JsonToken.Date: - case JsonToken.String: - case JsonToken.Raw: - case JsonToken.Bytes: - _currentState = (Peek() != JsonContainerType.None) ? State.PostValue : State.Finished; - - UpdateScopeWithFinishedValue(); - break; - } - } - - private void UpdateScopeWithFinishedValue() - { - if (_currentPosition.HasIndex) - _currentPosition.Position++; - } - - private void ValidateEnd(JsonToken endToken) - { - JsonContainerType currentObject = Pop(); - - if (GetTypeForCloseToken(endToken) != currentObject) - throw JsonReaderException.Create(this, "JsonToken {0} is not valid for closing JsonType {1}.".FormatWith(CultureInfo.InvariantCulture, endToken, currentObject)); - - _currentState = (Peek() != JsonContainerType.None) ? State.PostValue : State.Finished; - } - - /// - /// Sets the state based on current token type. - /// - protected void SetStateBasedOnCurrent() - { - JsonContainerType currentObject = Peek(); - - switch (currentObject) - { - case JsonContainerType.Object: - _currentState = State.Object; - break; - case JsonContainerType.Array: - _currentState = State.Array; - break; - case JsonContainerType.Constructor: - _currentState = State.Constructor; - break; - case JsonContainerType.None: - _currentState = State.Finished; - break; - default: - throw JsonReaderException.Create(this, "While setting the reader state back to current object an unexpected JsonType was encountered: {0}".FormatWith(CultureInfo.InvariantCulture, currentObject)); - } - } - - internal static bool IsPrimitiveToken(JsonToken token) - { - switch (token) - { - case JsonToken.Integer: - case JsonToken.Float: - case JsonToken.String: - case JsonToken.Boolean: - case JsonToken.Undefined: - case JsonToken.Null: - case JsonToken.Date: - case JsonToken.Bytes: - return true; - default: - return false; - } - } - - internal static bool IsStartToken(JsonToken token) - { - switch (token) - { - case JsonToken.StartObject: - case JsonToken.StartArray: - case JsonToken.StartConstructor: - return true; - default: - return false; - } - } - - private JsonContainerType GetTypeForCloseToken(JsonToken token) - { - switch (token) - { - case JsonToken.EndObject: - return JsonContainerType.Object; - case JsonToken.EndArray: - return JsonContainerType.Array; - case JsonToken.EndConstructor: - return JsonContainerType.Constructor; - default: - throw JsonReaderException.Create(this, "Not a valid close JsonToken: {0}".FormatWith(CultureInfo.InvariantCulture, token)); - } - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - void IDisposable.Dispose() - { - Dispose(true); - } - - /// - /// Releases unmanaged and - optionally - managed resources - /// - /// true to release both managed and unmanaged resources; false to release only unmanaged resources. - protected virtual void Dispose(bool disposing) - { - if (_currentState != State.Closed && disposing) - Close(); - } - - /// - /// Changes the to Closed. - /// - public virtual void Close() - { - _currentState = State.Closed; - _tokenType = JsonToken.None; - _value = null; - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/JsonReaderException.cs b/Src/Newtonsoft.Json/JsonReaderException.cs index e842f381..b54ab5f6 100644 --- a/Src/Newtonsoft.Json/JsonReaderException.cs +++ b/Src/Newtonsoft.Json/JsonReaderException.cs @@ -30,110 +30,110 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json { - /// - /// The exception thrown when an error occurs while reading Json text. - /// + /// + /// The exception thrown when an error occurs while reading Json text. + /// #if !(SILVERLIGHT || WINDOWS_PHONE || NETFX_CORE || PORTABLE || PORTABLE40) - [Serializable] + [Serializable] #endif - public class JsonReaderException : JsonException - { - /// - /// Gets the line number indicating where the error occurred. - /// - /// The line number indicating where the error occurred. - public int LineNumber { get; private set; } - - /// - /// Gets the line position indicating where the error occurred. - /// - /// The line position indicating where the error occurred. - public int LinePosition { get; private set; } - - /// - /// Gets the path to the JSON where the error occurred. - /// - /// The path to the JSON where the error occurred. - public string Path { get; private set; } - - /// - /// Initializes a new instance of the class. - /// - public JsonReaderException() + public class JsonReaderException : JsonException { - } + /// + /// Gets the line number indicating where the error occurred. + /// + /// The line number indicating where the error occurred. + public int LineNumber { get; private set; } - /// - /// Initializes a new instance of the class - /// with a specified error message. - /// - /// The error message that explains the reason for the exception. - public JsonReaderException(string message) - : base(message) - { - } + /// + /// Gets the line position indicating where the error occurred. + /// + /// The line position indicating where the error occurred. + public int LinePosition { get; private set; } - /// - /// Initializes a new instance of the class - /// with a specified error message and a reference to the inner exception that is the cause of this exception. - /// - /// The error message that explains the reason for the exception. - /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - public JsonReaderException(string message, Exception innerException) - : base(message, innerException) - { - } + /// + /// Gets the path to the JSON where the error occurred. + /// + /// The path to the JSON where the error occurred. + public string Path { get; private set; } + + /// + /// Initializes a new instance of the class. + /// + public JsonReaderException() + { + } + + /// + /// Initializes a new instance of the class + /// with a specified error message. + /// + /// The error message that explains the reason for the exception. + public JsonReaderException(string message) + : base(message) + { + } + + /// + /// Initializes a new instance of the class + /// with a specified error message and a reference to the inner exception that is the cause of this exception. + /// + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + public JsonReaderException(string message, Exception innerException) + : base(message, innerException) + { + } #if !(WINDOWS_PHONE || SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) - /// - /// Initializes a new instance of the class. - /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. - /// The parameter is null. - /// The class name is null or is zero (0). - public JsonReaderException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } + /// + /// Initializes a new instance of the class. + /// + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. + /// The parameter is null. + /// The class name is null or is zero (0). + public JsonReaderException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } #endif - internal JsonReaderException(string message, Exception innerException, string path, int lineNumber, int linePosition) - : base(message, innerException) - { - Path = path; - LineNumber = lineNumber; - LinePosition = linePosition; + internal JsonReaderException(string message, Exception innerException, string path, int lineNumber, int linePosition) + : base(message, innerException) + { + Path = path; + LineNumber = lineNumber; + LinePosition = linePosition; + } + + internal static JsonReaderException Create(JsonReader reader, string message) + { + return Create(reader, message, null); + } + + internal static JsonReaderException Create(JsonReader reader, string message, Exception ex) + { + return Create(reader as IJsonLineInfo, reader.Path, message, ex); + } + + internal static JsonReaderException Create(IJsonLineInfo lineInfo, string path, string message, Exception ex) + { + message = JsonPosition.FormatMessage(lineInfo, path, message); + + int lineNumber; + int linePosition; + if (lineInfo != null && lineInfo.HasLineInfo()) + { + lineNumber = lineInfo.LineNumber; + linePosition = lineInfo.LinePosition; + } + else + { + lineNumber = 0; + linePosition = 0; + } + + return new JsonReaderException(message, ex, path, lineNumber, linePosition); + } } - - internal static JsonReaderException Create(JsonReader reader, string message) - { - return Create(reader, message, null); - } - - internal static JsonReaderException Create(JsonReader reader, string message, Exception ex) - { - return Create(reader as IJsonLineInfo, reader.Path, message, ex); - } - - internal static JsonReaderException Create(IJsonLineInfo lineInfo, string path, string message, Exception ex) - { - message = JsonPosition.FormatMessage(lineInfo, path, message); - - int lineNumber; - int linePosition; - if (lineInfo != null && lineInfo.HasLineInfo()) - { - lineNumber = lineInfo.LineNumber; - linePosition = lineInfo.LinePosition; - } - else - { - lineNumber = 0; - linePosition = 0; - } - - return new JsonReaderException(message, ex, path, lineNumber, linePosition); - } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json/JsonSerializationException.cs b/Src/Newtonsoft.Json/JsonSerializationException.cs index 40cfdc00..08d9a92a 100644 --- a/Src/Newtonsoft.Json/JsonSerializationException.cs +++ b/Src/Newtonsoft.Json/JsonSerializationException.cs @@ -30,71 +30,71 @@ using System.Text; namespace Newtonsoft.Json { - /// - /// The exception thrown when an error occurs during Json serialization or deserialization. - /// + /// + /// The exception thrown when an error occurs during Json serialization or deserialization. + /// #if !(SILVERLIGHT || WINDOWS_PHONE || NETFX_CORE || PORTABLE40 || PORTABLE) - [Serializable] + [Serializable] #endif - public class JsonSerializationException : JsonException - { - /// - /// Initializes a new instance of the class. - /// - public JsonSerializationException() + public class JsonSerializationException : JsonException { - } + /// + /// Initializes a new instance of the class. + /// + public JsonSerializationException() + { + } - /// - /// Initializes a new instance of the class - /// with a specified error message. - /// - /// The error message that explains the reason for the exception. - public JsonSerializationException(string message) - : base(message) - { - } + /// + /// Initializes a new instance of the class + /// with a specified error message. + /// + /// The error message that explains the reason for the exception. + public JsonSerializationException(string message) + : base(message) + { + } - /// - /// Initializes a new instance of the class - /// with a specified error message and a reference to the inner exception that is the cause of this exception. - /// - /// The error message that explains the reason for the exception. - /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - public JsonSerializationException(string message, Exception innerException) - : base(message, innerException) - { - } + /// + /// Initializes a new instance of the class + /// with a specified error message and a reference to the inner exception that is the cause of this exception. + /// + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + public JsonSerializationException(string message, Exception innerException) + : base(message, innerException) + { + } #if !(WINDOWS_PHONE || SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) - /// - /// Initializes a new instance of the class. - /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. - /// The parameter is null. - /// The class name is null or is zero (0). - public JsonSerializationException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } + /// + /// Initializes a new instance of the class. + /// + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. + /// The parameter is null. + /// The class name is null or is zero (0). + public JsonSerializationException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } #endif - internal static JsonSerializationException Create(JsonReader reader, string message) - { - return Create(reader, message, null); - } + internal static JsonSerializationException Create(JsonReader reader, string message) + { + return Create(reader, message, null); + } - internal static JsonSerializationException Create(JsonReader reader, string message, Exception ex) - { - return Create(reader as IJsonLineInfo, reader.Path, message, ex); - } + internal static JsonSerializationException Create(JsonReader reader, string message, Exception ex) + { + return Create(reader as IJsonLineInfo, reader.Path, message, ex); + } - internal static JsonSerializationException Create(IJsonLineInfo lineInfo, string path, string message, Exception ex) - { - message = JsonPosition.FormatMessage(lineInfo, path, message); + internal static JsonSerializationException Create(IJsonLineInfo lineInfo, string path, string message, Exception ex) + { + message = JsonPosition.FormatMessage(lineInfo, path, message); - return new JsonSerializationException(message, ex); + return new JsonSerializationException(message, ex); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/JsonSerializer.cs b/Src/Newtonsoft.Json/JsonSerializer.cs index 381aa1e2..bd656d39 100644 --- a/Src/Newtonsoft.Json/JsonSerializer.cs +++ b/Src/Newtonsoft.Json/JsonSerializer.cs @@ -33,874 +33,864 @@ using Newtonsoft.Json.Converters; using Newtonsoft.Json.Serialization; using Newtonsoft.Json.Utilities; using System.Runtime.Serialization; -using ErrorEventArgs=Newtonsoft.Json.Serialization.ErrorEventArgs; +using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs; namespace Newtonsoft.Json { - /// - /// Serializes and deserializes objects into and from the JSON format. - /// The enables you to control how objects are encoded into JSON. - /// - public class JsonSerializer - { - #region Properties_binder - internal TypeNameHandling _typeNameHandling; - internal FormatterAssemblyStyle _typeNameAssemblyFormat; - internal PreserveReferencesHandling _preserveReferencesHandling; - internal ReferenceLoopHandling _referenceLoopHandling; - internal MissingMemberHandling _missingMemberHandling; - internal ObjectCreationHandling _objectCreationHandling; - internal NullValueHandling _nullValueHandling; - internal DefaultValueHandling _defaultValueHandling; - internal ConstructorHandling _constructorHandling; - internal JsonConverterCollection _converters; - internal IContractResolver _contractResolver; - internal ITraceWriter _traceWriter; - internal SerializationBinder _binder; - internal StreamingContext _context; - private IReferenceResolver _referenceResolver; - - private Formatting? _formatting; - private DateFormatHandling? _dateFormatHandling; - private DateTimeZoneHandling? _dateTimeZoneHandling; - private DateParseHandling? _dateParseHandling; - private FloatFormatHandling? _floatFormatHandling; - private FloatParseHandling? _floatParseHandling; - private StringEscapeHandling? _stringEscapeHandling; - private CultureInfo _culture; - private int? _maxDepth; - private bool _maxDepthSet; - private bool? _checkAdditionalContent; - private string _dateFormatString; - private bool _dateFormatStringSet; - /// - /// Occurs when the errors during serialization and deserialization. + /// Serializes and deserializes objects into and from the JSON format. + /// The enables you to control how objects are encoded into JSON. /// - public virtual event EventHandler Error; - - /// - /// Gets or sets the used by the serializer when resolving references. - /// - public virtual IReferenceResolver ReferenceResolver + public class JsonSerializer { - get { return GetReferenceResolver(); } - set - { - if (value == null) - throw new ArgumentNullException("value", "Reference resolver cannot be null."); + #region Properties_binder + internal TypeNameHandling _typeNameHandling; + internal FormatterAssemblyStyle _typeNameAssemblyFormat; + internal PreserveReferencesHandling _preserveReferencesHandling; + internal ReferenceLoopHandling _referenceLoopHandling; + internal MissingMemberHandling _missingMemberHandling; + internal ObjectCreationHandling _objectCreationHandling; + internal NullValueHandling _nullValueHandling; + internal DefaultValueHandling _defaultValueHandling; + internal ConstructorHandling _constructorHandling; + internal JsonConverterCollection _converters; + internal IContractResolver _contractResolver; + internal ITraceWriter _traceWriter; + internal SerializationBinder _binder; + internal StreamingContext _context; + private IReferenceResolver _referenceResolver; - _referenceResolver = value; - } - } + private Formatting? _formatting; + private DateFormatHandling? _dateFormatHandling; + private DateTimeZoneHandling? _dateTimeZoneHandling; + private DateParseHandling? _dateParseHandling; + private FloatFormatHandling? _floatFormatHandling; + private FloatParseHandling? _floatParseHandling; + private StringEscapeHandling? _stringEscapeHandling; + private CultureInfo _culture; + private int? _maxDepth; + private bool _maxDepthSet; + private bool? _checkAdditionalContent; + private string _dateFormatString; + private bool _dateFormatStringSet; - /// - /// Gets or sets the used by the serializer when resolving type names. - /// - public virtual SerializationBinder Binder - { - get - { - return _binder; - } - set - { - if (value == null) - throw new ArgumentNullException("value", "Serialization binder cannot be null."); + /// + /// Occurs when the errors during serialization and deserialization. + /// + public virtual event EventHandler Error; - _binder = value; - } - } - - /// - /// Gets or sets the used by the serializer when writing trace messages. - /// - /// The trace writer. - public virtual ITraceWriter TraceWriter - { - get - { - return _traceWriter; - } - set - { - _traceWriter = value; - } - } - - /// - /// Gets or sets how type name writing and reading is handled by the serializer. - /// - public virtual TypeNameHandling TypeNameHandling - { - get { return _typeNameHandling; } - set - { - if (value < TypeNameHandling.None || value > TypeNameHandling.Auto) - throw new ArgumentOutOfRangeException("value"); - - _typeNameHandling = value; - } - } - - /// - /// Gets or sets how a type name assembly is written and resolved by the serializer. - /// - /// The type name assembly format. - public virtual FormatterAssemblyStyle TypeNameAssemblyFormat - { - get { return _typeNameAssemblyFormat; } - set - { - if (value < FormatterAssemblyStyle.Simple || value > FormatterAssemblyStyle.Full) - throw new ArgumentOutOfRangeException("value"); - - _typeNameAssemblyFormat = value; - } - } - - /// - /// Gets or sets how object references are preserved by the serializer. - /// - public virtual PreserveReferencesHandling PreserveReferencesHandling - { - get { return _preserveReferencesHandling; } - set - { - if (value < PreserveReferencesHandling.None || value > PreserveReferencesHandling.All) - throw new ArgumentOutOfRangeException("value"); - - _preserveReferencesHandling = value; - } - } - - /// - /// Get or set how reference loops (e.g. a class referencing itself) is handled. - /// - public virtual ReferenceLoopHandling ReferenceLoopHandling - { - get { return _referenceLoopHandling; } - set - { - if (value < ReferenceLoopHandling.Error || value > ReferenceLoopHandling.Serialize) - throw new ArgumentOutOfRangeException("value"); - - _referenceLoopHandling = value; - } - } - - /// - /// Get or set how missing members (e.g. JSON contains a property that isn't a member on the object) are handled during deserialization. - /// - public virtual MissingMemberHandling MissingMemberHandling - { - get { return _missingMemberHandling; } - set - { - if (value < MissingMemberHandling.Ignore || value > MissingMemberHandling.Error) - throw new ArgumentOutOfRangeException("value"); - - _missingMemberHandling = value; - } - } - - /// - /// Get or set how null values are handled during serialization and deserialization. - /// - public virtual NullValueHandling NullValueHandling - { - get { return _nullValueHandling; } - set - { - if (value < NullValueHandling.Include || value > NullValueHandling.Ignore) - throw new ArgumentOutOfRangeException("value"); - - _nullValueHandling = value; - } - } - - /// - /// Get or set how null default are handled during serialization and deserialization. - /// - public virtual DefaultValueHandling DefaultValueHandling - { - get { return _defaultValueHandling; } - set - { - if (value < DefaultValueHandling.Include || value > DefaultValueHandling.IgnoreAndPopulate) - throw new ArgumentOutOfRangeException("value"); - - _defaultValueHandling = value; - } - } - - /// - /// Gets or sets how objects are created during deserialization. - /// - /// The object creation handling. - public virtual ObjectCreationHandling ObjectCreationHandling - { - get { return _objectCreationHandling; } - set - { - if (value < ObjectCreationHandling.Auto || value > ObjectCreationHandling.Replace) - throw new ArgumentOutOfRangeException("value"); - - _objectCreationHandling = value; - } - } - - /// - /// Gets or sets how constructors are used during deserialization. - /// - /// The constructor handling. - public virtual ConstructorHandling ConstructorHandling - { - get { return _constructorHandling; } - set - { - if (value < ConstructorHandling.Default || value > ConstructorHandling.AllowNonPublicDefaultConstructor) - throw new ArgumentOutOfRangeException("value"); - - _constructorHandling = value; - } - } - - /// - /// Gets a collection that will be used during serialization. - /// - /// Collection that will be used during serialization. - public virtual JsonConverterCollection Converters - { - get - { - if (_converters == null) - _converters = new JsonConverterCollection(); - - return _converters; - } - } - - /// - /// Gets or sets the contract resolver used by the serializer when - /// serializing .NET objects to JSON and vice versa. - /// - public virtual IContractResolver ContractResolver - { - get { return _contractResolver; } - set { _contractResolver = value ?? DefaultContractResolver.Instance; } - } - - /// - /// Gets or sets the used by the serializer when invoking serialization callback methods. - /// - /// The context. - public virtual StreamingContext Context - { - get { return _context; } - set { _context = value; } - } - - /// - /// Indicates how JSON text output is formatted. - /// - public virtual Formatting Formatting - { - get { return _formatting ?? JsonSerializerSettings.DefaultFormatting; } - set { _formatting = value; } - } - - /// - /// Get or set how dates are written to JSON text. - /// - public virtual DateFormatHandling DateFormatHandling - { - get { return _dateFormatHandling ?? JsonSerializerSettings.DefaultDateFormatHandling; } - set { _dateFormatHandling = value; } - } - - /// - /// Get or set how time zones are handling during serialization and deserialization. - /// - public virtual DateTimeZoneHandling DateTimeZoneHandling - { - get { return _dateTimeZoneHandling ?? JsonSerializerSettings.DefaultDateTimeZoneHandling; } - set { _dateTimeZoneHandling = value; } - } - - /// - /// Get or set how date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed when reading JSON. - /// - public virtual DateParseHandling DateParseHandling - { - get { return _dateParseHandling ?? JsonSerializerSettings.DefaultDateParseHandling; } - set { _dateParseHandling = value; } - } - - /// - /// Get or set how floating point numbers, e.g. 1.0 and 9.9, are parsed when reading JSON text. - /// - public virtual FloatParseHandling FloatParseHandling - { - get { return _floatParseHandling ?? JsonSerializerSettings.DefaultFloatParseHandling; } - set { _floatParseHandling = value; } - } - - /// - /// Get or set how special floating point numbers, e.g. , - /// and , - /// are written as JSON text. - /// - public virtual FloatFormatHandling FloatFormatHandling - { - get { return _floatFormatHandling ?? JsonSerializerSettings.DefaultFloatFormatHandling; } - set { _floatFormatHandling = value; } - } - - /// - /// Get or set how strings are escaped when writing JSON text. - /// - public virtual StringEscapeHandling StringEscapeHandling - { - get { return _stringEscapeHandling ?? JsonSerializerSettings.DefaultStringEscapeHandling; } - set { _stringEscapeHandling = value; } - } - - /// - /// Get or set how and values are formatting when writing JSON text. - /// - public virtual string DateFormatString - { - get { return _dateFormatString ?? JsonSerializerSettings.DefaultDateFormatString; } - set - { - _dateFormatString = value; - _dateFormatStringSet = true; - } - } - - /// - /// Gets or sets the culture used when reading JSON. Defaults to . - /// - public virtual CultureInfo Culture - { - get { return _culture ?? JsonSerializerSettings.DefaultCulture; } - set { _culture = value; } - } - - /// - /// Gets or sets the maximum depth allowed when reading JSON. Reading past this depth will throw a . - /// - public virtual int? MaxDepth - { - get { return _maxDepth; } - set - { - if (value <= 0) - throw new ArgumentException("Value must be positive.", "value"); - - _maxDepth = value; - _maxDepthSet = true; - } - } - - /// - /// Gets a value indicating whether there will be a check for additional JSON content after deserializing an object. - /// - /// - /// true if there will be a check for additional JSON content after deserializing an object; otherwise, false. - /// - public virtual bool CheckAdditionalContent - { - get { return _checkAdditionalContent ?? JsonSerializerSettings.DefaultCheckAdditionalContent; } - set { _checkAdditionalContent = value; } - } - - internal bool IsCheckAdditionalContentSet() - { - return (_checkAdditionalContent != null); - } - - #endregion - - /// - /// Initializes a new instance of the class. - /// - public JsonSerializer() - { - _referenceLoopHandling = JsonSerializerSettings.DefaultReferenceLoopHandling; - _missingMemberHandling = JsonSerializerSettings.DefaultMissingMemberHandling; - _nullValueHandling = JsonSerializerSettings.DefaultNullValueHandling; - _defaultValueHandling = JsonSerializerSettings.DefaultDefaultValueHandling; - _objectCreationHandling = JsonSerializerSettings.DefaultObjectCreationHandling; - _preserveReferencesHandling = JsonSerializerSettings.DefaultPreserveReferencesHandling; - _constructorHandling = JsonSerializerSettings.DefaultConstructorHandling; - _typeNameHandling = JsonSerializerSettings.DefaultTypeNameHandling; - _context = JsonSerializerSettings.DefaultContext; - _binder = DefaultSerializationBinder.Instance; - - _culture = JsonSerializerSettings.DefaultCulture; - _contractResolver = DefaultContractResolver.Instance; - } - - /// - /// Creates a new instance. - /// The will not use default settings. - /// - /// - /// A new instance. - /// The will not use default settings. - /// - public static JsonSerializer Create() - { - return new JsonSerializer(); - } - - /// - /// Creates a new instance using the specified . - /// The will not use default settings. - /// - /// The settings to be applied to the . - /// - /// A new instance using the specified . - /// The will not use default settings. - /// - public static JsonSerializer Create(JsonSerializerSettings settings) - { - JsonSerializer serializer = Create(); - - if (settings != null) - ApplySerializerSettings(serializer, settings); - - return serializer; - } - - /// - /// Creates a new instance. - /// The will use default settings. - /// - /// - /// A new instance. - /// The will use default settings. - /// - public static JsonSerializer CreateDefault() - { - // copy static to local variable to avoid concurrency issues - Func defaultSettingsCreator = JsonConvert.DefaultSettings; - JsonSerializerSettings defaultSettings = (defaultSettingsCreator != null) ? defaultSettingsCreator() : null; - - return Create(defaultSettings); - } - - /// - /// Creates a new instance using the specified . - /// The will use default settings. - /// - /// The settings to be applied to the . - /// - /// A new instance using the specified . - /// The will use default settings. - /// - public static JsonSerializer CreateDefault(JsonSerializerSettings settings) - { - JsonSerializer serializer = CreateDefault(); - if (settings != null) - ApplySerializerSettings(serializer, settings); - - return serializer; - } - - private static void ApplySerializerSettings(JsonSerializer serializer, JsonSerializerSettings settings) - { - if (!CollectionUtils.IsNullOrEmpty(settings.Converters)) - { - // insert settings converters at the beginning so they take precedence - // if user wants to remove one of the default converters they will have to do it manually - for (int i = 0; i < settings.Converters.Count; i++) + /// + /// Gets or sets the used by the serializer when resolving references. + /// + public virtual IReferenceResolver ReferenceResolver { - serializer.Converters.Insert(i, settings.Converters[i]); + get { return GetReferenceResolver(); } + set + { + if (value == null) + throw new ArgumentNullException("value", "Reference resolver cannot be null."); + + _referenceResolver = value; + } } - } - // serializer specific - if (settings._typeNameHandling != null) - serializer.TypeNameHandling = settings.TypeNameHandling; - if (settings._typeNameAssemblyFormat != null) - serializer.TypeNameAssemblyFormat = settings.TypeNameAssemblyFormat; - if (settings._preserveReferencesHandling != null) - serializer.PreserveReferencesHandling = settings.PreserveReferencesHandling; - if (settings._referenceLoopHandling != null) - serializer.ReferenceLoopHandling = settings.ReferenceLoopHandling; - if (settings._missingMemberHandling != null) - serializer.MissingMemberHandling = settings.MissingMemberHandling; - if (settings._objectCreationHandling != null) - serializer.ObjectCreationHandling = settings.ObjectCreationHandling; - if (settings._nullValueHandling != null) - serializer.NullValueHandling = settings.NullValueHandling; - if (settings._defaultValueHandling != null) - serializer.DefaultValueHandling = settings.DefaultValueHandling; - if (settings._constructorHandling != null) - serializer.ConstructorHandling = settings.ConstructorHandling; - if (settings._context != null) - serializer.Context = settings.Context; - if (settings._checkAdditionalContent != null) - serializer._checkAdditionalContent = settings._checkAdditionalContent; + /// + /// Gets or sets the used by the serializer when resolving type names. + /// + public virtual SerializationBinder Binder + { + get { return _binder; } + set + { + if (value == null) + throw new ArgumentNullException("value", "Serialization binder cannot be null."); - if (settings.Error != null) - serializer.Error += settings.Error; + _binder = value; + } + } - if (settings.ContractResolver != null) - serializer.ContractResolver = settings.ContractResolver; - if (settings.ReferenceResolver != null) - serializer.ReferenceResolver = settings.ReferenceResolver; - if (settings.TraceWriter != null) - serializer.TraceWriter = settings.TraceWriter; - if (settings.Binder != null) - serializer.Binder = settings.Binder; + /// + /// Gets or sets the used by the serializer when writing trace messages. + /// + /// The trace writer. + public virtual ITraceWriter TraceWriter + { + get { return _traceWriter; } + set { _traceWriter = value; } + } - // reader/writer specific - // unset values won't override reader/writer set values - if (settings._formatting != null) - serializer._formatting = settings._formatting; - if (settings._dateFormatHandling != null) - serializer._dateFormatHandling = settings._dateFormatHandling; - if (settings._dateTimeZoneHandling != null) - serializer._dateTimeZoneHandling = settings._dateTimeZoneHandling; - if (settings._dateParseHandling != null) - serializer._dateParseHandling = settings._dateParseHandling; - if (settings._dateFormatStringSet) - { - serializer._dateFormatString = settings._dateFormatString; - serializer._dateFormatStringSet = settings._dateFormatStringSet; - } - if (settings._floatFormatHandling != null) - serializer._floatFormatHandling = settings._floatFormatHandling; - if (settings._floatParseHandling != null) - serializer._floatParseHandling = settings._floatParseHandling; - if (settings._stringEscapeHandling != null) - serializer._stringEscapeHandling = settings._stringEscapeHandling; - if (settings._culture != null) - serializer._culture = settings._culture; - if (settings._maxDepthSet) - { - serializer._maxDepth = settings._maxDepth; - serializer._maxDepthSet = settings._maxDepthSet; - } - } + /// + /// Gets or sets how type name writing and reading is handled by the serializer. + /// + public virtual TypeNameHandling TypeNameHandling + { + get { return _typeNameHandling; } + set + { + if (value < TypeNameHandling.None || value > TypeNameHandling.Auto) + throw new ArgumentOutOfRangeException("value"); - /// - /// Populates the JSON values onto the target object. - /// - /// The that contains the JSON structure to reader values from. - /// The target object to populate values onto. - public void Populate(TextReader reader, object target) - { - Populate(new JsonTextReader(reader), target); - } + _typeNameHandling = value; + } + } - /// - /// Populates the JSON values onto the target object. - /// - /// The that contains the JSON structure to reader values from. - /// The target object to populate values onto. - public void Populate(JsonReader reader, object target) - { - PopulateInternal(reader, target); - } + /// + /// Gets or sets how a type name assembly is written and resolved by the serializer. + /// + /// The type name assembly format. + public virtual FormatterAssemblyStyle TypeNameAssemblyFormat + { + get { return _typeNameAssemblyFormat; } + set + { + if (value < FormatterAssemblyStyle.Simple || value > FormatterAssemblyStyle.Full) + throw new ArgumentOutOfRangeException("value"); - internal virtual void PopulateInternal(JsonReader reader, object target) - { - ValidationUtils.ArgumentNotNull(reader, "reader"); - ValidationUtils.ArgumentNotNull(target, "target"); + _typeNameAssemblyFormat = value; + } + } - JsonSerializerInternalReader serializerReader = new JsonSerializerInternalReader(this); - serializerReader.Populate(reader, target); - } + /// + /// Gets or sets how object references are preserved by the serializer. + /// + public virtual PreserveReferencesHandling PreserveReferencesHandling + { + get { return _preserveReferencesHandling; } + set + { + if (value < PreserveReferencesHandling.None || value > PreserveReferencesHandling.All) + throw new ArgumentOutOfRangeException("value"); - /// - /// Deserializes the Json structure contained by the specified . - /// - /// The that contains the JSON structure to deserialize. - /// The being deserialized. - public object Deserialize(JsonReader reader) - { - return Deserialize(reader, null); - } + _preserveReferencesHandling = value; + } + } - /// - /// Deserializes the Json structure contained by the specified - /// into an instance of the specified type. - /// - /// The containing the object. - /// The of object being deserialized. - /// The instance of being deserialized. - public object Deserialize(TextReader reader, Type objectType) - { - return Deserialize(new JsonTextReader(reader), objectType); - } + /// + /// Get or set how reference loops (e.g. a class referencing itself) is handled. + /// + public virtual ReferenceLoopHandling ReferenceLoopHandling + { + get { return _referenceLoopHandling; } + set + { + if (value < ReferenceLoopHandling.Error || value > ReferenceLoopHandling.Serialize) + throw new ArgumentOutOfRangeException("value"); - /// - /// Deserializes the Json structure contained by the specified - /// into an instance of the specified type. - /// - /// The containing the object. - /// The type of the object to deserialize. - /// The instance of being deserialized. - public T Deserialize(JsonReader reader) - { - return (T)Deserialize(reader, typeof(T)); - } + _referenceLoopHandling = value; + } + } - /// - /// Deserializes the Json structure contained by the specified - /// into an instance of the specified type. - /// - /// The containing the object. - /// The of object being deserialized. - /// The instance of being deserialized. - public object Deserialize(JsonReader reader, Type objectType) - { - return DeserializeInternal(reader, objectType); - } + /// + /// Get or set how missing members (e.g. JSON contains a property that isn't a member on the object) are handled during deserialization. + /// + public virtual MissingMemberHandling MissingMemberHandling + { + get { return _missingMemberHandling; } + set + { + if (value < MissingMemberHandling.Ignore || value > MissingMemberHandling.Error) + throw new ArgumentOutOfRangeException("value"); - internal virtual object DeserializeInternal(JsonReader reader, Type objectType) - { - ValidationUtils.ArgumentNotNull(reader, "reader"); + _missingMemberHandling = value; + } + } - // set serialization options onto reader - CultureInfo previousCulture = null; - if (_culture != null && !_culture.Equals(reader.Culture)) - { - previousCulture = reader.Culture; - reader.Culture = _culture; - } + /// + /// Get or set how null values are handled during serialization and deserialization. + /// + public virtual NullValueHandling NullValueHandling + { + get { return _nullValueHandling; } + set + { + if (value < NullValueHandling.Include || value > NullValueHandling.Ignore) + throw new ArgumentOutOfRangeException("value"); - DateTimeZoneHandling? previousDateTimeZoneHandling = null; - if (_dateTimeZoneHandling != null && reader.DateTimeZoneHandling != _dateTimeZoneHandling) - { - previousDateTimeZoneHandling = reader.DateTimeZoneHandling; - reader.DateTimeZoneHandling = _dateTimeZoneHandling.Value; - } + _nullValueHandling = value; + } + } - DateParseHandling? previousDateParseHandling = null; - if (_dateParseHandling != null && reader.DateParseHandling != _dateParseHandling) - { - previousDateParseHandling = reader.DateParseHandling; - reader.DateParseHandling = _dateParseHandling.Value; - } + /// + /// Get or set how null default are handled during serialization and deserialization. + /// + public virtual DefaultValueHandling DefaultValueHandling + { + get { return _defaultValueHandling; } + set + { + if (value < DefaultValueHandling.Include || value > DefaultValueHandling.IgnoreAndPopulate) + throw new ArgumentOutOfRangeException("value"); - FloatParseHandling? previousFloatParseHandling = null; - if (_floatParseHandling != null && reader.FloatParseHandling != _floatParseHandling) - { - previousFloatParseHandling = reader.FloatParseHandling; - reader.FloatParseHandling = _floatParseHandling.Value; - } + _defaultValueHandling = value; + } + } - int? previousMaxDepth = null; - if (_maxDepthSet && reader.MaxDepth != _maxDepth) - { - previousMaxDepth = reader.MaxDepth; - reader.MaxDepth = _maxDepth; - } + /// + /// Gets or sets how objects are created during deserialization. + /// + /// The object creation handling. + public virtual ObjectCreationHandling ObjectCreationHandling + { + get { return _objectCreationHandling; } + set + { + if (value < ObjectCreationHandling.Auto || value > ObjectCreationHandling.Replace) + throw new ArgumentOutOfRangeException("value"); - TraceJsonReader traceJsonReader = (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) - ? new TraceJsonReader(reader) - : null; + _objectCreationHandling = value; + } + } - JsonSerializerInternalReader serializerReader = new JsonSerializerInternalReader(this); - object value = serializerReader.Deserialize(traceJsonReader ?? reader, objectType, CheckAdditionalContent); + /// + /// Gets or sets how constructors are used during deserialization. + /// + /// The constructor handling. + public virtual ConstructorHandling ConstructorHandling + { + get { return _constructorHandling; } + set + { + if (value < ConstructorHandling.Default || value > ConstructorHandling.AllowNonPublicDefaultConstructor) + throw new ArgumentOutOfRangeException("value"); - if (traceJsonReader != null) - TraceWriter.Trace(TraceLevel.Verbose, "Deserialized JSON: " + Environment.NewLine + traceJsonReader.GetJson(), null); + _constructorHandling = value; + } + } - // reset reader back to previous options - if (previousCulture != null) - reader.Culture = previousCulture; - if (previousDateTimeZoneHandling != null) - reader.DateTimeZoneHandling = previousDateTimeZoneHandling.Value; - if (previousDateParseHandling != null) - reader.DateParseHandling = previousDateParseHandling.Value; - if (previousFloatParseHandling != null) - reader.FloatParseHandling = previousFloatParseHandling.Value; - if (_maxDepthSet) - reader.MaxDepth = previousMaxDepth; + /// + /// Gets a collection that will be used during serialization. + /// + /// Collection that will be used during serialization. + public virtual JsonConverterCollection Converters + { + get + { + if (_converters == null) + _converters = new JsonConverterCollection(); - return value; - } + return _converters; + } + } - /// - /// Serializes the specified and writes the Json structure - /// to a Stream using the specified . - /// - /// The used to write the Json structure. - /// The to serialize. - public void Serialize(TextWriter textWriter, object value) - { - Serialize(new JsonTextWriter(textWriter), value); - } + /// + /// Gets or sets the contract resolver used by the serializer when + /// serializing .NET objects to JSON and vice versa. + /// + public virtual IContractResolver ContractResolver + { + get { return _contractResolver; } + set { _contractResolver = value ?? DefaultContractResolver.Instance; } + } - /// - /// Serializes the specified and writes the Json structure - /// to a Stream using the specified . - /// - /// The used to write the Json structure. - /// The to serialize. - /// - /// The type of the value being serialized. - /// This parameter is used when is Auto to write out the type name if the type of the value does not match. - /// Specifing the type is optional. - /// - public void Serialize(JsonWriter jsonWriter, object value, Type objectType) - { - SerializeInternal(jsonWriter, value, objectType); - } + /// + /// Gets or sets the used by the serializer when invoking serialization callback methods. + /// + /// The context. + public virtual StreamingContext Context + { + get { return _context; } + set { _context = value; } + } - /// - /// Serializes the specified and writes the Json structure - /// to a Stream using the specified . - /// - /// The used to write the Json structure. - /// The to serialize. - /// - /// The type of the value being serialized. - /// This parameter is used when is Auto to write out the type name if the type of the value does not match. - /// Specifing the type is optional. - /// - public void Serialize(TextWriter textWriter, object value, Type objectType) - { - Serialize(new JsonTextWriter(textWriter), value, objectType); - } + /// + /// Indicates how JSON text output is formatted. + /// + public virtual Formatting Formatting + { + get { return _formatting ?? JsonSerializerSettings.DefaultFormatting; } + set { _formatting = value; } + } - /// - /// Serializes the specified and writes the Json structure - /// to a Stream using the specified . - /// - /// The used to write the Json structure. - /// The to serialize. - public void Serialize(JsonWriter jsonWriter, object value) - { - SerializeInternal(jsonWriter, value, null); - } + /// + /// Get or set how dates are written to JSON text. + /// + public virtual DateFormatHandling DateFormatHandling + { + get { return _dateFormatHandling ?? JsonSerializerSettings.DefaultDateFormatHandling; } + set { _dateFormatHandling = value; } + } - internal virtual void SerializeInternal(JsonWriter jsonWriter, object value, Type objectType) - { - ValidationUtils.ArgumentNotNull(jsonWriter, "jsonWriter"); + /// + /// Get or set how time zones are handling during serialization and deserialization. + /// + public virtual DateTimeZoneHandling DateTimeZoneHandling + { + get { return _dateTimeZoneHandling ?? JsonSerializerSettings.DefaultDateTimeZoneHandling; } + set { _dateTimeZoneHandling = value; } + } - // set serialization options onto writer - Formatting? previousFormatting = null; - if (_formatting != null && jsonWriter.Formatting != _formatting) - { - previousFormatting = jsonWriter.Formatting; - jsonWriter.Formatting = _formatting.Value; - } + /// + /// Get or set how date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed when reading JSON. + /// + public virtual DateParseHandling DateParseHandling + { + get { return _dateParseHandling ?? JsonSerializerSettings.DefaultDateParseHandling; } + set { _dateParseHandling = value; } + } - DateFormatHandling? previousDateFormatHandling = null; - if (_dateFormatHandling != null && jsonWriter.DateFormatHandling != _dateFormatHandling) - { - previousDateFormatHandling = jsonWriter.DateFormatHandling; - jsonWriter.DateFormatHandling = _dateFormatHandling.Value; - } + /// + /// Get or set how floating point numbers, e.g. 1.0 and 9.9, are parsed when reading JSON text. + /// + public virtual FloatParseHandling FloatParseHandling + { + get { return _floatParseHandling ?? JsonSerializerSettings.DefaultFloatParseHandling; } + set { _floatParseHandling = value; } + } - DateTimeZoneHandling? previousDateTimeZoneHandling = null; - if (_dateTimeZoneHandling != null && jsonWriter.DateTimeZoneHandling != _dateTimeZoneHandling) - { - previousDateTimeZoneHandling = jsonWriter.DateTimeZoneHandling; - jsonWriter.DateTimeZoneHandling = _dateTimeZoneHandling.Value; - } + /// + /// Get or set how special floating point numbers, e.g. , + /// and , + /// are written as JSON text. + /// + public virtual FloatFormatHandling FloatFormatHandling + { + get { return _floatFormatHandling ?? JsonSerializerSettings.DefaultFloatFormatHandling; } + set { _floatFormatHandling = value; } + } - FloatFormatHandling? previousFloatFormatHandling = null; - if (_floatFormatHandling != null && jsonWriter.FloatFormatHandling != _floatFormatHandling) - { - previousFloatFormatHandling = jsonWriter.FloatFormatHandling; - jsonWriter.FloatFormatHandling = _floatFormatHandling.Value; - } + /// + /// Get or set how strings are escaped when writing JSON text. + /// + public virtual StringEscapeHandling StringEscapeHandling + { + get { return _stringEscapeHandling ?? JsonSerializerSettings.DefaultStringEscapeHandling; } + set { _stringEscapeHandling = value; } + } - StringEscapeHandling? previousStringEscapeHandling = null; - if (_stringEscapeHandling != null && jsonWriter.StringEscapeHandling != _stringEscapeHandling) - { - previousStringEscapeHandling = jsonWriter.StringEscapeHandling; - jsonWriter.StringEscapeHandling = _stringEscapeHandling.Value; - } + /// + /// Get or set how and values are formatting when writing JSON text. + /// + public virtual string DateFormatString + { + get { return _dateFormatString ?? JsonSerializerSettings.DefaultDateFormatString; } + set + { + _dateFormatString = value; + _dateFormatStringSet = true; + } + } - CultureInfo previousCulture = null; - if (_culture != null && !_culture.Equals(jsonWriter.Culture)) - { - previousCulture = jsonWriter.Culture; - jsonWriter.Culture = _culture; - } + /// + /// Gets or sets the culture used when reading JSON. Defaults to . + /// + public virtual CultureInfo Culture + { + get { return _culture ?? JsonSerializerSettings.DefaultCulture; } + set { _culture = value; } + } - string previousDateFormatString = null; - if (_dateFormatStringSet && jsonWriter.DateFormatString != _dateFormatString) - { - previousDateFormatString = jsonWriter.DateFormatString; - jsonWriter.DateFormatString = _dateFormatString; - } + /// + /// Gets or sets the maximum depth allowed when reading JSON. Reading past this depth will throw a . + /// + public virtual int? MaxDepth + { + get { return _maxDepth; } + set + { + if (value <= 0) + throw new ArgumentException("Value must be positive.", "value"); - TraceJsonWriter traceJsonWriter = (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) - ? new TraceJsonWriter(jsonWriter) - : null; + _maxDepth = value; + _maxDepthSet = true; + } + } - JsonSerializerInternalWriter serializerWriter = new JsonSerializerInternalWriter(this); - serializerWriter.Serialize(traceJsonWriter ?? jsonWriter, value, objectType); + /// + /// Gets a value indicating whether there will be a check for additional JSON content after deserializing an object. + /// + /// + /// true if there will be a check for additional JSON content after deserializing an object; otherwise, false. + /// + public virtual bool CheckAdditionalContent + { + get { return _checkAdditionalContent ?? JsonSerializerSettings.DefaultCheckAdditionalContent; } + set { _checkAdditionalContent = value; } + } - if (traceJsonWriter != null) - TraceWriter.Trace(TraceLevel.Verbose, "Serialized JSON: " + Environment.NewLine + traceJsonWriter.GetJson(), null); + internal bool IsCheckAdditionalContentSet() + { + return (_checkAdditionalContent != null); + } + #endregion - // reset writer back to previous options - if (previousFormatting != null) - jsonWriter.Formatting = previousFormatting.Value; - if (previousDateFormatHandling != null) - jsonWriter.DateFormatHandling = previousDateFormatHandling.Value; - if (previousDateTimeZoneHandling != null) - jsonWriter.DateTimeZoneHandling = previousDateTimeZoneHandling.Value; - if (previousFloatFormatHandling != null) - jsonWriter.FloatFormatHandling = previousFloatFormatHandling.Value; - if (previousStringEscapeHandling != null) - jsonWriter.StringEscapeHandling = previousStringEscapeHandling.Value; - if (_dateFormatStringSet) - jsonWriter.DateFormatString = previousDateFormatString; - if (previousCulture != null) - jsonWriter.Culture = previousCulture; - } + /// + /// Initializes a new instance of the class. + /// + public JsonSerializer() + { + _referenceLoopHandling = JsonSerializerSettings.DefaultReferenceLoopHandling; + _missingMemberHandling = JsonSerializerSettings.DefaultMissingMemberHandling; + _nullValueHandling = JsonSerializerSettings.DefaultNullValueHandling; + _defaultValueHandling = JsonSerializerSettings.DefaultDefaultValueHandling; + _objectCreationHandling = JsonSerializerSettings.DefaultObjectCreationHandling; + _preserveReferencesHandling = JsonSerializerSettings.DefaultPreserveReferencesHandling; + _constructorHandling = JsonSerializerSettings.DefaultConstructorHandling; + _typeNameHandling = JsonSerializerSettings.DefaultTypeNameHandling; + _context = JsonSerializerSettings.DefaultContext; + _binder = DefaultSerializationBinder.Instance; - internal IReferenceResolver GetReferenceResolver() - { - if (_referenceResolver == null) - _referenceResolver = new DefaultReferenceResolver(); + _culture = JsonSerializerSettings.DefaultCulture; + _contractResolver = DefaultContractResolver.Instance; + } - return _referenceResolver; - } + /// + /// Creates a new instance. + /// The will not use default settings. + /// + /// + /// A new instance. + /// The will not use default settings. + /// + public static JsonSerializer Create() + { + return new JsonSerializer(); + } - internal JsonConverter GetMatchingConverter(Type type) - { - return GetMatchingConverter(_converters, type); - } + /// + /// Creates a new instance using the specified . + /// The will not use default settings. + /// + /// The settings to be applied to the . + /// + /// A new instance using the specified . + /// The will not use default settings. + /// + public static JsonSerializer Create(JsonSerializerSettings settings) + { + JsonSerializer serializer = Create(); - internal static JsonConverter GetMatchingConverter(IList converters, Type objectType) - { + if (settings != null) + ApplySerializerSettings(serializer, settings); + + return serializer; + } + + /// + /// Creates a new instance. + /// The will use default settings. + /// + /// + /// A new instance. + /// The will use default settings. + /// + public static JsonSerializer CreateDefault() + { + // copy static to local variable to avoid concurrency issues + Func defaultSettingsCreator = JsonConvert.DefaultSettings; + JsonSerializerSettings defaultSettings = (defaultSettingsCreator != null) ? defaultSettingsCreator() : null; + + return Create(defaultSettings); + } + + /// + /// Creates a new instance using the specified . + /// The will use default settings. + /// + /// The settings to be applied to the . + /// + /// A new instance using the specified . + /// The will use default settings. + /// + public static JsonSerializer CreateDefault(JsonSerializerSettings settings) + { + JsonSerializer serializer = CreateDefault(); + if (settings != null) + ApplySerializerSettings(serializer, settings); + + return serializer; + } + + private static void ApplySerializerSettings(JsonSerializer serializer, JsonSerializerSettings settings) + { + if (!CollectionUtils.IsNullOrEmpty(settings.Converters)) + { + // insert settings converters at the beginning so they take precedence + // if user wants to remove one of the default converters they will have to do it manually + for (int i = 0; i < settings.Converters.Count; i++) + { + serializer.Converters.Insert(i, settings.Converters[i]); + } + } + + // serializer specific + if (settings._typeNameHandling != null) + serializer.TypeNameHandling = settings.TypeNameHandling; + if (settings._typeNameAssemblyFormat != null) + serializer.TypeNameAssemblyFormat = settings.TypeNameAssemblyFormat; + if (settings._preserveReferencesHandling != null) + serializer.PreserveReferencesHandling = settings.PreserveReferencesHandling; + if (settings._referenceLoopHandling != null) + serializer.ReferenceLoopHandling = settings.ReferenceLoopHandling; + if (settings._missingMemberHandling != null) + serializer.MissingMemberHandling = settings.MissingMemberHandling; + if (settings._objectCreationHandling != null) + serializer.ObjectCreationHandling = settings.ObjectCreationHandling; + if (settings._nullValueHandling != null) + serializer.NullValueHandling = settings.NullValueHandling; + if (settings._defaultValueHandling != null) + serializer.DefaultValueHandling = settings.DefaultValueHandling; + if (settings._constructorHandling != null) + serializer.ConstructorHandling = settings.ConstructorHandling; + if (settings._context != null) + serializer.Context = settings.Context; + if (settings._checkAdditionalContent != null) + serializer._checkAdditionalContent = settings._checkAdditionalContent; + + if (settings.Error != null) + serializer.Error += settings.Error; + + if (settings.ContractResolver != null) + serializer.ContractResolver = settings.ContractResolver; + if (settings.ReferenceResolver != null) + serializer.ReferenceResolver = settings.ReferenceResolver; + if (settings.TraceWriter != null) + serializer.TraceWriter = settings.TraceWriter; + if (settings.Binder != null) + serializer.Binder = settings.Binder; + + // reader/writer specific + // unset values won't override reader/writer set values + if (settings._formatting != null) + serializer._formatting = settings._formatting; + if (settings._dateFormatHandling != null) + serializer._dateFormatHandling = settings._dateFormatHandling; + if (settings._dateTimeZoneHandling != null) + serializer._dateTimeZoneHandling = settings._dateTimeZoneHandling; + if (settings._dateParseHandling != null) + serializer._dateParseHandling = settings._dateParseHandling; + if (settings._dateFormatStringSet) + { + serializer._dateFormatString = settings._dateFormatString; + serializer._dateFormatStringSet = settings._dateFormatStringSet; + } + if (settings._floatFormatHandling != null) + serializer._floatFormatHandling = settings._floatFormatHandling; + if (settings._floatParseHandling != null) + serializer._floatParseHandling = settings._floatParseHandling; + if (settings._stringEscapeHandling != null) + serializer._stringEscapeHandling = settings._stringEscapeHandling; + if (settings._culture != null) + serializer._culture = settings._culture; + if (settings._maxDepthSet) + { + serializer._maxDepth = settings._maxDepth; + serializer._maxDepthSet = settings._maxDepthSet; + } + } + + /// + /// Populates the JSON values onto the target object. + /// + /// The that contains the JSON structure to reader values from. + /// The target object to populate values onto. + public void Populate(TextReader reader, object target) + { + Populate(new JsonTextReader(reader), target); + } + + /// + /// Populates the JSON values onto the target object. + /// + /// The that contains the JSON structure to reader values from. + /// The target object to populate values onto. + public void Populate(JsonReader reader, object target) + { + PopulateInternal(reader, target); + } + + internal virtual void PopulateInternal(JsonReader reader, object target) + { + ValidationUtils.ArgumentNotNull(reader, "reader"); + ValidationUtils.ArgumentNotNull(target, "target"); + + JsonSerializerInternalReader serializerReader = new JsonSerializerInternalReader(this); + serializerReader.Populate(reader, target); + } + + /// + /// Deserializes the Json structure contained by the specified . + /// + /// The that contains the JSON structure to deserialize. + /// The being deserialized. + public object Deserialize(JsonReader reader) + { + return Deserialize(reader, null); + } + + /// + /// Deserializes the Json structure contained by the specified + /// into an instance of the specified type. + /// + /// The containing the object. + /// The of object being deserialized. + /// The instance of being deserialized. + public object Deserialize(TextReader reader, Type objectType) + { + return Deserialize(new JsonTextReader(reader), objectType); + } + + /// + /// Deserializes the Json structure contained by the specified + /// into an instance of the specified type. + /// + /// The containing the object. + /// The type of the object to deserialize. + /// The instance of being deserialized. + public T Deserialize(JsonReader reader) + { + return (T)Deserialize(reader, typeof(T)); + } + + /// + /// Deserializes the Json structure contained by the specified + /// into an instance of the specified type. + /// + /// The containing the object. + /// The of object being deserialized. + /// The instance of being deserialized. + public object Deserialize(JsonReader reader, Type objectType) + { + return DeserializeInternal(reader, objectType); + } + + internal virtual object DeserializeInternal(JsonReader reader, Type objectType) + { + ValidationUtils.ArgumentNotNull(reader, "reader"); + + // set serialization options onto reader + CultureInfo previousCulture = null; + if (_culture != null && !_culture.Equals(reader.Culture)) + { + previousCulture = reader.Culture; + reader.Culture = _culture; + } + + DateTimeZoneHandling? previousDateTimeZoneHandling = null; + if (_dateTimeZoneHandling != null && reader.DateTimeZoneHandling != _dateTimeZoneHandling) + { + previousDateTimeZoneHandling = reader.DateTimeZoneHandling; + reader.DateTimeZoneHandling = _dateTimeZoneHandling.Value; + } + + DateParseHandling? previousDateParseHandling = null; + if (_dateParseHandling != null && reader.DateParseHandling != _dateParseHandling) + { + previousDateParseHandling = reader.DateParseHandling; + reader.DateParseHandling = _dateParseHandling.Value; + } + + FloatParseHandling? previousFloatParseHandling = null; + if (_floatParseHandling != null && reader.FloatParseHandling != _floatParseHandling) + { + previousFloatParseHandling = reader.FloatParseHandling; + reader.FloatParseHandling = _floatParseHandling.Value; + } + + int? previousMaxDepth = null; + if (_maxDepthSet && reader.MaxDepth != _maxDepth) + { + previousMaxDepth = reader.MaxDepth; + reader.MaxDepth = _maxDepth; + } + + TraceJsonReader traceJsonReader = (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) + ? new TraceJsonReader(reader) + : null; + + JsonSerializerInternalReader serializerReader = new JsonSerializerInternalReader(this); + 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) + reader.Culture = previousCulture; + if (previousDateTimeZoneHandling != null) + reader.DateTimeZoneHandling = previousDateTimeZoneHandling.Value; + if (previousDateParseHandling != null) + reader.DateParseHandling = previousDateParseHandling.Value; + if (previousFloatParseHandling != null) + reader.FloatParseHandling = previousFloatParseHandling.Value; + if (_maxDepthSet) + reader.MaxDepth = previousMaxDepth; + + return value; + } + + /// + /// Serializes the specified and writes the Json structure + /// to a Stream using the specified . + /// + /// The used to write the Json structure. + /// The to serialize. + public void Serialize(TextWriter textWriter, object value) + { + Serialize(new JsonTextWriter(textWriter), value); + } + + /// + /// Serializes the specified and writes the Json structure + /// to a Stream using the specified . + /// + /// The used to write the Json structure. + /// The to serialize. + /// + /// The type of the value being serialized. + /// This parameter is used when is Auto to write out the type name if the type of the value does not match. + /// Specifing the type is optional. + /// + public void Serialize(JsonWriter jsonWriter, object value, Type objectType) + { + SerializeInternal(jsonWriter, value, objectType); + } + + /// + /// Serializes the specified and writes the Json structure + /// to a Stream using the specified . + /// + /// The used to write the Json structure. + /// The to serialize. + /// + /// The type of the value being serialized. + /// This parameter is used when is Auto to write out the type name if the type of the value does not match. + /// Specifing the type is optional. + /// + public void Serialize(TextWriter textWriter, object value, Type objectType) + { + Serialize(new JsonTextWriter(textWriter), value, objectType); + } + + /// + /// Serializes the specified and writes the Json structure + /// to a Stream using the specified . + /// + /// The used to write the Json structure. + /// The to serialize. + public void Serialize(JsonWriter jsonWriter, object value) + { + SerializeInternal(jsonWriter, value, null); + } + + internal virtual void SerializeInternal(JsonWriter jsonWriter, object value, Type objectType) + { + ValidationUtils.ArgumentNotNull(jsonWriter, "jsonWriter"); + + // set serialization options onto writer + Formatting? previousFormatting = null; + if (_formatting != null && jsonWriter.Formatting != _formatting) + { + previousFormatting = jsonWriter.Formatting; + jsonWriter.Formatting = _formatting.Value; + } + + DateFormatHandling? previousDateFormatHandling = null; + if (_dateFormatHandling != null && jsonWriter.DateFormatHandling != _dateFormatHandling) + { + previousDateFormatHandling = jsonWriter.DateFormatHandling; + jsonWriter.DateFormatHandling = _dateFormatHandling.Value; + } + + DateTimeZoneHandling? previousDateTimeZoneHandling = null; + if (_dateTimeZoneHandling != null && jsonWriter.DateTimeZoneHandling != _dateTimeZoneHandling) + { + previousDateTimeZoneHandling = jsonWriter.DateTimeZoneHandling; + jsonWriter.DateTimeZoneHandling = _dateTimeZoneHandling.Value; + } + + FloatFormatHandling? previousFloatFormatHandling = null; + if (_floatFormatHandling != null && jsonWriter.FloatFormatHandling != _floatFormatHandling) + { + previousFloatFormatHandling = jsonWriter.FloatFormatHandling; + jsonWriter.FloatFormatHandling = _floatFormatHandling.Value; + } + + StringEscapeHandling? previousStringEscapeHandling = null; + if (_stringEscapeHandling != null && jsonWriter.StringEscapeHandling != _stringEscapeHandling) + { + previousStringEscapeHandling = jsonWriter.StringEscapeHandling; + jsonWriter.StringEscapeHandling = _stringEscapeHandling.Value; + } + + CultureInfo previousCulture = null; + if (_culture != null && !_culture.Equals(jsonWriter.Culture)) + { + previousCulture = jsonWriter.Culture; + jsonWriter.Culture = _culture; + } + + string previousDateFormatString = null; + if (_dateFormatStringSet && jsonWriter.DateFormatString != _dateFormatString) + { + previousDateFormatString = jsonWriter.DateFormatString; + jsonWriter.DateFormatString = _dateFormatString; + } + + TraceJsonWriter traceJsonWriter = (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) + ? new TraceJsonWriter(jsonWriter) + : null; + + JsonSerializerInternalWriter serializerWriter = new JsonSerializerInternalWriter(this); + 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) + jsonWriter.Formatting = previousFormatting.Value; + if (previousDateFormatHandling != null) + jsonWriter.DateFormatHandling = previousDateFormatHandling.Value; + if (previousDateTimeZoneHandling != null) + jsonWriter.DateTimeZoneHandling = previousDateTimeZoneHandling.Value; + if (previousFloatFormatHandling != null) + jsonWriter.FloatFormatHandling = previousFloatFormatHandling.Value; + if (previousStringEscapeHandling != null) + jsonWriter.StringEscapeHandling = previousStringEscapeHandling.Value; + if (_dateFormatStringSet) + jsonWriter.DateFormatString = previousDateFormatString; + if (previousCulture != null) + jsonWriter.Culture = previousCulture; + } + + internal IReferenceResolver GetReferenceResolver() + { + if (_referenceResolver == null) + _referenceResolver = new DefaultReferenceResolver(); + + return _referenceResolver; + } + + internal JsonConverter GetMatchingConverter(Type type) + { + return GetMatchingConverter(_converters, type); + } + + internal static JsonConverter GetMatchingConverter(IList converters, Type objectType) + { #if DEBUG - ValidationUtils.ArgumentNotNull(objectType, "objectType"); + ValidationUtils.ArgumentNotNull(objectType, "objectType"); #endif - if (converters != null) - { - for (int i = 0; i < converters.Count; i++) - { - JsonConverter converter = converters[i]; + if (converters != null) + { + for (int i = 0; i < converters.Count; i++) + { + JsonConverter converter = converters[i]; - if (converter.CanConvert(objectType)) - return converter; + if (converter.CanConvert(objectType)) + return converter; + } + } + + return null; } - } - return null; + internal void OnError(ErrorEventArgs e) + { + EventHandler error = Error; + if (error != null) + error(this, e); + } } - - internal void OnError(ErrorEventArgs e) - { - EventHandler error = Error; - if (error != null) - error(this, e); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/JsonSerializerSettings.cs b/Src/Newtonsoft.Json/JsonSerializerSettings.cs index e2c19849..8cb6f459 100644 --- a/Src/Newtonsoft.Json/JsonSerializerSettings.cs +++ b/Src/Newtonsoft.Json/JsonSerializerSettings.cs @@ -32,322 +32,322 @@ using System.Runtime.Serialization; namespace Newtonsoft.Json { - /// - /// Specifies the settings on a object. - /// - public class JsonSerializerSettings - { - internal const ReferenceLoopHandling DefaultReferenceLoopHandling = ReferenceLoopHandling.Error; - internal const MissingMemberHandling DefaultMissingMemberHandling = MissingMemberHandling.Ignore; - internal const NullValueHandling DefaultNullValueHandling = NullValueHandling.Include; - internal const DefaultValueHandling DefaultDefaultValueHandling = DefaultValueHandling.Include; - internal const ObjectCreationHandling DefaultObjectCreationHandling = ObjectCreationHandling.Auto; - internal const PreserveReferencesHandling DefaultPreserveReferencesHandling = PreserveReferencesHandling.None; - internal const ConstructorHandling DefaultConstructorHandling = ConstructorHandling.Default; - internal const TypeNameHandling DefaultTypeNameHandling = TypeNameHandling.None; - internal const FormatterAssemblyStyle DefaultTypeNameAssemblyFormat = FormatterAssemblyStyle.Simple; - internal static readonly StreamingContext DefaultContext; - - internal const Formatting DefaultFormatting = Formatting.None; - internal const DateFormatHandling DefaultDateFormatHandling = DateFormatHandling.IsoDateFormat; - internal const DateTimeZoneHandling DefaultDateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind; - internal const DateParseHandling DefaultDateParseHandling = DateParseHandling.DateTime; - internal const FloatParseHandling DefaultFloatParseHandling = FloatParseHandling.Double; - internal const FloatFormatHandling DefaultFloatFormatHandling = FloatFormatHandling.String; - internal const StringEscapeHandling DefaultStringEscapeHandling = StringEscapeHandling.Default; - internal const FormatterAssemblyStyle DefaultFormatterAssemblyStyle = FormatterAssemblyStyle.Simple; - internal static readonly CultureInfo DefaultCulture; - internal const bool DefaultCheckAdditionalContent = false; - internal const string DefaultDateFormatString = @"yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK"; - - internal Formatting? _formatting; - internal DateFormatHandling? _dateFormatHandling; - internal DateTimeZoneHandling? _dateTimeZoneHandling; - internal DateParseHandling? _dateParseHandling; - internal FloatFormatHandling? _floatFormatHandling; - internal FloatParseHandling? _floatParseHandling; - internal StringEscapeHandling? _stringEscapeHandling; - internal CultureInfo _culture; - internal bool? _checkAdditionalContent; - internal int? _maxDepth; - internal bool _maxDepthSet; - internal string _dateFormatString; - internal bool _dateFormatStringSet; - internal FormatterAssemblyStyle? _typeNameAssemblyFormat; - internal DefaultValueHandling? _defaultValueHandling; - internal PreserveReferencesHandling? _preserveReferencesHandling; - internal NullValueHandling? _nullValueHandling; - internal ObjectCreationHandling? _objectCreationHandling; - internal MissingMemberHandling? _missingMemberHandling; - internal ReferenceLoopHandling? _referenceLoopHandling; - internal StreamingContext? _context; - internal ConstructorHandling? _constructorHandling; - internal TypeNameHandling? _typeNameHandling; - /// - /// Gets or sets how reference loops (e.g. a class referencing itself) is handled. + /// Specifies the settings on a object. /// - /// Reference loop handling. - public ReferenceLoopHandling ReferenceLoopHandling + public class JsonSerializerSettings { - get { return _referenceLoopHandling ?? DefaultReferenceLoopHandling; } - set { _referenceLoopHandling = value; } + internal const ReferenceLoopHandling DefaultReferenceLoopHandling = ReferenceLoopHandling.Error; + internal const MissingMemberHandling DefaultMissingMemberHandling = MissingMemberHandling.Ignore; + internal const NullValueHandling DefaultNullValueHandling = NullValueHandling.Include; + internal const DefaultValueHandling DefaultDefaultValueHandling = DefaultValueHandling.Include; + internal const ObjectCreationHandling DefaultObjectCreationHandling = ObjectCreationHandling.Auto; + internal const PreserveReferencesHandling DefaultPreserveReferencesHandling = PreserveReferencesHandling.None; + internal const ConstructorHandling DefaultConstructorHandling = ConstructorHandling.Default; + internal const TypeNameHandling DefaultTypeNameHandling = TypeNameHandling.None; + internal const FormatterAssemblyStyle DefaultTypeNameAssemblyFormat = FormatterAssemblyStyle.Simple; + internal static readonly StreamingContext DefaultContext; + + internal const Formatting DefaultFormatting = Formatting.None; + internal const DateFormatHandling DefaultDateFormatHandling = DateFormatHandling.IsoDateFormat; + internal const DateTimeZoneHandling DefaultDateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind; + internal const DateParseHandling DefaultDateParseHandling = DateParseHandling.DateTime; + internal const FloatParseHandling DefaultFloatParseHandling = FloatParseHandling.Double; + internal const FloatFormatHandling DefaultFloatFormatHandling = FloatFormatHandling.String; + internal const StringEscapeHandling DefaultStringEscapeHandling = StringEscapeHandling.Default; + internal const FormatterAssemblyStyle DefaultFormatterAssemblyStyle = FormatterAssemblyStyle.Simple; + internal static readonly CultureInfo DefaultCulture; + internal const bool DefaultCheckAdditionalContent = false; + internal const string DefaultDateFormatString = @"yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK"; + + internal Formatting? _formatting; + internal DateFormatHandling? _dateFormatHandling; + internal DateTimeZoneHandling? _dateTimeZoneHandling; + internal DateParseHandling? _dateParseHandling; + internal FloatFormatHandling? _floatFormatHandling; + internal FloatParseHandling? _floatParseHandling; + internal StringEscapeHandling? _stringEscapeHandling; + internal CultureInfo _culture; + internal bool? _checkAdditionalContent; + internal int? _maxDepth; + internal bool _maxDepthSet; + internal string _dateFormatString; + internal bool _dateFormatStringSet; + internal FormatterAssemblyStyle? _typeNameAssemblyFormat; + internal DefaultValueHandling? _defaultValueHandling; + internal PreserveReferencesHandling? _preserveReferencesHandling; + internal NullValueHandling? _nullValueHandling; + internal ObjectCreationHandling? _objectCreationHandling; + internal MissingMemberHandling? _missingMemberHandling; + internal ReferenceLoopHandling? _referenceLoopHandling; + internal StreamingContext? _context; + internal ConstructorHandling? _constructorHandling; + internal TypeNameHandling? _typeNameHandling; + + /// + /// Gets or sets how reference loops (e.g. a class referencing itself) is handled. + /// + /// Reference loop handling. + public ReferenceLoopHandling ReferenceLoopHandling + { + get { return _referenceLoopHandling ?? DefaultReferenceLoopHandling; } + set { _referenceLoopHandling = value; } + } + + /// + /// Gets or sets how missing members (e.g. JSON contains a property that isn't a member on the object) are handled during deserialization. + /// + /// Missing member handling. + public MissingMemberHandling MissingMemberHandling + { + get { return _missingMemberHandling ?? DefaultMissingMemberHandling; } + set { _missingMemberHandling = value; } + } + + /// + /// Gets or sets how objects are created during deserialization. + /// + /// The object creation handling. + public ObjectCreationHandling ObjectCreationHandling + { + get { return _objectCreationHandling ?? DefaultObjectCreationHandling; } + set { _objectCreationHandling = value; } + } + + /// + /// Gets or sets how null values are handled during serialization and deserialization. + /// + /// Null value handling. + public NullValueHandling NullValueHandling + { + get { return _nullValueHandling ?? DefaultNullValueHandling; } + set { _nullValueHandling = value; } + } + + /// + /// Gets or sets how null default are handled during serialization and deserialization. + /// + /// The default value handling. + public DefaultValueHandling DefaultValueHandling + { + get { return _defaultValueHandling ?? DefaultDefaultValueHandling; } + set { _defaultValueHandling = value; } + } + + /// + /// Gets or sets a collection that will be used during serialization. + /// + /// The converters. + public IList Converters { get; set; } + + /// + /// Gets or sets how object references are preserved by the serializer. + /// + /// The preserve references handling. + public PreserveReferencesHandling PreserveReferencesHandling + { + get { return _preserveReferencesHandling ?? DefaultPreserveReferencesHandling; } + set { _preserveReferencesHandling = value; } + } + + /// + /// Gets or sets how type name writing and reading is handled by the serializer. + /// + /// The type name handling. + public TypeNameHandling TypeNameHandling + { + get { return _typeNameHandling ?? DefaultTypeNameHandling; } + set { _typeNameHandling = value; } + } + + /// + /// Gets or sets how a type name assembly is written and resolved by the serializer. + /// + /// The type name assembly format. + public FormatterAssemblyStyle TypeNameAssemblyFormat + { + get { return _typeNameAssemblyFormat ?? DefaultFormatterAssemblyStyle; } + set { _typeNameAssemblyFormat = value; } + } + + /// + /// Gets or sets how constructors are used during deserialization. + /// + /// The constructor handling. + public ConstructorHandling ConstructorHandling + { + get { return _constructorHandling ?? DefaultConstructorHandling; } + set { _constructorHandling = value; } + } + + /// + /// Gets or sets the contract resolver used by the serializer when + /// serializing .NET objects to JSON and vice versa. + /// + /// The contract resolver. + public IContractResolver ContractResolver { get; set; } + + /// + /// Gets or sets the used by the serializer when resolving references. + /// + /// The reference resolver. + public IReferenceResolver ReferenceResolver { get; set; } + + /// + /// Gets or sets the used by the serializer when writing trace messages. + /// + /// The trace writer. + public ITraceWriter TraceWriter { get; set; } + + /// + /// Gets or sets the used by the serializer when resolving type names. + /// + /// The binder. + public SerializationBinder Binder { get; set; } + + /// + /// Gets or sets the error handler called during serialization and deserialization. + /// + /// The error handler called during serialization and deserialization. + public EventHandler Error { get; set; } + + /// + /// Gets or sets the used by the serializer when invoking serialization callback methods. + /// + /// The context. + public StreamingContext Context + { + get { return _context ?? DefaultContext; } + set { _context = value; } + } + + /// + /// Get or set how and values are formatting when writing JSON text. + /// + public string DateFormatString + { + get { return _dateFormatString ?? DefaultDateFormatString; } + set + { + _dateFormatString = value; + _dateFormatStringSet = true; + } + } + + /// + /// Gets or sets the maximum depth allowed when reading JSON. Reading past this depth will throw a . + /// + public int? MaxDepth + { + get { return _maxDepth; } + set + { + if (value <= 0) + throw new ArgumentException("Value must be positive.", "value"); + + _maxDepth = value; + _maxDepthSet = true; + } + } + + /// + /// Indicates how JSON text output is formatted. + /// + public Formatting Formatting + { + get { return _formatting ?? DefaultFormatting; } + set { _formatting = value; } + } + + /// + /// Get or set how dates are written to JSON text. + /// + public DateFormatHandling DateFormatHandling + { + get { return _dateFormatHandling ?? DefaultDateFormatHandling; } + set { _dateFormatHandling = value; } + } + + /// + /// Get or set how time zones are handling during serialization and deserialization. + /// + public DateTimeZoneHandling DateTimeZoneHandling + { + get { return _dateTimeZoneHandling ?? DefaultDateTimeZoneHandling; } + set { _dateTimeZoneHandling = value; } + } + + /// + /// Get or set how date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed when reading JSON. + /// + public DateParseHandling DateParseHandling + { + get { return _dateParseHandling ?? DefaultDateParseHandling; } + set { _dateParseHandling = value; } + } + + /// + /// Get or set how special floating point numbers, e.g. , + /// and , + /// are written as JSON. + /// + public FloatFormatHandling FloatFormatHandling + { + get { return _floatFormatHandling ?? DefaultFloatFormatHandling; } + set { _floatFormatHandling = value; } + } + + /// + /// Get or set how floating point numbers, e.g. 1.0 and 9.9, are parsed when reading JSON text. + /// + public FloatParseHandling FloatParseHandling + { + get { return _floatParseHandling ?? DefaultFloatParseHandling; } + set { _floatParseHandling = value; } + } + + /// + /// Get or set how strings are escaped when writing JSON text. + /// + public StringEscapeHandling StringEscapeHandling + { + get { return _stringEscapeHandling ?? DefaultStringEscapeHandling; } + set { _stringEscapeHandling = value; } + } + + /// + /// Gets or sets the culture used when reading JSON. Defaults to . + /// + public CultureInfo Culture + { + get { return _culture ?? DefaultCulture; } + set { _culture = value; } + } + + /// + /// Gets a value indicating whether there will be a check for additional content after deserializing an object. + /// + /// + /// true if there will be a check for additional content after deserializing an object; otherwise, false. + /// + public bool CheckAdditionalContent + { + get { return _checkAdditionalContent ?? DefaultCheckAdditionalContent; } + set { _checkAdditionalContent = value; } + } + + static JsonSerializerSettings() + { + DefaultContext = new StreamingContext(); + DefaultCulture = CultureInfo.InvariantCulture; + } + + /// + /// Initializes a new instance of the class. + /// + public JsonSerializerSettings() + { + Converters = new List(); + } } - - /// - /// Gets or sets how missing members (e.g. JSON contains a property that isn't a member on the object) are handled during deserialization. - /// - /// Missing member handling. - public MissingMemberHandling MissingMemberHandling - { - get { return _missingMemberHandling ?? DefaultMissingMemberHandling; } - set { _missingMemberHandling = value; } - } - - /// - /// Gets or sets how objects are created during deserialization. - /// - /// The object creation handling. - public ObjectCreationHandling ObjectCreationHandling - { - get { return _objectCreationHandling ?? DefaultObjectCreationHandling; } - set { _objectCreationHandling = value; } - } - - /// - /// Gets or sets how null values are handled during serialization and deserialization. - /// - /// Null value handling. - public NullValueHandling NullValueHandling - { - get { return _nullValueHandling ?? DefaultNullValueHandling; } - set { _nullValueHandling = value; } - } - - /// - /// Gets or sets how null default are handled during serialization and deserialization. - /// - /// The default value handling. - public DefaultValueHandling DefaultValueHandling - { - get { return _defaultValueHandling ?? DefaultDefaultValueHandling; } - set { _defaultValueHandling = value; } - } - - /// - /// Gets or sets a collection that will be used during serialization. - /// - /// The converters. - public IList Converters { get; set; } - - /// - /// Gets or sets how object references are preserved by the serializer. - /// - /// The preserve references handling. - public PreserveReferencesHandling PreserveReferencesHandling - { - get { return _preserveReferencesHandling ?? DefaultPreserveReferencesHandling; } - set { _preserveReferencesHandling = value; } - } - - /// - /// Gets or sets how type name writing and reading is handled by the serializer. - /// - /// The type name handling. - public TypeNameHandling TypeNameHandling - { - get { return _typeNameHandling ?? DefaultTypeNameHandling; } - set { _typeNameHandling = value; } - } - - /// - /// Gets or sets how a type name assembly is written and resolved by the serializer. - /// - /// The type name assembly format. - public FormatterAssemblyStyle TypeNameAssemblyFormat - { - get { return _typeNameAssemblyFormat ?? DefaultFormatterAssemblyStyle; } - set { _typeNameAssemblyFormat = value; } - } - - /// - /// Gets or sets how constructors are used during deserialization. - /// - /// The constructor handling. - public ConstructorHandling ConstructorHandling - { - get { return _constructorHandling ?? DefaultConstructorHandling; } - set { _constructorHandling = value; } - } - - /// - /// Gets or sets the contract resolver used by the serializer when - /// serializing .NET objects to JSON and vice versa. - /// - /// The contract resolver. - public IContractResolver ContractResolver { get; set; } - - /// - /// Gets or sets the used by the serializer when resolving references. - /// - /// The reference resolver. - public IReferenceResolver ReferenceResolver { get; set; } - - /// - /// Gets or sets the used by the serializer when writing trace messages. - /// - /// The trace writer. - public ITraceWriter TraceWriter { get; set; } - - /// - /// Gets or sets the used by the serializer when resolving type names. - /// - /// The binder. - public SerializationBinder Binder { get; set; } - - /// - /// Gets or sets the error handler called during serialization and deserialization. - /// - /// The error handler called during serialization and deserialization. - public EventHandler Error { get; set; } - - /// - /// Gets or sets the used by the serializer when invoking serialization callback methods. - /// - /// The context. - public StreamingContext Context - { - get { return _context ?? DefaultContext; } - set { _context = value; } - } - - /// - /// Get or set how and values are formatting when writing JSON text. - /// - public string DateFormatString - { - get { return _dateFormatString ?? DefaultDateFormatString; } - set - { - _dateFormatString = value; - _dateFormatStringSet = true; - } - } - - /// - /// Gets or sets the maximum depth allowed when reading JSON. Reading past this depth will throw a . - /// - public int? MaxDepth - { - get { return _maxDepth; } - set - { - if (value <= 0) - throw new ArgumentException("Value must be positive.", "value"); - - _maxDepth = value; - _maxDepthSet = true; - } - } - - /// - /// Indicates how JSON text output is formatted. - /// - public Formatting Formatting - { - get { return _formatting ?? DefaultFormatting; } - set { _formatting = value; } - } - - /// - /// Get or set how dates are written to JSON text. - /// - public DateFormatHandling DateFormatHandling - { - get { return _dateFormatHandling ?? DefaultDateFormatHandling; } - set { _dateFormatHandling = value; } - } - - /// - /// Get or set how time zones are handling during serialization and deserialization. - /// - public DateTimeZoneHandling DateTimeZoneHandling - { - get { return _dateTimeZoneHandling ?? DefaultDateTimeZoneHandling; } - set { _dateTimeZoneHandling = value; } - } - - /// - /// Get or set how date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed when reading JSON. - /// - public DateParseHandling DateParseHandling - { - get { return _dateParseHandling ?? DefaultDateParseHandling; } - set { _dateParseHandling = value; } - } - - /// - /// Get or set how special floating point numbers, e.g. , - /// and , - /// are written as JSON. - /// - public FloatFormatHandling FloatFormatHandling - { - get { return _floatFormatHandling ?? DefaultFloatFormatHandling; } - set { _floatFormatHandling = value; } - } - - /// - /// Get or set how floating point numbers, e.g. 1.0 and 9.9, are parsed when reading JSON text. - /// - public FloatParseHandling FloatParseHandling - { - get { return _floatParseHandling ?? DefaultFloatParseHandling; } - set { _floatParseHandling = value; } - } - - /// - /// Get or set how strings are escaped when writing JSON text. - /// - public StringEscapeHandling StringEscapeHandling - { - get { return _stringEscapeHandling ?? DefaultStringEscapeHandling; } - set { _stringEscapeHandling = value; } - } - - /// - /// Gets or sets the culture used when reading JSON. Defaults to . - /// - public CultureInfo Culture - { - get { return _culture ?? DefaultCulture; } - set { _culture = value; } - } - - /// - /// Gets a value indicating whether there will be a check for additional content after deserializing an object. - /// - /// - /// true if there will be a check for additional content after deserializing an object; otherwise, false. - /// - public bool CheckAdditionalContent - { - get { return _checkAdditionalContent ?? DefaultCheckAdditionalContent; } - set { _checkAdditionalContent = value; } - } - - static JsonSerializerSettings() - { - DefaultContext = new StreamingContext(); - DefaultCulture = CultureInfo.InvariantCulture; - } - - /// - /// Initializes a new instance of the class. - /// - public JsonSerializerSettings() - { - Converters = new List(); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/JsonTextReader.cs b/Src/Newtonsoft.Json/JsonTextReader.cs index ddd004b9..33a0c04c 100644 --- a/Src/Newtonsoft.Json/JsonTextReader.cs +++ b/Src/Newtonsoft.Json/JsonTextReader.cs @@ -37,1532 +37,1531 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json { - internal enum ReadType - { - Read, - ReadAsInt32, - ReadAsBytes, - ReadAsString, - ReadAsDecimal, - ReadAsDateTime, + internal enum ReadType + { + Read, + ReadAsInt32, + ReadAsBytes, + ReadAsString, + ReadAsDecimal, + ReadAsDateTime, #if !NET20 - ReadAsDateTimeOffset + ReadAsDateTimeOffset #endif - } - - /// - /// Represents a reader that provides fast, non-cached, forward-only access to JSON text data. - /// - public class JsonTextReader : JsonReader, IJsonLineInfo - { - private const char UnicodeReplacementChar = '\uFFFD'; - - private readonly TextReader _reader; - private char[] _chars; - private int _charsUsed; - private int _charPos; - private int _lineStartPos; - private int _lineNumber; - private bool _isEndOfFile; - private StringBuffer _buffer; - private StringReference _stringReference; + } /// - /// Initializes a new instance of the class with the specified . + /// Represents a reader that provides fast, non-cached, forward-only access to JSON text data. /// - /// The TextReader containing the XML data to read. - public JsonTextReader(TextReader reader) + public class JsonTextReader : JsonReader, IJsonLineInfo { - if (reader == null) - throw new ArgumentNullException("reader"); + private const char UnicodeReplacementChar = '\uFFFD'; - _reader = reader; - _lineNumber = 1; - _chars = new char[1025]; - } + private readonly TextReader _reader; + private char[] _chars; + private int _charsUsed; + private int _charPos; + private int _lineStartPos; + private int _lineNumber; + private bool _isEndOfFile; + private StringBuffer _buffer; + private StringReference _stringReference; + + /// + /// Initializes a new instance of the class with the specified . + /// + /// The TextReader containing the XML data to read. + public JsonTextReader(TextReader reader) + { + if (reader == null) + throw new ArgumentNullException("reader"); + + _reader = reader; + _lineNumber = 1; + _chars = new char[1025]; + } #if DEBUG - internal void SetCharBuffer(char[] chars) - { - _chars = chars; - } + internal void SetCharBuffer(char[] chars) + { + _chars = chars; + } #endif - private StringBuffer GetBuffer() - { - if (_buffer == null) - { - _buffer = new StringBuffer(1025); - } - else - { - _buffer.Position = 0; - } - - return _buffer; - } - - private void OnNewLine(int pos) - { - _lineNumber++; - _lineStartPos = pos - 1; - } - - private void ParseString(char quote) - { - _charPos++; - - ShiftBufferIfNeeded(); - ReadStringIntoBuffer(quote); - - if (_readType == ReadType.ReadAsBytes) - { - byte[] data; - if (_stringReference.Length == 0) + private StringBuffer GetBuffer() { - data = new byte[0]; - } - else - { - data = Convert.FromBase64CharArray(_stringReference.Chars, _stringReference.StartIndex, _stringReference.Length); - } - - SetToken(JsonToken.Bytes, data); - } - else if (_readType == ReadType.ReadAsString) - { - string text = _stringReference.ToString(); - - SetToken(JsonToken.String, text); - _quoteChar = quote; - } - else - { - string text = _stringReference.ToString(); - - if (_dateParseHandling != DateParseHandling.None) - { - DateParseHandling dateParseHandling; - if (_readType == ReadType.ReadAsDateTime) - dateParseHandling = DateParseHandling.DateTime; -#if !NET20 - else if (_readType == ReadType.ReadAsDateTimeOffset) - dateParseHandling = DateParseHandling.DateTimeOffset; -#endif - else - dateParseHandling = _dateParseHandling; - - object dt; - if (DateTimeUtils.TryParseDateTime(text, dateParseHandling, DateTimeZoneHandling, out dt)) - { - SetToken(JsonToken.Date, dt); - return; - } - } - - SetToken(JsonToken.String, text); - _quoteChar = quote; - } - } - - private static void BlockCopyChars(char[] src, int srcOffset, char[] dst, int dstOffset, int count) - { - const int charByteCount = 2; - - Buffer.BlockCopy(src, srcOffset * charByteCount, dst, dstOffset * charByteCount, count * charByteCount); - } - - private void ShiftBufferIfNeeded() - { - // once in the last 10% of the buffer shift the remainling content to the start to avoid - // unnessesarly increasing the buffer size when reading numbers/strings - int length = _chars.Length; - if (length - _charPos <= length * 0.1) - { - int count = _charsUsed - _charPos; - if (count > 0) - BlockCopyChars(_chars, _charPos, _chars, 0, count); - - _lineStartPos -= _charPos; - _charPos = 0; - _charsUsed = count; - _chars[_charsUsed] = '\0'; - } - } - - private int ReadData(bool append) - { - return ReadData(append, 0); - } - - private int ReadData(bool append, int charsRequired) - { - if (_isEndOfFile) - return 0; - - // char buffer is full - if (_charsUsed + charsRequired >= _chars.Length - 1) - { - if (append) - { - // copy to new array either double the size of the current or big enough to fit required content - int newArrayLength = Math.Max(_chars.Length * 2, _charsUsed + charsRequired + 1); - - // increase the size of the buffer - char[] dst = new char[newArrayLength]; - - BlockCopyChars(_chars, 0, dst, 0, _chars.Length); - - _chars = dst; - } - else - { - int remainingCharCount = _charsUsed - _charPos; - - if (remainingCharCount + charsRequired + 1 >= _chars.Length) - { - // the remaining count plus the required is bigger than the current buffer size - char[] dst = new char[remainingCharCount + charsRequired + 1]; - - if (remainingCharCount > 0) - BlockCopyChars(_chars, _charPos, dst, 0, remainingCharCount); - - _chars = dst; - } - else - { - // copy any remaining data to the beginning of the buffer if needed and reset positions - if (remainingCharCount > 0) - BlockCopyChars(_chars, _charPos, _chars, 0, remainingCharCount); - } - - _lineStartPos -= _charPos; - _charPos = 0; - _charsUsed = remainingCharCount; - } - } - - int attemptCharReadCount = _chars.Length - _charsUsed - 1; - - int charsRead = _reader.Read(_chars, _charsUsed, attemptCharReadCount); - - _charsUsed += charsRead; - - if (charsRead == 0) - _isEndOfFile = true; - - _chars[_charsUsed] = '\0'; - return charsRead; - } - - private bool EnsureChars(int relativePosition, bool append) - { - if (_charPos + relativePosition >= _charsUsed) - return ReadChars(relativePosition, append); - - return true; - } - - private bool ReadChars(int relativePosition, bool append) - { - if (_isEndOfFile) - return false; - - int charsRequired = _charPos + relativePosition - _charsUsed + 1; - - int totalCharsRead = 0; - - // it is possible that the TextReader doesn't return all data at once - // repeat read until the required text is returned or the reader is out of content - do - { - int charsRead = ReadData(append, charsRequired - totalCharsRead); - - // no more content - if (charsRead == 0) - break; - - totalCharsRead += charsRead; - } - while (totalCharsRead < charsRequired); - - if (totalCharsRead < charsRequired) - return false; - return true; - } - - /// - /// Reads the next JSON token from the stream. - /// - /// - /// true if the next token was read successfully; false if there are no more tokens to read. - /// - [DebuggerStepThrough] - public override bool Read() - { - _readType = ReadType.Read; - if (!ReadInternal()) - { - SetToken(JsonToken.None); - return false; - } - - return true; - } - - /// - /// Reads the next JSON token from the stream as a . - /// - /// - /// A or a null reference if the next JSON token is null. This method will return null at the end of an array. - /// - public override byte[] ReadAsBytes() - { - return ReadAsBytesInternal(); - } - - /// - /// Reads the next JSON token from the stream as a . - /// - /// A . This method will return null at the end of an array. - public override decimal? ReadAsDecimal() - { - return ReadAsDecimalInternal(); - } - - /// - /// Reads the next JSON token from the stream as a . - /// - /// A . This method will return null at the end of an array. - public override int? ReadAsInt32() - { - return ReadAsInt32Internal(); - } - - /// - /// Reads the next JSON token from the stream as a . - /// - /// A . This method will return null at the end of an array. - public override string ReadAsString() - { - return ReadAsStringInternal(); - } - - /// - /// Reads the next JSON token from the stream as a . - /// - /// A . This method will return null at the end of an array. - public override DateTime? ReadAsDateTime() - { - return ReadAsDateTimeInternal(); - } - -#if !NET20 - /// - /// Reads the next JSON token from the stream as a . - /// - /// A . This method will return null at the end of an array. - public override DateTimeOffset? ReadAsDateTimeOffset() - { - return ReadAsDateTimeOffsetInternal(); - } -#endif - - internal override bool ReadInternal() - { - while (true) - { - switch (_currentState) - { - case State.Start: - case State.Property: - case State.Array: - case State.ArrayStart: - case State.Constructor: - case State.ConstructorStart: - return ParseValue(); - case State.Complete: - break; - case State.Object: - case State.ObjectStart: - return ParseObject(); - case State.PostValue: - // returns true if it hits - // end of object or array - if (ParsePostValue()) - return true; - break; - case State.Finished: - if (EnsureChars(0, false)) + if (_buffer == null) { - EatWhitespace(false); - if (_isEndOfFile) - { - return false; - } - if (_chars[_charPos] == '/') - { - ParseComment(); - return true; - } - else - { - throw JsonReaderException.Create(this, "Additional text encountered after finished reading JSON content: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos])); - } + _buffer = new StringBuffer(1025); } - return false; - case State.Closed: - break; - case State.Error: - break; - default: - throw JsonReaderException.Create(this, "Unexpected state: {0}.".FormatWith(CultureInfo.InvariantCulture, CurrentState)); - } - } - } - - private void ReadStringIntoBuffer(char quote) - { - int charPos = _charPos; - int initialPosition = _charPos; - int lastWritePosition = _charPos; - StringBuffer buffer = null; - - while (true) - { - switch (_chars[charPos++]) - { - case '\0': - if (_charsUsed == charPos - 1) + else { - charPos--; - - if (ReadData(true) == 0) - { - _charPos = charPos; - throw JsonReaderException.Create(this, "Unterminated string. Expected delimiter: {0}.".FormatWith(CultureInfo.InvariantCulture, quote)); - } - } - break; - case '\\': - _charPos = charPos; - if (!EnsureChars(0, true)) - { - _charPos = charPos; - throw JsonReaderException.Create(this, "Unterminated string. Expected delimiter: {0}.".FormatWith(CultureInfo.InvariantCulture, quote)); + _buffer.Position = 0; } - // start of escape sequence - int escapeStartPos = charPos - 1; + return _buffer; + } - char currentChar = _chars[charPos]; + private void OnNewLine(int pos) + { + _lineNumber++; + _lineStartPos = pos - 1; + } - char writeChar; + private void ParseString(char quote) + { + _charPos++; - switch (currentChar) + ShiftBufferIfNeeded(); + ReadStringIntoBuffer(quote); + + if (_readType == ReadType.ReadAsBytes) { - case 'b': - charPos++; - writeChar = '\b'; - break; - case 't': - charPos++; - writeChar = '\t'; - break; - case 'n': - charPos++; - writeChar = '\n'; - break; - case 'f': - charPos++; - writeChar = '\f'; - break; - case 'r': - charPos++; - writeChar = '\r'; - break; - case '\\': - charPos++; - writeChar = '\\'; - break; - case '"': - case '\'': - case '/': - writeChar = currentChar; - charPos++; - break; - case 'u': - charPos++; - _charPos = charPos; - writeChar = ParseUnicode(); - - if (StringUtils.IsLowSurrogate(writeChar)) + byte[] data; + if (_stringReference.Length == 0) { - // low surrogate with no preceding high surrogate; this char is replaced - writeChar = UnicodeReplacementChar; + data = new byte[0]; } - else if (StringUtils.IsHighSurrogate(writeChar)) + else { - bool anotherHighSurrogate; + data = Convert.FromBase64CharArray(_stringReference.Chars, _stringReference.StartIndex, _stringReference.Length); + } - // loop for handling situations where there are multiple consecutive high surrogates - do - { - anotherHighSurrogate = false; + SetToken(JsonToken.Bytes, data); + } + else if (_readType == ReadType.ReadAsString) + { + string text = _stringReference.ToString(); - // potential start of a surrogate pair - if (EnsureChars(2, true) && _chars[_charPos] == '\\' && _chars[_charPos + 1] == 'u') + SetToken(JsonToken.String, text); + _quoteChar = quote; + } + else + { + string text = _stringReference.ToString(); + + if (_dateParseHandling != DateParseHandling.None) + { + DateParseHandling dateParseHandling; + if (_readType == ReadType.ReadAsDateTime) + dateParseHandling = DateParseHandling.DateTime; +#if !NET20 + else if (_readType == ReadType.ReadAsDateTimeOffset) + dateParseHandling = DateParseHandling.DateTimeOffset; +#endif + else + dateParseHandling = _dateParseHandling; + + object dt; + if (DateTimeUtils.TryParseDateTime(text, dateParseHandling, DateTimeZoneHandling, out dt)) { - char highSurrogate = writeChar; + SetToken(JsonToken.Date, dt); + return; + } + } - _charPos += 2; - writeChar = ParseUnicode(); + SetToken(JsonToken.String, text); + _quoteChar = quote; + } + } - if (StringUtils.IsLowSurrogate(writeChar)) - { - // a valid surrogate pair! - } - else if (StringUtils.IsHighSurrogate(writeChar)) - { - // another high surrogate; replace current and start check over - highSurrogate = UnicodeReplacementChar; - anotherHighSurrogate = true; - } - else - { - // high surrogate not followed by low surrogate; original char is replaced - highSurrogate = UnicodeReplacementChar; - } + private static void BlockCopyChars(char[] src, int srcOffset, char[] dst, int dstOffset, int count) + { + const int charByteCount = 2; - if (buffer == null) - buffer = GetBuffer(); + Buffer.BlockCopy(src, srcOffset * charByteCount, dst, dstOffset * charByteCount, count * charByteCount); + } - WriteCharToBuffer(buffer, highSurrogate, lastWritePosition, escapeStartPos); - lastWritePosition = _charPos; + private void ShiftBufferIfNeeded() + { + // once in the last 10% of the buffer shift the remainling content to the start to avoid + // unnessesarly increasing the buffer size when reading numbers/strings + int length = _chars.Length; + if (length - _charPos <= length * 0.1) + { + int count = _charsUsed - _charPos; + if (count > 0) + BlockCopyChars(_chars, _charPos, _chars, 0, count); + + _lineStartPos -= _charPos; + _charPos = 0; + _charsUsed = count; + _chars[_charsUsed] = '\0'; + } + } + + private int ReadData(bool append) + { + return ReadData(append, 0); + } + + private int ReadData(bool append, int charsRequired) + { + if (_isEndOfFile) + return 0; + + // char buffer is full + if (_charsUsed + charsRequired >= _chars.Length - 1) + { + if (append) + { + // copy to new array either double the size of the current or big enough to fit required content + int newArrayLength = Math.Max(_chars.Length * 2, _charsUsed + charsRequired + 1); + + // increase the size of the buffer + char[] dst = new char[newArrayLength]; + + BlockCopyChars(_chars, 0, dst, 0, _chars.Length); + + _chars = dst; + } + else + { + int remainingCharCount = _charsUsed - _charPos; + + if (remainingCharCount + charsRequired + 1 >= _chars.Length) + { + // the remaining count plus the required is bigger than the current buffer size + char[] dst = new char[remainingCharCount + charsRequired + 1]; + + if (remainingCharCount > 0) + BlockCopyChars(_chars, _charPos, dst, 0, remainingCharCount); + + _chars = dst; } else { - // there are not enough remaining chars for the low surrogate or is not follow by unicode sequence - // replace high surrogate and continue on as usual - writeChar = UnicodeReplacementChar; + // copy any remaining data to the beginning of the buffer if needed and reset positions + if (remainingCharCount > 0) + BlockCopyChars(_chars, _charPos, _chars, 0, remainingCharCount); + } + + _lineStartPos -= _charPos; + _charPos = 0; + _charsUsed = remainingCharCount; + } + } + + int attemptCharReadCount = _chars.Length - _charsUsed - 1; + + int charsRead = _reader.Read(_chars, _charsUsed, attemptCharReadCount); + + _charsUsed += charsRead; + + if (charsRead == 0) + _isEndOfFile = true; + + _chars[_charsUsed] = '\0'; + return charsRead; + } + + private bool EnsureChars(int relativePosition, bool append) + { + if (_charPos + relativePosition >= _charsUsed) + return ReadChars(relativePosition, append); + + return true; + } + + private bool ReadChars(int relativePosition, bool append) + { + if (_isEndOfFile) + return false; + + int charsRequired = _charPos + relativePosition - _charsUsed + 1; + + int totalCharsRead = 0; + + // it is possible that the TextReader doesn't return all data at once + // repeat read until the required text is returned or the reader is out of content + do + { + int charsRead = ReadData(append, charsRequired - totalCharsRead); + + // no more content + if (charsRead == 0) + break; + + totalCharsRead += charsRead; + } while (totalCharsRead < charsRequired); + + if (totalCharsRead < charsRequired) + return false; + return true; + } + + /// + /// Reads the next JSON token from the stream. + /// + /// + /// true if the next token was read successfully; false if there are no more tokens to read. + /// + [DebuggerStepThrough] + public override bool Read() + { + _readType = ReadType.Read; + if (!ReadInternal()) + { + SetToken(JsonToken.None); + return false; + } + + return true; + } + + /// + /// Reads the next JSON token from the stream as a . + /// + /// + /// A or a null reference if the next JSON token is null. This method will return null at the end of an array. + /// + public override byte[] ReadAsBytes() + { + return ReadAsBytesInternal(); + } + + /// + /// Reads the next JSON token from the stream as a . + /// + /// A . This method will return null at the end of an array. + public override decimal? ReadAsDecimal() + { + return ReadAsDecimalInternal(); + } + + /// + /// Reads the next JSON token from the stream as a . + /// + /// A . This method will return null at the end of an array. + public override int? ReadAsInt32() + { + return ReadAsInt32Internal(); + } + + /// + /// Reads the next JSON token from the stream as a . + /// + /// A . This method will return null at the end of an array. + public override string ReadAsString() + { + return ReadAsStringInternal(); + } + + /// + /// Reads the next JSON token from the stream as a . + /// + /// A . This method will return null at the end of an array. + public override DateTime? ReadAsDateTime() + { + return ReadAsDateTimeInternal(); + } + +#if !NET20 + /// + /// Reads the next JSON token from the stream as a . + /// + /// A . This method will return null at the end of an array. + public override DateTimeOffset? ReadAsDateTimeOffset() + { + return ReadAsDateTimeOffsetInternal(); + } +#endif + + internal override bool ReadInternal() + { + while (true) + { + switch (_currentState) + { + case State.Start: + case State.Property: + case State.Array: + case State.ArrayStart: + case State.Constructor: + case State.ConstructorStart: + return ParseValue(); + case State.Complete: + break; + case State.Object: + case State.ObjectStart: + return ParseObject(); + case State.PostValue: + // returns true if it hits + // end of object or array + if (ParsePostValue()) + return true; + break; + case State.Finished: + if (EnsureChars(0, false)) + { + EatWhitespace(false); + if (_isEndOfFile) + { + return false; + } + if (_chars[_charPos] == '/') + { + ParseComment(); + return true; + } + else + { + throw JsonReaderException.Create(this, "Additional text encountered after finished reading JSON content: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos])); + } + } + return false; + case State.Closed: + break; + case State.Error: + break; + default: + throw JsonReaderException.Create(this, "Unexpected state: {0}.".FormatWith(CultureInfo.InvariantCulture, CurrentState)); + } + } + } + + private void ReadStringIntoBuffer(char quote) + { + int charPos = _charPos; + int initialPosition = _charPos; + int lastWritePosition = _charPos; + StringBuffer buffer = null; + + while (true) + { + switch (_chars[charPos++]) + { + case '\0': + if (_charsUsed == charPos - 1) + { + charPos--; + + if (ReadData(true) == 0) + { + _charPos = charPos; + throw JsonReaderException.Create(this, "Unterminated string. Expected delimiter: {0}.".FormatWith(CultureInfo.InvariantCulture, quote)); + } + } + break; + case '\\': + _charPos = charPos; + if (!EnsureChars(0, true)) + { + _charPos = charPos; + throw JsonReaderException.Create(this, "Unterminated string. Expected delimiter: {0}.".FormatWith(CultureInfo.InvariantCulture, quote)); + } + + // start of escape sequence + int escapeStartPos = charPos - 1; + + char currentChar = _chars[charPos]; + + char writeChar; + + switch (currentChar) + { + case 'b': + charPos++; + writeChar = '\b'; + break; + case 't': + charPos++; + writeChar = '\t'; + break; + case 'n': + charPos++; + writeChar = '\n'; + break; + case 'f': + charPos++; + writeChar = '\f'; + break; + case 'r': + charPos++; + writeChar = '\r'; + break; + case '\\': + charPos++; + writeChar = '\\'; + break; + case '"': + case '\'': + case '/': + writeChar = currentChar; + charPos++; + break; + case 'u': + charPos++; + _charPos = charPos; + writeChar = ParseUnicode(); + + if (StringUtils.IsLowSurrogate(writeChar)) + { + // low surrogate with no preceding high surrogate; this char is replaced + writeChar = UnicodeReplacementChar; + } + else if (StringUtils.IsHighSurrogate(writeChar)) + { + bool anotherHighSurrogate; + + // loop for handling situations where there are multiple consecutive high surrogates + do + { + anotherHighSurrogate = false; + + // potential start of a surrogate pair + if (EnsureChars(2, true) && _chars[_charPos] == '\\' && _chars[_charPos + 1] == 'u') + { + char highSurrogate = writeChar; + + _charPos += 2; + writeChar = ParseUnicode(); + + if (StringUtils.IsLowSurrogate(writeChar)) + { + // a valid surrogate pair! + } + else if (StringUtils.IsHighSurrogate(writeChar)) + { + // another high surrogate; replace current and start check over + highSurrogate = UnicodeReplacementChar; + anotherHighSurrogate = true; + } + else + { + // high surrogate not followed by low surrogate; original char is replaced + highSurrogate = UnicodeReplacementChar; + } + + if (buffer == null) + buffer = GetBuffer(); + + WriteCharToBuffer(buffer, highSurrogate, lastWritePosition, escapeStartPos); + lastWritePosition = _charPos; + } + else + { + // there are not enough remaining chars for the low surrogate or is not follow by unicode sequence + // replace high surrogate and continue on as usual + writeChar = UnicodeReplacementChar; + } + } while (anotherHighSurrogate); + } + + charPos = _charPos; + break; + default: + charPos++; + _charPos = charPos; + throw JsonReaderException.Create(this, "Bad JSON escape sequence: {0}.".FormatWith(CultureInfo.InvariantCulture, @"\" + currentChar)); + } + + if (buffer == null) + buffer = GetBuffer(); + + WriteCharToBuffer(buffer, writeChar, lastWritePosition, escapeStartPos); + + lastWritePosition = charPos; + break; + case StringUtils.CarriageReturn: + _charPos = charPos - 1; + ProcessCarriageReturn(true); + charPos = _charPos; + break; + case StringUtils.LineFeed: + _charPos = charPos - 1; + ProcessLineFeed(); + charPos = _charPos; + break; + case '"': + case '\'': + if (_chars[charPos - 1] == quote) + { + charPos--; + + if (initialPosition == lastWritePosition) + { + _stringReference = new StringReference(_chars, initialPosition, charPos - initialPosition); + } + else + { + if (buffer == null) + buffer = GetBuffer(); + + if (charPos > lastWritePosition) + buffer.Append(_chars, lastWritePosition, charPos - lastWritePosition); + + _stringReference = new StringReference(buffer.GetInternalBuffer(), 0, buffer.Position); + } + + charPos++; + _charPos = charPos; + return; + } + break; + } + } + } + + private void WriteCharToBuffer(StringBuffer buffer, char writeChar, int lastWritePosition, int writeToPosition) + { + if (writeToPosition > lastWritePosition) + { + buffer.Append(_chars, lastWritePosition, writeToPosition - lastWritePosition); + } + + buffer.Append(writeChar); + } + + private char ParseUnicode() + { + char writeChar; + if (EnsureChars(4, true)) + { + string hexValues = new string(_chars, _charPos, 4); + char hexChar = Convert.ToChar(int.Parse(hexValues, NumberStyles.HexNumber, NumberFormatInfo.InvariantInfo)); + writeChar = hexChar; + + _charPos += 4; + } + else + { + throw JsonReaderException.Create(this, "Unexpected end while parsing unicode character."); + } + return writeChar; + } + + private void ReadNumberIntoBuffer() + { + int charPos = _charPos; + + while (true) + { + switch (_chars[charPos++]) + { + case '\0': + if (_charsUsed == charPos - 1) + { + charPos--; + _charPos = charPos; + if (ReadData(true) == 0) + return; + } + else + { + _charPos = charPos - 1; + return; + } + break; + case '-': + case '+': + case 'a': + case 'A': + case 'b': + case 'B': + case 'c': + case 'C': + case 'd': + case 'D': + case 'e': + case 'E': + case 'f': + case 'F': + case 'x': + case 'X': + case '.': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + break; + default: + _charPos = charPos - 1; + return; + } + } + } + + private void ClearRecentString() + { + if (_buffer != null) + _buffer.Position = 0; + + _stringReference = new StringReference(); + } + + private bool ParsePostValue() + { + while (true) + { + char currentChar = _chars[_charPos]; + + switch (currentChar) + { + case '\0': + if (_charsUsed == _charPos) + { + if (ReadData(false) == 0) + { + _currentState = State.Finished; + return false; + } + } + else + { + _charPos++; + } + break; + case '}': + _charPos++; + SetToken(JsonToken.EndObject); + return true; + case ']': + _charPos++; + SetToken(JsonToken.EndArray); + return true; + case ')': + _charPos++; + SetToken(JsonToken.EndConstructor); + return true; + case '/': + ParseComment(); + return true; + case ',': + _charPos++; + + // finished parsing + SetStateBasedOnCurrent(); + return false; + case ' ': + case StringUtils.Tab: + // eat + _charPos++; + break; + case StringUtils.CarriageReturn: + ProcessCarriageReturn(false); + break; + case StringUtils.LineFeed: + ProcessLineFeed(); + break; + default: + if (char.IsWhiteSpace(currentChar)) + { + // eat + _charPos++; + } + else + { + throw JsonReaderException.Create(this, "After parsing a value an unexpected character was encountered: {0}.".FormatWith(CultureInfo.InvariantCulture, currentChar)); + } + break; + } + } + } + + private bool ParseObject() + { + while (true) + { + char currentChar = _chars[_charPos]; + + switch (currentChar) + { + case '\0': + if (_charsUsed == _charPos) + { + if (ReadData(false) == 0) + return false; + } + else + { + _charPos++; + } + break; + case '}': + SetToken(JsonToken.EndObject); + _charPos++; + return true; + case '/': + ParseComment(); + return true; + case StringUtils.CarriageReturn: + ProcessCarriageReturn(false); + break; + case StringUtils.LineFeed: + ProcessLineFeed(); + break; + case ' ': + case StringUtils.Tab: + // eat + _charPos++; + break; + default: + if (char.IsWhiteSpace(currentChar)) + { + // eat + _charPos++; + } + else + { + return ParseProperty(); + } + break; + } + } + } + + private bool ParseProperty() + { + char firstChar = _chars[_charPos]; + char quoteChar; + + if (firstChar == '"' || firstChar == '\'') + { + _charPos++; + quoteChar = firstChar; + ShiftBufferIfNeeded(); + ReadStringIntoBuffer(quoteChar); + } + else if (ValidIdentifierChar(firstChar)) + { + quoteChar = '\0'; + ShiftBufferIfNeeded(); + ParseUnquotedProperty(); + } + else + { + throw JsonReaderException.Create(this, "Invalid property identifier character: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos])); + } + + string propertyName = _stringReference.ToString(); + + EatWhitespace(false); + + if (_chars[_charPos] != ':') + throw JsonReaderException.Create(this, "Invalid character after parsing property name. Expected ':' but got: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos])); + + _charPos++; + + SetToken(JsonToken.PropertyName, propertyName); + _quoteChar = quoteChar; + ClearRecentString(); + + return true; + } + + private bool ValidIdentifierChar(char value) + { + return (char.IsLetterOrDigit(value) || value == '_' || value == '$'); + } + + private void ParseUnquotedProperty() + { + int initialPosition = _charPos; + + // parse unquoted property name until whitespace or colon + while (true) + { + switch (_chars[_charPos]) + { + case '\0': + if (_charsUsed == _charPos) + { + if (ReadData(true) == 0) + throw JsonReaderException.Create(this, "Unexpected end while parsing unquoted property name."); + + break; + } + + _stringReference = new StringReference(_chars, initialPosition, _charPos - initialPosition); + return; + default: + char currentChar = _chars[_charPos]; + + if (ValidIdentifierChar(currentChar)) + { + _charPos++; + break; + } + else if (char.IsWhiteSpace(currentChar) || currentChar == ':') + { + _stringReference = new StringReference(_chars, initialPosition, _charPos - initialPosition); + return; + } + + throw JsonReaderException.Create(this, "Invalid JavaScript property identifier character: {0}.".FormatWith(CultureInfo.InvariantCulture, currentChar)); + } + } + } + + private bool ParseValue() + { + while (true) + { + char currentChar = _chars[_charPos]; + + switch (currentChar) + { + case '\0': + if (_charsUsed == _charPos) + { + if (ReadData(false) == 0) + return false; + } + else + { + _charPos++; + } + break; + case '"': + case '\'': + ParseString(currentChar); + return true; + case 't': + ParseTrue(); + return true; + case 'f': + ParseFalse(); + return true; + case 'n': + if (EnsureChars(1, true)) + { + char next = _chars[_charPos + 1]; + + if (next == 'u') + ParseNull(); + else if (next == 'e') + ParseConstructor(); + else + throw JsonReaderException.Create(this, "Unexpected character encountered while parsing value: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos])); + } + else + { + throw JsonReaderException.Create(this, "Unexpected end."); + } + return true; + case 'N': + ParseNumberNaN(); + return true; + case 'I': + ParseNumberPositiveInfinity(); + return true; + case '-': + if (EnsureChars(1, true) && _chars[_charPos + 1] == 'I') + ParseNumberNegativeInfinity(); + else + ParseNumber(); + return true; + case '/': + ParseComment(); + return true; + case 'u': + ParseUndefined(); + return true; + case '{': + _charPos++; + SetToken(JsonToken.StartObject); + return true; + case '[': + _charPos++; + SetToken(JsonToken.StartArray); + return true; + case ']': + _charPos++; + SetToken(JsonToken.EndArray); + return true; + case ',': + // don't increment position, the next call to read will handle comma + // this is done to handle multiple empty comma values + SetToken(JsonToken.Undefined); + return true; + case ')': + _charPos++; + SetToken(JsonToken.EndConstructor); + return true; + case StringUtils.CarriageReturn: + ProcessCarriageReturn(false); + break; + case StringUtils.LineFeed: + ProcessLineFeed(); + break; + case ' ': + case StringUtils.Tab: + // eat + _charPos++; + break; + default: + if (char.IsWhiteSpace(currentChar)) + { + // eat + _charPos++; + break; + } + else if (char.IsNumber(currentChar) || currentChar == '-' || currentChar == '.') + { + ParseNumber(); + return true; + } + else + { + throw JsonReaderException.Create(this, "Unexpected character encountered while parsing value: {0}.".FormatWith(CultureInfo.InvariantCulture, currentChar)); + } + } + } + } + + private void ProcessLineFeed() + { + _charPos++; + OnNewLine(_charPos); + } + + private void ProcessCarriageReturn(bool append) + { + _charPos++; + + if (EnsureChars(1, append) && _chars[_charPos] == StringUtils.LineFeed) + _charPos++; + + OnNewLine(_charPos); + } + + private bool EatWhitespace(bool oneOrMore) + { + bool finished = false; + bool ateWhitespace = false; + while (!finished) + { + char currentChar = _chars[_charPos]; + + switch (currentChar) + { + case '\0': + if (_charsUsed == _charPos) + { + if (ReadData(false) == 0) + finished = true; + } + else + { + _charPos++; + } + break; + case StringUtils.CarriageReturn: + ProcessCarriageReturn(false); + break; + case StringUtils.LineFeed: + ProcessLineFeed(); + break; + default: + if (currentChar == ' ' || char.IsWhiteSpace(currentChar)) + { + ateWhitespace = true; + _charPos++; + } + else + { + finished = true; + } + break; + } + } + + return (!oneOrMore || ateWhitespace); + } + + private void ParseConstructor() + { + if (MatchValueWithTrailingSeperator("new")) + { + EatWhitespace(false); + + int initialPosition = _charPos; + int endPosition; + + while (true) + { + char currentChar = _chars[_charPos]; + if (currentChar == '\0') + { + if (_charsUsed == _charPos) + { + if (ReadData(true) == 0) + throw JsonReaderException.Create(this, "Unexpected end while parsing constructor."); + } + else + { + endPosition = _charPos; + _charPos++; + break; + } + } + else if (char.IsLetterOrDigit(currentChar)) + { + _charPos++; + } + else if (currentChar == StringUtils.CarriageReturn) + { + endPosition = _charPos; + ProcessCarriageReturn(true); + break; + } + else if (currentChar == StringUtils.LineFeed) + { + endPosition = _charPos; + ProcessLineFeed(); + break; + } + else if (char.IsWhiteSpace(currentChar)) + { + endPosition = _charPos; + _charPos++; + break; + } + else if (currentChar == '(') + { + endPosition = _charPos; + break; + } + else + { + throw JsonReaderException.Create(this, "Unexpected character while parsing constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, currentChar)); } - } while (anotherHighSurrogate); } - charPos = _charPos; - break; - default: - charPos++; - _charPos = charPos; - throw JsonReaderException.Create(this, "Bad JSON escape sequence: {0}.".FormatWith(CultureInfo.InvariantCulture, @"\" + currentChar)); - } + _stringReference = new StringReference(_chars, initialPosition, endPosition - initialPosition); + string constructorName = _stringReference.ToString(); - if (buffer == null) - buffer = GetBuffer(); + EatWhitespace(false); - WriteCharToBuffer(buffer, writeChar, lastWritePosition, escapeStartPos); - - lastWritePosition = charPos; - break; - case StringUtils.CarriageReturn: - _charPos = charPos - 1; - ProcessCarriageReturn(true); - charPos = _charPos; - break; - case StringUtils.LineFeed: - _charPos = charPos - 1; - ProcessLineFeed(); - charPos = _charPos; - break; - case '"': - case '\'': - if (_chars[charPos - 1] == quote) - { - charPos--; - - if (initialPosition == lastWritePosition) - { - _stringReference = new StringReference(_chars, initialPosition, charPos - initialPosition); - } - else - { - if (buffer == null) - buffer = GetBuffer(); - - if (charPos > lastWritePosition) - buffer.Append(_chars, lastWritePosition, charPos - lastWritePosition); - - _stringReference = new StringReference(buffer.GetInternalBuffer(), 0, buffer.Position); - } - - charPos++; - _charPos = charPos; - return; - } - break; - } - } - } - - private void WriteCharToBuffer(StringBuffer buffer, char writeChar, int lastWritePosition, int writeToPosition) - { - if (writeToPosition > lastWritePosition) - { - buffer.Append(_chars, lastWritePosition, writeToPosition - lastWritePosition); - } - - buffer.Append(writeChar); - } - - private char ParseUnicode() - { - char writeChar; - if (EnsureChars(4, true)) - { - string hexValues = new string(_chars, _charPos, 4); - char hexChar = Convert.ToChar(int.Parse(hexValues, NumberStyles.HexNumber, NumberFormatInfo.InvariantInfo)); - writeChar = hexChar; - - _charPos += 4; - } - else - { - throw JsonReaderException.Create(this, "Unexpected end while parsing unicode character."); - } - return writeChar; - } - - private void ReadNumberIntoBuffer() - { - int charPos = _charPos; - - while (true) - { - switch (_chars[charPos++]) - { - case '\0': - if (_charsUsed == charPos - 1) - { - charPos--; - _charPos = charPos; - if (ReadData(true) == 0) - return; - } - else - { - _charPos = charPos - 1; - return; - } - break; - case '-': - case '+': - case 'a': - case 'A': - case 'b': - case 'B': - case 'c': - case 'C': - case 'd': - case 'D': - case 'e': - case 'E': - case 'f': - case 'F': - case 'x': - case 'X': - case '.': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - break; - default: - _charPos = charPos - 1; - return; - } - } - } - - private void ClearRecentString() - { - if (_buffer != null) - _buffer.Position = 0; - - _stringReference = new StringReference(); - } - - private bool ParsePostValue() - { - while (true) - { - char currentChar = _chars[_charPos]; - - switch (currentChar) - { - case '\0': - if (_charsUsed == _charPos) - { - if (ReadData(false) == 0) - { - _currentState = State.Finished; - return false; - } - } - else - { - _charPos++; - } - break; - case '}': - _charPos++; - SetToken(JsonToken.EndObject); - return true; - case ']': - _charPos++; - SetToken(JsonToken.EndArray); - return true; - case ')': - _charPos++; - SetToken(JsonToken.EndConstructor); - return true; - case '/': - ParseComment(); - return true; - case ',': - _charPos++; - - // finished parsing - SetStateBasedOnCurrent(); - return false; - case ' ': - case StringUtils.Tab: - // eat - _charPos++; - break; - case StringUtils.CarriageReturn: - ProcessCarriageReturn(false); - break; - case StringUtils.LineFeed: - ProcessLineFeed(); - break; - default: - if (char.IsWhiteSpace(currentChar)) - { - // eat - _charPos++; - } - else - { - throw JsonReaderException.Create(this, "After parsing a value an unexpected character was encountered: {0}.".FormatWith(CultureInfo.InvariantCulture, currentChar)); - } - break; - } - } - } - - private bool ParseObject() - { - while (true) - { - char currentChar = _chars[_charPos]; - - switch (currentChar) - { - case '\0': - if (_charsUsed == _charPos) - { - if (ReadData(false) == 0) - return false; - } - else - { - _charPos++; - } - break; - case '}': - SetToken(JsonToken.EndObject); - _charPos++; - return true; - case '/': - ParseComment(); - return true; - case StringUtils.CarriageReturn: - ProcessCarriageReturn(false); - break; - case StringUtils.LineFeed: - ProcessLineFeed(); - break; - case ' ': - case StringUtils.Tab: - // eat - _charPos++; - break; - default: - if (char.IsWhiteSpace(currentChar)) - { - // eat - _charPos++; - } - else - { - return ParseProperty(); - } - break; - } - } - } - - private bool ParseProperty() - { - char firstChar = _chars[_charPos]; - char quoteChar; - - if (firstChar == '"' || firstChar == '\'') - { - _charPos++; - quoteChar = firstChar; - ShiftBufferIfNeeded(); - ReadStringIntoBuffer(quoteChar); - } - else if (ValidIdentifierChar(firstChar)) - { - quoteChar = '\0'; - ShiftBufferIfNeeded(); - ParseUnquotedProperty(); - } - else - { - throw JsonReaderException.Create(this, "Invalid property identifier character: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos])); - } - - string propertyName = _stringReference.ToString(); - - EatWhitespace(false); - - if (_chars[_charPos] != ':') - throw JsonReaderException.Create(this, "Invalid character after parsing property name. Expected ':' but got: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos])); - - _charPos++; - - SetToken(JsonToken.PropertyName, propertyName); - _quoteChar = quoteChar; - ClearRecentString(); - - return true; - } - - private bool ValidIdentifierChar(char value) - { - return (char.IsLetterOrDigit(value) || value == '_' || value == '$'); - } - - private void ParseUnquotedProperty() - { - int initialPosition = _charPos; - - // parse unquoted property name until whitespace or colon - while (true) - { - switch (_chars[_charPos]) - { - case '\0': - if (_charsUsed == _charPos) - { - if (ReadData(true) == 0) - throw JsonReaderException.Create(this, "Unexpected end while parsing unquoted property name."); - - break; - } - - _stringReference = new StringReference(_chars, initialPosition, _charPos - initialPosition); - return; - default: - char currentChar = _chars[_charPos]; - - if (ValidIdentifierChar(currentChar)) - { - _charPos++; - break; - } - else if (char.IsWhiteSpace(currentChar) || currentChar == ':') - { - _stringReference = new StringReference(_chars, initialPosition, _charPos - initialPosition); - return; - } - - throw JsonReaderException.Create(this, "Invalid JavaScript property identifier character: {0}.".FormatWith(CultureInfo.InvariantCulture, currentChar)); - } - } - } - - private bool ParseValue() - { - while (true) - { - char currentChar = _chars[_charPos]; - - switch (currentChar) - { - case '\0': - if (_charsUsed == _charPos) - { - if (ReadData(false) == 0) - return false; - } - else - { - _charPos++; - } - break; - case '"': - case '\'': - ParseString(currentChar); - return true; - case 't': - ParseTrue(); - return true; - case 'f': - ParseFalse(); - return true; - case 'n': - if (EnsureChars(1, true)) - { - char next = _chars[_charPos + 1]; - - if (next == 'u') - ParseNull(); - else if (next == 'e') - ParseConstructor(); - else - throw JsonReaderException.Create(this, "Unexpected character encountered while parsing value: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos])); - } - else - { - throw JsonReaderException.Create(this, "Unexpected end."); - } - return true; - case 'N': - ParseNumberNaN(); - return true; - case 'I': - ParseNumberPositiveInfinity(); - return true; - case '-': - if (EnsureChars(1, true) && _chars[_charPos + 1] == 'I') - ParseNumberNegativeInfinity(); - else - ParseNumber(); - return true; - case '/': - ParseComment(); - return true; - case 'u': - ParseUndefined(); - return true; - case '{': - _charPos++; - SetToken(JsonToken.StartObject); - return true; - case '[': - _charPos++; - SetToken(JsonToken.StartArray); - return true; - case ']': - _charPos++; - SetToken(JsonToken.EndArray); - return true; - case ',': - // don't increment position, the next call to read will handle comma - // this is done to handle multiple empty comma values - SetToken(JsonToken.Undefined); - return true; - case ')': - _charPos++; - SetToken(JsonToken.EndConstructor); - return true; - case StringUtils.CarriageReturn: - ProcessCarriageReturn(false); - break; - case StringUtils.LineFeed: - ProcessLineFeed(); - break; - case ' ': - case StringUtils.Tab: - // eat - _charPos++; - break; - default: - if (char.IsWhiteSpace(currentChar)) - { - // eat - _charPos++; - break; - } - else if (char.IsNumber(currentChar) || currentChar == '-' || currentChar == '.') - { - ParseNumber(); - return true; - } - else - { - throw JsonReaderException.Create(this, "Unexpected character encountered while parsing value: {0}.".FormatWith(CultureInfo.InvariantCulture, currentChar)); - } - } - } - } - - private void ProcessLineFeed() - { - _charPos++; - OnNewLine(_charPos); - } - - private void ProcessCarriageReturn(bool append) - { - _charPos++; - - if (EnsureChars(1, append) && _chars[_charPos] == StringUtils.LineFeed) - _charPos++; - - OnNewLine(_charPos); - } - - private bool EatWhitespace(bool oneOrMore) - { - bool finished = false; - bool ateWhitespace = false; - while (!finished) - { - char currentChar = _chars[_charPos]; - - switch (currentChar) - { - case '\0': - if (_charsUsed == _charPos) - { - if (ReadData(false) == 0) - finished = true; - } - else - { - _charPos++; - } - break; - case StringUtils.CarriageReturn: - ProcessCarriageReturn(false); - break; - case StringUtils.LineFeed: - ProcessLineFeed(); - break; - default: - if (currentChar == ' ' || char.IsWhiteSpace(currentChar)) - { - ateWhitespace = true; - _charPos++; - } - else - { - finished = true; - } - break; - } - } - - return (!oneOrMore || ateWhitespace); - } - - private void ParseConstructor() - { - if (MatchValueWithTrailingSeperator("new")) - { - EatWhitespace(false); - - int initialPosition = _charPos; - int endPosition; - - while (true) - { - char currentChar = _chars[_charPos]; - if (currentChar == '\0') - { - if (_charsUsed == _charPos) - { - if (ReadData(true) == 0) - throw JsonReaderException.Create(this, "Unexpected end while parsing constructor."); - } - else - { - endPosition = _charPos; - _charPos++; - break; - } - } - else if (char.IsLetterOrDigit(currentChar)) - { - _charPos++; - } - else if (currentChar == StringUtils.CarriageReturn) - { - endPosition = _charPos; - ProcessCarriageReturn(true); - break; - } - else if (currentChar == StringUtils.LineFeed) - { - endPosition = _charPos; - ProcessLineFeed(); - break; - } - else if (char.IsWhiteSpace(currentChar)) - { - endPosition = _charPos; - _charPos++; - break; - } - else if (currentChar == '(') - { - endPosition = _charPos; - break; - } - else - { - throw JsonReaderException.Create(this, "Unexpected character while parsing constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, currentChar)); - } - } - - _stringReference = new StringReference(_chars, initialPosition, endPosition - initialPosition); - string constructorName = _stringReference.ToString(); - - EatWhitespace(false); - - if (_chars[_charPos] != '(') - throw JsonReaderException.Create(this, "Unexpected character while parsing constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos])); - - _charPos++; - - ClearRecentString(); - - SetToken(JsonToken.StartConstructor, constructorName); - } - else - { - throw JsonReaderException.Create(this, "Unexpected content while parsing JSON."); - } - } - - private void ParseNumber() - { - ShiftBufferIfNeeded(); - - char firstChar = _chars[_charPos]; - int initialPosition = _charPos; - - ReadNumberIntoBuffer(); - - _stringReference = new StringReference(_chars, initialPosition, _charPos - initialPosition); - - object numberValue; - JsonToken numberType; - - bool singleDigit = (char.IsDigit(firstChar) && _stringReference.Length == 1); - bool nonBase10 = (firstChar == '0' && _stringReference.Length > 1 - && _stringReference.Chars[_stringReference.StartIndex + 1] != '.' - && _stringReference.Chars[_stringReference.StartIndex + 1] != 'e' - && _stringReference.Chars[_stringReference.StartIndex + 1] != 'E'); - - if (_readType == ReadType.ReadAsInt32) - { - if (singleDigit) - { - // digit char values start at 48 - numberValue = firstChar - 48; - } - else if (nonBase10) - { - string number = _stringReference.ToString(); - - // decimal.Parse doesn't support parsing hexadecimal values - int integer = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase) - ? Convert.ToInt32(number, 16) - : Convert.ToInt32(number, 8); - - numberValue = integer; - } - else - { - numberValue = ConvertUtils.Int32Parse(_stringReference.Chars, _stringReference.StartIndex, _stringReference.Length); - } - - numberType = JsonToken.Integer; - } - else if (_readType == ReadType.ReadAsDecimal) - { - if (singleDigit) - { - // digit char values start at 48 - numberValue = (decimal)firstChar - 48; - } - else if (nonBase10) - { - string number = _stringReference.ToString(); - - // decimal.Parse doesn't support parsing hexadecimal values - long integer = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase) - ? Convert.ToInt64(number, 16) - : Convert.ToInt64(number, 8); - - numberValue = Convert.ToDecimal(integer); - } - else - { - string number = _stringReference.ToString(); - - numberValue = decimal.Parse(number, NumberStyles.Number | NumberStyles.AllowExponent, CultureInfo.InvariantCulture); - } - - numberType = JsonToken.Float; - } - else - { - if (singleDigit) - { - // digit char values start at 48 - numberValue = (long)firstChar - 48; - numberType = JsonToken.Integer; - } - else if (nonBase10) - { - string number = _stringReference.ToString(); - - numberValue = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase) - ? Convert.ToInt64(number, 16) - : Convert.ToInt64(number, 8); - numberType = JsonToken.Integer; - } - else - { - long value; - ParseResult parseResult = ConvertUtils.Int64TryParse(_stringReference.Chars, _stringReference.StartIndex, _stringReference.Length, out value); - if (parseResult == ParseResult.Success) - { - numberValue = value; - numberType = JsonToken.Integer; - } - else if (parseResult == ParseResult.Invalid) - { - string number = _stringReference.ToString(); - - if (_floatParseHandling == FloatParseHandling.Decimal) - numberValue = decimal.Parse(number, NumberStyles.Number | NumberStyles.AllowExponent, CultureInfo.InvariantCulture); - else - numberValue = Convert.ToDouble(number, CultureInfo.InvariantCulture); - - numberType = JsonToken.Float; - } - else if (parseResult == ParseResult.Overflow) - { -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - string number = _stringReference.ToString(); - numberValue = BigInteger.Parse(number, CultureInfo.InvariantCulture); - numberType = JsonToken.Integer; -#else - // todo - validate number was a valid integer to make sure overflow was the reason for failure - throw JsonReaderException.Create(this, "JSON integer {0} is too large or small for an Int64.".FormatWith(CultureInfo.InvariantCulture, _stringReference.ToString())); -#endif - } - else - { - throw JsonReaderException.Create(this, "Unknown error parsing integer."); - } - } - } - - ClearRecentString(); - - SetToken(numberType, numberValue); - } - - private void ParseComment() - { - // should have already parsed / character before reaching this method - _charPos++; - - if (!EnsureChars(1, false) || _chars[_charPos] != '*') - throw JsonReaderException.Create(this, "Error parsing comment. Expected: *, got {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos])); - else - _charPos++; - - int initialPosition = _charPos; - - bool commentFinished = false; - - while (!commentFinished) - { - switch (_chars[_charPos]) - { - case '\0': - if (_charsUsed == _charPos) - { - if (ReadData(true) == 0) - throw JsonReaderException.Create(this, "Unexpected end while parsing comment."); - } - else - { - _charPos++; - } - break; - case '*': - _charPos++; - - if (EnsureChars(0, true)) - { - if (_chars[_charPos] == '/') - { - _stringReference = new StringReference(_chars, initialPosition, _charPos - initialPosition - 1); + if (_chars[_charPos] != '(') + throw JsonReaderException.Create(this, "Unexpected character while parsing constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos])); _charPos++; - commentFinished = true; - } + + ClearRecentString(); + + SetToken(JsonToken.StartConstructor, constructorName); + } + else + { + throw JsonReaderException.Create(this, "Unexpected content while parsing JSON."); } - break; - case StringUtils.CarriageReturn: - ProcessCarriageReturn(true); - break; - case StringUtils.LineFeed: - ProcessLineFeed(); - break; - default: - _charPos++; - break; } - } - SetToken(JsonToken.Comment, _stringReference.ToString()); - - ClearRecentString(); - } - - private bool MatchValue(string value) - { - if (!EnsureChars(value.Length - 1, true)) - return false; - - for (int i = 0; i < value.Length; i++) - { - if (_chars[_charPos + i] != value[i]) + private void ParseNumber() { - return false; - } - } + ShiftBufferIfNeeded(); - _charPos += value.Length; + char firstChar = _chars[_charPos]; + int initialPosition = _charPos; - return true; - } + ReadNumberIntoBuffer(); - private bool MatchValueWithTrailingSeperator(string value) - { - // will match value and then move to the next character, checking that it is a seperator character - bool match = MatchValue(value); + _stringReference = new StringReference(_chars, initialPosition, _charPos - initialPosition); - if (!match) - return false; + object numberValue; + JsonToken numberType; - if (!EnsureChars(0, false)) - return true; + bool singleDigit = (char.IsDigit(firstChar) && _stringReference.Length == 1); + bool nonBase10 = (firstChar == '0' && _stringReference.Length > 1 + && _stringReference.Chars[_stringReference.StartIndex + 1] != '.' + && _stringReference.Chars[_stringReference.StartIndex + 1] != 'e' + && _stringReference.Chars[_stringReference.StartIndex + 1] != 'E'); - return IsSeperator(_chars[_charPos]) || _chars[_charPos] == '\0'; - } + if (_readType == ReadType.ReadAsInt32) + { + if (singleDigit) + { + // digit char values start at 48 + numberValue = firstChar - 48; + } + else if (nonBase10) + { + string number = _stringReference.ToString(); - private bool IsSeperator(char c) - { - switch (c) - { - case '}': - case ']': - case ',': - return true; - case '/': - // check next character to see if start of a comment - if (!EnsureChars(1, false)) - return false; + // decimal.Parse doesn't support parsing hexadecimal values + int integer = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase) + ? Convert.ToInt32(number, 16) + : Convert.ToInt32(number, 8); - return (_chars[_charPos + 1] == '*'); - case ')': - if (CurrentState == State.Constructor || CurrentState == State.ConstructorStart) - return true; - break; - case ' ': - case StringUtils.Tab: - case StringUtils.LineFeed: - case StringUtils.CarriageReturn: - return true; - default: - if (char.IsWhiteSpace(c)) - return true; - break; - } + numberValue = integer; + } + else + { + numberValue = ConvertUtils.Int32Parse(_stringReference.Chars, _stringReference.StartIndex, _stringReference.Length); + } - return false; - } + numberType = JsonToken.Integer; + } + else if (_readType == ReadType.ReadAsDecimal) + { + if (singleDigit) + { + // digit char values start at 48 + numberValue = (decimal)firstChar - 48; + } + else if (nonBase10) + { + string number = _stringReference.ToString(); - private void ParseTrue() - { - // check characters equal 'true' - // and that it is followed by either a seperator character - // or the text ends - if (MatchValueWithTrailingSeperator(JsonConvert.True)) - { - SetToken(JsonToken.Boolean, true); - } - else - { - throw JsonReaderException.Create(this, "Error parsing boolean value."); - } - } + // decimal.Parse doesn't support parsing hexadecimal values + long integer = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase) + ? Convert.ToInt64(number, 16) + : Convert.ToInt64(number, 8); - private void ParseNull() - { - if (MatchValueWithTrailingSeperator(JsonConvert.Null)) - { - SetToken(JsonToken.Null); - } - else - { - throw JsonReaderException.Create(this, "Error parsing null value."); - } - } + numberValue = Convert.ToDecimal(integer); + } + else + { + string number = _stringReference.ToString(); - private void ParseUndefined() - { - if (MatchValueWithTrailingSeperator(JsonConvert.Undefined)) - { - SetToken(JsonToken.Undefined); - } - else - { - throw JsonReaderException.Create(this, "Error parsing undefined value."); - } - } + numberValue = decimal.Parse(number, NumberStyles.Number | NumberStyles.AllowExponent, CultureInfo.InvariantCulture); + } - private void ParseFalse() - { - if (MatchValueWithTrailingSeperator(JsonConvert.False)) - { - SetToken(JsonToken.Boolean, false); - } - else - { - throw JsonReaderException.Create(this, "Error parsing boolean value."); - } - } + numberType = JsonToken.Float; + } + else + { + if (singleDigit) + { + // digit char values start at 48 + numberValue = (long)firstChar - 48; + numberType = JsonToken.Integer; + } + else if (nonBase10) + { + string number = _stringReference.ToString(); - private void ParseNumberNegativeInfinity() - { - if (MatchValueWithTrailingSeperator(JsonConvert.NegativeInfinity)) - { - if (_floatParseHandling == FloatParseHandling.Decimal) - throw new JsonReaderException("Cannot read -Infinity as a decimal."); + numberValue = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase) + ? Convert.ToInt64(number, 16) + : Convert.ToInt64(number, 8); + numberType = JsonToken.Integer; + } + else + { + long value; + ParseResult parseResult = ConvertUtils.Int64TryParse(_stringReference.Chars, _stringReference.StartIndex, _stringReference.Length, out value); + if (parseResult == ParseResult.Success) + { + numberValue = value; + numberType = JsonToken.Integer; + } + else if (parseResult == ParseResult.Invalid) + { + string number = _stringReference.ToString(); - SetToken(JsonToken.Float, double.NegativeInfinity); - } - else - { - throw JsonReaderException.Create(this, "Error parsing negative infinity value."); - } - } + if (_floatParseHandling == FloatParseHandling.Decimal) + numberValue = decimal.Parse(number, NumberStyles.Number | NumberStyles.AllowExponent, CultureInfo.InvariantCulture); + else + numberValue = Convert.ToDouble(number, CultureInfo.InvariantCulture); - private void ParseNumberPositiveInfinity() - { - if (MatchValueWithTrailingSeperator(JsonConvert.PositiveInfinity)) - { - if (_floatParseHandling == FloatParseHandling.Decimal) - throw new JsonReaderException("Cannot read Infinity as a decimal."); - - SetToken(JsonToken.Float, double.PositiveInfinity); - } - else - { - throw JsonReaderException.Create(this, "Error parsing positive infinity value."); - } - } - - private void ParseNumberNaN() - { - if (MatchValueWithTrailingSeperator(JsonConvert.NaN)) - { - if (_floatParseHandling == FloatParseHandling.Decimal) - throw new JsonReaderException("Cannot read NaN as a decimal."); - - SetToken(JsonToken.Float, double.NaN); - } - else - { - throw JsonReaderException.Create(this, "Error parsing NaN value."); - } - } - - /// - /// Changes the state to closed. - /// - public override void Close() - { - base.Close(); - - if (CloseInput && _reader != null) -#if !(NETFX_CORE || PORTABLE40 || PORTABLE) - _reader.Close(); + numberType = JsonToken.Float; + } + else if (parseResult == ParseResult.Overflow) + { +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + string number = _stringReference.ToString(); + numberValue = BigInteger.Parse(number, CultureInfo.InvariantCulture); + numberType = JsonToken.Integer; #else - _reader.Dispose(); + // todo - validate number was a valid integer to make sure overflow was the reason for failure + throw JsonReaderException.Create(this, "JSON integer {0} is too large or small for an Int64.".FormatWith(CultureInfo.InvariantCulture, _stringReference.ToString())); +#endif + } + else + { + throw JsonReaderException.Create(this, "Unknown error parsing integer."); + } + } + } + + ClearRecentString(); + + SetToken(numberType, numberValue); + } + + private void ParseComment() + { + // should have already parsed / character before reaching this method + _charPos++; + + if (!EnsureChars(1, false) || _chars[_charPos] != '*') + throw JsonReaderException.Create(this, "Error parsing comment. Expected: *, got {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos])); + else + _charPos++; + + int initialPosition = _charPos; + + bool commentFinished = false; + + while (!commentFinished) + { + switch (_chars[_charPos]) + { + case '\0': + if (_charsUsed == _charPos) + { + if (ReadData(true) == 0) + throw JsonReaderException.Create(this, "Unexpected end while parsing comment."); + } + else + { + _charPos++; + } + break; + case '*': + _charPos++; + + if (EnsureChars(0, true)) + { + if (_chars[_charPos] == '/') + { + _stringReference = new StringReference(_chars, initialPosition, _charPos - initialPosition - 1); + + _charPos++; + commentFinished = true; + } + } + break; + case StringUtils.CarriageReturn: + ProcessCarriageReturn(true); + break; + case StringUtils.LineFeed: + ProcessLineFeed(); + break; + default: + _charPos++; + break; + } + } + + SetToken(JsonToken.Comment, _stringReference.ToString()); + + ClearRecentString(); + } + + private bool MatchValue(string value) + { + if (!EnsureChars(value.Length - 1, true)) + return false; + + for (int i = 0; i < value.Length; i++) + { + if (_chars[_charPos + i] != value[i]) + { + return false; + } + } + + _charPos += value.Length; + + return true; + } + + private bool MatchValueWithTrailingSeperator(string value) + { + // will match value and then move to the next character, checking that it is a seperator character + bool match = MatchValue(value); + + if (!match) + return false; + + if (!EnsureChars(0, false)) + return true; + + return IsSeperator(_chars[_charPos]) || _chars[_charPos] == '\0'; + } + + private bool IsSeperator(char c) + { + switch (c) + { + case '}': + case ']': + case ',': + return true; + case '/': + // check next character to see if start of a comment + if (!EnsureChars(1, false)) + return false; + + return (_chars[_charPos + 1] == '*'); + case ')': + if (CurrentState == State.Constructor || CurrentState == State.ConstructorStart) + return true; + break; + case ' ': + case StringUtils.Tab: + case StringUtils.LineFeed: + case StringUtils.CarriageReturn: + return true; + default: + if (char.IsWhiteSpace(c)) + return true; + break; + } + + return false; + } + + private void ParseTrue() + { + // check characters equal 'true' + // and that it is followed by either a seperator character + // or the text ends + if (MatchValueWithTrailingSeperator(JsonConvert.True)) + { + SetToken(JsonToken.Boolean, true); + } + else + { + throw JsonReaderException.Create(this, "Error parsing boolean value."); + } + } + + private void ParseNull() + { + if (MatchValueWithTrailingSeperator(JsonConvert.Null)) + { + SetToken(JsonToken.Null); + } + else + { + throw JsonReaderException.Create(this, "Error parsing null value."); + } + } + + private void ParseUndefined() + { + if (MatchValueWithTrailingSeperator(JsonConvert.Undefined)) + { + SetToken(JsonToken.Undefined); + } + else + { + throw JsonReaderException.Create(this, "Error parsing undefined value."); + } + } + + private void ParseFalse() + { + if (MatchValueWithTrailingSeperator(JsonConvert.False)) + { + SetToken(JsonToken.Boolean, false); + } + else + { + throw JsonReaderException.Create(this, "Error parsing boolean value."); + } + } + + private void ParseNumberNegativeInfinity() + { + if (MatchValueWithTrailingSeperator(JsonConvert.NegativeInfinity)) + { + if (_floatParseHandling == FloatParseHandling.Decimal) + throw new JsonReaderException("Cannot read -Infinity as a decimal."); + + SetToken(JsonToken.Float, double.NegativeInfinity); + } + else + { + throw JsonReaderException.Create(this, "Error parsing negative infinity value."); + } + } + + private void ParseNumberPositiveInfinity() + { + if (MatchValueWithTrailingSeperator(JsonConvert.PositiveInfinity)) + { + if (_floatParseHandling == FloatParseHandling.Decimal) + throw new JsonReaderException("Cannot read Infinity as a decimal."); + + SetToken(JsonToken.Float, double.PositiveInfinity); + } + else + { + throw JsonReaderException.Create(this, "Error parsing positive infinity value."); + } + } + + private void ParseNumberNaN() + { + if (MatchValueWithTrailingSeperator(JsonConvert.NaN)) + { + if (_floatParseHandling == FloatParseHandling.Decimal) + throw new JsonReaderException("Cannot read NaN as a decimal."); + + SetToken(JsonToken.Float, double.NaN); + } + else + { + throw JsonReaderException.Create(this, "Error parsing NaN value."); + } + } + + /// + /// Changes the state to closed. + /// + public override void Close() + { + base.Close(); + + if (CloseInput && _reader != null) +#if !(NETFX_CORE || PORTABLE40 || PORTABLE) + _reader.Close(); +#else + _reader.Dispose(); #endif - if (_buffer != null) - _buffer.Clear(); - } + if (_buffer != null) + _buffer.Clear(); + } - /// - /// Gets a value indicating whether the class can return line information. - /// - /// - /// true if LineNumber and LinePosition can be provided; otherwise, false. - /// - public bool HasLineInfo() - { - return true; - } + /// + /// Gets a value indicating whether the class can return line information. + /// + /// + /// true if LineNumber and LinePosition can be provided; otherwise, false. + /// + public bool HasLineInfo() + { + return true; + } - /// - /// Gets the current line number. - /// - /// - /// The current line number or 0 if no line information is available (for example, HasLineInfo returns false). - /// - public int LineNumber - { - get - { - if (CurrentState == State.Start && LinePosition == 0) - return 0; + /// + /// Gets the current line number. + /// + /// + /// The current line number or 0 if no line information is available (for example, HasLineInfo returns false). + /// + public int LineNumber + { + get + { + if (CurrentState == State.Start && LinePosition == 0) + return 0; - return _lineNumber; - } - } + return _lineNumber; + } + } - /// - /// Gets the current line position. - /// - /// - /// The current line position or 0 if no line information is available (for example, HasLineInfo returns false). - /// - public int LinePosition - { - get { return _charPos - _lineStartPos; } + /// + /// Gets the current line position. + /// + /// + /// The current line position or 0 if no line information is available (for example, HasLineInfo returns false). + /// + public int LinePosition + { + get { return _charPos - _lineStartPos; } + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/JsonTextWriter.cs b/Src/Newtonsoft.Json/JsonTextWriter.cs index 3ebb4e5c..5023c10f 100644 --- a/Src/Newtonsoft.Json/JsonTextWriter.cs +++ b/Src/Newtonsoft.Json/JsonTextWriter.cs @@ -36,696 +36,696 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json { - /// - /// Represents a writer that provides a fast, non-cached, forward-only way of generating Json data. - /// - public class JsonTextWriter : JsonWriter - { - private readonly TextWriter _writer; - private Base64Encoder _base64Encoder; - private char _indentChar; - private int _indentation; - private char _quoteChar; - private bool _quoteName; - private bool[] _charEscapeFlags; - private char[] _writeBuffer; - - private Base64Encoder Base64Encoder - { - get - { - if (_base64Encoder == null) - _base64Encoder = new Base64Encoder(_writer); - - return _base64Encoder; - } - } - /// - /// Gets or sets how many IndentChars to write for each level in the hierarchy when is set to Formatting.Indented. + /// Represents a writer that provides a fast, non-cached, forward-only way of generating Json data. /// - public int Indentation + public class JsonTextWriter : JsonWriter { - get { return _indentation; } - set - { - if (value < 0) - throw new ArgumentException("Indentation value must be greater than 0."); + private readonly TextWriter _writer; + private Base64Encoder _base64Encoder; + private char _indentChar; + private int _indentation; + private char _quoteChar; + private bool _quoteName; + private bool[] _charEscapeFlags; + private char[] _writeBuffer; - _indentation = value; - } - } + private Base64Encoder Base64Encoder + { + get + { + if (_base64Encoder == null) + _base64Encoder = new Base64Encoder(_writer); - /// - /// Gets or sets which character to use to quote attribute values. - /// - public char QuoteChar - { - get { return _quoteChar; } - set - { - if (value != '"' && value != '\'') - throw new ArgumentException(@"Invalid JavaScript string quote character. Valid quote characters are ' and ""."); + return _base64Encoder; + } + } - _quoteChar = value; - UpdateCharEscapeFlags(); - } - } + /// + /// Gets or sets how many IndentChars to write for each level in the hierarchy when is set to Formatting.Indented. + /// + public int Indentation + { + get { return _indentation; } + set + { + if (value < 0) + throw new ArgumentException("Indentation value must be greater than 0."); - /// - /// Gets or sets which character to use for indenting when is set to Formatting.Indented. - /// - public char IndentChar - { - get { return _indentChar; } - set { _indentChar = value; } - } + _indentation = value; + } + } - /// - /// Gets or sets a value indicating whether object names will be surrounded with quotes. - /// - public bool QuoteName - { - get { return _quoteName; } - set { _quoteName = value; } - } + /// + /// Gets or sets which character to use to quote attribute values. + /// + public char QuoteChar + { + get { return _quoteChar; } + set + { + if (value != '"' && value != '\'') + throw new ArgumentException(@"Invalid JavaScript string quote character. Valid quote characters are ' and ""."); - /// - /// Creates an instance of the JsonWriter class using the specified . - /// - /// The TextWriter to write to. - public JsonTextWriter(TextWriter textWriter) - { - if (textWriter == null) - throw new ArgumentNullException("textWriter"); + _quoteChar = value; + UpdateCharEscapeFlags(); + } + } - _writer = textWriter; - _quoteChar = '"'; - _quoteName = true; - _indentChar = ' '; - _indentation = 2; + /// + /// Gets or sets which character to use for indenting when is set to Formatting.Indented. + /// + public char IndentChar + { + get { return _indentChar; } + set { _indentChar = value; } + } - UpdateCharEscapeFlags(); - } + /// + /// Gets or sets a value indicating whether object names will be surrounded with quotes. + /// + public bool QuoteName + { + get { return _quoteName; } + set { _quoteName = value; } + } - /// - /// Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. - /// - public override void Flush() - { - _writer.Flush(); - } + /// + /// Creates an instance of the JsonWriter class using the specified . + /// + /// The TextWriter to write to. + public JsonTextWriter(TextWriter textWriter) + { + if (textWriter == null) + throw new ArgumentNullException("textWriter"); - /// - /// Closes this stream and the underlying stream. - /// - public override void Close() - { - base.Close(); + _writer = textWriter; + _quoteChar = '"'; + _quoteName = true; + _indentChar = ' '; + _indentation = 2; - if (CloseOutput && _writer != null) + UpdateCharEscapeFlags(); + } + + /// + /// Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. + /// + public override void Flush() + { + _writer.Flush(); + } + + /// + /// Closes this stream and the underlying stream. + /// + public override void Close() + { + base.Close(); + + if (CloseOutput && _writer != null) #if !(NETFX_CORE || PORTABLE40 || PORTABLE) - _writer.Close(); + _writer.Close(); #else - _writer.Dispose(); + _writer.Dispose(); #endif - } + } - /// - /// Writes the beginning of a Json object. - /// - public override void WriteStartObject() - { - InternalWriteStart(JsonToken.StartObject, JsonContainerType.Object); + /// + /// Writes the beginning of a Json object. + /// + public override void WriteStartObject() + { + InternalWriteStart(JsonToken.StartObject, JsonContainerType.Object); - _writer.Write("{"); - } + _writer.Write("{"); + } - /// - /// Writes the beginning of a Json array. - /// - public override void WriteStartArray() - { - InternalWriteStart(JsonToken.StartArray, JsonContainerType.Array); + /// + /// Writes the beginning of a Json array. + /// + public override void WriteStartArray() + { + InternalWriteStart(JsonToken.StartArray, JsonContainerType.Array); - _writer.Write("["); - } + _writer.Write("["); + } - /// - /// Writes the start of a constructor with the given name. - /// - /// The name of the constructor. - public override void WriteStartConstructor(string name) - { - InternalWriteStart(JsonToken.StartConstructor, JsonContainerType.Constructor); + /// + /// Writes the start of a constructor with the given name. + /// + /// The name of the constructor. + public override void WriteStartConstructor(string name) + { + InternalWriteStart(JsonToken.StartConstructor, JsonContainerType.Constructor); - _writer.Write("new "); - _writer.Write(name); - _writer.Write("("); - } + _writer.Write("new "); + _writer.Write(name); + _writer.Write("("); + } - /// - /// Writes the specified end token. - /// - /// The end token to write. - protected override void WriteEnd(JsonToken token) - { - switch (token) - { - case JsonToken.EndObject: - _writer.Write("}"); - break; - case JsonToken.EndArray: - _writer.Write("]"); - break; - case JsonToken.EndConstructor: - _writer.Write(")"); - break; - default: - throw JsonWriterException.Create(this, "Invalid JsonToken: " + token, null); - } - } + /// + /// Writes the specified end token. + /// + /// The end token to write. + protected override void WriteEnd(JsonToken token) + { + switch (token) + { + case JsonToken.EndObject: + _writer.Write("}"); + break; + case JsonToken.EndArray: + _writer.Write("]"); + break; + case JsonToken.EndConstructor: + _writer.Write(")"); + break; + default: + throw JsonWriterException.Create(this, "Invalid JsonToken: " + token, null); + } + } - /// - /// Writes the property name of a name/value pair on a Json object. - /// - /// The name of the property. - public override void WritePropertyName(string name) - { - InternalWritePropertyName(name); + /// + /// Writes the property name of a name/value pair on a Json object. + /// + /// The name of the property. + public override void WritePropertyName(string name) + { + InternalWritePropertyName(name); - WriteEscapedString(name, _quoteName); + WriteEscapedString(name, _quoteName); - _writer.Write(':'); - } + _writer.Write(':'); + } - /// - /// Writes the property name of a name/value pair on a JSON object. - /// - /// The name of the property. - /// A flag to indicate whether the text should be escaped when it is written as a JSON property name. - public override void WritePropertyName(string name, bool escape) - { - InternalWritePropertyName(name); + /// + /// Writes the property name of a name/value pair on a JSON object. + /// + /// The name of the property. + /// A flag to indicate whether the text should be escaped when it is written as a JSON property name. + public override void WritePropertyName(string name, bool escape) + { + InternalWritePropertyName(name); - if (escape) - { - WriteEscapedString(name, _quoteName); - } - else - { - if (_quoteName) - _writer.Write(_quoteChar); + if (escape) + { + WriteEscapedString(name, _quoteName); + } + else + { + if (_quoteName) + _writer.Write(_quoteChar); - _writer.Write(name); + _writer.Write(name); - if (_quoteName) - _writer.Write(_quoteChar); - } + if (_quoteName) + _writer.Write(_quoteChar); + } - _writer.Write(':'); - } + _writer.Write(':'); + } - internal override void OnStringEscapeHandlingChanged() - { - UpdateCharEscapeFlags(); - } + internal override void OnStringEscapeHandlingChanged() + { + UpdateCharEscapeFlags(); + } - private void UpdateCharEscapeFlags() - { - if (StringEscapeHandling == StringEscapeHandling.EscapeHtml) - _charEscapeFlags = JavaScriptUtils.HtmlCharEscapeFlags; - else if (_quoteChar == '"') - _charEscapeFlags = JavaScriptUtils.DoubleQuoteCharEscapeFlags; - else - _charEscapeFlags = JavaScriptUtils.SingleQuoteCharEscapeFlags; - } + private void UpdateCharEscapeFlags() + { + if (StringEscapeHandling == StringEscapeHandling.EscapeHtml) + _charEscapeFlags = JavaScriptUtils.HtmlCharEscapeFlags; + else if (_quoteChar == '"') + _charEscapeFlags = JavaScriptUtils.DoubleQuoteCharEscapeFlags; + else + _charEscapeFlags = JavaScriptUtils.SingleQuoteCharEscapeFlags; + } - /// - /// Writes indent characters. - /// - protected override void WriteIndent() - { - _writer.Write(Environment.NewLine); + /// + /// Writes indent characters. + /// + protected override void WriteIndent() + { + _writer.Write(Environment.NewLine); - // levels of indentation multiplied by the indent count - int currentIndentCount = Top*_indentation; + // levels of indentation multiplied by the indent count + int currentIndentCount = Top * _indentation; - while (currentIndentCount > 0) - { - // write up to a max of 10 characters at once to avoid creating too many new strings - int writeCount = Math.Min(currentIndentCount, 10); + while (currentIndentCount > 0) + { + // write up to a max of 10 characters at once to avoid creating too many new strings + int writeCount = Math.Min(currentIndentCount, 10); - _writer.Write(new string(_indentChar, writeCount)); + _writer.Write(new string(_indentChar, writeCount)); - currentIndentCount -= writeCount; - } - } + currentIndentCount -= writeCount; + } + } - /// - /// Writes the JSON value delimiter. - /// - protected override void WriteValueDelimiter() - { - _writer.Write(','); - } + /// + /// Writes the JSON value delimiter. + /// + protected override void WriteValueDelimiter() + { + _writer.Write(','); + } - /// - /// Writes an indent space. - /// - protected override void WriteIndentSpace() - { - _writer.Write(' '); - } + /// + /// Writes an indent space. + /// + protected override void WriteIndentSpace() + { + _writer.Write(' '); + } - private void WriteValueInternal(string value, JsonToken token) - { - _writer.Write(value); - } + private void WriteValueInternal(string value, JsonToken token) + { + _writer.Write(value); + } - #region WriteValue methods - /// - /// Writes a value. - /// An error will raised if the value cannot be written as a single JSON token. - /// - /// The value to write. - public override void WriteValue(object value) - { + #region WriteValue methods + /// + /// Writes a value. + /// An error will raised if the value cannot be written as a single JSON token. + /// + /// The value to write. + public override void WriteValue(object value) + { #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE || PORTABLE40) - if (value is BigInteger) - { - InternalWriteValue(JsonToken.Integer); - WriteValueInternal(((BigInteger)value).ToString(CultureInfo.InvariantCulture), JsonToken.String); - } - else + if (value is BigInteger) + { + InternalWriteValue(JsonToken.Integer); + WriteValueInternal(((BigInteger)value).ToString(CultureInfo.InvariantCulture), JsonToken.String); + } + else #endif - { - base.WriteValue(value); - } - } + { + base.WriteValue(value); + } + } - /// - /// Writes a null value. - /// - public override void WriteNull() - { - InternalWriteValue(JsonToken.Null); - WriteValueInternal(JsonConvert.Null, JsonToken.Null); - } + /// + /// Writes a null value. + /// + public override void WriteNull() + { + InternalWriteValue(JsonToken.Null); + WriteValueInternal(JsonConvert.Null, JsonToken.Null); + } - /// - /// Writes an undefined value. - /// - public override void WriteUndefined() - { - InternalWriteValue(JsonToken.Undefined); - WriteValueInternal(JsonConvert.Undefined, JsonToken.Undefined); - } + /// + /// Writes an undefined value. + /// + public override void WriteUndefined() + { + InternalWriteValue(JsonToken.Undefined); + WriteValueInternal(JsonConvert.Undefined, JsonToken.Undefined); + } - /// - /// Writes raw JSON. - /// - /// The raw JSON to write. - public override void WriteRaw(string json) - { - InternalWriteRaw(); + /// + /// Writes raw JSON. + /// + /// The raw JSON to write. + public override void WriteRaw(string json) + { + InternalWriteRaw(); - _writer.Write(json); - } + _writer.Write(json); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(string value) - { - InternalWriteValue(JsonToken.String); + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(string value) + { + InternalWriteValue(JsonToken.String); - if (value == null) - WriteValueInternal(JsonConvert.Null, JsonToken.Null); - else - WriteEscapedString(value, true); - } + if (value == null) + WriteValueInternal(JsonConvert.Null, JsonToken.Null); + else + WriteEscapedString(value, true); + } - private void WriteEscapedString(string value, bool quote) - { - EnsureWriteBuffer(); - JavaScriptUtils.WriteEscapedJavaScriptString(_writer, value, _quoteChar, quote, _charEscapeFlags, StringEscapeHandling, ref _writeBuffer); - } + private void WriteEscapedString(string value, bool quote) + { + EnsureWriteBuffer(); + JavaScriptUtils.WriteEscapedJavaScriptString(_writer, value, _quoteChar, quote, _charEscapeFlags, StringEscapeHandling, ref _writeBuffer); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(int value) - { - InternalWriteValue(JsonToken.Integer); - WriteIntegerValue(value); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(int value) + { + InternalWriteValue(JsonToken.Integer); + WriteIntegerValue(value); + } - /// - /// Writes a value. - /// - /// The value to write. - [CLSCompliant(false)] - public override void WriteValue(uint value) - { - InternalWriteValue(JsonToken.Integer); - WriteIntegerValue(value); - } + /// + /// Writes a value. + /// + /// The value to write. + [CLSCompliant(false)] + public override void WriteValue(uint value) + { + InternalWriteValue(JsonToken.Integer); + WriteIntegerValue(value); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(long value) - { - InternalWriteValue(JsonToken.Integer); - WriteIntegerValue(value); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(long value) + { + InternalWriteValue(JsonToken.Integer); + WriteIntegerValue(value); + } - /// - /// Writes a value. - /// - /// The value to write. - [CLSCompliant(false)] - public override void WriteValue(ulong value) - { - InternalWriteValue(JsonToken.Integer); - WriteIntegerValue(value); - } + /// + /// Writes a value. + /// + /// The value to write. + [CLSCompliant(false)] + public override void WriteValue(ulong value) + { + InternalWriteValue(JsonToken.Integer); + WriteIntegerValue(value); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(float value) - { - InternalWriteValue(JsonToken.Float); - WriteValueInternal(JsonConvert.ToString(value, FloatFormatHandling, QuoteChar, false), JsonToken.Float); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(float value) + { + InternalWriteValue(JsonToken.Float); + WriteValueInternal(JsonConvert.ToString(value, FloatFormatHandling, QuoteChar, false), JsonToken.Float); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(float? value) - { - if (value == null) - { - WriteNull(); - } - else - { - InternalWriteValue(JsonToken.Float); - WriteValueInternal(JsonConvert.ToString(value.Value, FloatFormatHandling, QuoteChar, true), JsonToken.Float); - } - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(float? value) + { + if (value == null) + { + WriteNull(); + } + else + { + InternalWriteValue(JsonToken.Float); + WriteValueInternal(JsonConvert.ToString(value.Value, FloatFormatHandling, QuoteChar, true), JsonToken.Float); + } + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(double value) - { - InternalWriteValue(JsonToken.Float); - WriteValueInternal(JsonConvert.ToString(value, FloatFormatHandling, QuoteChar, false), JsonToken.Float); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(double value) + { + InternalWriteValue(JsonToken.Float); + WriteValueInternal(JsonConvert.ToString(value, FloatFormatHandling, QuoteChar, false), JsonToken.Float); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(double? value) - { - if (value == null) - { - WriteNull(); - } - else - { - InternalWriteValue(JsonToken.Float); - WriteValueInternal(JsonConvert.ToString(value.Value, FloatFormatHandling, QuoteChar, true), JsonToken.Float); - } - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(double? value) + { + if (value == null) + { + WriteNull(); + } + else + { + InternalWriteValue(JsonToken.Float); + WriteValueInternal(JsonConvert.ToString(value.Value, FloatFormatHandling, QuoteChar, true), JsonToken.Float); + } + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(bool value) - { - InternalWriteValue(JsonToken.Boolean); - WriteValueInternal(JsonConvert.ToString(value), JsonToken.Boolean); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(bool value) + { + InternalWriteValue(JsonToken.Boolean); + WriteValueInternal(JsonConvert.ToString(value), JsonToken.Boolean); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(short value) - { - InternalWriteValue(JsonToken.Integer); - WriteIntegerValue(value); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(short value) + { + InternalWriteValue(JsonToken.Integer); + WriteIntegerValue(value); + } - /// - /// Writes a value. - /// - /// The value to write. - [CLSCompliant(false)] - public override void WriteValue(ushort value) - { - InternalWriteValue(JsonToken.Integer); - WriteIntegerValue(value); - } + /// + /// Writes a value. + /// + /// The value to write. + [CLSCompliant(false)] + public override void WriteValue(ushort value) + { + InternalWriteValue(JsonToken.Integer); + WriteIntegerValue(value); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(char value) - { - InternalWriteValue(JsonToken.String); - WriteValueInternal(JsonConvert.ToString(value), JsonToken.String); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(char value) + { + InternalWriteValue(JsonToken.String); + WriteValueInternal(JsonConvert.ToString(value), JsonToken.String); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(byte value) - { - InternalWriteValue(JsonToken.Integer); - WriteIntegerValue(value); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(byte value) + { + InternalWriteValue(JsonToken.Integer); + WriteIntegerValue(value); + } - /// - /// Writes a value. - /// - /// The value to write. - [CLSCompliant(false)] - public override void WriteValue(sbyte value) - { - InternalWriteValue(JsonToken.Integer); - WriteIntegerValue(value); - } + /// + /// Writes a value. + /// + /// The value to write. + [CLSCompliant(false)] + public override void WriteValue(sbyte value) + { + InternalWriteValue(JsonToken.Integer); + WriteIntegerValue(value); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(decimal value) - { - InternalWriteValue(JsonToken.Float); - WriteValueInternal(JsonConvert.ToString(value), JsonToken.Float); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(decimal value) + { + InternalWriteValue(JsonToken.Float); + WriteValueInternal(JsonConvert.ToString(value), JsonToken.Float); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(DateTime value) - { - InternalWriteValue(JsonToken.Date); - value = DateTimeUtils.EnsureDateTime(value, DateTimeZoneHandling); + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(DateTime value) + { + InternalWriteValue(JsonToken.Date); + value = DateTimeUtils.EnsureDateTime(value, DateTimeZoneHandling); - if (string.IsNullOrEmpty(DateFormatString)) - { - EnsureWriteBuffer(); + if (string.IsNullOrEmpty(DateFormatString)) + { + EnsureWriteBuffer(); - int pos = 0; - _writeBuffer[pos++] = _quoteChar; - pos = DateTimeUtils.WriteDateTimeString(_writeBuffer, pos, value, null, value.Kind, DateFormatHandling); - _writeBuffer[pos++] = _quoteChar; + int pos = 0; + _writeBuffer[pos++] = _quoteChar; + pos = DateTimeUtils.WriteDateTimeString(_writeBuffer, pos, value, null, value.Kind, DateFormatHandling); + _writeBuffer[pos++] = _quoteChar; - _writer.Write(_writeBuffer, 0, pos); - } - else - { - _writer.Write(_quoteChar); - _writer.Write(value.ToString(DateFormatString, Culture)); - _writer.Write(_quoteChar); - } - } + _writer.Write(_writeBuffer, 0, pos); + } + else + { + _writer.Write(_quoteChar); + _writer.Write(value.ToString(DateFormatString, Culture)); + _writer.Write(_quoteChar); + } + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(byte[] value) - { - if (value == null) - { - WriteNull(); - } - else - { - InternalWriteValue(JsonToken.Bytes); - _writer.Write(_quoteChar); - Base64Encoder.Encode(value, 0, value.Length); - Base64Encoder.Flush(); - _writer.Write(_quoteChar); - } - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(byte[] value) + { + if (value == null) + { + WriteNull(); + } + else + { + InternalWriteValue(JsonToken.Bytes); + _writer.Write(_quoteChar); + Base64Encoder.Encode(value, 0, value.Length); + Base64Encoder.Flush(); + _writer.Write(_quoteChar); + } + } #if !NET20 - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(DateTimeOffset value) - { - InternalWriteValue(JsonToken.Date); + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(DateTimeOffset value) + { + InternalWriteValue(JsonToken.Date); - if (string.IsNullOrEmpty(DateFormatString)) - { - EnsureWriteBuffer(); + if (string.IsNullOrEmpty(DateFormatString)) + { + EnsureWriteBuffer(); - int pos = 0; - _writeBuffer[pos++] = _quoteChar; - pos = DateTimeUtils.WriteDateTimeString(_writeBuffer, pos, (DateFormatHandling == DateFormatHandling.IsoDateFormat) ? value.DateTime : value.UtcDateTime, value.Offset, DateTimeKind.Local, DateFormatHandling); - _writeBuffer[pos++] = _quoteChar; + int pos = 0; + _writeBuffer[pos++] = _quoteChar; + pos = DateTimeUtils.WriteDateTimeString(_writeBuffer, pos, (DateFormatHandling == DateFormatHandling.IsoDateFormat) ? value.DateTime : value.UtcDateTime, value.Offset, DateTimeKind.Local, DateFormatHandling); + _writeBuffer[pos++] = _quoteChar; - _writer.Write(_writeBuffer, 0, pos); - } - else - { - _writer.Write(_quoteChar); - _writer.Write(value.ToString(DateFormatString, Culture)); - _writer.Write(_quoteChar); - } - } + _writer.Write(_writeBuffer, 0, pos); + } + else + { + _writer.Write(_quoteChar); + _writer.Write(value.ToString(DateFormatString, Culture)); + _writer.Write(_quoteChar); + } + } #endif - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(Guid value) - { - InternalWriteValue(JsonToken.String); - WriteValueInternal(JsonConvert.ToString(value, _quoteChar), JsonToken.String); - } - - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(TimeSpan value) - { - InternalWriteValue(JsonToken.String); - WriteValueInternal(JsonConvert.ToString(value, _quoteChar), JsonToken.String); - } - - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(Uri value) - { - if (value == null) - { - WriteNull(); - } - else - { - InternalWriteValue(JsonToken.String); - WriteValueInternal(JsonConvert.ToString(value, _quoteChar), JsonToken.String); - } - } - #endregion - - /// - /// Writes out a comment /*...*/ containing the specified text. - /// - /// Text to place inside the comment. - public override void WriteComment(string text) - { - InternalWriteComment(); - - _writer.Write("/*"); - _writer.Write(text); - _writer.Write("*/"); - } - - /// - /// Writes out the given white space. - /// - /// The string of white space characters. - public override void WriteWhitespace(string ws) - { - InternalWriteWhitespace(ws); - - _writer.Write(ws); - } - - private void EnsureWriteBuffer() - { - if (_writeBuffer == null) - _writeBuffer = new char[64]; - } - - private void WriteIntegerValue(long value) - { - EnsureWriteBuffer(); - - if (value >= 0 && value <= 9) - { - _writer.Write((char)('0' + value)); - } - else - { - ulong uvalue = (value < 0) ? (ulong)-value : (ulong)value; - - if (value < 0) - _writer.Write('-'); - - WriteIntegerValue(uvalue); - } - } - - private void WriteIntegerValue(ulong uvalue) - { - EnsureWriteBuffer(); - - if (uvalue <= 9) - { - _writer.Write((char)('0' + uvalue)); - } - else - { - int totalLength = MathUtils.IntLength(uvalue); - int length = 0; - - do + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(Guid value) { - _writeBuffer[totalLength - ++length] = (char)('0' + (uvalue % 10)); - uvalue /= 10; - } while (uvalue != 0); + InternalWriteValue(JsonToken.String); + WriteValueInternal(JsonConvert.ToString(value, _quoteChar), JsonToken.String); + } - _writer.Write(_writeBuffer, 0, length); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(TimeSpan value) + { + InternalWriteValue(JsonToken.String); + WriteValueInternal(JsonConvert.ToString(value, _quoteChar), JsonToken.String); + } + + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(Uri value) + { + if (value == null) + { + WriteNull(); + } + else + { + InternalWriteValue(JsonToken.String); + WriteValueInternal(JsonConvert.ToString(value, _quoteChar), JsonToken.String); + } + } + #endregion + + /// + /// Writes out a comment /*...*/ containing the specified text. + /// + /// Text to place inside the comment. + public override void WriteComment(string text) + { + InternalWriteComment(); + + _writer.Write("/*"); + _writer.Write(text); + _writer.Write("*/"); + } + + /// + /// Writes out the given white space. + /// + /// The string of white space characters. + public override void WriteWhitespace(string ws) + { + InternalWriteWhitespace(ws); + + _writer.Write(ws); + } + + private void EnsureWriteBuffer() + { + if (_writeBuffer == null) + _writeBuffer = new char[64]; + } + + private void WriteIntegerValue(long value) + { + EnsureWriteBuffer(); + + if (value >= 0 && value <= 9) + { + _writer.Write((char)('0' + value)); + } + else + { + ulong uvalue = (value < 0) ? (ulong)-value : (ulong)value; + + if (value < 0) + _writer.Write('-'); + + WriteIntegerValue(uvalue); + } + } + + private void WriteIntegerValue(ulong uvalue) + { + EnsureWriteBuffer(); + + if (uvalue <= 9) + { + _writer.Write((char)('0' + uvalue)); + } + else + { + int totalLength = MathUtils.IntLength(uvalue); + int length = 0; + + do + { + _writeBuffer[totalLength - ++length] = (char)('0' + (uvalue % 10)); + uvalue /= 10; + } while (uvalue != 0); + + _writer.Write(_writeBuffer, 0, length); + } + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/JsonToken.cs b/Src/Newtonsoft.Json/JsonToken.cs index 313659c7..a159902f 100644 --- a/Src/Newtonsoft.Json/JsonToken.cs +++ b/Src/Newtonsoft.Json/JsonToken.cs @@ -29,82 +29,99 @@ using System.Text; namespace Newtonsoft.Json { - /// - /// Specifies the type of Json token. - /// - public enum JsonToken - { /// - /// This is returned by the if a method has not been called. + /// Specifies the type of Json token. /// - None, - /// - /// An object start token. - /// - StartObject, - /// - /// An array start token. - /// - StartArray, - /// - /// A constructor start token. - /// - StartConstructor, - /// - /// An object property name. - /// - PropertyName, - /// - /// A comment. - /// - Comment, - /// - /// Raw JSON. - /// - Raw, - /// - /// An integer. - /// - Integer, - /// - /// A float. - /// - Float, - /// - /// A string. - /// - String, - /// - /// A boolean. - /// - Boolean, - /// - /// A null token. - /// - Null, - /// - /// An undefined token. - /// - Undefined, - /// - /// An object end token. - /// - EndObject, - /// - /// An array end token. - /// - EndArray, - /// - /// A constructor end token. - /// - EndConstructor, - /// - /// A Date. - /// - Date, - /// - /// Byte data. - /// - Bytes - } + public enum JsonToken + { + /// + /// This is returned by the if a method has not been called. + /// + None, + + /// + /// An object start token. + /// + StartObject, + + /// + /// An array start token. + /// + StartArray, + + /// + /// A constructor start token. + /// + StartConstructor, + + /// + /// An object property name. + /// + PropertyName, + + /// + /// A comment. + /// + Comment, + + /// + /// Raw JSON. + /// + Raw, + + /// + /// An integer. + /// + Integer, + + /// + /// A float. + /// + Float, + + /// + /// A string. + /// + String, + + /// + /// A boolean. + /// + Boolean, + + /// + /// A null token. + /// + Null, + + /// + /// An undefined token. + /// + Undefined, + + /// + /// An object end token. + /// + EndObject, + + /// + /// An array end token. + /// + EndArray, + + /// + /// A constructor end token. + /// + EndConstructor, + + /// + /// A Date. + /// + Date, + + /// + /// Byte data. + /// + Bytes + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/JsonValidatingReader.cs b/Src/Newtonsoft.Json/JsonValidatingReader.cs index a2926218..b66dff92 100644 --- a/Src/Newtonsoft.Json/JsonValidatingReader.cs +++ b/Src/Newtonsoft.Json/JsonValidatingReader.cs @@ -38,880 +38,880 @@ using System.IO; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json { - /// - /// Represents a reader that provides validation. - /// - public class JsonValidatingReader : JsonReader, IJsonLineInfo - { - private class SchemaScope + /// + /// Represents a reader that provides validation. + /// + public class JsonValidatingReader : JsonReader, IJsonLineInfo { - private readonly JTokenType _tokenType; - private readonly IList _schemas; - private readonly Dictionary _requiredProperties; - - public string CurrentPropertyName { get; set; } - public int ArrayItemCount { get; set; } - public bool IsUniqueArray { get; set; } - public bool IsEnum { get; set; } - public IList UniqueArrayItems { get; set; } - public JTokenWriter CurrentItemWriter { get; set; } - - public IList Schemas - { - get { return _schemas; } - } - - public Dictionary RequiredProperties - { - get { return _requiredProperties; } - } - - public JTokenType TokenType - { - get { return _tokenType; } - } - - public SchemaScope(JTokenType tokenType, IList schemas) - { - _tokenType = tokenType; - _schemas = schemas; - - _requiredProperties = schemas.SelectMany(GetRequiredProperties).Distinct().ToDictionary(p => p, p => false); - - if (tokenType == JTokenType.Array && schemas.Any(s => s.UniqueItems)) + private class SchemaScope { - IsUniqueArray = true; - UniqueArrayItems = new List(); - } - } + private readonly JTokenType _tokenType; + private readonly IList _schemas; + private readonly Dictionary _requiredProperties; - private IEnumerable GetRequiredProperties(JsonSchemaModel schema) - { - if (schema == null || schema.Properties == null) - return Enumerable.Empty(); + public string CurrentPropertyName { get; set; } + public int ArrayItemCount { get; set; } + public bool IsUniqueArray { get; set; } + public bool IsEnum { get; set; } + public IList UniqueArrayItems { get; set; } + public JTokenWriter CurrentItemWriter { get; set; } - return schema.Properties.Where(p => p.Value.Required).Select(p => p.Key); - } - - } - - private readonly JsonReader _reader; - private readonly Stack _stack; - private JsonSchema _schema; - private JsonSchemaModel _model; - private SchemaScope _currentScope; - - /// - /// Sets an event handler for receiving schema validation errors. - /// - public event ValidationEventHandler ValidationEventHandler; - - /// - /// Gets the text value of the current JSON token. - /// - /// - public override object Value - { - get { return _reader.Value; } - } - - /// - /// Gets the depth of the current token in the JSON document. - /// - /// The depth of the current token in the JSON document. - public override int Depth - { - get { return _reader.Depth; } - } - - /// - /// Gets the path of the current JSON token. - /// - public override string Path - { - get { return _reader.Path; } - } - - /// - /// Gets the quotation mark character used to enclose the value of a string. - /// - /// - public override char QuoteChar - { - get { return _reader.QuoteChar; } - protected internal set { } - } - - /// - /// Gets the type of the current JSON token. - /// - /// - public override JsonToken TokenType - { - get { return _reader.TokenType; } - } - - /// - /// Gets the Common Language Runtime (CLR) type for the current JSON token. - /// - /// - public override Type ValueType - { - get { return _reader.ValueType; } - } - - private void Push(SchemaScope scope) - { - _stack.Push(scope); - _currentScope = scope; - } - - private SchemaScope Pop() - { - SchemaScope poppedScope = _stack.Pop(); - _currentScope = (_stack.Count != 0) - ? _stack.Peek() - : null; - - return poppedScope; - } - - private IList CurrentSchemas - { - get { return _currentScope.Schemas; } - } - - private static readonly IList EmptySchemaList = new List(); - - private IList CurrentMemberSchemas - { - get - { - if (_currentScope == null) - return new List(new [] { _model }); - - if (_currentScope.Schemas == null || _currentScope.Schemas.Count == 0) - return EmptySchemaList; - - switch (_currentScope.TokenType) - { - case JTokenType.None: - return _currentScope.Schemas; - case JTokenType.Object: + public IList Schemas { - if (_currentScope.CurrentPropertyName == null) - throw new JsonReaderException("CurrentPropertyName has not been set on scope."); + get { return _schemas; } + } - IList schemas = new List(); + public Dictionary RequiredProperties + { + get { return _requiredProperties; } + } - foreach (JsonSchemaModel schema in CurrentSchemas) - { - JsonSchemaModel propertySchema; - if (schema.Properties != null && schema.Properties.TryGetValue(_currentScope.CurrentPropertyName, out propertySchema)) + public JTokenType TokenType + { + get { return _tokenType; } + } + + public SchemaScope(JTokenType tokenType, IList schemas) + { + _tokenType = tokenType; + _schemas = schemas; + + _requiredProperties = schemas.SelectMany(GetRequiredProperties).Distinct().ToDictionary(p => p, p => false); + + if (tokenType == JTokenType.Array && schemas.Any(s => s.UniqueItems)) { - schemas.Add(propertySchema); + IsUniqueArray = true; + UniqueArrayItems = new List(); } - if (schema.PatternProperties != null) + } + + private IEnumerable GetRequiredProperties(JsonSchemaModel schema) + { + if (schema == null || schema.Properties == null) + return Enumerable.Empty(); + + return schema.Properties.Where(p => p.Value.Required).Select(p => p.Key); + } + } + + private readonly JsonReader _reader; + private readonly Stack _stack; + private JsonSchema _schema; + private JsonSchemaModel _model; + private SchemaScope _currentScope; + + /// + /// Sets an event handler for receiving schema validation errors. + /// + public event ValidationEventHandler ValidationEventHandler; + + /// + /// Gets the text value of the current JSON token. + /// + /// + public override object Value + { + get { return _reader.Value; } + } + + /// + /// Gets the depth of the current token in the JSON document. + /// + /// The depth of the current token in the JSON document. + public override int Depth + { + get { return _reader.Depth; } + } + + /// + /// Gets the path of the current JSON token. + /// + public override string Path + { + get { return _reader.Path; } + } + + /// + /// Gets the quotation mark character used to enclose the value of a string. + /// + /// + public override char QuoteChar + { + get { return _reader.QuoteChar; } + protected internal set { } + } + + /// + /// Gets the type of the current JSON token. + /// + /// + public override JsonToken TokenType + { + get { return _reader.TokenType; } + } + + /// + /// Gets the Common Language Runtime (CLR) type for the current JSON token. + /// + /// + public override Type ValueType + { + get { return _reader.ValueType; } + } + + private void Push(SchemaScope scope) + { + _stack.Push(scope); + _currentScope = scope; + } + + private SchemaScope Pop() + { + SchemaScope poppedScope = _stack.Pop(); + _currentScope = (_stack.Count != 0) + ? _stack.Peek() + : null; + + return poppedScope; + } + + private IList CurrentSchemas + { + get { return _currentScope.Schemas; } + } + + private static readonly IList EmptySchemaList = new List(); + + private IList CurrentMemberSchemas + { + get + { + if (_currentScope == null) + return new List(new[] { _model }); + + if (_currentScope.Schemas == null || _currentScope.Schemas.Count == 0) + return EmptySchemaList; + + switch (_currentScope.TokenType) { - foreach (KeyValuePair patternProperty in schema.PatternProperties) - { - if (Regex.IsMatch(_currentScope.CurrentPropertyName, patternProperty.Key)) + case JTokenType.None: + return _currentScope.Schemas; + case JTokenType.Object: { - schemas.Add(patternProperty.Value); + if (_currentScope.CurrentPropertyName == null) + throw new JsonReaderException("CurrentPropertyName has not been set on scope."); + + IList schemas = new List(); + + foreach (JsonSchemaModel schema in CurrentSchemas) + { + JsonSchemaModel propertySchema; + if (schema.Properties != null && schema.Properties.TryGetValue(_currentScope.CurrentPropertyName, out propertySchema)) + { + schemas.Add(propertySchema); + } + if (schema.PatternProperties != null) + { + foreach (KeyValuePair patternProperty in schema.PatternProperties) + { + if (Regex.IsMatch(_currentScope.CurrentPropertyName, patternProperty.Key)) + { + schemas.Add(patternProperty.Value); + } + } + } + + if (schemas.Count == 0 && schema.AllowAdditionalProperties && schema.AdditionalProperties != null) + schemas.Add(schema.AdditionalProperties); + } + + return schemas; } - } + case JTokenType.Array: + { + IList schemas = new List(); + + foreach (JsonSchemaModel schema in CurrentSchemas) + { + if (!schema.PositionalItemsValidation) + { + if (schema.Items != null && schema.Items.Count > 0) + schemas.Add(schema.Items[0]); + } + else + { + if (schema.Items != null && schema.Items.Count > 0) + { + if (schema.Items.Count > (_currentScope.ArrayItemCount - 1)) + schemas.Add(schema.Items[_currentScope.ArrayItemCount - 1]); + } + + if (schema.AllowAdditionalItems && schema.AdditionalItems != null) + schemas.Add(schema.AdditionalItems); + } + } + + return schemas; + } + case JTokenType.Constructor: + return EmptySchemaList; + default: + throw new ArgumentOutOfRangeException("TokenType", "Unexpected token type: {0}".FormatWith(CultureInfo.InvariantCulture, _currentScope.TokenType)); } - - if (schemas.Count == 0 && schema.AllowAdditionalProperties && schema.AdditionalProperties != null) - schemas.Add(schema.AdditionalProperties); - } - - return schemas; } - case JTokenType.Array: - { - IList schemas = new List(); - - foreach (JsonSchemaModel schema in CurrentSchemas) - { - if (!schema.PositionalItemsValidation) - { - if (schema.Items != null && schema.Items.Count > 0) - schemas.Add(schema.Items[0]); - } - else - { - if (schema.Items != null && schema.Items.Count > 0) - { - if (schema.Items.Count > (_currentScope.ArrayItemCount - 1)) - schemas.Add(schema.Items[_currentScope.ArrayItemCount - 1]); - } - - if (schema.AllowAdditionalItems && schema.AdditionalItems != null) - schemas.Add(schema.AdditionalItems); - } - } - - return schemas; - } - case JTokenType.Constructor: - return EmptySchemaList; - default: - throw new ArgumentOutOfRangeException("TokenType", "Unexpected token type: {0}".FormatWith(CultureInfo.InvariantCulture, _currentScope.TokenType)); } - } - } - private void RaiseError(string message, JsonSchemaModel schema) - { - IJsonLineInfo lineInfo = this; + private void RaiseError(string message, JsonSchemaModel schema) + { + IJsonLineInfo lineInfo = this; - string exceptionMessage = (lineInfo.HasLineInfo()) - ? message + " Line {0}, position {1}.".FormatWith(CultureInfo.InvariantCulture, lineInfo.LineNumber, lineInfo.LinePosition) - : message; + string exceptionMessage = (lineInfo.HasLineInfo()) + ? message + " Line {0}, position {1}.".FormatWith(CultureInfo.InvariantCulture, lineInfo.LineNumber, lineInfo.LinePosition) + : message; - OnValidationEvent(new JsonSchemaException(exceptionMessage, null, Path, lineInfo.LineNumber, lineInfo.LinePosition)); - } + OnValidationEvent(new JsonSchemaException(exceptionMessage, null, Path, lineInfo.LineNumber, lineInfo.LinePosition)); + } - private void OnValidationEvent(JsonSchemaException exception) - { - ValidationEventHandler handler = ValidationEventHandler; - if (handler != null) - handler(this, new ValidationEventArgs(exception)); - else - throw exception; - } + private void OnValidationEvent(JsonSchemaException exception) + { + ValidationEventHandler handler = ValidationEventHandler; + if (handler != null) + handler(this, new ValidationEventArgs(exception)); + else + throw exception; + } - /// - /// Initializes a new instance of the class that - /// validates the content returned from the given . - /// - /// The to read from while validating. - public JsonValidatingReader(JsonReader reader) - { - ValidationUtils.ArgumentNotNull(reader, "reader"); - _reader = reader; - _stack = new Stack(); - } + /// + /// Initializes a new instance of the class that + /// validates the content returned from the given . + /// + /// The to read from while validating. + public JsonValidatingReader(JsonReader reader) + { + ValidationUtils.ArgumentNotNull(reader, "reader"); + _reader = reader; + _stack = new Stack(); + } - /// - /// Gets or sets the schema. - /// - /// The schema. - public JsonSchema Schema - { - get { return _schema; } - set - { - if (TokenType != JsonToken.None) - throw new InvalidOperationException("Cannot change schema while validating JSON."); + /// + /// Gets or sets the schema. + /// + /// The schema. + public JsonSchema Schema + { + get { return _schema; } + set + { + if (TokenType != JsonToken.None) + throw new InvalidOperationException("Cannot change schema while validating JSON."); - _schema = value; - _model = null; - } - } + _schema = value; + _model = null; + } + } - /// - /// Gets the used to construct this . - /// - /// The specified in the constructor. - public JsonReader Reader - { - get { return _reader; } - } + /// + /// Gets the used to construct this . + /// + /// The specified in the constructor. + public JsonReader Reader + { + get { return _reader; } + } - private void ValidateNotDisallowed(JsonSchemaModel schema) - { - if (schema == null) - return; + private void ValidateNotDisallowed(JsonSchemaModel schema) + { + if (schema == null) + return; - JsonSchemaType? currentNodeType = GetCurrentNodeSchemaType(); - if (currentNodeType != null) - { - if (JsonSchemaGenerator.HasFlag(schema.Disallow, currentNodeType.Value)) - RaiseError("Type {0} is disallowed.".FormatWith(CultureInfo.InvariantCulture, currentNodeType), schema); - } - } + JsonSchemaType? currentNodeType = GetCurrentNodeSchemaType(); + if (currentNodeType != null) + { + if (JsonSchemaGenerator.HasFlag(schema.Disallow, currentNodeType.Value)) + RaiseError("Type {0} is disallowed.".FormatWith(CultureInfo.InvariantCulture, currentNodeType), schema); + } + } - private JsonSchemaType? GetCurrentNodeSchemaType() - { - switch (_reader.TokenType) - { - case JsonToken.StartObject: - return JsonSchemaType.Object; - case JsonToken.StartArray: - return JsonSchemaType.Array; - case JsonToken.Integer: - return JsonSchemaType.Integer; - case JsonToken.Float: - return JsonSchemaType.Float; - case JsonToken.String: - return JsonSchemaType.String; - case JsonToken.Boolean: - return JsonSchemaType.Boolean; - case JsonToken.Null: - return JsonSchemaType.Null; - default: - return null; - } - } + private JsonSchemaType? GetCurrentNodeSchemaType() + { + switch (_reader.TokenType) + { + case JsonToken.StartObject: + return JsonSchemaType.Object; + case JsonToken.StartArray: + return JsonSchemaType.Array; + case JsonToken.Integer: + return JsonSchemaType.Integer; + case JsonToken.Float: + return JsonSchemaType.Float; + case JsonToken.String: + return JsonSchemaType.String; + case JsonToken.Boolean: + return JsonSchemaType.Boolean; + case JsonToken.Null: + return JsonSchemaType.Null; + default: + return null; + } + } - /// - /// Reads the next JSON token from the stream as a . - /// - /// A . - public override int? ReadAsInt32() - { - int? i = _reader.ReadAsInt32(); + /// + /// Reads the next JSON token from the stream as a . + /// + /// A . + public override int? ReadAsInt32() + { + int? i = _reader.ReadAsInt32(); - ValidateCurrentToken(); - return i; - } + ValidateCurrentToken(); + return i; + } - /// - /// Reads the next JSON token from the stream as a . - /// - /// - /// A or a null reference if the next JSON token is null. - /// - public override byte[] ReadAsBytes() - { - byte[] data = _reader.ReadAsBytes(); + /// + /// Reads the next JSON token from the stream as a . + /// + /// + /// A or a null reference if the next JSON token is null. + /// + public override byte[] ReadAsBytes() + { + byte[] data = _reader.ReadAsBytes(); - ValidateCurrentToken(); - return data; - } + ValidateCurrentToken(); + return data; + } - /// - /// Reads the next JSON token from the stream as a . - /// - /// A . - public override decimal? ReadAsDecimal() - { - decimal? d = _reader.ReadAsDecimal(); + /// + /// Reads the next JSON token from the stream as a . + /// + /// A . + public override decimal? ReadAsDecimal() + { + decimal? d = _reader.ReadAsDecimal(); - ValidateCurrentToken(); - return d; - } + ValidateCurrentToken(); + return d; + } - /// - /// Reads the next JSON token from the stream as a . - /// - /// A . This method will return null at the end of an array. - public override string ReadAsString() - { - string s = _reader.ReadAsString(); + /// + /// Reads the next JSON token from the stream as a . + /// + /// A . This method will return null at the end of an array. + public override string ReadAsString() + { + string s = _reader.ReadAsString(); - ValidateCurrentToken(); - return s; - } + ValidateCurrentToken(); + return s; + } - /// - /// Reads the next JSON token from the stream as a . - /// - /// A . This method will return null at the end of an array. - public override DateTime? ReadAsDateTime() - { - DateTime? dateTime = _reader.ReadAsDateTime(); + /// + /// Reads the next JSON token from the stream as a . + /// + /// A . This method will return null at the end of an array. + public override DateTime? ReadAsDateTime() + { + DateTime? dateTime = _reader.ReadAsDateTime(); - ValidateCurrentToken(); - return dateTime; - } + ValidateCurrentToken(); + return dateTime; + } #if !NET20 - /// - /// Reads the next JSON token from the stream as a . - /// - /// A . - public override DateTimeOffset? ReadAsDateTimeOffset() - { - DateTimeOffset? dateTimeOffset = _reader.ReadAsDateTimeOffset(); + /// + /// Reads the next JSON token from the stream as a . + /// + /// A . + public override DateTimeOffset? ReadAsDateTimeOffset() + { + DateTimeOffset? dateTimeOffset = _reader.ReadAsDateTimeOffset(); - ValidateCurrentToken(); - return dateTimeOffset; - } + ValidateCurrentToken(); + return dateTimeOffset; + } #endif - /// - /// Reads the next JSON token from the stream. - /// - /// - /// true if the next token was read successfully; false if there are no more tokens to read. - /// - public override bool Read() - { - if (!_reader.Read()) - return false; - - if (_reader.TokenType == JsonToken.Comment) - return true; - - ValidateCurrentToken(); - return true; - } - - private void ValidateCurrentToken() - { - // first time validate has been called. build model - if (_model == null) - { - JsonSchemaModelBuilder builder = new JsonSchemaModelBuilder(); - _model = builder.Build(_schema); - - if (!JsonWriter.IsStartToken(_reader.TokenType)) - Push(new SchemaScope(JTokenType.None, CurrentMemberSchemas)); - } - - switch (_reader.TokenType) - { - case JsonToken.StartObject: - ProcessValue(); - IList objectSchemas = CurrentMemberSchemas.Where(ValidateObject).ToList(); - Push(new SchemaScope(JTokenType.Object, objectSchemas)); - WriteToken(CurrentSchemas); - break; - case JsonToken.StartArray: - ProcessValue(); - IList arraySchemas = CurrentMemberSchemas.Where(ValidateArray).ToList(); - Push(new SchemaScope(JTokenType.Array, arraySchemas)); - WriteToken(CurrentSchemas); - break; - case JsonToken.StartConstructor: - ProcessValue(); - Push(new SchemaScope(JTokenType.Constructor, null)); - WriteToken(CurrentSchemas); - break; - case JsonToken.PropertyName: - WriteToken(CurrentSchemas); - foreach (JsonSchemaModel schema in CurrentSchemas) - { - ValidatePropertyName(schema); - } - break; - case JsonToken.Raw: - ProcessValue(); - break; - case JsonToken.Integer: - ProcessValue(); - WriteToken(CurrentMemberSchemas); - foreach (JsonSchemaModel schema in CurrentMemberSchemas) - { - ValidateInteger(schema); - } - break; - case JsonToken.Float: - ProcessValue(); - WriteToken(CurrentMemberSchemas); - foreach (JsonSchemaModel schema in CurrentMemberSchemas) - { - ValidateFloat(schema); - } - break; - case JsonToken.String: - ProcessValue(); - WriteToken(CurrentMemberSchemas); - foreach (JsonSchemaModel schema in CurrentMemberSchemas) - { - ValidateString(schema); - } - break; - case JsonToken.Boolean: - ProcessValue(); - WriteToken(CurrentMemberSchemas); - foreach (JsonSchemaModel schema in CurrentMemberSchemas) - { - ValidateBoolean(schema); - } - break; - case JsonToken.Null: - ProcessValue(); - WriteToken(CurrentMemberSchemas); - foreach (JsonSchemaModel schema in CurrentMemberSchemas) - { - ValidateNull(schema); - } - break; - case JsonToken.EndObject: - WriteToken(CurrentSchemas); - foreach (JsonSchemaModel schema in CurrentSchemas) - { - ValidateEndObject(schema); - } - Pop(); - break; - case JsonToken.EndArray: - WriteToken(CurrentSchemas); - foreach (JsonSchemaModel schema in CurrentSchemas) - { - ValidateEndArray(schema); - } - Pop(); - break; - case JsonToken.EndConstructor: - WriteToken(CurrentSchemas); - Pop(); - break; - case JsonToken.Undefined: - case JsonToken.Date: - case JsonToken.Bytes: - // these have no equivalent in JSON schema - WriteToken(CurrentMemberSchemas); - break; - case JsonToken.None: - // no content, do nothing - break; - default: - throw new ArgumentOutOfRangeException(); - } - } - - private void WriteToken(IList schemas) - { - foreach (SchemaScope schemaScope in _stack) - { - bool isInUniqueArray = (schemaScope.TokenType == JTokenType.Array && schemaScope.IsUniqueArray && schemaScope.ArrayItemCount > 0); - - if (isInUniqueArray || schemaScope.IsEnum || schemas.Any(s => s.Enum != null)) + /// + /// Reads the next JSON token from the stream. + /// + /// + /// true if the next token was read successfully; false if there are no more tokens to read. + /// + public override bool Read() { - if (schemaScope.CurrentItemWriter == null) - { - if (JsonWriter.IsEndToken(_reader.TokenType)) - continue; + if (!_reader.Read()) + return false; - schemaScope.CurrentItemWriter = new JTokenWriter(); - } + if (_reader.TokenType == JsonToken.Comment) + return true; - schemaScope.CurrentItemWriter.WriteToken(_reader, false); - - // finished writing current item - if (schemaScope.CurrentItemWriter.Top == 0 && _reader.TokenType != JsonToken.PropertyName) - { - JToken finishedItem = schemaScope.CurrentItemWriter.Token; - - // start next item with new writer - schemaScope.CurrentItemWriter = null; - - if (isInUniqueArray) - { - if (schemaScope.UniqueArrayItems.Contains(finishedItem, JToken.EqualityComparer)) - RaiseError("Non-unique array item at index {0}.".FormatWith(CultureInfo.InvariantCulture, schemaScope.ArrayItemCount - 1), schemaScope.Schemas.First(s => s.UniqueItems)); - - schemaScope.UniqueArrayItems.Add(finishedItem); - } - else if (schemaScope.IsEnum || schemas.Any(s => s.Enum != null)) - { - foreach (JsonSchemaModel schema in schemas) - { - if (schema.Enum != null) - { - if (!schema.Enum.ContainsValue(finishedItem, JToken.EqualityComparer)) - { - StringWriter sw = new StringWriter(CultureInfo.InvariantCulture); - finishedItem.WriteTo(new JsonTextWriter(sw)); - - RaiseError("Value {0} is not defined in enum.".FormatWith(CultureInfo.InvariantCulture, sw.ToString()), schema); - } - } - } - } - } - } - } - } - - private void ValidateEndObject(JsonSchemaModel schema) - { - if (schema == null) - return; - - Dictionary requiredProperties = _currentScope.RequiredProperties; - - if (requiredProperties != null) - { - List unmatchedRequiredProperties = - requiredProperties.Where(kv => !kv.Value).Select(kv => kv.Key).ToList(); - - if (unmatchedRequiredProperties.Count > 0) - RaiseError("Required properties are missing from object: {0}.".FormatWith(CultureInfo.InvariantCulture, string.Join(", ", unmatchedRequiredProperties.ToArray())), schema); - } - } - - private void ValidateEndArray(JsonSchemaModel schema) - { - if (schema == null) - return; - - int arrayItemCount = _currentScope.ArrayItemCount; - - if (schema.MaximumItems != null && arrayItemCount > schema.MaximumItems) - RaiseError("Array item count {0} exceeds maximum count of {1}.".FormatWith(CultureInfo.InvariantCulture, arrayItemCount, schema.MaximumItems), schema); - - if (schema.MinimumItems != null && arrayItemCount < schema.MinimumItems) - RaiseError("Array item count {0} is less than minimum count of {1}.".FormatWith(CultureInfo.InvariantCulture, arrayItemCount, schema.MinimumItems), schema); - } - - private void ValidateNull(JsonSchemaModel schema) - { - if (schema == null) - return; - - if (!TestType(schema, JsonSchemaType.Null)) - return; - - ValidateNotDisallowed(schema); - } - - private void ValidateBoolean(JsonSchemaModel schema) - { - if (schema == null) - return; - - if (!TestType(schema, JsonSchemaType.Boolean)) - return; - - ValidateNotDisallowed(schema); - } - - private void ValidateString(JsonSchemaModel schema) - { - if (schema == null) - return; - - if (!TestType(schema, JsonSchemaType.String)) - return; - - ValidateNotDisallowed(schema); - - string value = _reader.Value.ToString(); - - if (schema.MaximumLength != null && value.Length > schema.MaximumLength) - RaiseError("String '{0}' exceeds maximum length of {1}.".FormatWith(CultureInfo.InvariantCulture, value, schema.MaximumLength), schema); - - if (schema.MinimumLength != null && value.Length < schema.MinimumLength) - RaiseError("String '{0}' is less than minimum length of {1}.".FormatWith(CultureInfo.InvariantCulture, value, schema.MinimumLength), schema); - - if (schema.Patterns != null) - { - foreach (string pattern in schema.Patterns) - { - if (!Regex.IsMatch(value, pattern)) - RaiseError("String '{0}' does not match regex pattern '{1}'.".FormatWith(CultureInfo.InvariantCulture, value, pattern), schema); - } - } - } - - private void ValidateInteger(JsonSchemaModel schema) - { - if (schema == null) - return; - - if (!TestType(schema, JsonSchemaType.Integer)) - return; - - ValidateNotDisallowed(schema); - - object value = _reader.Value; - - if (schema.Maximum != null) - { - if (JValue.Compare(JTokenType.Integer, value, schema.Maximum) > 0) - RaiseError("Integer {0} exceeds maximum value of {1}.".FormatWith(CultureInfo.InvariantCulture, value, schema.Maximum), schema); - if (schema.ExclusiveMaximum && JValue.Compare(JTokenType.Integer, value, schema.Maximum) == 0) - RaiseError("Integer {0} equals maximum value of {1} and exclusive maximum is true.".FormatWith(CultureInfo.InvariantCulture, value, schema.Maximum), schema); - } - - if (schema.Minimum != null) - { - if (JValue.Compare(JTokenType.Integer, value, schema.Minimum) < 0) - RaiseError("Integer {0} is less than minimum value of {1}.".FormatWith(CultureInfo.InvariantCulture, value, schema.Minimum), schema); - if (schema.ExclusiveMinimum && JValue.Compare(JTokenType.Integer, value, schema.Minimum) == 0) - RaiseError("Integer {0} equals minimum value of {1} and exclusive minimum is true.".FormatWith(CultureInfo.InvariantCulture, value, schema.Minimum), schema); - } - - if (schema.DivisibleBy != null) - { - bool notDivisible; -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (value is BigInteger) - { - // not that this will lose any decimal point on DivisibleBy - // so manually raise an error if DivisibleBy is not an integer and value is not zero - BigInteger i = (BigInteger)value; - bool divisibleNonInteger = !Math.Abs(schema.DivisibleBy.Value - Math.Truncate(schema.DivisibleBy.Value)).Equals(0); - if (divisibleNonInteger) - notDivisible = i != 0; - else - notDivisible = i % new BigInteger(schema.DivisibleBy.Value) != 0; - } - else -#endif - notDivisible = !IsZero(Convert.ToInt64(value, CultureInfo.InvariantCulture) % schema.DivisibleBy.Value); - - if (notDivisible) - RaiseError("Integer {0} is not evenly divisible by {1}.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(value), schema.DivisibleBy), schema); - } - } - - private void ProcessValue() - { - if (_currentScope != null && _currentScope.TokenType == JTokenType.Array) - { - _currentScope.ArrayItemCount++; - - foreach (JsonSchemaModel currentSchema in CurrentSchemas) - { - // if there is positional validation and the array index is past the number of item validation schemas and there is no additonal items then error - if (currentSchema != null - && currentSchema.PositionalItemsValidation - && !currentSchema.AllowAdditionalItems - && (currentSchema.Items == null || _currentScope.ArrayItemCount - 1 >= currentSchema.Items.Count)) - { - RaiseError("Index {0} has not been defined and the schema does not allow additional items.".FormatWith(CultureInfo.InvariantCulture, _currentScope.ArrayItemCount), currentSchema); - } - } - } - } - - private void ValidateFloat(JsonSchemaModel schema) - { - if (schema == null) - return; - - if (!TestType(schema, JsonSchemaType.Float)) - return; - - ValidateNotDisallowed(schema); - - double value = Convert.ToDouble(_reader.Value, CultureInfo.InvariantCulture); - - if (schema.Maximum != null) - { - if (value > schema.Maximum) - RaiseError("Float {0} exceeds maximum value of {1}.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(value), schema.Maximum), schema); - if (schema.ExclusiveMaximum && value == schema.Maximum) - RaiseError("Float {0} equals maximum value of {1} and exclusive maximum is true.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(value), schema.Maximum), schema); - } - - if (schema.Minimum != null) - { - if (value < schema.Minimum) - RaiseError("Float {0} is less than minimum value of {1}.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(value), schema.Minimum), schema); - if (schema.ExclusiveMinimum && value == schema.Minimum) - RaiseError("Float {0} equals minimum value of {1} and exclusive minimum is true.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(value), schema.Minimum), schema); - } - - if (schema.DivisibleBy != null) - { - double remainder = FloatingPointRemainder(value, schema.DivisibleBy.Value); - - if (!IsZero(remainder)) - RaiseError("Float {0} is not evenly divisible by {1}.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(value), schema.DivisibleBy), schema); - } - } - - private static double FloatingPointRemainder(double dividend, double divisor) - { - return dividend - Math.Floor(dividend/divisor)*divisor; - } - - private static bool IsZero(double value) - { - const double epsilon = 2.2204460492503131e-016; - - return Math.Abs(value) < 10.0 * epsilon; - } - - private void ValidatePropertyName(JsonSchemaModel schema) - { - if (schema == null) - return; - - string propertyName = Convert.ToString(_reader.Value, CultureInfo.InvariantCulture); - - if (_currentScope.RequiredProperties.ContainsKey(propertyName)) - _currentScope.RequiredProperties[propertyName] = true; - - if (!schema.AllowAdditionalProperties) - { - bool propertyDefinied = IsPropertyDefinied(schema, propertyName); - - if (!propertyDefinied) - RaiseError("Property '{0}' has not been defined and the schema does not allow additional properties.".FormatWith(CultureInfo.InvariantCulture, propertyName), schema); - } - - _currentScope.CurrentPropertyName = propertyName; - } - - private bool IsPropertyDefinied(JsonSchemaModel schema, string propertyName) - { - if (schema.Properties != null && schema.Properties.ContainsKey(propertyName)) - return true; - - if (schema.PatternProperties != null) - { - foreach (string pattern in schema.PatternProperties.Keys) - { - if (Regex.IsMatch(propertyName, pattern)) + ValidateCurrentToken(); return true; } - } - return false; + private void ValidateCurrentToken() + { + // first time validate has been called. build model + if (_model == null) + { + JsonSchemaModelBuilder builder = new JsonSchemaModelBuilder(); + _model = builder.Build(_schema); + + if (!JsonWriter.IsStartToken(_reader.TokenType)) + Push(new SchemaScope(JTokenType.None, CurrentMemberSchemas)); + } + + switch (_reader.TokenType) + { + case JsonToken.StartObject: + ProcessValue(); + IList objectSchemas = CurrentMemberSchemas.Where(ValidateObject).ToList(); + Push(new SchemaScope(JTokenType.Object, objectSchemas)); + WriteToken(CurrentSchemas); + break; + case JsonToken.StartArray: + ProcessValue(); + IList arraySchemas = CurrentMemberSchemas.Where(ValidateArray).ToList(); + Push(new SchemaScope(JTokenType.Array, arraySchemas)); + WriteToken(CurrentSchemas); + break; + case JsonToken.StartConstructor: + ProcessValue(); + Push(new SchemaScope(JTokenType.Constructor, null)); + WriteToken(CurrentSchemas); + break; + case JsonToken.PropertyName: + WriteToken(CurrentSchemas); + foreach (JsonSchemaModel schema in CurrentSchemas) + { + ValidatePropertyName(schema); + } + break; + case JsonToken.Raw: + ProcessValue(); + break; + case JsonToken.Integer: + ProcessValue(); + WriteToken(CurrentMemberSchemas); + foreach (JsonSchemaModel schema in CurrentMemberSchemas) + { + ValidateInteger(schema); + } + break; + case JsonToken.Float: + ProcessValue(); + WriteToken(CurrentMemberSchemas); + foreach (JsonSchemaModel schema in CurrentMemberSchemas) + { + ValidateFloat(schema); + } + break; + case JsonToken.String: + ProcessValue(); + WriteToken(CurrentMemberSchemas); + foreach (JsonSchemaModel schema in CurrentMemberSchemas) + { + ValidateString(schema); + } + break; + case JsonToken.Boolean: + ProcessValue(); + WriteToken(CurrentMemberSchemas); + foreach (JsonSchemaModel schema in CurrentMemberSchemas) + { + ValidateBoolean(schema); + } + break; + case JsonToken.Null: + ProcessValue(); + WriteToken(CurrentMemberSchemas); + foreach (JsonSchemaModel schema in CurrentMemberSchemas) + { + ValidateNull(schema); + } + break; + case JsonToken.EndObject: + WriteToken(CurrentSchemas); + foreach (JsonSchemaModel schema in CurrentSchemas) + { + ValidateEndObject(schema); + } + Pop(); + break; + case JsonToken.EndArray: + WriteToken(CurrentSchemas); + foreach (JsonSchemaModel schema in CurrentSchemas) + { + ValidateEndArray(schema); + } + Pop(); + break; + case JsonToken.EndConstructor: + WriteToken(CurrentSchemas); + Pop(); + break; + case JsonToken.Undefined: + case JsonToken.Date: + case JsonToken.Bytes: + // these have no equivalent in JSON schema + WriteToken(CurrentMemberSchemas); + break; + case JsonToken.None: + // no content, do nothing + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + + private void WriteToken(IList schemas) + { + foreach (SchemaScope schemaScope in _stack) + { + bool isInUniqueArray = (schemaScope.TokenType == JTokenType.Array && schemaScope.IsUniqueArray && schemaScope.ArrayItemCount > 0); + + if (isInUniqueArray || schemaScope.IsEnum || schemas.Any(s => s.Enum != null)) + { + if (schemaScope.CurrentItemWriter == null) + { + if (JsonWriter.IsEndToken(_reader.TokenType)) + continue; + + schemaScope.CurrentItemWriter = new JTokenWriter(); + } + + schemaScope.CurrentItemWriter.WriteToken(_reader, false); + + // finished writing current item + if (schemaScope.CurrentItemWriter.Top == 0 && _reader.TokenType != JsonToken.PropertyName) + { + JToken finishedItem = schemaScope.CurrentItemWriter.Token; + + // start next item with new writer + schemaScope.CurrentItemWriter = null; + + if (isInUniqueArray) + { + if (schemaScope.UniqueArrayItems.Contains(finishedItem, JToken.EqualityComparer)) + RaiseError("Non-unique array item at index {0}.".FormatWith(CultureInfo.InvariantCulture, schemaScope.ArrayItemCount - 1), schemaScope.Schemas.First(s => s.UniqueItems)); + + schemaScope.UniqueArrayItems.Add(finishedItem); + } + else if (schemaScope.IsEnum || schemas.Any(s => s.Enum != null)) + { + foreach (JsonSchemaModel schema in schemas) + { + if (schema.Enum != null) + { + if (!schema.Enum.ContainsValue(finishedItem, JToken.EqualityComparer)) + { + StringWriter sw = new StringWriter(CultureInfo.InvariantCulture); + finishedItem.WriteTo(new JsonTextWriter(sw)); + + RaiseError("Value {0} is not defined in enum.".FormatWith(CultureInfo.InvariantCulture, sw.ToString()), schema); + } + } + } + } + } + } + } + } + + private void ValidateEndObject(JsonSchemaModel schema) + { + if (schema == null) + return; + + Dictionary requiredProperties = _currentScope.RequiredProperties; + + if (requiredProperties != null) + { + List unmatchedRequiredProperties = + requiredProperties.Where(kv => !kv.Value).Select(kv => kv.Key).ToList(); + + if (unmatchedRequiredProperties.Count > 0) + RaiseError("Required properties are missing from object: {0}.".FormatWith(CultureInfo.InvariantCulture, string.Join(", ", unmatchedRequiredProperties.ToArray())), schema); + } + } + + private void ValidateEndArray(JsonSchemaModel schema) + { + if (schema == null) + return; + + int arrayItemCount = _currentScope.ArrayItemCount; + + if (schema.MaximumItems != null && arrayItemCount > schema.MaximumItems) + RaiseError("Array item count {0} exceeds maximum count of {1}.".FormatWith(CultureInfo.InvariantCulture, arrayItemCount, schema.MaximumItems), schema); + + if (schema.MinimumItems != null && arrayItemCount < schema.MinimumItems) + RaiseError("Array item count {0} is less than minimum count of {1}.".FormatWith(CultureInfo.InvariantCulture, arrayItemCount, schema.MinimumItems), schema); + } + + private void ValidateNull(JsonSchemaModel schema) + { + if (schema == null) + return; + + if (!TestType(schema, JsonSchemaType.Null)) + return; + + ValidateNotDisallowed(schema); + } + + private void ValidateBoolean(JsonSchemaModel schema) + { + if (schema == null) + return; + + if (!TestType(schema, JsonSchemaType.Boolean)) + return; + + ValidateNotDisallowed(schema); + } + + private void ValidateString(JsonSchemaModel schema) + { + if (schema == null) + return; + + if (!TestType(schema, JsonSchemaType.String)) + return; + + ValidateNotDisallowed(schema); + + string value = _reader.Value.ToString(); + + if (schema.MaximumLength != null && value.Length > schema.MaximumLength) + RaiseError("String '{0}' exceeds maximum length of {1}.".FormatWith(CultureInfo.InvariantCulture, value, schema.MaximumLength), schema); + + if (schema.MinimumLength != null && value.Length < schema.MinimumLength) + RaiseError("String '{0}' is less than minimum length of {1}.".FormatWith(CultureInfo.InvariantCulture, value, schema.MinimumLength), schema); + + if (schema.Patterns != null) + { + foreach (string pattern in schema.Patterns) + { + if (!Regex.IsMatch(value, pattern)) + RaiseError("String '{0}' does not match regex pattern '{1}'.".FormatWith(CultureInfo.InvariantCulture, value, pattern), schema); + } + } + } + + private void ValidateInteger(JsonSchemaModel schema) + { + if (schema == null) + return; + + if (!TestType(schema, JsonSchemaType.Integer)) + return; + + ValidateNotDisallowed(schema); + + object value = _reader.Value; + + if (schema.Maximum != null) + { + if (JValue.Compare(JTokenType.Integer, value, schema.Maximum) > 0) + RaiseError("Integer {0} exceeds maximum value of {1}.".FormatWith(CultureInfo.InvariantCulture, value, schema.Maximum), schema); + if (schema.ExclusiveMaximum && JValue.Compare(JTokenType.Integer, value, schema.Maximum) == 0) + RaiseError("Integer {0} equals maximum value of {1} and exclusive maximum is true.".FormatWith(CultureInfo.InvariantCulture, value, schema.Maximum), schema); + } + + if (schema.Minimum != null) + { + if (JValue.Compare(JTokenType.Integer, value, schema.Minimum) < 0) + RaiseError("Integer {0} is less than minimum value of {1}.".FormatWith(CultureInfo.InvariantCulture, value, schema.Minimum), schema); + if (schema.ExclusiveMinimum && JValue.Compare(JTokenType.Integer, value, schema.Minimum) == 0) + RaiseError("Integer {0} equals minimum value of {1} and exclusive minimum is true.".FormatWith(CultureInfo.InvariantCulture, value, schema.Minimum), schema); + } + + if (schema.DivisibleBy != null) + { + bool notDivisible; +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (value is BigInteger) + { + // not that this will lose any decimal point on DivisibleBy + // so manually raise an error if DivisibleBy is not an integer and value is not zero + BigInteger i = (BigInteger)value; + bool divisibleNonInteger = !Math.Abs(schema.DivisibleBy.Value - Math.Truncate(schema.DivisibleBy.Value)).Equals(0); + if (divisibleNonInteger) + notDivisible = i != 0; + else + notDivisible = i % new BigInteger(schema.DivisibleBy.Value) != 0; + } + else +#endif + notDivisible = !IsZero(Convert.ToInt64(value, CultureInfo.InvariantCulture) % schema.DivisibleBy.Value); + + if (notDivisible) + RaiseError("Integer {0} is not evenly divisible by {1}.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(value), schema.DivisibleBy), schema); + } + } + + private void ProcessValue() + { + if (_currentScope != null && _currentScope.TokenType == JTokenType.Array) + { + _currentScope.ArrayItemCount++; + + foreach (JsonSchemaModel currentSchema in CurrentSchemas) + { + // if there is positional validation and the array index is past the number of item validation schemas and there is no additonal items then error + if (currentSchema != null + && currentSchema.PositionalItemsValidation + && !currentSchema.AllowAdditionalItems + && (currentSchema.Items == null || _currentScope.ArrayItemCount - 1 >= currentSchema.Items.Count)) + { + RaiseError("Index {0} has not been defined and the schema does not allow additional items.".FormatWith(CultureInfo.InvariantCulture, _currentScope.ArrayItemCount), currentSchema); + } + } + } + } + + private void ValidateFloat(JsonSchemaModel schema) + { + if (schema == null) + return; + + if (!TestType(schema, JsonSchemaType.Float)) + return; + + ValidateNotDisallowed(schema); + + double value = Convert.ToDouble(_reader.Value, CultureInfo.InvariantCulture); + + if (schema.Maximum != null) + { + if (value > schema.Maximum) + RaiseError("Float {0} exceeds maximum value of {1}.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(value), schema.Maximum), schema); + if (schema.ExclusiveMaximum && value == schema.Maximum) + RaiseError("Float {0} equals maximum value of {1} and exclusive maximum is true.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(value), schema.Maximum), schema); + } + + if (schema.Minimum != null) + { + if (value < schema.Minimum) + RaiseError("Float {0} is less than minimum value of {1}.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(value), schema.Minimum), schema); + if (schema.ExclusiveMinimum && value == schema.Minimum) + RaiseError("Float {0} equals minimum value of {1} and exclusive minimum is true.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(value), schema.Minimum), schema); + } + + if (schema.DivisibleBy != null) + { + double remainder = FloatingPointRemainder(value, schema.DivisibleBy.Value); + + if (!IsZero(remainder)) + RaiseError("Float {0} is not evenly divisible by {1}.".FormatWith(CultureInfo.InvariantCulture, JsonConvert.ToString(value), schema.DivisibleBy), schema); + } + } + + private static double FloatingPointRemainder(double dividend, double divisor) + { + return dividend - Math.Floor(dividend / divisor) * divisor; + } + + private static bool IsZero(double value) + { + const double epsilon = 2.2204460492503131e-016; + + return Math.Abs(value) < 10.0 * epsilon; + } + + private void ValidatePropertyName(JsonSchemaModel schema) + { + if (schema == null) + return; + + string propertyName = Convert.ToString(_reader.Value, CultureInfo.InvariantCulture); + + if (_currentScope.RequiredProperties.ContainsKey(propertyName)) + _currentScope.RequiredProperties[propertyName] = true; + + if (!schema.AllowAdditionalProperties) + { + bool propertyDefinied = IsPropertyDefinied(schema, propertyName); + + if (!propertyDefinied) + RaiseError("Property '{0}' has not been defined and the schema does not allow additional properties.".FormatWith(CultureInfo.InvariantCulture, propertyName), schema); + } + + _currentScope.CurrentPropertyName = propertyName; + } + + private bool IsPropertyDefinied(JsonSchemaModel schema, string propertyName) + { + if (schema.Properties != null && schema.Properties.ContainsKey(propertyName)) + return true; + + if (schema.PatternProperties != null) + { + foreach (string pattern in schema.PatternProperties.Keys) + { + if (Regex.IsMatch(propertyName, pattern)) + return true; + } + } + + return false; + } + + private bool ValidateArray(JsonSchemaModel schema) + { + if (schema == null) + return true; + + return (TestType(schema, JsonSchemaType.Array)); + } + + private bool ValidateObject(JsonSchemaModel schema) + { + if (schema == null) + return true; + + return (TestType(schema, JsonSchemaType.Object)); + } + + private bool TestType(JsonSchemaModel currentSchema, JsonSchemaType currentType) + { + if (!JsonSchemaGenerator.HasFlag(currentSchema.Type, currentType)) + { + RaiseError("Invalid type. Expected {0} but got {1}.".FormatWith(CultureInfo.InvariantCulture, currentSchema.Type, currentType), currentSchema); + return false; + } + + return true; + } + + bool IJsonLineInfo.HasLineInfo() + { + IJsonLineInfo lineInfo = _reader as IJsonLineInfo; + return lineInfo != null && lineInfo.HasLineInfo(); + } + + int IJsonLineInfo.LineNumber + { + get + { + IJsonLineInfo lineInfo = _reader as IJsonLineInfo; + return (lineInfo != null) ? lineInfo.LineNumber : 0; + } + } + + int IJsonLineInfo.LinePosition + { + get + { + IJsonLineInfo lineInfo = _reader as IJsonLineInfo; + return (lineInfo != null) ? lineInfo.LinePosition : 0; + } + } } - - private bool ValidateArray(JsonSchemaModel schema) - { - if (schema == null) - return true; - - return (TestType(schema, JsonSchemaType.Array)); - } - - private bool ValidateObject(JsonSchemaModel schema) - { - if (schema == null) - return true; - - return (TestType(schema, JsonSchemaType.Object)); - } - - private bool TestType(JsonSchemaModel currentSchema, JsonSchemaType currentType) - { - if (!JsonSchemaGenerator.HasFlag(currentSchema.Type, currentType)) - { - RaiseError("Invalid type. Expected {0} but got {1}.".FormatWith(CultureInfo.InvariantCulture, currentSchema.Type, currentType), currentSchema); - return false; - } - - return true; - } - - bool IJsonLineInfo.HasLineInfo() - { - IJsonLineInfo lineInfo = _reader as IJsonLineInfo; - return lineInfo != null && lineInfo.HasLineInfo(); - } - - int IJsonLineInfo.LineNumber - { - get - { - IJsonLineInfo lineInfo = _reader as IJsonLineInfo; - return (lineInfo != null) ? lineInfo.LineNumber : 0; - } - } - - int IJsonLineInfo.LinePosition - { - get - { - IJsonLineInfo lineInfo = _reader as IJsonLineInfo; - return (lineInfo != null) ? lineInfo.LinePosition : 0; - } - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/JsonWriter.cs b/Src/Newtonsoft.Json/JsonWriter.cs index ce444d0d..0e679889 100644 --- a/Src/Newtonsoft.Json/JsonWriter.cs +++ b/Src/Newtonsoft.Json/JsonWriter.cs @@ -35,1488 +35,1489 @@ using System.Globalization; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json { - /// - /// Represents a writer that provides a fast, non-cached, forward-only way of generating Json data. - /// - public abstract class JsonWriter : IDisposable - { - internal enum State + /// + /// Represents a writer that provides a fast, non-cached, forward-only way of generating Json data. + /// + public abstract class JsonWriter : IDisposable { - Start, - Property, - ObjectStart, - Object, - ArrayStart, - Array, - ConstructorStart, - Constructor, - Closed, - Error - } - - // array that gives a new state based on the current state an the token being written - private static readonly State[][] StateArray; - - internal static readonly State[][] StateArrayTempate = new[] { -// Start PropertyName ObjectStart Object ArrayStart Array ConstructorStart Constructor Closed Error -// -/* None */new[]{ State.Error, State.Error, State.Error, State.Error, State.Error, State.Error, State.Error, State.Error, State.Error, State.Error }, -/* StartObject */new[]{ State.ObjectStart, State.ObjectStart, State.Error, State.Error, State.ObjectStart, State.ObjectStart, State.ObjectStart, State.ObjectStart, State.Error, State.Error }, -/* StartArray */new[]{ State.ArrayStart, State.ArrayStart, State.Error, State.Error, State.ArrayStart, State.ArrayStart, State.ArrayStart, State.ArrayStart, State.Error, State.Error }, -/* StartConstructor */new[]{ State.ConstructorStart, State.ConstructorStart, State.Error, State.Error, State.ConstructorStart, State.ConstructorStart, State.ConstructorStart, State.ConstructorStart, State.Error, State.Error }, -/* Property */new[]{ State.Property, State.Error, State.Property, State.Property, State.Error, State.Error, State.Error, State.Error, State.Error, State.Error }, -/* Comment */new[]{ State.Start, State.Property, State.ObjectStart, State.Object, State.ArrayStart, State.Array, State.Constructor, State.Constructor, State.Error, State.Error }, -/* Raw */new[]{ State.Start, State.Property, State.ObjectStart, State.Object, State.ArrayStart, State.Array, State.Constructor, State.Constructor, State.Error, State.Error }, -/* Value (this will be copied) */new[]{ State.Start, State.Object, State.Error, State.Error, State.Array, State.Array, State.Constructor, State.Constructor, State.Error, State.Error } - }; - - internal static State[][] BuildStateArray() - { - var allStates = StateArrayTempate.ToList(); - var errorStates = StateArrayTempate[0]; - var valueStates = StateArrayTempate[7]; - - foreach (JsonToken valueToken in EnumUtils.GetValues(typeof(JsonToken))) - { - if (allStates.Count <= (int)valueToken) + internal enum State { - switch (valueToken) - { - case JsonToken.Integer: - case JsonToken.Float: - case JsonToken.String: - case JsonToken.Boolean: - case JsonToken.Null: - case JsonToken.Undefined: - case JsonToken.Date: - case JsonToken.Bytes: - allStates.Add(valueStates); - break; - default: - allStates.Add(errorStates); - break; - } + Start, + Property, + ObjectStart, + Object, + ArrayStart, + Array, + ConstructorStart, + Constructor, + Closed, + Error } - } - return allStates.ToArray(); - } + // array that gives a new state based on the current state an the token being written + private static readonly State[][] StateArray; - static JsonWriter() - { - StateArray = BuildStateArray(); - } - - private readonly List _stack; - private JsonPosition _currentPosition; - private State _currentState; - private Formatting _formatting; - - /// - /// Gets or sets a value indicating whether the underlying stream or - /// should be closed when the writer is closed. - /// - /// - /// true to close the underlying stream or when - /// the writer is closed; otherwise false. The default is true. - /// - public bool CloseOutput { get; set; } - - /// - /// Gets the top. - /// - /// The top. - protected internal int Top - { - get - { - int depth = _stack.Count; - if (Peek() != JsonContainerType.None) - depth++; - - return depth; - } - } - - /// - /// Gets the state of the writer. - /// - public WriteState WriteState - { - get - { - switch (_currentState) + internal static readonly State[][] StateArrayTempate = new[] { - case State.Error: - return WriteState.Error; - case State.Closed: - return WriteState.Closed; - case State.Object: - case State.ObjectStart: - return WriteState.Object; - case State.Array: - case State.ArrayStart: - return WriteState.Array; - case State.Constructor: - case State.ConstructorStart: - return WriteState.Constructor; - case State.Property: - return WriteState.Property; - case State.Start: - return WriteState.Start; - default: - throw JsonWriterException.Create(this, "Invalid state: " + _currentState, null); - } - } - } + // Start PropertyName ObjectStart Object ArrayStart Array ConstructorStart Constructor Closed Error + // + /* None */new[] { State.Error, State.Error, State.Error, State.Error, State.Error, State.Error, State.Error, State.Error, State.Error, State.Error }, + /* StartObject */new[] { State.ObjectStart, State.ObjectStart, State.Error, State.Error, State.ObjectStart, State.ObjectStart, State.ObjectStart, State.ObjectStart, State.Error, State.Error }, + /* StartArray */new[] { State.ArrayStart, State.ArrayStart, State.Error, State.Error, State.ArrayStart, State.ArrayStart, State.ArrayStart, State.ArrayStart, State.Error, State.Error }, + /* StartConstructor */new[] { State.ConstructorStart, State.ConstructorStart, State.Error, State.Error, State.ConstructorStart, State.ConstructorStart, State.ConstructorStart, State.ConstructorStart, State.Error, State.Error }, + /* Property */new[] { State.Property, State.Error, State.Property, State.Property, State.Error, State.Error, State.Error, State.Error, State.Error, State.Error }, + /* Comment */new[] { State.Start, State.Property, State.ObjectStart, State.Object, State.ArrayStart, State.Array, State.Constructor, State.Constructor, State.Error, State.Error }, + /* Raw */new[] { State.Start, State.Property, State.ObjectStart, State.Object, State.ArrayStart, State.Array, State.Constructor, State.Constructor, State.Error, State.Error }, + /* Value (this will be copied) */new[] { State.Start, State.Object, State.Error, State.Error, State.Array, State.Array, State.Constructor, State.Constructor, State.Error, State.Error } + }; - internal string ContainerPath - { - get - { - if (_currentPosition.Type == JsonContainerType.None) - return string.Empty; - - return JsonPosition.BuildPath(_stack); - } - } - - /// - /// Gets the path of the writer. - /// - public string Path - { - get - { - if (_currentPosition.Type == JsonContainerType.None) - return string.Empty; - - bool insideContainer = (_currentState != State.ArrayStart - && _currentState != State.ConstructorStart - && _currentState != State.ObjectStart); - - IEnumerable positions = (!insideContainer) - ? _stack - : _stack.Concat(new[] { _currentPosition }); - - return JsonPosition.BuildPath(positions); - } - } - - private DateFormatHandling _dateFormatHandling; - private DateTimeZoneHandling _dateTimeZoneHandling; - private StringEscapeHandling _stringEscapeHandling; - private FloatFormatHandling _floatFormatHandling; - private string _dateFormatString; - private CultureInfo _culture; - - /// - /// Indicates how JSON text output is formatted. - /// - public Formatting Formatting - { - get { return _formatting; } - set { _formatting = value; } - } - - /// - /// Get or set how dates are written to JSON text. - /// - public DateFormatHandling DateFormatHandling - { - get { return _dateFormatHandling; } - set { _dateFormatHandling = value; } - } - - /// - /// Get or set how time zones are handling when writing JSON text. - /// - public DateTimeZoneHandling DateTimeZoneHandling - { - get { return _dateTimeZoneHandling; } - set { _dateTimeZoneHandling = value; } - } - - /// - /// Get or set how strings are escaped when writing JSON text. - /// - public StringEscapeHandling StringEscapeHandling - { - get { return _stringEscapeHandling; } - set - { - _stringEscapeHandling = value; - OnStringEscapeHandlingChanged(); - } - } - - internal virtual void OnStringEscapeHandlingChanged() - { - // hacky but there is a calculated value that relies on StringEscapeHandling - } - - /// - /// Get or set how special floating point numbers, e.g. , - /// and , - /// are written to JSON text. - /// - public FloatFormatHandling FloatFormatHandling - { - get { return _floatFormatHandling; } - set { _floatFormatHandling = value; } - } - - /// - /// Get or set how and values are formatting when writing JSON text. - /// - public string DateFormatString - { - get { return _dateFormatString; } - set { _dateFormatString = value; } - } - - /// - /// Gets or sets the culture used when writing JSON. Defaults to . - /// - public CultureInfo Culture - { - get { return _culture ?? CultureInfo.InvariantCulture; } - set { _culture = value; } - } - - /// - /// Creates an instance of the JsonWriter class. - /// - protected JsonWriter() - { - _stack = new List(4); - _currentState = State.Start; - _formatting = Formatting.None; - _dateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind; - - CloseOutput = true; - } - - internal void UpdateScopeWithFinishedValue() - { - if (_currentPosition.HasIndex) - _currentPosition.Position++; - } - - private void Push(JsonContainerType value) - { - if (_currentPosition.Type != JsonContainerType.None) - _stack.Add(_currentPosition); - - _currentPosition = new JsonPosition(value); - } - - private JsonContainerType Pop() - { - JsonPosition oldPosition = _currentPosition; - - if (_stack.Count > 0) - { - _currentPosition = _stack[_stack.Count - 1]; - _stack.RemoveAt(_stack.Count - 1); - } - else - { - _currentPosition = new JsonPosition(); - } - - return oldPosition.Type; - } - - private JsonContainerType Peek() - { - return _currentPosition.Type; - } - - /// - /// Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. - /// - public abstract void Flush(); - - /// - /// Closes this stream and the underlying stream. - /// - public virtual void Close() - { - AutoCompleteAll(); - } - - /// - /// Writes the beginning of a Json object. - /// - public virtual void WriteStartObject() - { - InternalWriteStart(JsonToken.StartObject, JsonContainerType.Object); - } - - /// - /// Writes the end of a Json object. - /// - public virtual void WriteEndObject() - { - InternalWriteEnd(JsonContainerType.Object); - } - - /// - /// Writes the beginning of a Json array. - /// - public virtual void WriteStartArray() - { - InternalWriteStart(JsonToken.StartArray, JsonContainerType.Array); - } - - /// - /// Writes the end of an array. - /// - public virtual void WriteEndArray() - { - InternalWriteEnd(JsonContainerType.Array); - } - - /// - /// Writes the start of a constructor with the given name. - /// - /// The name of the constructor. - public virtual void WriteStartConstructor(string name) - { - InternalWriteStart(JsonToken.StartConstructor, JsonContainerType.Constructor); - } - - /// - /// Writes the end constructor. - /// - public virtual void WriteEndConstructor() - { - InternalWriteEnd(JsonContainerType.Constructor); - } - - /// - /// Writes the property name of a name/value pair on a JSON object. - /// - /// The name of the property. - public virtual void WritePropertyName(string name) - { - InternalWritePropertyName(name); - } - - /// - /// Writes the property name of a name/value pair on a JSON object. - /// - /// The name of the property. - /// A flag to indicate whether the text should be escaped when it is written as a JSON property name. - public virtual void WritePropertyName(string name, bool escape) - { - WritePropertyName(name); - } - - /// - /// Writes the end of the current Json object or array. - /// - public virtual void WriteEnd() - { - WriteEnd(Peek()); - } - - /// - /// Writes the current token and its children. - /// - /// The to read the token from. - public void WriteToken(JsonReader reader) - { - WriteToken(reader, true, true); - } - - /// - /// Writes the current token. - /// - /// The to read the token from. - /// A flag indicating whether the current token's children should be written. - public void WriteToken(JsonReader reader, bool writeChildren) - { - ValidationUtils.ArgumentNotNull(reader, "reader"); - - WriteToken(reader, writeChildren, true); - } - - internal void WriteToken(JsonReader reader, bool writeChildren, bool writeDateConstructorAsDate) - { - int initialDepth; - - if (reader.TokenType == JsonToken.None) - initialDepth = -1; - else if (!IsStartToken(reader.TokenType)) - initialDepth = reader.Depth + 1; - else - initialDepth = reader.Depth; - - WriteToken(reader, initialDepth, writeChildren, writeDateConstructorAsDate); - } - - internal void WriteToken(JsonReader reader, int initialDepth, bool writeChildren, bool writeDateConstructorAsDate) - { - do - { - switch (reader.TokenType) + internal static State[][] BuildStateArray() { - case JsonToken.None: - // read to next - break; - case JsonToken.StartObject: - WriteStartObject(); - break; - case JsonToken.StartArray: - WriteStartArray(); - break; - case JsonToken.StartConstructor: - string constructorName = reader.Value.ToString(); - // write a JValue date when the constructor is for a date - if (writeDateConstructorAsDate && string.Equals(constructorName, "Date", StringComparison.Ordinal)) - WriteConstructorDate(reader); - else - WriteStartConstructor(reader.Value.ToString()); - break; - case JsonToken.PropertyName: - WritePropertyName(reader.Value.ToString()); - break; - case JsonToken.Comment: - WriteComment((reader.Value != null) ? reader.Value.ToString() : null); - break; - case JsonToken.Integer: -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE || PORTABLE40) - if (reader.Value is BigInteger) + var allStates = StateArrayTempate.ToList(); + var errorStates = StateArrayTempate[0]; + var valueStates = StateArrayTempate[7]; + + foreach (JsonToken valueToken in EnumUtils.GetValues(typeof(JsonToken))) { - WriteValue((BigInteger)reader.Value); + if (allStates.Count <= (int)valueToken) + { + switch (valueToken) + { + case JsonToken.Integer: + case JsonToken.Float: + case JsonToken.String: + case JsonToken.Boolean: + case JsonToken.Null: + case JsonToken.Undefined: + case JsonToken.Date: + case JsonToken.Bytes: + allStates.Add(valueStates); + break; + default: + allStates.Add(errorStates); + break; + } + } } - else -#endif + + return allStates.ToArray(); + } + + static JsonWriter() + { + StateArray = BuildStateArray(); + } + + private readonly List _stack; + private JsonPosition _currentPosition; + private State _currentState; + private Formatting _formatting; + + /// + /// Gets or sets a value indicating whether the underlying stream or + /// should be closed when the writer is closed. + /// + /// + /// true to close the underlying stream or when + /// the writer is closed; otherwise false. The default is true. + /// + public bool CloseOutput { get; set; } + + /// + /// Gets the top. + /// + /// The top. + protected internal int Top + { + get { - WriteValue(Convert.ToInt64(reader.Value, CultureInfo.InvariantCulture)); + int depth = _stack.Count; + if (Peek() != JsonContainerType.None) + depth++; + + return depth; } - break; - case JsonToken.Float: - object value = reader.Value; - - if (value is decimal) - WriteValue((decimal)value); - else if (value is double) - WriteValue((double)value); - else if (value is float) - WriteValue((float)value); - else - WriteValue(Convert.ToDouble(value, CultureInfo.InvariantCulture)); - break; - case JsonToken.String: - WriteValue(reader.Value.ToString()); - break; - case JsonToken.Boolean: - WriteValue(Convert.ToBoolean(reader.Value, CultureInfo.InvariantCulture)); - break; - case JsonToken.Null: - WriteNull(); - break; - case JsonToken.Undefined: - WriteUndefined(); - break; - case JsonToken.EndObject: - WriteEndObject(); - break; - case JsonToken.EndArray: - WriteEndArray(); - break; - case JsonToken.EndConstructor: - WriteEndConstructor(); - break; - case JsonToken.Date: -#if !NET20 - if (reader.Value is DateTimeOffset) - WriteValue((DateTimeOffset)reader.Value); - else -#endif - WriteValue(Convert.ToDateTime(reader.Value, CultureInfo.InvariantCulture)); - break; - case JsonToken.Raw: - WriteRawValue((reader.Value != null) ? reader.Value.ToString() : null); - break; - case JsonToken.Bytes: - WriteValue((byte[])reader.Value); - break; - default: - throw MiscellaneousUtils.CreateArgumentOutOfRangeException("TokenType", reader.TokenType, "Unexpected token type."); - } - } - while ( - // stop if we have reached the end of the token being read - initialDepth - 1 < reader.Depth - (IsEndToken(reader.TokenType) ? 1 : 0) - && writeChildren - && reader.Read()); - } - - private void WriteConstructorDate(JsonReader reader) - { - if (!reader.Read()) - throw JsonWriterException.Create(this, "Unexpected end when reading date constructor.", null); - if (reader.TokenType != JsonToken.Integer) - throw JsonWriterException.Create(this, "Unexpected token when reading date constructor. Expected Integer, got " + reader.TokenType, null); - - long ticks = (long)reader.Value; - DateTime date = DateTimeUtils.ConvertJavaScriptTicksToDateTime(ticks); - - if (!reader.Read()) - throw JsonWriterException.Create(this, "Unexpected end when reading date constructor.", null); - if (reader.TokenType != JsonToken.EndConstructor) - throw JsonWriterException.Create(this, "Unexpected token when reading date constructor. Expected EndConstructor, got " + reader.TokenType, null); - - WriteValue(date); - } - - internal static bool IsEndToken(JsonToken token) - { - switch (token) - { - case JsonToken.EndObject: - case JsonToken.EndArray: - case JsonToken.EndConstructor: - return true; - default: - return false; - } - } - - internal static bool IsStartToken(JsonToken token) - { - switch (token) - { - case JsonToken.StartObject: - case JsonToken.StartArray: - case JsonToken.StartConstructor: - return true; - default: - return false; - } - } - - private void WriteEnd(JsonContainerType type) - { - switch (type) - { - case JsonContainerType.Object: - WriteEndObject(); - break; - case JsonContainerType.Array: - WriteEndArray(); - break; - case JsonContainerType.Constructor: - WriteEndConstructor(); - break; - default: - throw JsonWriterException.Create(this, "Unexpected type when writing end: " + type, null); - } - } - - private void AutoCompleteAll() - { - while (Top > 0) - { - WriteEnd(); - } - } - - private JsonToken GetCloseTokenForType(JsonContainerType type) - { - switch (type) - { - case JsonContainerType.Object: - return JsonToken.EndObject; - case JsonContainerType.Array: - return JsonToken.EndArray; - case JsonContainerType.Constructor: - return JsonToken.EndConstructor; - default: - throw JsonWriterException.Create(this, "No close token for type: " + type, null); - } - } - - private void AutoCompleteClose(JsonContainerType type) - { - // write closing symbol and calculate new state - int levelsToComplete = 0; - - if (_currentPosition.Type == type) - { - levelsToComplete = 1; - } - else - { - int top = Top - 2; - for (int i = top; i >= 0; i--) - { - int currentLevel = top - i; - - if (_stack[currentLevel].Type == type) - { - levelsToComplete = i + 2; - break; - } - } - } - - if (levelsToComplete == 0) - throw JsonWriterException.Create(this, "No token to close.", null); - - for (int i = 0; i < levelsToComplete; i++) - { - JsonToken token = GetCloseTokenForType(Pop()); - - if (_currentState == State.Property) - WriteNull(); - - if (_formatting == Formatting.Indented) - { - if (_currentState != State.ObjectStart && _currentState != State.ArrayStart) - WriteIndent(); } - WriteEnd(token); - - JsonContainerType currentLevelType = Peek(); - - switch (currentLevelType) + /// + /// Gets the state of the writer. + /// + public WriteState WriteState { - case JsonContainerType.Object: - _currentState = State.Object; - break; - case JsonContainerType.Array: - _currentState = State.Array; - break; - case JsonContainerType.Constructor: - _currentState = State.Array; - break; - case JsonContainerType.None: + get + { + switch (_currentState) + { + case State.Error: + return WriteState.Error; + case State.Closed: + return WriteState.Closed; + case State.Object: + case State.ObjectStart: + return WriteState.Object; + case State.Array: + case State.ArrayStart: + return WriteState.Array; + case State.Constructor: + case State.ConstructorStart: + return WriteState.Constructor; + case State.Property: + return WriteState.Property; + case State.Start: + return WriteState.Start; + default: + throw JsonWriterException.Create(this, "Invalid state: " + _currentState, null); + } + } + } + + internal string ContainerPath + { + get + { + if (_currentPosition.Type == JsonContainerType.None) + return string.Empty; + + return JsonPosition.BuildPath(_stack); + } + } + + /// + /// Gets the path of the writer. + /// + public string Path + { + get + { + if (_currentPosition.Type == JsonContainerType.None) + return string.Empty; + + bool insideContainer = (_currentState != State.ArrayStart + && _currentState != State.ConstructorStart + && _currentState != State.ObjectStart); + + IEnumerable positions = (!insideContainer) + ? _stack + : _stack.Concat(new[] { _currentPosition }); + + return JsonPosition.BuildPath(positions); + } + } + + private DateFormatHandling _dateFormatHandling; + private DateTimeZoneHandling _dateTimeZoneHandling; + private StringEscapeHandling _stringEscapeHandling; + private FloatFormatHandling _floatFormatHandling; + private string _dateFormatString; + private CultureInfo _culture; + + /// + /// Indicates how JSON text output is formatted. + /// + public Formatting Formatting + { + get { return _formatting; } + set { _formatting = value; } + } + + /// + /// Get or set how dates are written to JSON text. + /// + public DateFormatHandling DateFormatHandling + { + get { return _dateFormatHandling; } + set { _dateFormatHandling = value; } + } + + /// + /// Get or set how time zones are handling when writing JSON text. + /// + public DateTimeZoneHandling DateTimeZoneHandling + { + get { return _dateTimeZoneHandling; } + set { _dateTimeZoneHandling = value; } + } + + /// + /// Get or set how strings are escaped when writing JSON text. + /// + public StringEscapeHandling StringEscapeHandling + { + get { return _stringEscapeHandling; } + set + { + _stringEscapeHandling = value; + OnStringEscapeHandlingChanged(); + } + } + + internal virtual void OnStringEscapeHandlingChanged() + { + // hacky but there is a calculated value that relies on StringEscapeHandling + } + + /// + /// Get or set how special floating point numbers, e.g. , + /// and , + /// are written to JSON text. + /// + public FloatFormatHandling FloatFormatHandling + { + get { return _floatFormatHandling; } + set { _floatFormatHandling = value; } + } + + /// + /// Get or set how and values are formatting when writing JSON text. + /// + public string DateFormatString + { + get { return _dateFormatString; } + set { _dateFormatString = value; } + } + + /// + /// Gets or sets the culture used when writing JSON. Defaults to . + /// + public CultureInfo Culture + { + get { return _culture ?? CultureInfo.InvariantCulture; } + set { _culture = value; } + } + + /// + /// Creates an instance of the JsonWriter class. + /// + protected JsonWriter() + { + _stack = new List(4); _currentState = State.Start; - break; - default: - throw JsonWriterException.Create(this, "Unknown JsonType: " + currentLevelType, null); + _formatting = Formatting.None; + _dateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind; + + CloseOutput = true; } - } - } - /// - /// Writes the specified end token. - /// - /// The end token to write. - protected virtual void WriteEnd(JsonToken token) - { - } + internal void UpdateScopeWithFinishedValue() + { + if (_currentPosition.HasIndex) + _currentPosition.Position++; + } - /// - /// Writes indent characters. - /// - protected virtual void WriteIndent() - { - } + private void Push(JsonContainerType value) + { + if (_currentPosition.Type != JsonContainerType.None) + _stack.Add(_currentPosition); - /// - /// Writes the JSON value delimiter. - /// - protected virtual void WriteValueDelimiter() - { - } + _currentPosition = new JsonPosition(value); + } - /// - /// Writes an indent space. - /// - protected virtual void WriteIndentSpace() - { - } + private JsonContainerType Pop() + { + JsonPosition oldPosition = _currentPosition; - internal void AutoComplete(JsonToken tokenBeingWritten) - { - // gets new state based on the current state and what is being written - State newState = StateArray[(int)tokenBeingWritten][(int)_currentState]; + if (_stack.Count > 0) + { + _currentPosition = _stack[_stack.Count - 1]; + _stack.RemoveAt(_stack.Count - 1); + } + else + { + _currentPosition = new JsonPosition(); + } - if (newState == State.Error) - throw JsonWriterException.Create(this, "Token {0} in state {1} would result in an invalid JSON object.".FormatWith(CultureInfo.InvariantCulture, tokenBeingWritten.ToString(), _currentState.ToString()), null); + return oldPosition.Type; + } - if ((_currentState == State.Object || _currentState == State.Array || _currentState == State.Constructor) && tokenBeingWritten != JsonToken.Comment) - { - WriteValueDelimiter(); - } + private JsonContainerType Peek() + { + return _currentPosition.Type; + } - if (_formatting == Formatting.Indented) - { - if (_currentState == State.Property) - WriteIndentSpace(); + /// + /// Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. + /// + public abstract void Flush(); - // don't indent a property when it is the first token to be written (i.e. at the start) - if ((_currentState == State.Array || _currentState == State.ArrayStart || _currentState == State.Constructor || _currentState == State.ConstructorStart) - || (tokenBeingWritten == JsonToken.PropertyName && _currentState != State.Start)) - WriteIndent(); - } + /// + /// Closes this stream and the underlying stream. + /// + public virtual void Close() + { + AutoCompleteAll(); + } - _currentState = newState; - } + /// + /// Writes the beginning of a Json object. + /// + public virtual void WriteStartObject() + { + InternalWriteStart(JsonToken.StartObject, JsonContainerType.Object); + } - #region WriteValue methods - /// - /// Writes a null value. - /// - public virtual void WriteNull() - { - InternalWriteValue(JsonToken.Null); - } + /// + /// Writes the end of a Json object. + /// + public virtual void WriteEndObject() + { + InternalWriteEnd(JsonContainerType.Object); + } - /// - /// Writes an undefined value. - /// - public virtual void WriteUndefined() - { - InternalWriteValue(JsonToken.Undefined); - } + /// + /// Writes the beginning of a Json array. + /// + public virtual void WriteStartArray() + { + InternalWriteStart(JsonToken.StartArray, JsonContainerType.Array); + } - /// - /// Writes raw JSON without changing the writer's state. - /// - /// The raw JSON to write. - public virtual void WriteRaw(string json) - { - InternalWriteRaw(); - } + /// + /// Writes the end of an array. + /// + public virtual void WriteEndArray() + { + InternalWriteEnd(JsonContainerType.Array); + } - /// - /// Writes raw JSON where a value is expected and updates the writer's state. - /// - /// The raw JSON to write. - public virtual void WriteRawValue(string json) - { - // hack. want writer to change state as if a value had been written - UpdateScopeWithFinishedValue(); - AutoComplete(JsonToken.Undefined); - WriteRaw(json); - } + /// + /// Writes the start of a constructor with the given name. + /// + /// The name of the constructor. + public virtual void WriteStartConstructor(string name) + { + InternalWriteStart(JsonToken.StartConstructor, JsonContainerType.Constructor); + } - /// - /// Writes a value. - /// - /// The value to write. - public virtual void WriteValue(string value) - { - InternalWriteValue(JsonToken.String); - } + /// + /// Writes the end constructor. + /// + public virtual void WriteEndConstructor() + { + InternalWriteEnd(JsonContainerType.Constructor); + } - /// - /// Writes a value. - /// - /// The value to write. - public virtual void WriteValue(int value) - { - InternalWriteValue(JsonToken.Integer); - } + /// + /// Writes the property name of a name/value pair on a JSON object. + /// + /// The name of the property. + public virtual void WritePropertyName(string name) + { + InternalWritePropertyName(name); + } - /// - /// Writes a value. - /// - /// The value to write. - [CLSCompliant(false)] - public virtual void WriteValue(uint value) - { - InternalWriteValue(JsonToken.Integer); - } + /// + /// Writes the property name of a name/value pair on a JSON object. + /// + /// The name of the property. + /// A flag to indicate whether the text should be escaped when it is written as a JSON property name. + public virtual void WritePropertyName(string name, bool escape) + { + WritePropertyName(name); + } - /// - /// Writes a value. - /// - /// The value to write. - public virtual void WriteValue(long value) - { - InternalWriteValue(JsonToken.Integer); - } + /// + /// Writes the end of the current Json object or array. + /// + public virtual void WriteEnd() + { + WriteEnd(Peek()); + } - /// - /// Writes a value. - /// - /// The value to write. - [CLSCompliant(false)] - public virtual void WriteValue(ulong value) - { - InternalWriteValue(JsonToken.Integer); - } + /// + /// Writes the current token and its children. + /// + /// The to read the token from. + public void WriteToken(JsonReader reader) + { + WriteToken(reader, true, true); + } - /// - /// Writes a value. - /// - /// The value to write. - public virtual void WriteValue(float value) - { - InternalWriteValue(JsonToken.Float); - } + /// + /// Writes the current token. + /// + /// The to read the token from. + /// A flag indicating whether the current token's children should be written. + public void WriteToken(JsonReader reader, bool writeChildren) + { + ValidationUtils.ArgumentNotNull(reader, "reader"); - /// - /// Writes a value. - /// - /// The value to write. - public virtual void WriteValue(double value) - { - InternalWriteValue(JsonToken.Float); - } + WriteToken(reader, writeChildren, true); + } - /// - /// Writes a value. - /// - /// The value to write. - public virtual void WriteValue(bool value) - { - InternalWriteValue(JsonToken.Boolean); - } + internal void WriteToken(JsonReader reader, bool writeChildren, bool writeDateConstructorAsDate) + { + int initialDepth; - /// - /// Writes a value. - /// - /// The value to write. - public virtual void WriteValue(short value) - { - InternalWriteValue(JsonToken.Integer); - } + if (reader.TokenType == JsonToken.None) + initialDepth = -1; + else if (!IsStartToken(reader.TokenType)) + initialDepth = reader.Depth + 1; + else + initialDepth = reader.Depth; - /// - /// Writes a value. - /// - /// The value to write. - [CLSCompliant(false)] - public virtual void WriteValue(ushort value) - { - InternalWriteValue(JsonToken.Integer); - } + WriteToken(reader, initialDepth, writeChildren, writeDateConstructorAsDate); + } - /// - /// Writes a value. - /// - /// The value to write. - public virtual void WriteValue(char value) - { - InternalWriteValue(JsonToken.String); - } - - /// - /// Writes a value. - /// - /// The value to write. - public virtual void WriteValue(byte value) - { - InternalWriteValue(JsonToken.Integer); - } - - /// - /// Writes a value. - /// - /// The value to write. - [CLSCompliant(false)] - public virtual void WriteValue(sbyte value) - { - InternalWriteValue(JsonToken.Integer); - } - - /// - /// Writes a value. - /// - /// The value to write. - public virtual void WriteValue(decimal value) - { - InternalWriteValue(JsonToken.Float); - } - - /// - /// Writes a value. - /// - /// The value to write. - public virtual void WriteValue(DateTime value) - { - InternalWriteValue(JsonToken.Date); - } - -#if !NET20 - /// - /// Writes a value. - /// - /// The value to write. - public virtual void WriteValue(DateTimeOffset value) - { - InternalWriteValue(JsonToken.Date); - } -#endif - - /// - /// Writes a value. - /// - /// The value to write. - public virtual void WriteValue(Guid value) - { - InternalWriteValue(JsonToken.String); - } - - /// - /// Writes a value. - /// - /// The value to write. - public virtual void WriteValue(TimeSpan value) - { - InternalWriteValue(JsonToken.String); - } - - /// - /// Writes a value. - /// - /// The value to write. - public virtual void WriteValue(int? value) - { - if (value == null) - WriteNull(); - else - WriteValue(value.Value); - } - - /// - /// Writes a value. - /// - /// The value to write. - [CLSCompliant(false)] - public virtual void WriteValue(uint? value) - { - if (value == null) - WriteNull(); - else - WriteValue(value.Value); - } - - /// - /// Writes a value. - /// - /// The value to write. - public virtual void WriteValue(long? value) - { - if (value == null) - WriteNull(); - else - WriteValue(value.Value); - } - - /// - /// Writes a value. - /// - /// The value to write. - [CLSCompliant(false)] - public virtual void WriteValue(ulong? value) - { - if (value == null) - WriteNull(); - else - WriteValue(value.Value); - } - - /// - /// Writes a value. - /// - /// The value to write. - public virtual void WriteValue(float? value) - { - if (value == null) - WriteNull(); - else - WriteValue(value.Value); - } - - /// - /// Writes a value. - /// - /// The value to write. - public virtual void WriteValue(double? value) - { - if (value == null) - WriteNull(); - else - WriteValue(value.Value); - } - - /// - /// Writes a value. - /// - /// The value to write. - public virtual void WriteValue(bool? value) - { - if (value == null) - WriteNull(); - else - WriteValue(value.Value); - } - - /// - /// Writes a value. - /// - /// The value to write. - public virtual void WriteValue(short? value) - { - if (value == null) - WriteNull(); - else - WriteValue(value.Value); - } - - /// - /// Writes a value. - /// - /// The value to write. - [CLSCompliant(false)] - public virtual void WriteValue(ushort? value) - { - if (value == null) - WriteNull(); - else - WriteValue(value.Value); - } - - /// - /// Writes a value. - /// - /// The value to write. - public virtual void WriteValue(char? value) - { - if (value == null) - WriteNull(); - else - WriteValue(value.Value); - } - - /// - /// Writes a value. - /// - /// The value to write. - public virtual void WriteValue(byte? value) - { - if (value == null) - WriteNull(); - else - WriteValue(value.Value); - } - - /// - /// Writes a value. - /// - /// The value to write. - [CLSCompliant(false)] - public virtual void WriteValue(sbyte? value) - { - if (value == null) - WriteNull(); - else - WriteValue(value.Value); - } - - /// - /// Writes a value. - /// - /// The value to write. - public virtual void WriteValue(decimal? value) - { - if (value == null) - WriteNull(); - else - WriteValue(value.Value); - } - - /// - /// Writes a value. - /// - /// The value to write. - public virtual void WriteValue(DateTime? value) - { - if (value == null) - WriteNull(); - else - WriteValue(value.Value); - } - -#if !NET20 - /// - /// Writes a value. - /// - /// The value to write. - public virtual void WriteValue(DateTimeOffset? value) - { - if (value == null) - WriteNull(); - else - WriteValue(value.Value); - } -#endif - - /// - /// Writes a value. - /// - /// The value to write. - public virtual void WriteValue(Guid? value) - { - if (value == null) - WriteNull(); - else - WriteValue(value.Value); - } - - /// - /// Writes a value. - /// - /// The value to write. - public virtual void WriteValue(TimeSpan? value) - { - if (value == null) - WriteNull(); - else - WriteValue(value.Value); - } - - /// - /// Writes a value. - /// - /// The value to write. - public virtual void WriteValue(byte[] value) - { - if (value == null) - WriteNull(); - else - InternalWriteValue(JsonToken.Bytes); - } - - /// - /// Writes a value. - /// - /// The value to write. - public virtual void WriteValue(Uri value) - { - if (value == null) - WriteNull(); - else - InternalWriteValue(JsonToken.String); - } - - /// - /// Writes a value. - /// An error will raised if the value cannot be written as a single JSON token. - /// - /// The value to write. - public virtual void WriteValue(object value) - { - if (value == null) - { - WriteNull(); - } - else - { + internal void WriteToken(JsonReader reader, int initialDepth, bool writeChildren, bool writeDateConstructorAsDate) + { + do + { + switch (reader.TokenType) + { + case JsonToken.None: + // read to next + break; + case JsonToken.StartObject: + WriteStartObject(); + break; + case JsonToken.StartArray: + WriteStartArray(); + break; + case JsonToken.StartConstructor: + string constructorName = reader.Value.ToString(); + // write a JValue date when the constructor is for a date + if (writeDateConstructorAsDate && string.Equals(constructorName, "Date", StringComparison.Ordinal)) + WriteConstructorDate(reader); + else + WriteStartConstructor(reader.Value.ToString()); + break; + case JsonToken.PropertyName: + WritePropertyName(reader.Value.ToString()); + break; + case JsonToken.Comment: + WriteComment((reader.Value != null) ? reader.Value.ToString() : null); + break; + case JsonToken.Integer: #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE || PORTABLE40) - // this is here because adding a WriteValue(BigInteger) to JsonWriter will - // mean the user has to add a reference to System.Numerics.dll - if (value is BigInteger) - throw CreateUnsupportedTypeException(this, value); + 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; - WriteValue(this, ConvertUtils.GetTypeCode(value), value); - } - } - #endregion - - /// - /// Writes out a comment /*...*/ containing the specified text. - /// - /// Text to place inside the comment. - public virtual void WriteComment(string text) - { - InternalWriteComment(); - } - - /// - /// Writes out the given white space. - /// - /// The string of white space characters. - public virtual void WriteWhitespace(string ws) - { - InternalWriteWhitespace(ws); - } - - void IDisposable.Dispose() - { - Dispose(true); - } - - private void Dispose(bool disposing) - { - if (_currentState != State.Closed) - Close(); - } - - internal static void WriteValue(JsonWriter writer, PrimitiveTypeCode typeCode, object value) - { - switch (typeCode) - { - case PrimitiveTypeCode.Char: - writer.WriteValue((char)value); - break; - case PrimitiveTypeCode.CharNullable: - writer.WriteValue((value == null) ? (char?)null : (char)value); - break; - case PrimitiveTypeCode.Boolean: - writer.WriteValue((bool)value); - break; - case PrimitiveTypeCode.BooleanNullable: - writer.WriteValue((value == null) ? (bool?)null : (bool)value); - break; - case PrimitiveTypeCode.SByte: - writer.WriteValue((sbyte)value); - break; - case PrimitiveTypeCode.SByteNullable: - writer.WriteValue((value == null) ? (sbyte?)null : (sbyte)value); - break; - case PrimitiveTypeCode.Int16: - writer.WriteValue((short)value); - break; - case PrimitiveTypeCode.Int16Nullable: - writer.WriteValue((value == null) ? (short?)null : (short)value); - break; - case PrimitiveTypeCode.UInt16: - writer.WriteValue((ushort)value); - break; - case PrimitiveTypeCode.UInt16Nullable: - writer.WriteValue((value == null) ? (ushort?)null : (ushort)value); - break; - case PrimitiveTypeCode.Int32: - writer.WriteValue((int)value); - break; - case PrimitiveTypeCode.Int32Nullable: - writer.WriteValue((value == null) ? (int?)null : (int)value); - break; - case PrimitiveTypeCode.Byte: - writer.WriteValue((byte)value); - break; - case PrimitiveTypeCode.ByteNullable: - writer.WriteValue((value == null) ? (byte?)null : (byte)value); - break; - case PrimitiveTypeCode.UInt32: - writer.WriteValue((uint)value); - break; - case PrimitiveTypeCode.UInt32Nullable: - writer.WriteValue((value == null) ? (uint?)null : (uint)value); - break; - case PrimitiveTypeCode.Int64: - writer.WriteValue((long)value); - break; - case PrimitiveTypeCode.Int64Nullable: - writer.WriteValue((value == null) ? (long?)null : (long)value); - break; - case PrimitiveTypeCode.UInt64: - writer.WriteValue((ulong)value); - break; - case PrimitiveTypeCode.UInt64Nullable: - writer.WriteValue((value == null) ? (ulong?)null : (ulong)value); - break; - case PrimitiveTypeCode.Single: - writer.WriteValue((float)value); - break; - case PrimitiveTypeCode.SingleNullable: - writer.WriteValue((value == null) ? (float?)null : (float)value); - break; - case PrimitiveTypeCode.Double: - writer.WriteValue((double)value); - break; - case PrimitiveTypeCode.DoubleNullable: - writer.WriteValue((value == null) ? (double?)null : (double)value); - break; - case PrimitiveTypeCode.DateTime: - writer.WriteValue((DateTime)value); - break; - case PrimitiveTypeCode.DateTimeNullable: - writer.WriteValue((value == null) ? (DateTime?)null : (DateTime)value); - break; + if (value is decimal) + WriteValue((decimal)value); + else if (value is double) + WriteValue((double)value); + else if (value is float) + WriteValue((float)value); + else + WriteValue(Convert.ToDouble(value, CultureInfo.InvariantCulture)); + break; + case JsonToken.String: + WriteValue(reader.Value.ToString()); + break; + case JsonToken.Boolean: + WriteValue(Convert.ToBoolean(reader.Value, CultureInfo.InvariantCulture)); + break; + case JsonToken.Null: + WriteNull(); + break; + case JsonToken.Undefined: + WriteUndefined(); + break; + case JsonToken.EndObject: + WriteEndObject(); + break; + case JsonToken.EndArray: + WriteEndArray(); + break; + case JsonToken.EndConstructor: + WriteEndConstructor(); + break; + case JsonToken.Date: #if !NET20 - case PrimitiveTypeCode.DateTimeOffset: - writer.WriteValue((DateTimeOffset)value); - break; - case PrimitiveTypeCode.DateTimeOffsetNullable: - writer.WriteValue((value == null) ? (DateTimeOffset?)null : (DateTimeOffset)value); - break; + if (reader.Value is DateTimeOffset) + WriteValue((DateTimeOffset)reader.Value); + else #endif - case PrimitiveTypeCode.Decimal: - writer.WriteValue((decimal)value); - break; - case PrimitiveTypeCode.DecimalNullable: - writer.WriteValue((value == null) ? (decimal?)null : (decimal)value); - break; - case PrimitiveTypeCode.Guid: - writer.WriteValue((Guid)value); - break; - case PrimitiveTypeCode.GuidNullable: - writer.WriteValue((value == null) ? (Guid?)null : (Guid)value); - break; - case PrimitiveTypeCode.TimeSpan: - writer.WriteValue((TimeSpan)value); - break; - case PrimitiveTypeCode.TimeSpanNullable: - writer.WriteValue((value == null) ? (TimeSpan?)null : (TimeSpan)value); - break; + WriteValue(Convert.ToDateTime(reader.Value, CultureInfo.InvariantCulture)); + break; + case JsonToken.Raw: + WriteRawValue((reader.Value != null) ? reader.Value.ToString() : null); + break; + case JsonToken.Bytes: + WriteValue((byte[])reader.Value); + break; + default: + throw MiscellaneousUtils.CreateArgumentOutOfRangeException("TokenType", reader.TokenType, "Unexpected token type."); + } + } while ( + // stop if we have reached the end of the token being read + initialDepth - 1 < reader.Depth - (IsEndToken(reader.TokenType) ? 1 : 0) + && writeChildren + && reader.Read()); + } + + private void WriteConstructorDate(JsonReader reader) + { + if (!reader.Read()) + throw JsonWriterException.Create(this, "Unexpected end when reading date constructor.", null); + if (reader.TokenType != JsonToken.Integer) + throw JsonWriterException.Create(this, "Unexpected token when reading date constructor. Expected Integer, got " + reader.TokenType, null); + + long ticks = (long)reader.Value; + DateTime date = DateTimeUtils.ConvertJavaScriptTicksToDateTime(ticks); + + if (!reader.Read()) + throw JsonWriterException.Create(this, "Unexpected end when reading date constructor.", null); + if (reader.TokenType != JsonToken.EndConstructor) + throw JsonWriterException.Create(this, "Unexpected token when reading date constructor. Expected EndConstructor, got " + reader.TokenType, null); + + WriteValue(date); + } + + internal static bool IsEndToken(JsonToken token) + { + switch (token) + { + case JsonToken.EndObject: + case JsonToken.EndArray: + case JsonToken.EndConstructor: + return true; + default: + return false; + } + } + + internal static bool IsStartToken(JsonToken token) + { + switch (token) + { + case JsonToken.StartObject: + case JsonToken.StartArray: + case JsonToken.StartConstructor: + return true; + default: + return false; + } + } + + private void WriteEnd(JsonContainerType type) + { + switch (type) + { + case JsonContainerType.Object: + WriteEndObject(); + break; + case JsonContainerType.Array: + WriteEndArray(); + break; + case JsonContainerType.Constructor: + WriteEndConstructor(); + break; + default: + throw JsonWriterException.Create(this, "Unexpected type when writing end: " + type, null); + } + } + + private void AutoCompleteAll() + { + while (Top > 0) + { + WriteEnd(); + } + } + + private JsonToken GetCloseTokenForType(JsonContainerType type) + { + switch (type) + { + case JsonContainerType.Object: + return JsonToken.EndObject; + case JsonContainerType.Array: + return JsonToken.EndArray; + case JsonContainerType.Constructor: + return JsonToken.EndConstructor; + default: + throw JsonWriterException.Create(this, "No close token for type: " + type, null); + } + } + + private void AutoCompleteClose(JsonContainerType type) + { + // write closing symbol and calculate new state + int levelsToComplete = 0; + + if (_currentPosition.Type == type) + { + levelsToComplete = 1; + } + else + { + int top = Top - 2; + for (int i = top; i >= 0; i--) + { + int currentLevel = top - i; + + if (_stack[currentLevel].Type == type) + { + levelsToComplete = i + 2; + break; + } + } + } + + if (levelsToComplete == 0) + throw JsonWriterException.Create(this, "No token to close.", null); + + for (int i = 0; i < levelsToComplete; i++) + { + JsonToken token = GetCloseTokenForType(Pop()); + + if (_currentState == State.Property) + WriteNull(); + + if (_formatting == Formatting.Indented) + { + if (_currentState != State.ObjectStart && _currentState != State.ArrayStart) + WriteIndent(); + } + + WriteEnd(token); + + JsonContainerType currentLevelType = Peek(); + + switch (currentLevelType) + { + case JsonContainerType.Object: + _currentState = State.Object; + break; + case JsonContainerType.Array: + _currentState = State.Array; + break; + case JsonContainerType.Constructor: + _currentState = State.Array; + break; + case JsonContainerType.None: + _currentState = State.Start; + break; + default: + throw JsonWriterException.Create(this, "Unknown JsonType: " + currentLevelType, null); + } + } + } + + /// + /// Writes the specified end token. + /// + /// The end token to write. + protected virtual void WriteEnd(JsonToken token) + { + } + + /// + /// Writes indent characters. + /// + protected virtual void WriteIndent() + { + } + + /// + /// Writes the JSON value delimiter. + /// + protected virtual void WriteValueDelimiter() + { + } + + /// + /// Writes an indent space. + /// + protected virtual void WriteIndentSpace() + { + } + + internal void AutoComplete(JsonToken tokenBeingWritten) + { + // gets new state based on the current state and what is being written + State newState = StateArray[(int)tokenBeingWritten][(int)_currentState]; + + if (newState == State.Error) + throw JsonWriterException.Create(this, "Token {0} in state {1} would result in an invalid JSON object.".FormatWith(CultureInfo.InvariantCulture, tokenBeingWritten.ToString(), _currentState.ToString()), null); + + if ((_currentState == State.Object || _currentState == State.Array || _currentState == State.Constructor) && tokenBeingWritten != JsonToken.Comment) + { + WriteValueDelimiter(); + } + + if (_formatting == Formatting.Indented) + { + if (_currentState == State.Property) + WriteIndentSpace(); + + // don't indent a property when it is the first token to be written (i.e. at the start) + if ((_currentState == State.Array || _currentState == State.ArrayStart || _currentState == State.Constructor || _currentState == State.ConstructorStart) + || (tokenBeingWritten == JsonToken.PropertyName && _currentState != State.Start)) + WriteIndent(); + } + + _currentState = newState; + } + + #region WriteValue methods + /// + /// Writes a null value. + /// + public virtual void WriteNull() + { + InternalWriteValue(JsonToken.Null); + } + + /// + /// Writes an undefined value. + /// + public virtual void WriteUndefined() + { + InternalWriteValue(JsonToken.Undefined); + } + + /// + /// Writes raw JSON without changing the writer's state. + /// + /// The raw JSON to write. + public virtual void WriteRaw(string json) + { + InternalWriteRaw(); + } + + /// + /// Writes raw JSON where a value is expected and updates the writer's state. + /// + /// The raw JSON to write. + public virtual void WriteRawValue(string json) + { + // hack. want writer to change state as if a value had been written + UpdateScopeWithFinishedValue(); + AutoComplete(JsonToken.Undefined); + WriteRaw(json); + } + + /// + /// Writes a value. + /// + /// The value to write. + public virtual void WriteValue(string value) + { + InternalWriteValue(JsonToken.String); + } + + /// + /// Writes a value. + /// + /// The value to write. + public virtual void WriteValue(int value) + { + InternalWriteValue(JsonToken.Integer); + } + + /// + /// Writes a value. + /// + /// The value to write. + [CLSCompliant(false)] + public virtual void WriteValue(uint value) + { + InternalWriteValue(JsonToken.Integer); + } + + /// + /// Writes a value. + /// + /// The value to write. + public virtual void WriteValue(long value) + { + InternalWriteValue(JsonToken.Integer); + } + + /// + /// Writes a value. + /// + /// The value to write. + [CLSCompliant(false)] + public virtual void WriteValue(ulong value) + { + InternalWriteValue(JsonToken.Integer); + } + + /// + /// Writes a value. + /// + /// The value to write. + public virtual void WriteValue(float value) + { + InternalWriteValue(JsonToken.Float); + } + + /// + /// Writes a value. + /// + /// The value to write. + public virtual void WriteValue(double value) + { + InternalWriteValue(JsonToken.Float); + } + + /// + /// Writes a value. + /// + /// The value to write. + public virtual void WriteValue(bool value) + { + InternalWriteValue(JsonToken.Boolean); + } + + /// + /// Writes a value. + /// + /// The value to write. + public virtual void WriteValue(short value) + { + InternalWriteValue(JsonToken.Integer); + } + + /// + /// Writes a value. + /// + /// The value to write. + [CLSCompliant(false)] + public virtual void WriteValue(ushort value) + { + InternalWriteValue(JsonToken.Integer); + } + + /// + /// Writes a value. + /// + /// The value to write. + public virtual void WriteValue(char value) + { + InternalWriteValue(JsonToken.String); + } + + /// + /// Writes a value. + /// + /// The value to write. + public virtual void WriteValue(byte value) + { + InternalWriteValue(JsonToken.Integer); + } + + /// + /// Writes a value. + /// + /// The value to write. + [CLSCompliant(false)] + public virtual void WriteValue(sbyte value) + { + InternalWriteValue(JsonToken.Integer); + } + + /// + /// Writes a value. + /// + /// The value to write. + public virtual void WriteValue(decimal value) + { + InternalWriteValue(JsonToken.Float); + } + + /// + /// Writes a value. + /// + /// The value to write. + public virtual void WriteValue(DateTime value) + { + InternalWriteValue(JsonToken.Date); + } + +#if !NET20 + /// + /// Writes a value. + /// + /// The value to write. + public virtual void WriteValue(DateTimeOffset value) + { + InternalWriteValue(JsonToken.Date); + } +#endif + + /// + /// Writes a value. + /// + /// The value to write. + public virtual void WriteValue(Guid value) + { + InternalWriteValue(JsonToken.String); + } + + /// + /// Writes a value. + /// + /// The value to write. + public virtual void WriteValue(TimeSpan value) + { + InternalWriteValue(JsonToken.String); + } + + /// + /// Writes a value. + /// + /// The value to write. + public virtual void WriteValue(int? value) + { + if (value == null) + WriteNull(); + else + WriteValue(value.Value); + } + + /// + /// Writes a value. + /// + /// The value to write. + [CLSCompliant(false)] + public virtual void WriteValue(uint? value) + { + if (value == null) + WriteNull(); + else + WriteValue(value.Value); + } + + /// + /// Writes a value. + /// + /// The value to write. + public virtual void WriteValue(long? value) + { + if (value == null) + WriteNull(); + else + WriteValue(value.Value); + } + + /// + /// Writes a value. + /// + /// The value to write. + [CLSCompliant(false)] + public virtual void WriteValue(ulong? value) + { + if (value == null) + WriteNull(); + else + WriteValue(value.Value); + } + + /// + /// Writes a value. + /// + /// The value to write. + public virtual void WriteValue(float? value) + { + if (value == null) + WriteNull(); + else + WriteValue(value.Value); + } + + /// + /// Writes a value. + /// + /// The value to write. + public virtual void WriteValue(double? value) + { + if (value == null) + WriteNull(); + else + WriteValue(value.Value); + } + + /// + /// Writes a value. + /// + /// The value to write. + public virtual void WriteValue(bool? value) + { + if (value == null) + WriteNull(); + else + WriteValue(value.Value); + } + + /// + /// Writes a value. + /// + /// The value to write. + public virtual void WriteValue(short? value) + { + if (value == null) + WriteNull(); + else + WriteValue(value.Value); + } + + /// + /// Writes a value. + /// + /// The value to write. + [CLSCompliant(false)] + public virtual void WriteValue(ushort? value) + { + if (value == null) + WriteNull(); + else + WriteValue(value.Value); + } + + /// + /// Writes a value. + /// + /// The value to write. + public virtual void WriteValue(char? value) + { + if (value == null) + WriteNull(); + else + WriteValue(value.Value); + } + + /// + /// Writes a value. + /// + /// The value to write. + public virtual void WriteValue(byte? value) + { + if (value == null) + WriteNull(); + else + WriteValue(value.Value); + } + + /// + /// Writes a value. + /// + /// The value to write. + [CLSCompliant(false)] + public virtual void WriteValue(sbyte? value) + { + if (value == null) + WriteNull(); + else + WriteValue(value.Value); + } + + /// + /// Writes a value. + /// + /// The value to write. + public virtual void WriteValue(decimal? value) + { + if (value == null) + WriteNull(); + else + WriteValue(value.Value); + } + + /// + /// Writes a value. + /// + /// The value to write. + public virtual void WriteValue(DateTime? value) + { + if (value == null) + WriteNull(); + else + WriteValue(value.Value); + } + +#if !NET20 + /// + /// Writes a value. + /// + /// The value to write. + public virtual void WriteValue(DateTimeOffset? value) + { + if (value == null) + WriteNull(); + else + WriteValue(value.Value); + } +#endif + + /// + /// Writes a value. + /// + /// The value to write. + public virtual void WriteValue(Guid? value) + { + if (value == null) + WriteNull(); + else + WriteValue(value.Value); + } + + /// + /// Writes a value. + /// + /// The value to write. + public virtual void WriteValue(TimeSpan? value) + { + if (value == null) + WriteNull(); + else + WriteValue(value.Value); + } + + /// + /// Writes a value. + /// + /// The value to write. + public virtual void WriteValue(byte[] value) + { + if (value == null) + WriteNull(); + else + InternalWriteValue(JsonToken.Bytes); + } + + /// + /// Writes a value. + /// + /// The value to write. + public virtual void WriteValue(Uri value) + { + if (value == null) + WriteNull(); + else + InternalWriteValue(JsonToken.String); + } + + /// + /// Writes a value. + /// An error will raised if the value cannot be written as a single JSON token. + /// + /// The value to write. + public virtual void WriteValue(object value) + { + if (value == null) + { + WriteNull(); + } + else + { +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE || PORTABLE40) + // this is here because adding a WriteValue(BigInteger) to JsonWriter will + // mean the user has to add a reference to System.Numerics.dll + if (value is BigInteger) + throw CreateUnsupportedTypeException(this, value); +#endif + + WriteValue(this, ConvertUtils.GetTypeCode(value), value); + } + } + #endregion + + /// + /// Writes out a comment /*...*/ containing the specified text. + /// + /// Text to place inside the comment. + public virtual void WriteComment(string text) + { + InternalWriteComment(); + } + + /// + /// Writes out the given white space. + /// + /// The string of white space characters. + public virtual void WriteWhitespace(string ws) + { + InternalWriteWhitespace(ws); + } + + void IDisposable.Dispose() + { + Dispose(true); + } + + private void Dispose(bool disposing) + { + if (_currentState != State.Closed) + Close(); + } + + internal static void WriteValue(JsonWriter writer, PrimitiveTypeCode typeCode, object value) + { + switch (typeCode) + { + case PrimitiveTypeCode.Char: + writer.WriteValue((char)value); + break; + case PrimitiveTypeCode.CharNullable: + writer.WriteValue((value == null) ? (char?)null : (char)value); + break; + case PrimitiveTypeCode.Boolean: + writer.WriteValue((bool)value); + break; + case PrimitiveTypeCode.BooleanNullable: + writer.WriteValue((value == null) ? (bool?)null : (bool)value); + break; + case PrimitiveTypeCode.SByte: + writer.WriteValue((sbyte)value); + break; + case PrimitiveTypeCode.SByteNullable: + writer.WriteValue((value == null) ? (sbyte?)null : (sbyte)value); + break; + case PrimitiveTypeCode.Int16: + writer.WriteValue((short)value); + break; + case PrimitiveTypeCode.Int16Nullable: + writer.WriteValue((value == null) ? (short?)null : (short)value); + break; + case PrimitiveTypeCode.UInt16: + writer.WriteValue((ushort)value); + break; + case PrimitiveTypeCode.UInt16Nullable: + writer.WriteValue((value == null) ? (ushort?)null : (ushort)value); + break; + case PrimitiveTypeCode.Int32: + writer.WriteValue((int)value); + break; + case PrimitiveTypeCode.Int32Nullable: + writer.WriteValue((value == null) ? (int?)null : (int)value); + break; + case PrimitiveTypeCode.Byte: + writer.WriteValue((byte)value); + break; + case PrimitiveTypeCode.ByteNullable: + writer.WriteValue((value == null) ? (byte?)null : (byte)value); + break; + case PrimitiveTypeCode.UInt32: + writer.WriteValue((uint)value); + break; + case PrimitiveTypeCode.UInt32Nullable: + writer.WriteValue((value == null) ? (uint?)null : (uint)value); + break; + case PrimitiveTypeCode.Int64: + writer.WriteValue((long)value); + break; + case PrimitiveTypeCode.Int64Nullable: + writer.WriteValue((value == null) ? (long?)null : (long)value); + break; + case PrimitiveTypeCode.UInt64: + writer.WriteValue((ulong)value); + break; + case PrimitiveTypeCode.UInt64Nullable: + writer.WriteValue((value == null) ? (ulong?)null : (ulong)value); + break; + case PrimitiveTypeCode.Single: + writer.WriteValue((float)value); + break; + case PrimitiveTypeCode.SingleNullable: + writer.WriteValue((value == null) ? (float?)null : (float)value); + break; + case PrimitiveTypeCode.Double: + writer.WriteValue((double)value); + break; + case PrimitiveTypeCode.DoubleNullable: + writer.WriteValue((value == null) ? (double?)null : (double)value); + break; + case PrimitiveTypeCode.DateTime: + writer.WriteValue((DateTime)value); + break; + case PrimitiveTypeCode.DateTimeNullable: + writer.WriteValue((value == null) ? (DateTime?)null : (DateTime)value); + break; +#if !NET20 + case PrimitiveTypeCode.DateTimeOffset: + writer.WriteValue((DateTimeOffset)value); + break; + case PrimitiveTypeCode.DateTimeOffsetNullable: + writer.WriteValue((value == null) ? (DateTimeOffset?)null : (DateTimeOffset)value); + break; +#endif + case PrimitiveTypeCode.Decimal: + writer.WriteValue((decimal)value); + break; + case PrimitiveTypeCode.DecimalNullable: + writer.WriteValue((value == null) ? (decimal?)null : (decimal)value); + break; + case PrimitiveTypeCode.Guid: + writer.WriteValue((Guid)value); + break; + case PrimitiveTypeCode.GuidNullable: + writer.WriteValue((value == null) ? (Guid?)null : (Guid)value); + break; + case PrimitiveTypeCode.TimeSpan: + writer.WriteValue((TimeSpan)value); + break; + case PrimitiveTypeCode.TimeSpanNullable: + writer.WriteValue((value == null) ? (TimeSpan?)null : (TimeSpan)value); + break; #if !(PORTABLE || PORTABLE40 || NET35 || NET20 || WINDOWS_PHONE || SILVERLIGHT) - case PrimitiveTypeCode.BigInteger: - // this will call to WriteValue(object) - writer.WriteValue((BigInteger)value); - break; - case PrimitiveTypeCode.BigIntegerNullable: - // this will call to WriteValue(object) - writer.WriteValue((value == null) ? (BigInteger?)null : (BigInteger)value); - break; + case PrimitiveTypeCode.BigInteger: + // this will call to WriteValue(object) + writer.WriteValue((BigInteger)value); + break; + case PrimitiveTypeCode.BigIntegerNullable: + // this will call to WriteValue(object) + writer.WriteValue((value == null) ? (BigInteger?)null : (BigInteger)value); + break; #endif - case PrimitiveTypeCode.Uri: - writer.WriteValue((Uri)value); - break; - case PrimitiveTypeCode.String: - writer.WriteValue((string)value); - break; - case PrimitiveTypeCode.Bytes: - writer.WriteValue((byte[])value); - break; + case PrimitiveTypeCode.Uri: + writer.WriteValue((Uri)value); + break; + case PrimitiveTypeCode.String: + writer.WriteValue((string)value); + break; + case PrimitiveTypeCode.Bytes: + writer.WriteValue((byte[])value); + break; #if !(PORTABLE || NETFX_CORE) - case PrimitiveTypeCode.DBNull: - writer.WriteNull(); - break; + case PrimitiveTypeCode.DBNull: + writer.WriteNull(); + break; #endif - default: + default: #if !(PORTABLE || NETFX_CORE) - if (value is IConvertible) - { - // the value is a non-standard IConvertible - // convert to the underlying value and retry - IConvertible convertable = (IConvertible)value; + if (value is IConvertible) + { + // the value is a non-standard IConvertible + // convert to the underlying value and retry + IConvertible convertable = (IConvertible)value; - TypeInformation typeInformation = ConvertUtils.GetTypeInformation(convertable); + TypeInformation typeInformation = ConvertUtils.GetTypeInformation(convertable); - // if convertable has an underlying typecode of Object then attempt to convert it to a string - PrimitiveTypeCode resolvedTypeCode = (typeInformation.TypeCode == PrimitiveTypeCode.Object) ? PrimitiveTypeCode.String : typeInformation.TypeCode; - Type resolvedType = (typeInformation.TypeCode == PrimitiveTypeCode.Object) ? typeof(string) : typeInformation.Type; + // if convertable has an underlying typecode of Object then attempt to convert it to a string + PrimitiveTypeCode resolvedTypeCode = (typeInformation.TypeCode == PrimitiveTypeCode.Object) ? PrimitiveTypeCode.String : typeInformation.TypeCode; + Type resolvedType = (typeInformation.TypeCode == PrimitiveTypeCode.Object) ? typeof(string) : typeInformation.Type; - object convertedValue = convertable.ToType(resolvedType, CultureInfo.InvariantCulture); + object convertedValue = convertable.ToType(resolvedType, CultureInfo.InvariantCulture); - WriteValue(writer, resolvedTypeCode, convertedValue); - break; - } - else + WriteValue(writer, resolvedTypeCode, convertedValue); + break; + } + else #endif - { - throw CreateUnsupportedTypeException(writer, value); - } - } - } + { + throw CreateUnsupportedTypeException(writer, value); + } + } + } - private static JsonWriterException CreateUnsupportedTypeException(JsonWriter writer, object value) - { - return JsonWriterException.Create(writer, "Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType()), null); - } + private static JsonWriterException CreateUnsupportedTypeException(JsonWriter writer, object value) + { + return JsonWriterException.Create(writer, "Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType()), null); + } - /// - /// Sets the state of the JsonWriter, - /// - /// The JsonToken being written. - /// The value being written. - protected void SetWriteState(JsonToken token, object value) - { - switch (token) - { - case JsonToken.StartObject: - InternalWriteStart(token, JsonContainerType.Object); - break; - case JsonToken.StartArray: - InternalWriteStart(token, JsonContainerType.Array); - break; - case JsonToken.StartConstructor: - InternalWriteStart(token, JsonContainerType.Constructor); - break; - case JsonToken.PropertyName: - if (!(value is string)) - throw new ArgumentException("A name is required when setting property name state.", "value"); + /// + /// Sets the state of the JsonWriter, + /// + /// The JsonToken being written. + /// The value being written. + protected void SetWriteState(JsonToken token, object value) + { + switch (token) + { + case JsonToken.StartObject: + InternalWriteStart(token, JsonContainerType.Object); + break; + case JsonToken.StartArray: + InternalWriteStart(token, JsonContainerType.Array); + break; + case JsonToken.StartConstructor: + InternalWriteStart(token, JsonContainerType.Constructor); + break; + case JsonToken.PropertyName: + if (!(value is string)) + throw new ArgumentException("A name is required when setting property name state.", "value"); - InternalWritePropertyName((string)value); - break; - case JsonToken.Comment: - InternalWriteComment(); - break; - case JsonToken.Raw: - InternalWriteRaw(); - break; - case JsonToken.Integer: - case JsonToken.Float: - case JsonToken.String: - case JsonToken.Boolean: - case JsonToken.Date: - case JsonToken.Bytes: - case JsonToken.Null: - case JsonToken.Undefined: - InternalWriteValue(token); - break; - case JsonToken.EndObject: - InternalWriteEnd(JsonContainerType.Object); - break; - case JsonToken.EndArray: - InternalWriteEnd(JsonContainerType.Array); - break; - case JsonToken.EndConstructor: - InternalWriteEnd(JsonContainerType.Constructor); - break; - default: - throw new ArgumentOutOfRangeException("token"); - } - } + InternalWritePropertyName((string)value); + break; + case JsonToken.Comment: + InternalWriteComment(); + break; + case JsonToken.Raw: + InternalWriteRaw(); + break; + case JsonToken.Integer: + case JsonToken.Float: + case JsonToken.String: + case JsonToken.Boolean: + case JsonToken.Date: + case JsonToken.Bytes: + case JsonToken.Null: + case JsonToken.Undefined: + InternalWriteValue(token); + break; + case JsonToken.EndObject: + InternalWriteEnd(JsonContainerType.Object); + break; + case JsonToken.EndArray: + InternalWriteEnd(JsonContainerType.Array); + break; + case JsonToken.EndConstructor: + InternalWriteEnd(JsonContainerType.Constructor); + break; + default: + throw new ArgumentOutOfRangeException("token"); + } + } - internal void InternalWriteEnd(JsonContainerType container) - { - AutoCompleteClose(container); - } + internal void InternalWriteEnd(JsonContainerType container) + { + AutoCompleteClose(container); + } - internal void InternalWritePropertyName(string name) - { - _currentPosition.PropertyName = name; - AutoComplete(JsonToken.PropertyName); - } + internal void InternalWritePropertyName(string name) + { + _currentPosition.PropertyName = name; + AutoComplete(JsonToken.PropertyName); + } - internal void InternalWriteRaw() - { - } + internal void InternalWriteRaw() + { + } - internal void InternalWriteStart(JsonToken token, JsonContainerType container) - { - UpdateScopeWithFinishedValue(); - AutoComplete(token); - Push(container); - } + internal void InternalWriteStart(JsonToken token, JsonContainerType container) + { + UpdateScopeWithFinishedValue(); + AutoComplete(token); + Push(container); + } - internal void InternalWriteValue(JsonToken token) - { - UpdateScopeWithFinishedValue(); - AutoComplete(token); - } + internal void InternalWriteValue(JsonToken token) + { + UpdateScopeWithFinishedValue(); + AutoComplete(token); + } - internal void InternalWriteWhitespace(string ws) - { - if (ws != null) - { - if (!StringUtils.IsWhiteSpace(ws)) - throw JsonWriterException.Create(this, "Only white space characters should be used.", null); - } - } + internal void InternalWriteWhitespace(string ws) + { + if (ws != null) + { + if (!StringUtils.IsWhiteSpace(ws)) + throw JsonWriterException.Create(this, "Only white space characters should be used.", null); + } + } - internal void InternalWriteComment() - { - AutoComplete(JsonToken.Comment); + internal void InternalWriteComment() + { + AutoComplete(JsonToken.Comment); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/JsonWriterException.cs b/Src/Newtonsoft.Json/JsonWriterException.cs index 6c34172f..f956261c 100644 --- a/Src/Newtonsoft.Json/JsonWriterException.cs +++ b/Src/Newtonsoft.Json/JsonWriterException.cs @@ -30,78 +30,78 @@ using System.Text; namespace Newtonsoft.Json { - /// - /// The exception thrown when an error occurs while reading Json text. - /// + /// + /// The exception thrown when an error occurs while reading Json text. + /// #if !(SILVERLIGHT || WINDOWS_PHONE || NETFX_CORE || PORTABLE40 || PORTABLE) - [Serializable] + [Serializable] #endif - public class JsonWriterException : JsonException - { - /// - /// Gets the path to the JSON where the error occurred. - /// - /// The path to the JSON where the error occurred. - public string Path { get; private set; } - - /// - /// Initializes a new instance of the class. - /// - public JsonWriterException() + public class JsonWriterException : JsonException { - } + /// + /// Gets the path to the JSON where the error occurred. + /// + /// The path to the JSON where the error occurred. + public string Path { get; private set; } - /// - /// Initializes a new instance of the class - /// with a specified error message. - /// - /// The error message that explains the reason for the exception. - public JsonWriterException(string message) - : base(message) - { - } + /// + /// Initializes a new instance of the class. + /// + public JsonWriterException() + { + } - /// - /// Initializes a new instance of the class - /// with a specified error message and a reference to the inner exception that is the cause of this exception. - /// - /// The error message that explains the reason for the exception. - /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - public JsonWriterException(string message, Exception innerException) - : base(message, innerException) - { - } + /// + /// Initializes a new instance of the class + /// with a specified error message. + /// + /// The error message that explains the reason for the exception. + public JsonWriterException(string message) + : base(message) + { + } + + /// + /// Initializes a new instance of the class + /// with a specified error message and a reference to the inner exception that is the cause of this exception. + /// + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + public JsonWriterException(string message, Exception innerException) + : base(message, innerException) + { + } #if !(WINDOWS_PHONE || SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) - /// - /// Initializes a new instance of the class. - /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. - /// The parameter is null. - /// The class name is null or is zero (0). - public JsonWriterException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } + /// + /// Initializes a new instance of the class. + /// + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. + /// The parameter is null. + /// The class name is null or is zero (0). + public JsonWriterException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } #endif - internal JsonWriterException(string message, Exception innerException, string path) - : base(message, innerException) - { - Path = path; - } + internal JsonWriterException(string message, Exception innerException, string path) + : base(message, innerException) + { + Path = path; + } - internal static JsonWriterException Create(JsonWriter writer, string message, Exception ex) - { - return Create(writer.ContainerPath, message, ex); - } + internal static JsonWriterException Create(JsonWriter writer, string message, Exception ex) + { + return Create(writer.ContainerPath, message, ex); + } - internal static JsonWriterException Create(string path, string message, Exception ex) - { - message = JsonPosition.FormatMessage(null, path, message); + internal static JsonWriterException Create(string path, string message, Exception ex) + { + message = JsonPosition.FormatMessage(null, path, message); - return new JsonWriterException(message, ex, path); + return new JsonWriterException(message, ex, path); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Linq/Extensions.cs b/Src/Newtonsoft.Json/Linq/Extensions.cs index 39424615..f74665b7 100644 --- a/Src/Newtonsoft.Json/Linq/Extensions.cs +++ b/Src/Newtonsoft.Json/Linq/Extensions.cs @@ -31,281 +31,282 @@ using System.Globalization; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json.Linq { - /// - /// Contains the LINQ to JSON extension methods. - /// - public static class Extensions - { /// - /// Returns a collection of tokens that contains the ancestors of every token in the source collection. + /// Contains the LINQ to JSON extension methods. /// - /// The type of the objects in source, constrained to . - /// An of that contains the source collection. - /// An of that contains the ancestors of every node in the source collection. - public static IJEnumerable Ancestors(this IEnumerable source) where T : JToken + public static class Extensions { - ValidationUtils.ArgumentNotNull(source, "source"); - - return source.SelectMany(j => j.Ancestors()).AsJEnumerable(); - } - - //TODO - //public static IEnumerable AncestorsAndSelf(this IEnumerable source) where T : JObject - //{ - // ValidationUtils.ArgumentNotNull(source, "source"); - - // return source.SelectMany(j => j.AncestorsAndSelf()); - //} - - /// - /// Returns a collection of tokens that contains the descendants of every token in the source collection. - /// - /// The type of the objects in source, constrained to . - /// An of that contains the source collection. - /// An of that contains the descendants of every node in the source collection. - public static IJEnumerable Descendants(this IEnumerable source) where T : JContainer - { - ValidationUtils.ArgumentNotNull(source, "source"); - - return source.SelectMany(j => j.Descendants()).AsJEnumerable(); - } - - //TODO - //public static IEnumerable DescendantsAndSelf(this IEnumerable source) where T : JContainer - //{ - // ValidationUtils.ArgumentNotNull(source, "source"); - - // return source.SelectMany(j => j.DescendantsAndSelf()); - //} - - /// - /// Returns a collection of child properties of every object in the source collection. - /// - /// An of that contains the source collection. - /// An of that contains the properties of every object in the source collection. - public static IJEnumerable Properties(this IEnumerable source) - { - ValidationUtils.ArgumentNotNull(source, "source"); - - return source.SelectMany(d => d.Properties()).AsJEnumerable(); - } - - /// - /// Returns a collection of child values of every object in the source collection with the given key. - /// - /// An of that contains the source collection. - /// The token key. - /// An of that contains the values of every node in the source collection with the given key. - public static IJEnumerable Values(this IEnumerable source, object key) - { - return Values(source, key).AsJEnumerable(); - } - - /// - /// Returns a collection of child values of every object in the source collection. - /// - /// An of that contains the source collection. - /// An of that contains the values of every node in the source collection. - public static IJEnumerable Values(this IEnumerable source) - { - return source.Values(null); - } - - /// - /// Returns a collection of converted child values of every object in the source collection with the given key. - /// - /// The type to convert the values to. - /// An of that contains the source collection. - /// The token key. - /// An that contains the converted values of every node in the source collection with the given key. - public static IEnumerable Values(this IEnumerable source, object key) - { - return Values(source, key); - } - - /// - /// Returns a collection of converted child values of every object in the source collection. - /// - /// The type to convert the values to. - /// An of that contains the source collection. - /// An that contains the converted values of every node in the source collection. - public static IEnumerable Values(this IEnumerable source) - { - return Values(source, null); - } - - /// - /// Converts the value. - /// - /// The type to convert the value to. - /// A cast as a of . - /// A converted value. - public static U Value(this IEnumerable value) - { - return value.Value(); - } - - /// - /// Converts the value. - /// - /// The source collection type. - /// The type to convert the value to. - /// A cast as a of . - /// A converted value. - public static U Value(this IEnumerable value) where T : JToken - { - ValidationUtils.ArgumentNotNull(value, "source"); - - JToken token = value as JToken; - if (token == null) - throw new ArgumentException("Source value must be a JToken."); - - return token.Convert(); - } - - - internal static IEnumerable Values(this IEnumerable source, object key) where T : JToken - { - ValidationUtils.ArgumentNotNull(source, "source"); - - foreach (JToken token in source) - { - if (key == null) + /// + /// Returns a collection of tokens that contains the ancestors of every token in the source collection. + /// + /// The type of the objects in source, constrained to . + /// An of that contains the source collection. + /// An of that contains the ancestors of every node in the source collection. + public static IJEnumerable Ancestors(this IEnumerable source) where T : JToken { - if (token is JValue) - { - yield return Convert((JValue)token); - } - else - { - foreach (JToken t in token.Children()) + ValidationUtils.ArgumentNotNull(source, "source"); + + return source.SelectMany(j => j.Ancestors()).AsJEnumerable(); + } + + //TODO + //public static IEnumerable AncestorsAndSelf(this IEnumerable source) where T : JObject + //{ + // ValidationUtils.ArgumentNotNull(source, "source"); + + // return source.SelectMany(j => j.AncestorsAndSelf()); + //} + + /// + /// Returns a collection of tokens that contains the descendants of every token in the source collection. + /// + /// The type of the objects in source, constrained to . + /// An of that contains the source collection. + /// An of that contains the descendants of every node in the source collection. + public static IJEnumerable Descendants(this IEnumerable source) where T : JContainer + { + ValidationUtils.ArgumentNotNull(source, "source"); + + return source.SelectMany(j => j.Descendants()).AsJEnumerable(); + } + + //TODO + //public static IEnumerable DescendantsAndSelf(this IEnumerable source) where T : JContainer + //{ + // ValidationUtils.ArgumentNotNull(source, "source"); + + // return source.SelectMany(j => j.DescendantsAndSelf()); + //} + + /// + /// Returns a collection of child properties of every object in the source collection. + /// + /// An of that contains the source collection. + /// An of that contains the properties of every object in the source collection. + public static IJEnumerable Properties(this IEnumerable source) + { + ValidationUtils.ArgumentNotNull(source, "source"); + + return source.SelectMany(d => d.Properties()).AsJEnumerable(); + } + + /// + /// Returns a collection of child values of every object in the source collection with the given key. + /// + /// An of that contains the source collection. + /// The token key. + /// An of that contains the values of every node in the source collection with the given key. + public static IJEnumerable Values(this IEnumerable source, object key) + { + return Values(source, key).AsJEnumerable(); + } + + /// + /// Returns a collection of child values of every object in the source collection. + /// + /// An of that contains the source collection. + /// An of that contains the values of every node in the source collection. + public static IJEnumerable Values(this IEnumerable source) + { + return source.Values(null); + } + + /// + /// Returns a collection of converted child values of every object in the source collection with the given key. + /// + /// The type to convert the values to. + /// An of that contains the source collection. + /// The token key. + /// An that contains the converted values of every node in the source collection with the given key. + public static IEnumerable Values(this IEnumerable source, object key) + { + return Values(source, key); + } + + /// + /// Returns a collection of converted child values of every object in the source collection. + /// + /// The type to convert the values to. + /// An of that contains the source collection. + /// An that contains the converted values of every node in the source collection. + public static IEnumerable Values(this IEnumerable source) + { + return Values(source, null); + } + + /// + /// Converts the value. + /// + /// The type to convert the value to. + /// A cast as a of . + /// A converted value. + public static U Value(this IEnumerable value) + { + return value.Value(); + } + + /// + /// Converts the value. + /// + /// The source collection type. + /// The type to convert the value to. + /// A cast as a of . + /// A converted value. + public static U Value(this IEnumerable value) where T : JToken + { + ValidationUtils.ArgumentNotNull(value, "source"); + + JToken token = value as JToken; + if (token == null) + throw new ArgumentException("Source value must be a JToken."); + + return token.Convert(); + } + + + internal static IEnumerable Values(this IEnumerable source, object key) where T : JToken + { + ValidationUtils.ArgumentNotNull(source, "source"); + + foreach (JToken token in source) { - yield return t.Convert(); + if (key == null) + { + if (token is JValue) + { + yield return Convert((JValue)token); + } + else + { + foreach (JToken t in token.Children()) + { + yield return t.Convert(); + } + } + } + else + { + JToken value = token[key]; + if (value != null) + yield return value.Convert(); + } } - } + + yield break; } - else + + //TODO + //public static IEnumerable InDocumentOrder(this IEnumerable source) where T : JObject; + + //public static IEnumerable Children(this IEnumerable source) where T : JToken + //{ + // ValidationUtils.ArgumentNotNull(source, "source"); + + // return source.SelectMany(c => c.Children()); + //} + + /// + /// Returns a collection of child tokens of every array in the source collection. + /// + /// The source collection type. + /// An of that contains the source collection. + /// An of that contains the values of every node in the source collection. + public static IJEnumerable Children(this IEnumerable source) where T : JToken { - JToken value = token[key]; - if (value != null) - yield return value.Convert(); + return Children(source).AsJEnumerable(); } - } - yield break; - } - - //TODO - //public static IEnumerable InDocumentOrder(this IEnumerable source) where T : JObject; - - //public static IEnumerable Children(this IEnumerable source) where T : JToken - //{ - // ValidationUtils.ArgumentNotNull(source, "source"); - - // return source.SelectMany(c => c.Children()); - //} - - /// - /// Returns a collection of child tokens of every array in the source collection. - /// - /// The source collection type. - /// An of that contains the source collection. - /// An of that contains the values of every node in the source collection. - public static IJEnumerable Children(this IEnumerable source) where T : JToken - { - return Children(source).AsJEnumerable(); - } - - /// - /// Returns a collection of converted child tokens of every array in the source collection. - /// - /// An of that contains the source collection. - /// The type to convert the values to. - /// The source collection type. - /// An that contains the converted values of every node in the source collection. - public static IEnumerable Children(this IEnumerable source) where T : JToken - { - ValidationUtils.ArgumentNotNull(source, "source"); - - return source.SelectMany(c => c.Children()).Convert(); - } - - internal static IEnumerable Convert(this IEnumerable source) where T : JToken - { - ValidationUtils.ArgumentNotNull(source, "source"); - - foreach (T token in source) - { - yield return Convert(token); - } - } - - internal static U Convert(this T token) where T : JToken - { - if (token == null) - return default(U); - - if (token is U - // don't want to cast JValue to its interfaces, want to get the internal value - && typeof(U) != typeof(IComparable) && typeof(U) != typeof(IFormattable)) - { - // HACK - return (U)(object)token; - } - else - { - JValue value = token as JValue; - if (value == null) - throw new InvalidCastException("Cannot cast {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, token.GetType(), typeof(T))); - - if (value.Value is U) - return (U)value.Value; - - Type targetType = typeof(U); - - if (ReflectionUtils.IsNullableType(targetType)) + /// + /// Returns a collection of converted child tokens of every array in the source collection. + /// + /// An of that contains the source collection. + /// The type to convert the values to. + /// The source collection type. + /// An that contains the converted values of every node in the source collection. + public static IEnumerable Children(this IEnumerable source) where T : JToken { - if (value.Value == null) - return default(U); + ValidationUtils.ArgumentNotNull(source, "source"); - targetType = Nullable.GetUnderlyingType(targetType); + return source.SelectMany(c => c.Children()).Convert(); } - return (U)System.Convert.ChangeType(value.Value, targetType, CultureInfo.InvariantCulture); - } - } + internal static IEnumerable Convert(this IEnumerable source) where T : JToken + { + ValidationUtils.ArgumentNotNull(source, "source"); - //TODO - //public static void Remove(this IEnumerable source) where T : JContainer; + foreach (T token in source) + { + yield return Convert(token); + } + } - /// - /// Returns the input typed as . - /// - /// An of that contains the source collection. - /// The input typed as . - public static IJEnumerable AsJEnumerable(this IEnumerable source) - { - return source.AsJEnumerable(); - } + internal static U Convert(this T token) where T : JToken + { + if (token == null) + return default(U); - /// - /// Returns the input typed as . - /// - /// The source collection type. - /// An of that contains the source collection. - /// The input typed as . - public static IJEnumerable AsJEnumerable(this IEnumerable source) where T : JToken - { - if (source == null) - return null; - else if (source is IJEnumerable) - return (IJEnumerable)source; - else - return new JEnumerable(source); + if (token is U + // don't want to cast JValue to its interfaces, want to get the internal value + && typeof(U) != typeof(IComparable) && typeof(U) != typeof(IFormattable)) + { + // HACK + return (U)(object)token; + } + else + { + JValue value = token as JValue; + if (value == null) + throw new InvalidCastException("Cannot cast {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, token.GetType(), typeof(T))); + + if (value.Value is U) + return (U)value.Value; + + Type targetType = typeof(U); + + if (ReflectionUtils.IsNullableType(targetType)) + { + if (value.Value == null) + return default(U); + + targetType = Nullable.GetUnderlyingType(targetType); + } + + return (U)System.Convert.ChangeType(value.Value, targetType, CultureInfo.InvariantCulture); + } + } + + //TODO + //public static void Remove(this IEnumerable source) where T : JContainer; + + /// + /// Returns the input typed as . + /// + /// An of that contains the source collection. + /// The input typed as . + public static IJEnumerable AsJEnumerable(this IEnumerable source) + { + return source.AsJEnumerable(); + } + + /// + /// Returns the input typed as . + /// + /// The source collection type. + /// An of that contains the source collection. + /// The input typed as . + public static IJEnumerable AsJEnumerable(this IEnumerable source) where T : JToken + { + if (source == null) + return null; + else if (source is IJEnumerable) + return (IJEnumerable)source; + else + return new JEnumerable(source); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Linq/IJEnumerable.cs b/Src/Newtonsoft.Json/Linq/IJEnumerable.cs index d4ab9d11..67d8cbe3 100644 --- a/Src/Newtonsoft.Json/Linq/IJEnumerable.cs +++ b/Src/Newtonsoft.Json/Linq/IJEnumerable.cs @@ -27,20 +27,20 @@ using System.Collections.Generic; namespace Newtonsoft.Json.Linq { - /// - /// Represents a collection of objects. - /// - /// The type of token - public interface IJEnumerable< -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40) - out -#endif - T> : IEnumerable where T : JToken - { /// - /// Gets the with the specified key. + /// Represents a collection of objects. /// - /// - IJEnumerable this[object key] { get; } - } + /// The type of token + public interface IJEnumerable< +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40) + out +#endif + T> : IEnumerable where T : JToken + { + /// + /// Gets the with the specified key. + /// + /// + IJEnumerable this[object key] { get; } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Linq/JArray.cs b/Src/Newtonsoft.Json/Linq/JArray.cs index 2b39791f..fb0fbe3d 100644 --- a/Src/Newtonsoft.Json/Linq/JArray.cs +++ b/Src/Newtonsoft.Json/Linq/JArray.cs @@ -31,329 +31,325 @@ using System.Globalization; namespace Newtonsoft.Json.Linq { - /// - /// Represents a JSON array. - /// - /// - /// - /// - public class JArray : JContainer, IList - { - private readonly List _values = new List(); - /// - /// Gets the container's children tokens. + /// Represents a JSON array. /// - /// The container's children tokens. - protected override IList ChildrenTokens - { - get { return _values; } - } - - /// - /// Gets the node type for this . - /// - /// The type. - public override JTokenType Type - { - get { return JTokenType.Array; } - } - - /// - /// Initializes a new instance of the class. - /// - public JArray() - { - } - - /// - /// Initializes a new instance of the class from another object. - /// - /// A object to copy from. - public JArray(JArray other) - : base(other) - { - } - - /// - /// Initializes a new instance of the class with the specified content. - /// - /// The contents of the array. - public JArray(params object[] content) - : this((object)content) - { - } - - /// - /// Initializes a new instance of the class with the specified content. - /// - /// The contents of the array. - public JArray(object content) - { - Add(content); - } - - internal override bool DeepEquals(JToken node) - { - JArray t = node as JArray; - return (t != null && ContentsEqual(t)); - } - - internal override JToken CloneToken() - { - return new JArray(this); - } - - /// - /// Loads an from a . - /// - /// A that will be read for the content of the . - /// A that contains the JSON that was read from the specified . - public static new JArray Load(JsonReader reader) - { - if (reader.TokenType == JsonToken.None) - { - if (!reader.Read()) - throw JsonReaderException.Create(reader, "Error reading JArray from JsonReader."); - } - - while (reader.TokenType == JsonToken.Comment) - { - reader.Read(); - } - - if (reader.TokenType != JsonToken.StartArray) - throw JsonReaderException.Create(reader, "Error reading JArray from JsonReader. Current JsonReader item is not an array: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); - - JArray a = new JArray(); - a.SetLineInfo(reader as IJsonLineInfo); - - a.ReadTokenFrom(reader); - - return a; - } - - /// - /// Load a from a string that contains JSON. - /// - /// A that contains JSON. - /// A populated from the string that contains JSON. /// /// /// - public static new JArray Parse(string json) + public class JArray : JContainer, IList { - JsonReader reader = new JsonTextReader(new StringReader(json)); + private readonly List _values = new List(); - JArray a = Load(reader); + /// + /// Gets the container's children tokens. + /// + /// The container's children tokens. + protected override IList ChildrenTokens + { + get { return _values; } + } - if (reader.Read() && reader.TokenType != JsonToken.Comment) - throw JsonReaderException.Create(reader, "Additional text found in JSON string after parsing content."); + /// + /// Gets the node type for this . + /// + /// The type. + public override JTokenType Type + { + get { return JTokenType.Array; } + } - return a; + /// + /// Initializes a new instance of the class. + /// + public JArray() + { + } + + /// + /// Initializes a new instance of the class from another object. + /// + /// A object to copy from. + public JArray(JArray other) + : base(other) + { + } + + /// + /// Initializes a new instance of the class with the specified content. + /// + /// The contents of the array. + public JArray(params object[] content) + : this((object)content) + { + } + + /// + /// Initializes a new instance of the class with the specified content. + /// + /// The contents of the array. + public JArray(object content) + { + Add(content); + } + + internal override bool DeepEquals(JToken node) + { + JArray t = node as JArray; + return (t != null && ContentsEqual(t)); + } + + internal override JToken CloneToken() + { + return new JArray(this); + } + + /// + /// Loads an from a . + /// + /// A that will be read for the content of the . + /// A that contains the JSON that was read from the specified . + public new static JArray Load(JsonReader reader) + { + if (reader.TokenType == JsonToken.None) + { + if (!reader.Read()) + throw JsonReaderException.Create(reader, "Error reading JArray from JsonReader."); + } + + while (reader.TokenType == JsonToken.Comment) + { + reader.Read(); + } + + if (reader.TokenType != JsonToken.StartArray) + throw JsonReaderException.Create(reader, "Error reading JArray from JsonReader. Current JsonReader item is not an array: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); + + JArray a = new JArray(); + a.SetLineInfo(reader as IJsonLineInfo); + + a.ReadTokenFrom(reader); + + return a; + } + + /// + /// Load a from a string that contains JSON. + /// + /// A that contains JSON. + /// A populated from the string that contains JSON. + /// + /// + /// + public new static JArray Parse(string json) + { + JsonReader reader = new JsonTextReader(new StringReader(json)); + + JArray a = Load(reader); + + if (reader.Read() && reader.TokenType != JsonToken.Comment) + throw JsonReaderException.Create(reader, "Additional text found in JSON string after parsing content."); + + return a; + } + + /// + /// Creates a from an object. + /// + /// The object that will be used to create . + /// A with the values of the specified object + public new static JArray FromObject(object o) + { + return FromObject(o, JsonSerializer.CreateDefault()); + } + + /// + /// Creates a from an object. + /// + /// The object that will be used to create . + /// The that will be used to read the object. + /// A with the values of the specified object + public new static JArray FromObject(object o, JsonSerializer jsonSerializer) + { + JToken token = FromObjectInternal(o, jsonSerializer); + + if (token.Type != JTokenType.Array) + throw new ArgumentException("Object serialized to {0}. JArray instance expected.".FormatWith(CultureInfo.InvariantCulture, token.Type)); + + return (JArray)token; + } + + /// + /// Writes this token to a . + /// + /// A into which this method will write. + /// A collection of which will be used when writing the token. + public override void WriteTo(JsonWriter writer, params JsonConverter[] converters) + { + writer.WriteStartArray(); + + for (int i = 0; i < _values.Count; i++) + { + _values[i].WriteTo(writer, converters); + } + + writer.WriteEndArray(); + } + + /// + /// Gets the with the specified key. + /// + /// The with the specified key. + public override JToken this[object key] + { + get + { + ValidationUtils.ArgumentNotNull(key, "o"); + + if (!(key is int)) + throw new ArgumentException("Accessed JArray values with invalid key value: {0}. Array position index expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key))); + + return GetItem((int)key); + } + set + { + ValidationUtils.ArgumentNotNull(key, "o"); + + if (!(key is int)) + throw new ArgumentException("Set JArray values with invalid key value: {0}. Array position index expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key))); + + SetItem((int)key, value); + } + } + + /// + /// Gets or sets the at the specified index. + /// + /// + public JToken this[int index] + { + get { return GetItem(index); } + set { SetItem(index, value); } + } + + #region IList Members + /// + /// Determines the index of a specific item in the . + /// + /// The object to locate in the . + /// + /// The index of if found in the list; otherwise, -1. + /// + public int IndexOf(JToken item) + { + return IndexOfItem(item); + } + + /// + /// Inserts an item to the at the specified index. + /// + /// The zero-based index at which should be inserted. + /// The object to insert into the . + /// + /// is not a valid index in the . + /// The is read-only. + public void Insert(int index, JToken item) + { + InsertItem(index, item, false); + } + + /// + /// Removes the item at the specified index. + /// + /// The zero-based index of the item to remove. + /// + /// is not a valid index in the . + /// The is read-only. + public void RemoveAt(int index) + { + RemoveItemAt(index); + } + + /// + /// Returns an enumerator that iterates through the collection. + /// + /// + /// A that can be used to iterate through the collection. + /// + public IEnumerator GetEnumerator() + { + return Children().GetEnumerator(); + } + #endregion + + #region ICollection Members + /// + /// Adds an item to the . + /// + /// The object to add to the . + /// The is read-only. + public void Add(JToken item) + { + Add((object)item); + } + + /// + /// Removes all items from the . + /// + /// The is read-only. + public void Clear() + { + ClearItems(); + } + + /// + /// Determines whether the contains a specific value. + /// + /// The object to locate in the . + /// + /// true if is found in the ; otherwise, false. + /// + public bool Contains(JToken item) + { + return ContainsItem(item); + } + + /// + /// Copies to. + /// + /// The array. + /// Index of the array. + public void CopyTo(JToken[] array, int arrayIndex) + { + CopyItemsTo(array, arrayIndex); + } + + /// + /// Gets a value indicating whether the is read-only. + /// + /// true if the is read-only; otherwise, false. + public bool IsReadOnly + { + get { return false; } + } + + /// + /// Removes the first occurrence of a specific object from the . + /// + /// The object to remove from the . + /// + /// true if was successfully removed from the ; otherwise, false. This method also returns false if is not found in the original . + /// + /// The is read-only. + public bool Remove(JToken item) + { + return RemoveItem(item); + } + #endregion + + internal override int GetDeepHashCode() + { + return ContentsHashCode(); + } } - - /// - /// Creates a from an object. - /// - /// The object that will be used to create . - /// A with the values of the specified object - public static new JArray FromObject(object o) - { - return FromObject(o, JsonSerializer.CreateDefault()); - } - - /// - /// Creates a from an object. - /// - /// The object that will be used to create . - /// The that will be used to read the object. - /// A with the values of the specified object - public static new JArray FromObject(object o, JsonSerializer jsonSerializer) - { - JToken token = FromObjectInternal(o, jsonSerializer); - - if (token.Type != JTokenType.Array) - throw new ArgumentException("Object serialized to {0}. JArray instance expected.".FormatWith(CultureInfo.InvariantCulture, token.Type)); - - return (JArray)token; - } - - /// - /// Writes this token to a . - /// - /// A into which this method will write. - /// A collection of which will be used when writing the token. - public override void WriteTo(JsonWriter writer, params JsonConverter[] converters) - { - writer.WriteStartArray(); - - for (int i = 0; i < _values.Count; i++) - { - _values[i].WriteTo(writer, converters); - } - - writer.WriteEndArray(); - } - - /// - /// Gets the with the specified key. - /// - /// The with the specified key. - public override JToken this[object key] - { - get - { - ValidationUtils.ArgumentNotNull(key, "o"); - - if (!(key is int)) - throw new ArgumentException("Accessed JArray values with invalid key value: {0}. Array position index expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key))); - - return GetItem((int)key); - } - set - { - ValidationUtils.ArgumentNotNull(key, "o"); - - if (!(key is int)) - throw new ArgumentException("Set JArray values with invalid key value: {0}. Array position index expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key))); - - SetItem((int)key, value); - } - } - - /// - /// Gets or sets the at the specified index. - /// - /// - public JToken this[int index] - { - get { return GetItem(index); } - set { SetItem(index, value); } - } - - #region IList Members - - /// - /// Determines the index of a specific item in the . - /// - /// The object to locate in the . - /// - /// The index of if found in the list; otherwise, -1. - /// - public int IndexOf(JToken item) - { - return IndexOfItem(item); - } - - /// - /// Inserts an item to the at the specified index. - /// - /// The zero-based index at which should be inserted. - /// The object to insert into the . - /// - /// is not a valid index in the . - /// The is read-only. - public void Insert(int index, JToken item) - { - InsertItem(index, item, false); - } - - /// - /// Removes the item at the specified index. - /// - /// The zero-based index of the item to remove. - /// - /// is not a valid index in the . - /// The is read-only. - public void RemoveAt(int index) - { - RemoveItemAt(index); - } - - /// - /// Returns an enumerator that iterates through the collection. - /// - /// - /// A that can be used to iterate through the collection. - /// - public IEnumerator GetEnumerator() - { - return Children().GetEnumerator(); - } - - #endregion - - #region ICollection Members - - /// - /// Adds an item to the . - /// - /// The object to add to the . - /// The is read-only. - public void Add(JToken item) - { - Add((object)item); - } - - /// - /// Removes all items from the . - /// - /// The is read-only. - public void Clear() - { - ClearItems(); - } - - /// - /// Determines whether the contains a specific value. - /// - /// The object to locate in the . - /// - /// true if is found in the ; otherwise, false. - /// - public bool Contains(JToken item) - { - return ContainsItem(item); - } - - /// - /// Copies to. - /// - /// The array. - /// Index of the array. - public void CopyTo(JToken[] array, int arrayIndex) - { - CopyItemsTo(array, arrayIndex); - } - - /// - /// Gets a value indicating whether the is read-only. - /// - /// true if the is read-only; otherwise, false. - public bool IsReadOnly - { - get { return false; } - } - - /// - /// Removes the first occurrence of a specific object from the . - /// - /// The object to remove from the . - /// - /// true if was successfully removed from the ; otherwise, false. This method also returns false if is not found in the original . - /// - /// The is read-only. - public bool Remove(JToken item) - { - return RemoveItem(item); - } - - #endregion - - internal override int GetDeepHashCode() - { - return ContentsHashCode(); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Linq/JConstructor.cs b/Src/Newtonsoft.Json/Linq/JConstructor.cs index 30bba5e4..d9b8acee 100644 --- a/Src/Newtonsoft.Json/Linq/JConstructor.cs +++ b/Src/Newtonsoft.Json/Linq/JConstructor.cs @@ -30,177 +30,177 @@ using System.Globalization; namespace Newtonsoft.Json.Linq { - /// - /// Represents a JSON constructor. - /// - public class JConstructor : JContainer - { - private string _name; - private readonly List _values = new List(); - /// - /// Gets the container's children tokens. + /// Represents a JSON constructor. /// - /// The container's children tokens. - protected override IList ChildrenTokens + public class JConstructor : JContainer { - get { return _values; } + private string _name; + private readonly List _values = new List(); + + /// + /// Gets the container's children tokens. + /// + /// The container's children tokens. + protected override IList ChildrenTokens + { + get { return _values; } + } + + /// + /// Gets or sets the name of this constructor. + /// + /// The constructor name. + public string Name + { + get { return _name; } + set { _name = value; } + } + + /// + /// Gets the node type for this . + /// + /// The type. + public override JTokenType Type + { + get { return JTokenType.Constructor; } + } + + /// + /// Initializes a new instance of the class. + /// + public JConstructor() + { + } + + /// + /// Initializes a new instance of the class from another object. + /// + /// A object to copy from. + public JConstructor(JConstructor other) + : base(other) + { + _name = other.Name; + } + + /// + /// Initializes a new instance of the class with the specified name and content. + /// + /// The constructor name. + /// The contents of the constructor. + public JConstructor(string name, params object[] content) + : this(name, (object)content) + { + } + + /// + /// Initializes a new instance of the class with the specified name and content. + /// + /// The constructor name. + /// The contents of the constructor. + public JConstructor(string name, object content) + : this(name) + { + Add(content); + } + + /// + /// Initializes a new instance of the class with the specified name. + /// + /// The constructor name. + public JConstructor(string name) + { + ValidationUtils.ArgumentNotNullOrEmpty(name, "name"); + + _name = name; + } + + internal override bool DeepEquals(JToken node) + { + JConstructor c = node as JConstructor; + return (c != null && _name == c.Name && ContentsEqual(c)); + } + + internal override JToken CloneToken() + { + return new JConstructor(this); + } + + /// + /// Writes this token to a . + /// + /// A into which this method will write. + /// A collection of which will be used when writing the token. + public override void WriteTo(JsonWriter writer, params JsonConverter[] converters) + { + writer.WriteStartConstructor(_name); + + foreach (JToken token in Children()) + { + token.WriteTo(writer, converters); + } + + writer.WriteEndConstructor(); + } + + /// + /// Gets the with the specified key. + /// + /// The with the specified key. + public override JToken this[object key] + { + get + { + ValidationUtils.ArgumentNotNull(key, "o"); + + if (!(key is int)) + throw new ArgumentException("Accessed JConstructor values with invalid key value: {0}. Argument position index expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key))); + + return GetItem((int)key); + } + set + { + ValidationUtils.ArgumentNotNull(key, "o"); + + if (!(key is int)) + throw new ArgumentException("Set JConstructor values with invalid key value: {0}. Argument position index expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key))); + + SetItem((int)key, value); + } + } + + internal override int GetDeepHashCode() + { + return _name.GetHashCode() ^ ContentsHashCode(); + } + + /// + /// Loads an from a . + /// + /// A that will be read for the content of the . + /// A that contains the JSON that was read from the specified . + public new static JConstructor Load(JsonReader reader) + { + if (reader.TokenType == JsonToken.None) + { + if (!reader.Read()) + throw JsonReaderException.Create(reader, "Error reading JConstructor from JsonReader."); + } + + while (reader.TokenType == JsonToken.Comment) + { + reader.Read(); + } + + if (reader.TokenType != JsonToken.StartConstructor) + throw JsonReaderException.Create(reader, "Error reading JConstructor from JsonReader. Current JsonReader item is not a constructor: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); + + JConstructor c = new JConstructor((string)reader.Value); + c.SetLineInfo(reader as IJsonLineInfo); + + c.ReadTokenFrom(reader); + + return c; + } } - - /// - /// Gets or sets the name of this constructor. - /// - /// The constructor name. - public string Name - { - get { return _name; } - set { _name = value; } - } - - /// - /// Gets the node type for this . - /// - /// The type. - public override JTokenType Type - { - get { return JTokenType.Constructor; } - } - - /// - /// Initializes a new instance of the class. - /// - public JConstructor() - { - } - - /// - /// Initializes a new instance of the class from another object. - /// - /// A object to copy from. - public JConstructor(JConstructor other) - : base(other) - { - _name = other.Name; - } - - /// - /// Initializes a new instance of the class with the specified name and content. - /// - /// The constructor name. - /// The contents of the constructor. - public JConstructor(string name, params object[] content) - : this(name, (object)content) - { - } - - /// - /// Initializes a new instance of the class with the specified name and content. - /// - /// The constructor name. - /// The contents of the constructor. - public JConstructor(string name, object content) - : this(name) - { - Add(content); - } - - /// - /// Initializes a new instance of the class with the specified name. - /// - /// The constructor name. - public JConstructor(string name) - { - ValidationUtils.ArgumentNotNullOrEmpty(name, "name"); - - _name = name; - } - - internal override bool DeepEquals(JToken node) - { - JConstructor c = node as JConstructor; - return (c != null && _name == c.Name && ContentsEqual(c)); - } - - internal override JToken CloneToken() - { - return new JConstructor(this); - } - - /// - /// Writes this token to a . - /// - /// A into which this method will write. - /// A collection of which will be used when writing the token. - public override void WriteTo(JsonWriter writer, params JsonConverter[] converters) - { - writer.WriteStartConstructor(_name); - - foreach (JToken token in Children()) - { - token.WriteTo(writer, converters); - } - - writer.WriteEndConstructor(); - } - - /// - /// Gets the with the specified key. - /// - /// The with the specified key. - public override JToken this[object key] - { - get - { - ValidationUtils.ArgumentNotNull(key, "o"); - - if (!(key is int)) - throw new ArgumentException("Accessed JConstructor values with invalid key value: {0}. Argument position index expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key))); - - return GetItem((int)key); - } - set - { - ValidationUtils.ArgumentNotNull(key, "o"); - - if (!(key is int)) - throw new ArgumentException("Set JConstructor values with invalid key value: {0}. Argument position index expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key))); - - SetItem((int)key, value); - } - } - - internal override int GetDeepHashCode() - { - return _name.GetHashCode() ^ ContentsHashCode(); - } - - /// - /// Loads an from a . - /// - /// A that will be read for the content of the . - /// A that contains the JSON that was read from the specified . - public static new JConstructor Load(JsonReader reader) - { - if (reader.TokenType == JsonToken.None) - { - if (!reader.Read()) - throw JsonReaderException.Create(reader, "Error reading JConstructor from JsonReader."); - } - - while (reader.TokenType == JsonToken.Comment) - { - reader.Read(); - } - - if (reader.TokenType != JsonToken.StartConstructor) - throw JsonReaderException.Create(reader, "Error reading JConstructor from JsonReader. Current JsonReader item is not a constructor: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); - - JConstructor c = new JConstructor((string)reader.Value); - c.SetLineInfo(reader as IJsonLineInfo); - - c.ReadTokenFrom(reader); - - return c; - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Linq/JContainer.cs b/Src/Newtonsoft.Json/Linq/JContainer.cs index d1bcf30a..3a71dc52 100644 --- a/Src/Newtonsoft.Json/Linq/JContainer.cs +++ b/Src/Newtonsoft.Json/Linq/JContainer.cs @@ -37,986 +37,975 @@ using System.ComponentModel; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json.Linq { - /// - /// Represents a token that can contain other tokens. - /// - public abstract class JContainer : JToken, IList + /// + /// Represents a token that can contain other tokens. + /// + public abstract class JContainer : JToken, IList #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - , ITypedList, IBindingList + , ITypedList, IBindingList #elif PORTABLE , INotifyCollectionChanged #endif - , IList + , IList #if !(SILVERLIGHT || NET20 || NET35 || NETFX_CORE || PORTABLE40 || PORTABLE) - , INotifyCollectionChanged + , INotifyCollectionChanged #endif - { + { #if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) - internal ListChangedEventHandler _listChanged; - internal AddingNewEventHandler _addingNew; + internal ListChangedEventHandler _listChanged; + internal AddingNewEventHandler _addingNew; - /// - /// Occurs when the list changes or an item in the list changes. - /// - public event ListChangedEventHandler ListChanged - { - add { _listChanged += value; } - remove { _listChanged -= value; } - } + /// + /// Occurs when the list changes or an item in the list changes. + /// + public event ListChangedEventHandler ListChanged + { + add { _listChanged += value; } + remove { _listChanged -= value; } + } - /// - /// Occurs before an item is added to the collection. - /// - public event AddingNewEventHandler AddingNew - { - add { _addingNew += value; } - remove { _addingNew -= value; } - } + /// + /// Occurs before an item is added to the collection. + /// + public event AddingNewEventHandler AddingNew + { + add { _addingNew += value; } + remove { _addingNew -= value; } + } #endif #if SILVERLIGHT || !(NET20 || NET35 || PORTABLE40) - internal NotifyCollectionChangedEventHandler _collectionChanged; + internal NotifyCollectionChangedEventHandler _collectionChanged; - /// - /// Occurs when the items list of the collection has changed, or the collection is reset. - /// - public event NotifyCollectionChangedEventHandler CollectionChanged - { - add { _collectionChanged += value; } - remove { _collectionChanged -= value; } - } + /// + /// Occurs when the items list of the collection has changed, or the collection is reset. + /// + public event NotifyCollectionChangedEventHandler CollectionChanged + { + add { _collectionChanged += value; } + remove { _collectionChanged -= value; } + } #endif - /// - /// Gets the container's children tokens. - /// - /// The container's children tokens. - protected abstract IList ChildrenTokens { get; } + /// + /// Gets the container's children tokens. + /// + /// The container's children tokens. + protected abstract IList ChildrenTokens { get; } - private object _syncRoot; + private object _syncRoot; #if !(PORTABLE40) - private bool _busy; + private bool _busy; #endif - internal JContainer() - { - } + internal JContainer() + { + } - internal JContainer(JContainer other) - : this() - { - ValidationUtils.ArgumentNotNull(other, "c"); + internal JContainer(JContainer other) + : this() + { + ValidationUtils.ArgumentNotNull(other, "c"); - foreach (JToken child in other) - { - Add(child); - } - } + foreach (JToken child in other) + { + Add(child); + } + } - internal void CheckReentrancy() - { + internal void CheckReentrancy() + { #if !(PORTABLE40) - if (_busy) - throw new InvalidOperationException("Cannot change {0} during a collection change event.".FormatWith(CultureInfo.InvariantCulture, GetType())); + if (_busy) + throw new InvalidOperationException("Cannot change {0} during a collection change event.".FormatWith(CultureInfo.InvariantCulture, GetType())); #endif - } + } - internal virtual IList CreateChildrenCollection() - { - return new List(); - } + internal virtual IList CreateChildrenCollection() + { + return new List(); + } #if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) - /// - /// Raises the event. - /// - /// The instance containing the event data. - protected virtual void OnAddingNew(AddingNewEventArgs e) - { - AddingNewEventHandler handler = _addingNew; - if (handler != null) - handler(this, e); - } - - /// - /// Raises the event. - /// - /// The instance containing the event data. - protected virtual void OnListChanged(ListChangedEventArgs e) - { - ListChangedEventHandler handler = _listChanged; - - if (handler != null) - { - _busy = true; - try + /// + /// Raises the event. + /// + /// The instance containing the event data. + protected virtual void OnAddingNew(AddingNewEventArgs e) { - handler(this, e); + AddingNewEventHandler handler = _addingNew; + if (handler != null) + handler(this, e); } - finally + + /// + /// Raises the event. + /// + /// The instance containing the event data. + protected virtual void OnListChanged(ListChangedEventArgs e) { - _busy = false; + ListChangedEventHandler handler = _listChanged; + + if (handler != null) + { + _busy = true; + try + { + handler(this, e); + } + finally + { + _busy = false; + } + } } - } - } #endif #if SILVERLIGHT || !(NET20 || NET35 || PORTABLE40) - /// - /// Raises the event. - /// - /// The instance containing the event data. - protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e) - { - NotifyCollectionChangedEventHandler handler = _collectionChanged; + /// + /// Raises the event. + /// + /// The instance containing the event data. + protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e) + { + NotifyCollectionChangedEventHandler handler = _collectionChanged; - if (handler != null) - { - _busy = true; - try - { - handler(this, e); + if (handler != null) + { + _busy = true; + try + { + handler(this, e); + } + finally + { + _busy = false; + } + } } - finally - { - _busy = false; - } - } - } #endif - /// - /// Gets a value indicating whether this token has child tokens. - /// - /// - /// true if this token has child values; otherwise, false. - /// - public override bool HasValues - { - get { return ChildrenTokens.Count > 0; } - } - - internal bool ContentsEqual(JContainer container) - { - if (container == this) - return true; - - IList t1 = ChildrenTokens; - IList t2 = container.ChildrenTokens; - - if (t1.Count != t2.Count) - return false; - - for (int i = 0; i < t1.Count; i++) - { - if (!t1[i].DeepEquals(t2[i])) - return false; - } - - return true; - } - - /// - /// Get the first child token of this token. - /// - /// - /// A containing the first child token of the . - /// - public override JToken First - { - get { return ChildrenTokens.FirstOrDefault(); } - } - - /// - /// Get the last child token of this token. - /// - /// - /// A containing the last child token of the . - /// - public override JToken Last - { - get { return ChildrenTokens.LastOrDefault(); } - } - - /// - /// Returns a collection of the child tokens of this token, in document order. - /// - /// - /// An of containing the child tokens of this , in document order. - /// - public override JEnumerable Children() - { - return new JEnumerable(ChildrenTokens); - } - - /// - /// Returns a collection of the child values of this token, in document order. - /// - /// The type to convert the values to. - /// - /// A containing the child values of this , in document order. - /// - public override IEnumerable Values() - { - return ChildrenTokens.Convert(); - } - - /// - /// Returns a collection of the descendant tokens for this token in document order. - /// - /// An containing the descendant tokens of the . - public IEnumerable Descendants() - { - foreach (JToken o in ChildrenTokens) - { - yield return o; - JContainer c = o as JContainer; - if (c != null) + /// + /// Gets a value indicating whether this token has child tokens. + /// + /// + /// true if this token has child values; otherwise, false. + /// + public override bool HasValues { - foreach (JToken d in c.Descendants()) - { - yield return d; - } + get { return ChildrenTokens.Count > 0; } } - } - } - internal bool IsMultiContent(object content) - { - return (content is IEnumerable && !(content is string) && !(content is JToken) && !(content is byte[])); - } + internal bool ContentsEqual(JContainer container) + { + if (container == this) + return true; - internal JToken EnsureParentToken(JToken item, bool skipParentCheck) - { - if (item == null) - return new JValue((object) null); + IList t1 = ChildrenTokens; + IList t2 = container.ChildrenTokens; - if (skipParentCheck) - return item; + if (t1.Count != t2.Count) + return false; - // to avoid a token having multiple parents or creating a recursive loop, create a copy if... - // the item already has a parent - // the item is being added to itself - // the item is being added to the root parent of itself - if (item.Parent != null || item == this || (item.HasValues && Root == item)) - item = item.CloneToken(); + for (int i = 0; i < t1.Count; i++) + { + if (!t1[i].DeepEquals(t2[i])) + return false; + } - return item; - } + return true; + } - private class JTokenReferenceEqualityComparer : IEqualityComparer - { - public static readonly JTokenReferenceEqualityComparer Instance = new JTokenReferenceEqualityComparer(); + /// + /// Get the first child token of this token. + /// + /// + /// A containing the first child token of the . + /// + public override JToken First + { + get { return ChildrenTokens.FirstOrDefault(); } + } - public bool Equals(JToken x, JToken y) - { - return ReferenceEquals(x, y); - } + /// + /// Get the last child token of this token. + /// + /// + /// A containing the last child token of the . + /// + public override JToken Last + { + get { return ChildrenTokens.LastOrDefault(); } + } - public int GetHashCode(JToken obj) - { - if (obj == null) - return 0; + /// + /// Returns a collection of the child tokens of this token, in document order. + /// + /// + /// An of containing the child tokens of this , in document order. + /// + public override JEnumerable Children() + { + return new JEnumerable(ChildrenTokens); + } - return obj.GetHashCode(); - } - } + /// + /// Returns a collection of the child values of this token, in document order. + /// + /// The type to convert the values to. + /// + /// A containing the child values of this , in document order. + /// + public override IEnumerable Values() + { + return ChildrenTokens.Convert(); + } - internal int IndexOfItem(JToken item) - { - return ChildrenTokens.IndexOf(item, JTokenReferenceEqualityComparer.Instance); - } + /// + /// Returns a collection of the descendant tokens for this token in document order. + /// + /// An containing the descendant tokens of the . + public IEnumerable Descendants() + { + foreach (JToken o in ChildrenTokens) + { + yield return o; + JContainer c = o as JContainer; + if (c != null) + { + foreach (JToken d in c.Descendants()) + { + yield return d; + } + } + } + } - internal virtual void InsertItem(int index, JToken item, bool skipParentCheck) - { - if (index > ChildrenTokens.Count) - throw new ArgumentOutOfRangeException("index", "Index must be within the bounds of the List."); + internal bool IsMultiContent(object content) + { + return (content is IEnumerable && !(content is string) && !(content is JToken) && !(content is byte[])); + } - CheckReentrancy(); + internal JToken EnsureParentToken(JToken item, bool skipParentCheck) + { + if (item == null) + return new JValue((object)null); - item = EnsureParentToken(item, skipParentCheck); + if (skipParentCheck) + return item; - JToken previous = (index == 0) ? null : ChildrenTokens[index - 1]; - // haven't inserted new token yet so next token is still at the inserting index - JToken next = (index == ChildrenTokens.Count) ? null : ChildrenTokens[index]; + // to avoid a token having multiple parents or creating a recursive loop, create a copy if... + // the item already has a parent + // the item is being added to itself + // the item is being added to the root parent of itself + if (item.Parent != null || item == this || (item.HasValues && Root == item)) + item = item.CloneToken(); - ValidateToken(item, null); + return item; + } - item.Parent = this; + private class JTokenReferenceEqualityComparer : IEqualityComparer + { + public static readonly JTokenReferenceEqualityComparer Instance = new JTokenReferenceEqualityComparer(); - item.Previous = previous; - if (previous != null) - previous.Next = item; + public bool Equals(JToken x, JToken y) + { + return ReferenceEquals(x, y); + } - item.Next = next; - if (next != null) - next.Previous = item; - - ChildrenTokens.Insert(index, item); + public int GetHashCode(JToken obj) + { + if (obj == null) + return 0; + + return obj.GetHashCode(); + } + } + + internal int IndexOfItem(JToken item) + { + return ChildrenTokens.IndexOf(item, JTokenReferenceEqualityComparer.Instance); + } + + internal virtual void InsertItem(int index, JToken item, bool skipParentCheck) + { + if (index > ChildrenTokens.Count) + throw new ArgumentOutOfRangeException("index", "Index must be within the bounds of the List."); + + CheckReentrancy(); + + item = EnsureParentToken(item, skipParentCheck); + + JToken previous = (index == 0) ? null : ChildrenTokens[index - 1]; + // haven't inserted new token yet so next token is still at the inserting index + JToken next = (index == ChildrenTokens.Count) ? null : ChildrenTokens[index]; + + ValidateToken(item, null); + + item.Parent = this; + + item.Previous = previous; + if (previous != null) + previous.Next = item; + + item.Next = next; + if (next != null) + next.Previous = item; + + ChildrenTokens.Insert(index, item); #if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) - if (_listChanged != null) - OnListChanged(new ListChangedEventArgs(ListChangedType.ItemAdded, index)); + if (_listChanged != null) + OnListChanged(new ListChangedEventArgs(ListChangedType.ItemAdded, index)); #endif #if SILVERLIGHT || !(NET20 || NET35 || PORTABLE40) - if (_collectionChanged != null) - OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index)); + if (_collectionChanged != null) + OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index)); #endif - } + } - internal virtual void RemoveItemAt(int index) - { - if (index < 0) - throw new ArgumentOutOfRangeException("index", "Index is less than 0."); - if (index >= ChildrenTokens.Count) - throw new ArgumentOutOfRangeException("index", "Index is equal to or greater than Count."); + internal virtual void RemoveItemAt(int index) + { + if (index < 0) + throw new ArgumentOutOfRangeException("index", "Index is less than 0."); + if (index >= ChildrenTokens.Count) + throw new ArgumentOutOfRangeException("index", "Index is equal to or greater than Count."); - CheckReentrancy(); + CheckReentrancy(); - JToken item = ChildrenTokens[index]; - JToken previous = (index == 0) ? null : ChildrenTokens[index - 1]; - JToken next = (index == ChildrenTokens.Count - 1) ? null : ChildrenTokens[index + 1]; + JToken item = ChildrenTokens[index]; + JToken previous = (index == 0) ? null : ChildrenTokens[index - 1]; + JToken next = (index == ChildrenTokens.Count - 1) ? null : ChildrenTokens[index + 1]; - if (previous != null) - previous.Next = next; - if (next != null) - next.Previous = previous; + if (previous != null) + previous.Next = next; + if (next != null) + next.Previous = previous; - item.Parent = null; - item.Previous = null; - item.Next = null; + item.Parent = null; + item.Previous = null; + item.Next = null; - ChildrenTokens.RemoveAt(index); + ChildrenTokens.RemoveAt(index); #if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) - if (_listChanged != null) - OnListChanged(new ListChangedEventArgs(ListChangedType.ItemDeleted, index)); + if (_listChanged != null) + OnListChanged(new ListChangedEventArgs(ListChangedType.ItemDeleted, index)); #endif #if SILVERLIGHT || !(NET20 || NET35 || PORTABLE40) - if (_collectionChanged != null) - OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, index)); + if (_collectionChanged != null) + OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, index)); #endif - } + } - internal virtual bool RemoveItem(JToken item) - { - int index = IndexOfItem(item); - if (index >= 0) - { - RemoveItemAt(index); - return true; - } + internal virtual bool RemoveItem(JToken item) + { + int index = IndexOfItem(item); + if (index >= 0) + { + RemoveItemAt(index); + return true; + } - return false; - } + return false; + } - internal virtual JToken GetItem(int index) - { - return ChildrenTokens[index]; - } + internal virtual JToken GetItem(int index) + { + return ChildrenTokens[index]; + } - internal virtual void SetItem(int index, JToken item) - { - if (index < 0) - throw new ArgumentOutOfRangeException("index", "Index is less than 0."); - if (index >= ChildrenTokens.Count) - throw new ArgumentOutOfRangeException("index", "Index is equal to or greater than Count."); + internal virtual void SetItem(int index, JToken item) + { + if (index < 0) + throw new ArgumentOutOfRangeException("index", "Index is less than 0."); + if (index >= ChildrenTokens.Count) + throw new ArgumentOutOfRangeException("index", "Index is equal to or greater than Count."); - JToken existing = ChildrenTokens[index]; + JToken existing = ChildrenTokens[index]; - if (IsTokenUnchanged(existing, item)) - return; + if (IsTokenUnchanged(existing, item)) + return; - CheckReentrancy(); + CheckReentrancy(); - item = EnsureParentToken(item, false); + item = EnsureParentToken(item, false); - ValidateToken(item, existing); + ValidateToken(item, existing); - JToken previous = (index == 0) ? null : ChildrenTokens[index - 1]; - JToken next = (index == ChildrenTokens.Count - 1) ? null : ChildrenTokens[index + 1]; + JToken previous = (index == 0) ? null : ChildrenTokens[index - 1]; + JToken next = (index == ChildrenTokens.Count - 1) ? null : ChildrenTokens[index + 1]; - item.Parent = this; + item.Parent = this; - item.Previous = previous; - if (previous != null) - previous.Next = item; + item.Previous = previous; + if (previous != null) + previous.Next = item; - item.Next = next; - if (next != null) - next.Previous = item; + item.Next = next; + if (next != null) + next.Previous = item; - ChildrenTokens[index] = item; + ChildrenTokens[index] = item; - existing.Parent = null; - existing.Previous = null; - existing.Next = null; + existing.Parent = null; + existing.Previous = null; + existing.Next = null; #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - if (_listChanged != null) - OnListChanged(new ListChangedEventArgs(ListChangedType.ItemChanged, index)); + if (_listChanged != null) + OnListChanged(new ListChangedEventArgs(ListChangedType.ItemChanged, index)); #endif #if SILVERLIGHT || !(NET20 || NET35 || PORTABLE40) - if (_collectionChanged != null) - OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, item, existing, index)); + if (_collectionChanged != null) + OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, item, existing, index)); #endif - } + } - internal virtual void ClearItems() - { - CheckReentrancy(); + internal virtual void ClearItems() + { + CheckReentrancy(); - foreach (JToken item in ChildrenTokens) - { - item.Parent = null; - item.Previous = null; - item.Next = null; - } + foreach (JToken item in ChildrenTokens) + { + item.Parent = null; + item.Previous = null; + item.Next = null; + } - ChildrenTokens.Clear(); + ChildrenTokens.Clear(); #if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) - if (_listChanged != null) - OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1)); + if (_listChanged != null) + OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1)); #endif #if SILVERLIGHT || !(NET20 || NET35 || PORTABLE40) - if (_collectionChanged != null) - OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); + if (_collectionChanged != null) + OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); #endif - } - - internal virtual void ReplaceItem(JToken existing, JToken replacement) - { - if (existing == null || existing.Parent != this) - return; - - int index = IndexOfItem(existing); - SetItem(index, replacement); - } - - internal virtual bool ContainsItem(JToken item) - { - return (IndexOfItem(item) != -1); - } - - internal virtual void CopyItemsTo(Array array, int arrayIndex) - { - if (array == null) - throw new ArgumentNullException("array"); - if (arrayIndex < 0) - throw new ArgumentOutOfRangeException("arrayIndex", "arrayIndex is less than 0."); - if (arrayIndex >= array.Length && arrayIndex != 0) - throw new ArgumentException("arrayIndex is equal to or greater than the length of array."); - if (Count > array.Length - arrayIndex) - throw new ArgumentException("The number of elements in the source JObject is greater than the available space from arrayIndex to the end of the destination array."); - - int index = 0; - foreach (JToken token in ChildrenTokens) - { - array.SetValue(token, arrayIndex + index); - index++; - } - } - - internal static bool IsTokenUnchanged(JToken currentValue, JToken newValue) - { - JValue v1 = currentValue as JValue; - if (v1 != null) - { - // null will get turned into a JValue of type null - if (v1.Type == JTokenType.Null && newValue == null) - return true; - - return v1.Equals(newValue); - } - - return false; - } - - internal virtual void ValidateToken(JToken o, JToken existing) - { - ValidationUtils.ArgumentNotNull(o, "o"); - - if (o.Type == JTokenType.Property) - throw new ArgumentException("Can not add {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, o.GetType(), GetType())); - } - - /// - /// Adds the specified content as children of this . - /// - /// The content to be added. - public virtual void Add(object content) - { - AddInternal(ChildrenTokens.Count, content, false); - } - - internal void AddAndSkipParentCheck(JToken token) - { - AddInternal(ChildrenTokens.Count, token, true); - } - - /// - /// Adds the specified content as the first children of this . - /// - /// The content to be added. - public void AddFirst(object content) - { - AddInternal(0, content, false); - } - - internal void AddInternal(int index, object content, bool skipParentCheck) - { - if (IsMultiContent(content)) - { - IEnumerable enumerable = (IEnumerable)content; - - int multiIndex = index; - foreach (object c in enumerable) - { - AddInternal(multiIndex, c, skipParentCheck); - multiIndex++; - } - } - else - { - JToken item = CreateFromContent(content); - - InsertItem(index, item, skipParentCheck); - } - } - - internal JToken CreateFromContent(object content) - { - if (content is JToken) - return (JToken)content; - - return new JValue(content); - } - - /// - /// Creates an that can be used to add tokens to the . - /// - /// An that is ready to have content written to it. - public JsonWriter CreateWriter() - { - return new JTokenWriter(this); - } - - /// - /// Replaces the children nodes of this token with the specified content. - /// - /// The content. - public void ReplaceAll(object content) - { - ClearItems(); - Add(content); - } - - /// - /// Removes the child nodes from this token. - /// - public void RemoveAll() - { - ClearItems(); - } - - internal void ReadTokenFrom(JsonReader reader) - { - int startDepth = reader.Depth; - - if (!reader.Read()) - throw JsonReaderException.Create(reader, "Error reading {0} from JsonReader.".FormatWith(CultureInfo.InvariantCulture, GetType().Name)); - - ReadContentFrom(reader); - - int endDepth = reader.Depth; - - if (endDepth > startDepth) - throw JsonReaderException.Create(reader, "Unexpected end of content while loading {0}.".FormatWith(CultureInfo.InvariantCulture, GetType().Name)); - } - - internal void ReadContentFrom(JsonReader r) - { - ValidationUtils.ArgumentNotNull(r, "r"); - IJsonLineInfo lineInfo = r as IJsonLineInfo; - - JContainer parent = this; - - do - { - if (parent is JProperty && ((JProperty)parent).Value != null) - { - if (parent == this) - return; - - parent = parent.Parent; } - switch (r.TokenType) + internal virtual void ReplaceItem(JToken existing, JToken replacement) { - case JsonToken.None: - // new reader. move to actual content - break; - case JsonToken.StartArray: - JArray a = new JArray(); - a.SetLineInfo(lineInfo); - parent.Add(a); - parent = a; - break; + if (existing == null || existing.Parent != this) + return; - case JsonToken.EndArray: - if (parent == this) - return; + int index = IndexOfItem(existing); + SetItem(index, replacement); + } - parent = parent.Parent; - break; - case JsonToken.StartObject: - JObject o = new JObject(); - o.SetLineInfo(lineInfo); - parent.Add(o); - parent = o; - break; - case JsonToken.EndObject: - if (parent == this) - return; + internal virtual bool ContainsItem(JToken item) + { + return (IndexOfItem(item) != -1); + } - parent = parent.Parent; - break; - case JsonToken.StartConstructor: - JConstructor constructor = new JConstructor(r.Value.ToString()); - constructor.SetLineInfo(constructor); - parent.Add(constructor); - parent = constructor; - break; - case JsonToken.EndConstructor: - if (parent == this) - return; + internal virtual void CopyItemsTo(Array array, int arrayIndex) + { + if (array == null) + throw new ArgumentNullException("array"); + if (arrayIndex < 0) + throw new ArgumentOutOfRangeException("arrayIndex", "arrayIndex is less than 0."); + if (arrayIndex >= array.Length && arrayIndex != 0) + throw new ArgumentException("arrayIndex is equal to or greater than the length of array."); + if (Count > array.Length - arrayIndex) + throw new ArgumentException("The number of elements in the source JObject is greater than the available space from arrayIndex to the end of the destination array."); - parent = parent.Parent; - break; - case JsonToken.String: - case JsonToken.Integer: - case JsonToken.Float: - case JsonToken.Date: - case JsonToken.Boolean: - case JsonToken.Bytes: - JValue v = new JValue(r.Value); - v.SetLineInfo(lineInfo); - parent.Add(v); - break; - case JsonToken.Comment: - v = JValue.CreateComment(r.Value.ToString()); - v.SetLineInfo(lineInfo); - parent.Add(v); - break; - case JsonToken.Null: - v = new JValue(null, JTokenType.Null); - v.SetLineInfo(lineInfo); - parent.Add(v); - break; - case JsonToken.Undefined: - v = new JValue(null, JTokenType.Undefined); - v.SetLineInfo(lineInfo); - parent.Add(v); - break; - case JsonToken.PropertyName: - string propertyName = r.Value.ToString(); - JProperty property = new JProperty(propertyName); - property.SetLineInfo(lineInfo); - JObject parentObject = (JObject) parent; - // handle multiple properties with the same name in JSON - JProperty existingPropertyWithName = parentObject.Property(propertyName); - if (existingPropertyWithName == null) - parent.Add(property); + int index = 0; + foreach (JToken token in ChildrenTokens) + { + array.SetValue(token, arrayIndex + index); + index++; + } + } + + internal static bool IsTokenUnchanged(JToken currentValue, JToken newValue) + { + JValue v1 = currentValue as JValue; + if (v1 != null) + { + // null will get turned into a JValue of type null + if (v1.Type == JTokenType.Null && newValue == null) + return true; + + return v1.Equals(newValue); + } + + return false; + } + + internal virtual void ValidateToken(JToken o, JToken existing) + { + ValidationUtils.ArgumentNotNull(o, "o"); + + if (o.Type == JTokenType.Property) + throw new ArgumentException("Can not add {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, o.GetType(), GetType())); + } + + /// + /// Adds the specified content as children of this . + /// + /// The content to be added. + public virtual void Add(object content) + { + AddInternal(ChildrenTokens.Count, content, false); + } + + internal void AddAndSkipParentCheck(JToken token) + { + AddInternal(ChildrenTokens.Count, token, true); + } + + /// + /// Adds the specified content as the first children of this . + /// + /// The content to be added. + public void AddFirst(object content) + { + AddInternal(0, content, false); + } + + internal void AddInternal(int index, object content, bool skipParentCheck) + { + if (IsMultiContent(content)) + { + IEnumerable enumerable = (IEnumerable)content; + + int multiIndex = index; + foreach (object c in enumerable) + { + AddInternal(multiIndex, c, skipParentCheck); + multiIndex++; + } + } else - existingPropertyWithName.Replace(property); - parent = property; - break; - default: - throw new InvalidOperationException("The JsonReader should not be on a token of type {0}.".FormatWith(CultureInfo.InvariantCulture, r.TokenType)); - } - } - while (r.Read()); - } + { + JToken item = CreateFromContent(content); - internal int ContentsHashCode() - { - int hashCode = 0; - foreach (JToken item in ChildrenTokens) - { - hashCode ^= item.GetDeepHashCode(); - } - return hashCode; - } + InsertItem(index, item, skipParentCheck); + } + } + + internal JToken CreateFromContent(object content) + { + if (content is JToken) + return (JToken)content; + + return new JValue(content); + } + + /// + /// Creates an that can be used to add tokens to the . + /// + /// An that is ready to have content written to it. + public JsonWriter CreateWriter() + { + return new JTokenWriter(this); + } + + /// + /// Replaces the children nodes of this token with the specified content. + /// + /// The content. + public void ReplaceAll(object content) + { + ClearItems(); + Add(content); + } + + /// + /// Removes the child nodes from this token. + /// + public void RemoveAll() + { + ClearItems(); + } + + internal void ReadTokenFrom(JsonReader reader) + { + int startDepth = reader.Depth; + + if (!reader.Read()) + throw JsonReaderException.Create(reader, "Error reading {0} from JsonReader.".FormatWith(CultureInfo.InvariantCulture, GetType().Name)); + + ReadContentFrom(reader); + + int endDepth = reader.Depth; + + if (endDepth > startDepth) + throw JsonReaderException.Create(reader, "Unexpected end of content while loading {0}.".FormatWith(CultureInfo.InvariantCulture, GetType().Name)); + } + + internal void ReadContentFrom(JsonReader r) + { + ValidationUtils.ArgumentNotNull(r, "r"); + IJsonLineInfo lineInfo = r as IJsonLineInfo; + + JContainer parent = this; + + do + { + if (parent is JProperty && ((JProperty)parent).Value != null) + { + if (parent == this) + return; + + parent = parent.Parent; + } + + switch (r.TokenType) + { + case JsonToken.None: + // new reader. move to actual content + break; + case JsonToken.StartArray: + JArray a = new JArray(); + a.SetLineInfo(lineInfo); + parent.Add(a); + parent = a; + break; + + case JsonToken.EndArray: + if (parent == this) + return; + + parent = parent.Parent; + break; + case JsonToken.StartObject: + JObject o = new JObject(); + o.SetLineInfo(lineInfo); + parent.Add(o); + parent = o; + break; + case JsonToken.EndObject: + if (parent == this) + return; + + parent = parent.Parent; + break; + case JsonToken.StartConstructor: + JConstructor constructor = new JConstructor(r.Value.ToString()); + constructor.SetLineInfo(constructor); + parent.Add(constructor); + parent = constructor; + break; + case JsonToken.EndConstructor: + if (parent == this) + return; + + parent = parent.Parent; + break; + case JsonToken.String: + case JsonToken.Integer: + case JsonToken.Float: + case JsonToken.Date: + case JsonToken.Boolean: + case JsonToken.Bytes: + JValue v = new JValue(r.Value); + v.SetLineInfo(lineInfo); + parent.Add(v); + break; + case JsonToken.Comment: + v = JValue.CreateComment(r.Value.ToString()); + v.SetLineInfo(lineInfo); + parent.Add(v); + break; + case JsonToken.Null: + v = new JValue(null, JTokenType.Null); + v.SetLineInfo(lineInfo); + parent.Add(v); + break; + case JsonToken.Undefined: + v = new JValue(null, JTokenType.Undefined); + v.SetLineInfo(lineInfo); + parent.Add(v); + break; + case JsonToken.PropertyName: + string propertyName = r.Value.ToString(); + JProperty property = new JProperty(propertyName); + property.SetLineInfo(lineInfo); + JObject parentObject = (JObject)parent; + // handle multiple properties with the same name in JSON + JProperty existingPropertyWithName = parentObject.Property(propertyName); + if (existingPropertyWithName == null) + parent.Add(property); + else + existingPropertyWithName.Replace(property); + parent = property; + break; + default: + throw new InvalidOperationException("The JsonReader should not be on a token of type {0}.".FormatWith(CultureInfo.InvariantCulture, r.TokenType)); + } + } while (r.Read()); + } + + internal int ContentsHashCode() + { + int hashCode = 0; + foreach (JToken item in ChildrenTokens) + { + hashCode ^= item.GetDeepHashCode(); + } + return hashCode; + } #if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) - string ITypedList.GetListName(PropertyDescriptor[] listAccessors) - { - return string.Empty; - } + string ITypedList.GetListName(PropertyDescriptor[] listAccessors) + { + return string.Empty; + } - PropertyDescriptorCollection ITypedList.GetItemProperties(PropertyDescriptor[] listAccessors) - { - ICustomTypeDescriptor d = First as ICustomTypeDescriptor; - if (d != null) - return d.GetProperties(); + PropertyDescriptorCollection ITypedList.GetItemProperties(PropertyDescriptor[] listAccessors) + { + ICustomTypeDescriptor d = First as ICustomTypeDescriptor; + if (d != null) + return d.GetProperties(); - return null; - } + return null; + } #endif - #region IList Members + #region IList Members + int IList.IndexOf(JToken item) + { + return IndexOfItem(item); + } - int IList.IndexOf(JToken item) - { - return IndexOfItem(item); - } + void IList.Insert(int index, JToken item) + { + InsertItem(index, item, false); + } - void IList.Insert(int index, JToken item) - { - InsertItem(index, item, false); - } + void IList.RemoveAt(int index) + { + RemoveItemAt(index); + } - void IList.RemoveAt(int index) - { - RemoveItemAt(index); - } + JToken IList.this[int index] + { + get { return GetItem(index); } + set { SetItem(index, value); } + } + #endregion - JToken IList.this[int index] - { - get { return GetItem(index); } - set { SetItem(index, value); } - } + #region ICollection Members + void ICollection.Add(JToken item) + { + Add(item); + } - #endregion + void ICollection.Clear() + { + ClearItems(); + } - #region ICollection Members + bool ICollection.Contains(JToken item) + { + return ContainsItem(item); + } - void ICollection.Add(JToken item) - { - Add(item); - } + void ICollection.CopyTo(JToken[] array, int arrayIndex) + { + CopyItemsTo(array, arrayIndex); + } - void ICollection.Clear() - { - ClearItems(); - } + bool ICollection.IsReadOnly + { + get { return false; } + } - bool ICollection.Contains(JToken item) - { - return ContainsItem(item); - } + bool ICollection.Remove(JToken item) + { + return RemoveItem(item); + } + #endregion - void ICollection.CopyTo(JToken[] array, int arrayIndex) - { - CopyItemsTo(array, arrayIndex); - } + private JToken EnsureValue(object value) + { + if (value == null) + return null; - bool ICollection.IsReadOnly - { - get { return false; } - } + if (value is JToken) + return (JToken)value; - bool ICollection.Remove(JToken item) - { - return RemoveItem(item); - } + throw new ArgumentException("Argument is not a JToken."); + } - #endregion + #region IList Members + int IList.Add(object value) + { + Add(EnsureValue(value)); + return Count - 1; + } - private JToken EnsureValue(object value) - { - if (value == null) - return null; + void IList.Clear() + { + ClearItems(); + } - if (value is JToken) - return (JToken) value; + bool IList.Contains(object value) + { + return ContainsItem(EnsureValue(value)); + } - throw new ArgumentException("Argument is not a JToken."); - } + int IList.IndexOf(object value) + { + return IndexOfItem(EnsureValue(value)); + } - #region IList Members + void IList.Insert(int index, object value) + { + InsertItem(index, EnsureValue(value), false); + } - int IList.Add(object value) - { - Add(EnsureValue(value)); - return Count - 1; - } + bool IList.IsFixedSize + { + get { return false; } + } - void IList.Clear() - { - ClearItems(); - } + bool IList.IsReadOnly + { + get { return false; } + } - bool IList.Contains(object value) - { - return ContainsItem(EnsureValue(value)); - } + void IList.Remove(object value) + { + RemoveItem(EnsureValue(value)); + } - int IList.IndexOf(object value) - { - return IndexOfItem(EnsureValue(value)); - } + void IList.RemoveAt(int index) + { + RemoveItemAt(index); + } - void IList.Insert(int index, object value) - { - InsertItem(index, EnsureValue(value), false); - } + object IList.this[int index] + { + get { return GetItem(index); } + set { SetItem(index, EnsureValue(value)); } + } + #endregion - bool IList.IsFixedSize - { - get { return false; } - } + #region ICollection Members + void ICollection.CopyTo(Array array, int index) + { + CopyItemsTo(array, index); + } - bool IList.IsReadOnly - { - get { return false; } - } + /// + /// Gets the count of child JSON tokens. + /// + /// The count of child JSON tokens + public int Count + { + get { return ChildrenTokens.Count; } + } - void IList.Remove(object value) - { - RemoveItem(EnsureValue(value)); - } + bool ICollection.IsSynchronized + { + get { return false; } + } - void IList.RemoveAt(int index) - { - RemoveItemAt(index); - } + object ICollection.SyncRoot + { + get + { + if (_syncRoot == null) + Interlocked.CompareExchange(ref _syncRoot, new object(), null); - object IList.this[int index] - { - get { return GetItem(index); } - set { SetItem(index, EnsureValue(value)); } - } - - #endregion - - #region ICollection Members - - void ICollection.CopyTo(Array array, int index) - { - CopyItemsTo(array, index); - } - - /// - /// Gets the count of child JSON tokens. - /// - /// The count of child JSON tokens - public int Count - { - get { return ChildrenTokens.Count; } - } - - bool ICollection.IsSynchronized - { - get { return false; } - } - - object ICollection.SyncRoot - { - get - { - if (_syncRoot == null) - Interlocked.CompareExchange(ref _syncRoot, new object(), null); - - return _syncRoot; - } - - } - - #endregion - - #region IBindingList Members + return _syncRoot; + } + } + #endregion + #region IBindingList Members #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - void IBindingList.AddIndex(PropertyDescriptor property) - { - } + void IBindingList.AddIndex(PropertyDescriptor property) + { + } - object IBindingList.AddNew() - { - AddingNewEventArgs args = new AddingNewEventArgs(); - OnAddingNew(args); + object IBindingList.AddNew() + { + AddingNewEventArgs args = new AddingNewEventArgs(); + OnAddingNew(args); - if (args.NewObject == null) - throw new JsonException("Could not determine new value to add to '{0}'.".FormatWith(CultureInfo.InvariantCulture, GetType())); + if (args.NewObject == null) + throw new JsonException("Could not determine new value to add to '{0}'.".FormatWith(CultureInfo.InvariantCulture, GetType())); - if (!(args.NewObject is JToken)) - throw new JsonException("New item to be added to collection must be compatible with {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JToken))); + if (!(args.NewObject is JToken)) + throw new JsonException("New item to be added to collection must be compatible with {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JToken))); - JToken newItem = (JToken)args.NewObject; - Add(newItem); + JToken newItem = (JToken)args.NewObject; + Add(newItem); - return newItem; - } + return newItem; + } - bool IBindingList.AllowEdit - { - get { return true; } - } + bool IBindingList.AllowEdit + { + get { return true; } + } - bool IBindingList.AllowNew - { - get { return true; } - } + bool IBindingList.AllowNew + { + get { return true; } + } - bool IBindingList.AllowRemove - { - get { return true; } - } + bool IBindingList.AllowRemove + { + get { return true; } + } - void IBindingList.ApplySort(PropertyDescriptor property, ListSortDirection direction) - { - throw new NotSupportedException(); - } + void IBindingList.ApplySort(PropertyDescriptor property, ListSortDirection direction) + { + throw new NotSupportedException(); + } - int IBindingList.Find(PropertyDescriptor property, object key) - { - throw new NotSupportedException(); - } + int IBindingList.Find(PropertyDescriptor property, object key) + { + throw new NotSupportedException(); + } - bool IBindingList.IsSorted - { - get { return false; } - } + bool IBindingList.IsSorted + { + get { return false; } + } - void IBindingList.RemoveIndex(PropertyDescriptor property) - { - } + void IBindingList.RemoveIndex(PropertyDescriptor property) + { + } - void IBindingList.RemoveSort() - { - throw new NotSupportedException(); - } + void IBindingList.RemoveSort() + { + throw new NotSupportedException(); + } - ListSortDirection IBindingList.SortDirection - { - get { return ListSortDirection.Ascending; } - } + ListSortDirection IBindingList.SortDirection + { + get { return ListSortDirection.Ascending; } + } - PropertyDescriptor IBindingList.SortProperty - { - get { return null; } - } + PropertyDescriptor IBindingList.SortProperty + { + get { return null; } + } - bool IBindingList.SupportsChangeNotification - { - get { return true; } - } + bool IBindingList.SupportsChangeNotification + { + get { return true; } + } - bool IBindingList.SupportsSearching - { - get { return false; } - } + bool IBindingList.SupportsSearching + { + get { return false; } + } - bool IBindingList.SupportsSorting - { - get { return false; } - } + bool IBindingList.SupportsSorting + { + get { return false; } + } #endif - - #endregion - } + #endregion + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Linq/JEnumerable.cs b/Src/Newtonsoft.Json/Linq/JEnumerable.cs index d29b5ea0..403eea63 100644 --- a/Src/Newtonsoft.Json/Linq/JEnumerable.cs +++ b/Src/Newtonsoft.Json/Linq/JEnumerable.cs @@ -34,85 +34,85 @@ using System.Collections; namespace Newtonsoft.Json.Linq { - /// - /// Represents a collection of objects. - /// - /// The type of token - public struct JEnumerable : IJEnumerable where T : JToken - { /// - /// An empty collection of objects. + /// Represents a collection of objects. /// - public static readonly JEnumerable Empty = new JEnumerable(Enumerable.Empty()); - - private readonly IEnumerable _enumerable; - - /// - /// Initializes a new instance of the struct. - /// - /// The enumerable. - public JEnumerable(IEnumerable enumerable) + /// The type of token + public struct JEnumerable : IJEnumerable where T : JToken { - ValidationUtils.ArgumentNotNull(enumerable, "enumerable"); + /// + /// An empty collection of objects. + /// + public static readonly JEnumerable Empty = new JEnumerable(Enumerable.Empty()); - _enumerable = enumerable; + private readonly IEnumerable _enumerable; + + /// + /// Initializes a new instance of the struct. + /// + /// The enumerable. + public JEnumerable(IEnumerable enumerable) + { + ValidationUtils.ArgumentNotNull(enumerable, "enumerable"); + + _enumerable = enumerable; + } + + /// + /// Returns an enumerator that iterates through the collection. + /// + /// + /// A that can be used to iterate through the collection. + /// + public IEnumerator GetEnumerator() + { + return _enumerable.GetEnumerator(); + } + + /// + /// Returns an enumerator that iterates through a collection. + /// + /// + /// An object that can be used to iterate through the collection. + /// + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + /// + /// Gets the with the specified key. + /// + /// + public IJEnumerable this[object key] + { + get { return new JEnumerable(Extensions.Values(_enumerable, key)); } + } + + /// + /// Determines whether the specified is equal to this instance. + /// + /// The to compare with this instance. + /// + /// true if the specified is equal to this instance; otherwise, false. + /// + public override bool Equals(object obj) + { + if (obj is JEnumerable) + return _enumerable.Equals(((JEnumerable)obj)._enumerable); + + return false; + } + + /// + /// Returns a hash code for this instance. + /// + /// + /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. + /// + public override int GetHashCode() + { + return _enumerable.GetHashCode(); + } } - - /// - /// Returns an enumerator that iterates through the collection. - /// - /// - /// A that can be used to iterate through the collection. - /// - public IEnumerator GetEnumerator() - { - return _enumerable.GetEnumerator(); - } - - /// - /// Returns an enumerator that iterates through a collection. - /// - /// - /// An object that can be used to iterate through the collection. - /// - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - /// - /// Gets the with the specified key. - /// - /// - public IJEnumerable this[object key] - { - get { return new JEnumerable(Extensions.Values(_enumerable, key)); } - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public override bool Equals(object obj) - { - if (obj is JEnumerable) - return _enumerable.Equals(((JEnumerable)obj)._enumerable); - - return false; - } - - /// - /// Returns a hash code for this instance. - /// - /// - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - /// - public override int GetHashCode() - { - return _enumerable.GetHashCode(); - } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Linq/JObject.cs b/Src/Newtonsoft.Json/Linq/JObject.cs index c22240c6..68a709c8 100644 --- a/Src/Newtonsoft.Json/Linq/JObject.cs +++ b/Src/Newtonsoft.Json/Linq/JObject.cs @@ -41,761 +41,761 @@ using System.Globalization; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json.Linq { - /// - /// Represents a JSON object. - /// - /// - /// - /// - public class JObject : JContainer, IDictionary, INotifyPropertyChanged -#if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) - , ICustomTypeDescriptor -#endif -#if !(SILVERLIGHT || NET20 || NETFX_CORE || PORTABLE40 || PORTABLE) - , INotifyPropertyChanging -#endif - { - private readonly JPropertyKeyedCollection _properties = new JPropertyKeyedCollection(); - /// - /// Gets the container's children tokens. + /// Represents a JSON object. /// - /// The container's children tokens. - protected override IList ChildrenTokens - { - get { return _properties; } - } - - /// - /// Occurs when a property value changes. - /// - public event PropertyChangedEventHandler PropertyChanged; - -#if !(SILVERLIGHT || NET20 || NETFX_CORE || PORTABLE || PORTABLE40) - /// - /// Occurs when a property value is changing. - /// - public event PropertyChangingEventHandler PropertyChanging; -#endif - - /// - /// Initializes a new instance of the class. - /// - public JObject() - { - } - - /// - /// Initializes a new instance of the class from another object. - /// - /// A object to copy from. - public JObject(JObject other) - : base(other) - { - } - - /// - /// Initializes a new instance of the class with the specified content. - /// - /// The contents of the object. - public JObject(params object[] content) - : this((object)content) - { - } - - /// - /// Initializes a new instance of the class with the specified content. - /// - /// The contents of the object. - public JObject(object content) - { - Add(content); - } - - internal override bool DeepEquals(JToken node) - { - JObject t = node as JObject; - if (t == null) - return false; - - return _properties.Compare(t._properties); - } - - internal override void InsertItem(int index, JToken item, bool skipParentCheck) - { - // don't add comments to JObject, no name to reference comment by - if (item != null && item.Type == JTokenType.Comment) - return; - - base.InsertItem(index, item, skipParentCheck); - } - - internal override void ValidateToken(JToken o, JToken existing) - { - ValidationUtils.ArgumentNotNull(o, "o"); - - if (o.Type != JTokenType.Property) - throw new ArgumentException("Can not add {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, o.GetType(), GetType())); - - JProperty newProperty = (JProperty) o; - - if (existing != null) - { - JProperty existingProperty = (JProperty) existing; - - if (newProperty.Name == existingProperty.Name) - return; - } - - if (_properties.TryGetValue(newProperty.Name, out existing)) - throw new ArgumentException("Can not add property {0} to {1}. Property with the same name already exists on object.".FormatWith(CultureInfo.InvariantCulture, newProperty.Name, GetType())); - } - - internal void InternalPropertyChanged(JProperty childProperty) - { - OnPropertyChanged(childProperty.Name); -#if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) - if (_listChanged != null) - OnListChanged(new ListChangedEventArgs(ListChangedType.ItemChanged, IndexOfItem(childProperty))); -#endif -#if SILVERLIGHT || !(NET20 || NET35 || PORTABLE40) - if (_collectionChanged != null) - OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, childProperty, childProperty, IndexOfItem(childProperty))); -#endif - } - - internal void InternalPropertyChanging(JProperty childProperty) - { -#if !(SILVERLIGHT || NET20 || NETFX_CORE || PORTABLE40 || PORTABLE) - OnPropertyChanging(childProperty.Name); -#endif - } - - internal override JToken CloneToken() - { - return new JObject(this); - } - - /// - /// Gets the node type for this . - /// - /// The type. - public override JTokenType Type - { - get { return JTokenType.Object; } - } - - /// - /// Gets an of this object's properties. - /// - /// An of this object's properties. - public IEnumerable Properties() - { - return _properties.Cast(); - } - - /// - /// Gets a the specified name. - /// - /// The property name. - /// A with the specified name or null. - public JProperty Property(string name) - { - if (name == null) - return null; - - JToken property; - _properties.TryGetValue(name, out property); - return (JProperty)property; - } - - /// - /// Gets an of this object's property values. - /// - /// An of this object's property values. - public JEnumerable PropertyValues() - { - return new JEnumerable(Properties().Select(p => p.Value)); - } - - /// - /// Gets the with the specified key. - /// - /// The with the specified key. - public override JToken this[object key] - { - get - { - ValidationUtils.ArgumentNotNull(key, "o"); - - string propertyName = key as string; - if (propertyName == null) - throw new ArgumentException("Accessed JObject values with invalid key value: {0}. Object property name expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key))); - - return this[propertyName]; - } - set - { - ValidationUtils.ArgumentNotNull(key, "o"); - - string propertyName = key as string; - if (propertyName == null) - throw new ArgumentException("Set JObject values with invalid key value: {0}. Object property name expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key))); - - this[propertyName] = value; - } - } - - /// - /// Gets or sets the with the specified property name. - /// - /// - public JToken this[string propertyName] - { - get - { - ValidationUtils.ArgumentNotNull(propertyName, "propertyName"); - - JProperty property = Property(propertyName); - - return (property != null) ? property.Value : null; - } - set - { - JProperty property = Property(propertyName); - if (property != null) - { - property.Value = value; - } - else - { -#if !(SILVERLIGHT || NET20 || NETFX_CORE || PORTABLE40 || PORTABLE) - OnPropertyChanging(propertyName); -#endif - Add(new JProperty(propertyName, value)); - OnPropertyChanged(propertyName); - } - } - } - - /// - /// Loads an from a . - /// - /// A that will be read for the content of the . - /// A that contains the JSON that was read from the specified . - public static new JObject Load(JsonReader reader) - { - ValidationUtils.ArgumentNotNull(reader, "reader"); - - if (reader.TokenType == JsonToken.None) - { - if (!reader.Read()) - throw JsonReaderException.Create(reader, "Error reading JObject from JsonReader."); - } - - while (reader.TokenType == JsonToken.Comment) - { - reader.Read(); - } - - if (reader.TokenType != JsonToken.StartObject) - { - throw JsonReaderException.Create(reader, "Error reading JObject from JsonReader. Current JsonReader item is not an object: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); - } - - JObject o = new JObject(); - o.SetLineInfo(reader as IJsonLineInfo); - - o.ReadTokenFrom(reader); - - return o; - } - - /// - /// Load a from a string that contains JSON. - /// - /// A that contains JSON. - /// A populated from the string that contains JSON. /// /// /// - public static new JObject Parse(string json) + public class JObject : JContainer, IDictionary, INotifyPropertyChanged +#if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) + , ICustomTypeDescriptor +#endif +#if !(SILVERLIGHT || NET20 || NETFX_CORE || PORTABLE40 || PORTABLE) + , INotifyPropertyChanging +#endif { - JsonReader reader = new JsonTextReader(new StringReader(json)); + private readonly JPropertyKeyedCollection _properties = new JPropertyKeyedCollection(); - JObject o = Load(reader); - - if (reader.Read() && reader.TokenType != JsonToken.Comment) - throw JsonReaderException.Create(reader, "Additional text found in JSON string after parsing content."); - - return o; - } - - /// - /// Creates a from an object. - /// - /// The object that will be used to create . - /// A with the values of the specified object - public static new JObject FromObject(object o) - { - return FromObject(o, JsonSerializer.CreateDefault()); - } - - /// - /// Creates a from an object. - /// - /// The object that will be used to create . - /// The that will be used to read the object. - /// A with the values of the specified object - public static new JObject FromObject(object o, JsonSerializer jsonSerializer) - { - JToken token = FromObjectInternal(o, jsonSerializer); - - if (token != null && token.Type != JTokenType.Object) - throw new ArgumentException("Object serialized to {0}. JObject instance expected.".FormatWith(CultureInfo.InvariantCulture, token.Type)); - - return (JObject)token; - } - - /// - /// Writes this token to a . - /// - /// A into which this method will write. - /// A collection of which will be used when writing the token. - public override void WriteTo(JsonWriter writer, params JsonConverter[] converters) - { - writer.WriteStartObject(); - - for (int i = 0; i < _properties.Count; i++) - { - _properties[i].WriteTo(writer, converters); - } - - writer.WriteEndObject(); - } - - /// - /// Gets the with the specified property name. - /// - /// Name of the property. - /// The with the specified property name. - public JToken GetValue(string propertyName) - { - return GetValue(propertyName, StringComparison.Ordinal); - } - - /// - /// Gets the with the specified property name. - /// The exact property name will be searched for first and if no matching property is found then - /// the will be used to match a property. - /// - /// Name of the property. - /// One of the enumeration values that specifies how the strings will be compared. - /// The with the specified property name. - public JToken GetValue(string propertyName, StringComparison comparison) - { - if (propertyName == null) - return null; - - // attempt to get value via dictionary first for performance - JProperty property = Property(propertyName); - if (property != null) - return property.Value; - - // test above already uses this comparison so no need to repeat - if (comparison != StringComparison.Ordinal) - { - foreach (JProperty p in _properties) + /// + /// Gets the container's children tokens. + /// + /// The container's children tokens. + protected override IList ChildrenTokens { - if (string.Equals(p.Name, propertyName, comparison)) - return p.Value; + get { return _properties; } } - } - return null; - } + /// + /// Occurs when a property value changes. + /// + public event PropertyChangedEventHandler PropertyChanged; - /// - /// Tries to get the with the specified property name. - /// The exact property name will be searched for first and if no matching property is found then - /// the will be used to match a property. - /// - /// Name of the property. - /// The value. - /// One of the enumeration values that specifies how the strings will be compared. - /// true if a value was successfully retrieved; otherwise, false. - public bool TryGetValue(string propertyName, StringComparison comparison, out JToken value) - { - value = GetValue(propertyName, comparison); - return (value != null); - } +#if !(SILVERLIGHT || NET20 || NETFX_CORE || PORTABLE || PORTABLE40) + /// + /// Occurs when a property value is changing. + /// + public event PropertyChangingEventHandler PropertyChanging; +#endif - #region IDictionary Members - /// - /// Adds the specified property name. - /// - /// Name of the property. - /// The value. - public void Add(string propertyName, JToken value) - { - Add(new JProperty(propertyName, value)); - } + /// + /// Initializes a new instance of the class. + /// + public JObject() + { + } - bool IDictionary.ContainsKey(string key) - { - return _properties.Contains(key); - } + /// + /// Initializes a new instance of the class from another object. + /// + /// A object to copy from. + public JObject(JObject other) + : base(other) + { + } - ICollection IDictionary.Keys - { - // todo: make order the collection returned match JObject order - get { return _properties.Keys; } - } + /// + /// Initializes a new instance of the class with the specified content. + /// + /// The contents of the object. + public JObject(params object[] content) + : this((object)content) + { + } - /// - /// Removes the property with the specified name. - /// - /// Name of the property. - /// true if item was successfully removed; otherwise, false. - public bool Remove(string propertyName) - { - JProperty property = Property(propertyName); - if (property == null) - return false; + /// + /// Initializes a new instance of the class with the specified content. + /// + /// The contents of the object. + public JObject(object content) + { + Add(content); + } - property.Remove(); - return true; - } + internal override bool DeepEquals(JToken node) + { + JObject t = node as JObject; + if (t == null) + return false; - /// - /// Tries the get value. - /// - /// Name of the property. - /// The value. - /// true if a value was successfully retrieved; otherwise, false. - public bool TryGetValue(string propertyName, out JToken value) - { - JProperty property = Property(propertyName); - if (property == null) - { - value = null; - return false; - } + return _properties.Compare(t._properties); + } - value = property.Value; - return true; - } + internal override void InsertItem(int index, JToken item, bool skipParentCheck) + { + // don't add comments to JObject, no name to reference comment by + if (item != null && item.Type == JTokenType.Comment) + return; - ICollection IDictionary.Values - { - get - { - // todo: need to wrap _properties.Values with a collection to get the JProperty value - throw new NotImplementedException(); - } - } + base.InsertItem(index, item, skipParentCheck); + } - #endregion + internal override void ValidateToken(JToken o, JToken existing) + { + ValidationUtils.ArgumentNotNull(o, "o"); - #region ICollection> Members + if (o.Type != JTokenType.Property) + throw new ArgumentException("Can not add {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, o.GetType(), GetType())); - void ICollection>.Add(KeyValuePair item) - { - Add(new JProperty(item.Key, item.Value)); - } + JProperty newProperty = (JProperty)o; - void ICollection>.Clear() - { - RemoveAll(); - } + if (existing != null) + { + JProperty existingProperty = (JProperty)existing; - bool ICollection>.Contains(KeyValuePair item) - { - JProperty property = Property(item.Key); - if (property == null) - return false; + if (newProperty.Name == existingProperty.Name) + return; + } - return (property.Value == item.Value); - } + if (_properties.TryGetValue(newProperty.Name, out existing)) + throw new ArgumentException("Can not add property {0} to {1}. Property with the same name already exists on object.".FormatWith(CultureInfo.InvariantCulture, newProperty.Name, GetType())); + } - void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex) - { - if (array == null) - throw new ArgumentNullException("array"); - if (arrayIndex < 0) - throw new ArgumentOutOfRangeException("arrayIndex", "arrayIndex is less than 0."); - if (arrayIndex >= array.Length && arrayIndex != 0) - throw new ArgumentException("arrayIndex is equal to or greater than the length of array."); - if (Count > array.Length - arrayIndex) - throw new ArgumentException("The number of elements in the source JObject is greater than the available space from arrayIndex to the end of the destination array."); + internal void InternalPropertyChanged(JProperty childProperty) + { + OnPropertyChanged(childProperty.Name); +#if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) + if (_listChanged != null) + OnListChanged(new ListChangedEventArgs(ListChangedType.ItemChanged, IndexOfItem(childProperty))); +#endif +#if SILVERLIGHT || !(NET20 || NET35 || PORTABLE40) + if (_collectionChanged != null) + OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, childProperty, childProperty, IndexOfItem(childProperty))); +#endif + } - int index = 0; - foreach (JProperty property in _properties) - { - array[arrayIndex + index] = new KeyValuePair(property.Name, property.Value); - index++; - } - } + internal void InternalPropertyChanging(JProperty childProperty) + { +#if !(SILVERLIGHT || NET20 || NETFX_CORE || PORTABLE40 || PORTABLE) + OnPropertyChanging(childProperty.Name); +#endif + } - bool ICollection>.IsReadOnly - { - get { return false; } - } + internal override JToken CloneToken() + { + return new JObject(this); + } - bool ICollection>.Remove(KeyValuePair item) - { - if (!((ICollection>)this).Contains(item)) - return false; + /// + /// Gets the node type for this . + /// + /// The type. + public override JTokenType Type + { + get { return JTokenType.Object; } + } - ((IDictionary)this).Remove(item.Key); - return true; - } + /// + /// Gets an of this object's properties. + /// + /// An of this object's properties. + public IEnumerable Properties() + { + return _properties.Cast(); + } - #endregion + /// + /// Gets a the specified name. + /// + /// The property name. + /// A with the specified name or null. + public JProperty Property(string name) + { + if (name == null) + return null; - internal override int GetDeepHashCode() - { - return ContentsHashCode(); - } + JToken property; + _properties.TryGetValue(name, out property); + return (JProperty)property; + } - /// - /// Returns an enumerator that iterates through the collection. - /// - /// - /// A that can be used to iterate through the collection. - /// - public IEnumerator> GetEnumerator() - { - foreach (JProperty property in _properties) - { - yield return new KeyValuePair(property.Name, property.Value); - } - } + /// + /// Gets an of this object's property values. + /// + /// An of this object's property values. + public JEnumerable PropertyValues() + { + return new JEnumerable(Properties().Select(p => p.Value)); + } - /// - /// Raises the event with the provided arguments. - /// - /// Name of the property. - protected virtual void OnPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } + /// + /// Gets the with the specified key. + /// + /// The with the specified key. + public override JToken this[object key] + { + get + { + ValidationUtils.ArgumentNotNull(key, "o"); + + string propertyName = key as string; + if (propertyName == null) + throw new ArgumentException("Accessed JObject values with invalid key value: {0}. Object property name expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key))); + + return this[propertyName]; + } + set + { + ValidationUtils.ArgumentNotNull(key, "o"); + + string propertyName = key as string; + if (propertyName == null) + throw new ArgumentException("Set JObject values with invalid key value: {0}. Object property name expected.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.ToString(key))); + + this[propertyName] = value; + } + } + + /// + /// Gets or sets the with the specified property name. + /// + /// + public JToken this[string propertyName] + { + get + { + ValidationUtils.ArgumentNotNull(propertyName, "propertyName"); + + JProperty property = Property(propertyName); + + return (property != null) ? property.Value : null; + } + set + { + JProperty property = Property(propertyName); + if (property != null) + { + property.Value = value; + } + else + { +#if !(SILVERLIGHT || NET20 || NETFX_CORE || PORTABLE40 || PORTABLE) + OnPropertyChanging(propertyName); +#endif + Add(new JProperty(propertyName, value)); + OnPropertyChanged(propertyName); + } + } + } + + /// + /// Loads an from a . + /// + /// A that will be read for the content of the . + /// A that contains the JSON that was read from the specified . + public new static JObject Load(JsonReader reader) + { + ValidationUtils.ArgumentNotNull(reader, "reader"); + + if (reader.TokenType == JsonToken.None) + { + if (!reader.Read()) + throw JsonReaderException.Create(reader, "Error reading JObject from JsonReader."); + } + + while (reader.TokenType == JsonToken.Comment) + { + reader.Read(); + } + + if (reader.TokenType != JsonToken.StartObject) + { + throw JsonReaderException.Create(reader, "Error reading JObject from JsonReader. Current JsonReader item is not an object: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); + } + + JObject o = new JObject(); + o.SetLineInfo(reader as IJsonLineInfo); + + o.ReadTokenFrom(reader); + + return o; + } + + /// + /// Load a from a string that contains JSON. + /// + /// A that contains JSON. + /// A populated from the string that contains JSON. + /// + /// + /// + public new static JObject Parse(string json) + { + JsonReader reader = new JsonTextReader(new StringReader(json)); + + JObject o = Load(reader); + + if (reader.Read() && reader.TokenType != JsonToken.Comment) + throw JsonReaderException.Create(reader, "Additional text found in JSON string after parsing content."); + + return o; + } + + /// + /// Creates a from an object. + /// + /// The object that will be used to create . + /// A with the values of the specified object + public new static JObject FromObject(object o) + { + return FromObject(o, JsonSerializer.CreateDefault()); + } + + /// + /// Creates a from an object. + /// + /// The object that will be used to create . + /// The that will be used to read the object. + /// A with the values of the specified object + public new static JObject FromObject(object o, JsonSerializer jsonSerializer) + { + JToken token = FromObjectInternal(o, jsonSerializer); + + if (token != null && token.Type != JTokenType.Object) + throw new ArgumentException("Object serialized to {0}. JObject instance expected.".FormatWith(CultureInfo.InvariantCulture, token.Type)); + + return (JObject)token; + } + + /// + /// Writes this token to a . + /// + /// A into which this method will write. + /// A collection of which will be used when writing the token. + public override void WriteTo(JsonWriter writer, params JsonConverter[] converters) + { + writer.WriteStartObject(); + + for (int i = 0; i < _properties.Count; i++) + { + _properties[i].WriteTo(writer, converters); + } + + writer.WriteEndObject(); + } + + /// + /// Gets the with the specified property name. + /// + /// Name of the property. + /// The with the specified property name. + public JToken GetValue(string propertyName) + { + return GetValue(propertyName, StringComparison.Ordinal); + } + + /// + /// Gets the with the specified property name. + /// The exact property name will be searched for first and if no matching property is found then + /// the will be used to match a property. + /// + /// Name of the property. + /// One of the enumeration values that specifies how the strings will be compared. + /// The with the specified property name. + public JToken GetValue(string propertyName, StringComparison comparison) + { + if (propertyName == null) + return null; + + // attempt to get value via dictionary first for performance + JProperty property = Property(propertyName); + if (property != null) + return property.Value; + + // test above already uses this comparison so no need to repeat + if (comparison != StringComparison.Ordinal) + { + foreach (JProperty p in _properties) + { + if (string.Equals(p.Name, propertyName, comparison)) + return p.Value; + } + } + + return null; + } + + /// + /// Tries to get the with the specified property name. + /// The exact property name will be searched for first and if no matching property is found then + /// the will be used to match a property. + /// + /// Name of the property. + /// The value. + /// One of the enumeration values that specifies how the strings will be compared. + /// true if a value was successfully retrieved; otherwise, false. + public bool TryGetValue(string propertyName, StringComparison comparison, out JToken value) + { + value = GetValue(propertyName, comparison); + return (value != null); + } + + #region IDictionary Members + /// + /// Adds the specified property name. + /// + /// Name of the property. + /// The value. + public void Add(string propertyName, JToken value) + { + Add(new JProperty(propertyName, value)); + } + + bool IDictionary.ContainsKey(string key) + { + return _properties.Contains(key); + } + + ICollection IDictionary.Keys + { + // todo: make order the collection returned match JObject order + get { return _properties.Keys; } + } + + /// + /// Removes the property with the specified name. + /// + /// Name of the property. + /// true if item was successfully removed; otherwise, false. + public bool Remove(string propertyName) + { + JProperty property = Property(propertyName); + if (property == null) + return false; + + property.Remove(); + return true; + } + + /// + /// Tries the get value. + /// + /// Name of the property. + /// The value. + /// true if a value was successfully retrieved; otherwise, false. + public bool TryGetValue(string propertyName, out JToken value) + { + JProperty property = Property(propertyName); + if (property == null) + { + value = null; + return false; + } + + value = property.Value; + return true; + } + + ICollection IDictionary.Values + { + get + { + // todo: need to wrap _properties.Values with a collection to get the JProperty value + throw new NotImplementedException(); + } + } + #endregion + + #region ICollection> Members + void ICollection>.Add(KeyValuePair item) + { + Add(new JProperty(item.Key, item.Value)); + } + + void ICollection>.Clear() + { + RemoveAll(); + } + + bool ICollection>.Contains(KeyValuePair item) + { + JProperty property = Property(item.Key); + if (property == null) + return false; + + return (property.Value == item.Value); + } + + void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex) + { + if (array == null) + throw new ArgumentNullException("array"); + if (arrayIndex < 0) + throw new ArgumentOutOfRangeException("arrayIndex", "arrayIndex is less than 0."); + if (arrayIndex >= array.Length && arrayIndex != 0) + throw new ArgumentException("arrayIndex is equal to or greater than the length of array."); + if (Count > array.Length - arrayIndex) + throw new ArgumentException("The number of elements in the source JObject is greater than the available space from arrayIndex to the end of the destination array."); + + int index = 0; + foreach (JProperty property in _properties) + { + array[arrayIndex + index] = new KeyValuePair(property.Name, property.Value); + index++; + } + } + + bool ICollection>.IsReadOnly + { + get { return false; } + } + + bool ICollection>.Remove(KeyValuePair item) + { + if (!((ICollection>)this).Contains(item)) + return false; + + ((IDictionary)this).Remove(item.Key); + return true; + } + #endregion + + internal override int GetDeepHashCode() + { + return ContentsHashCode(); + } + + /// + /// Returns an enumerator that iterates through the collection. + /// + /// + /// A that can be used to iterate through the collection. + /// + public IEnumerator> GetEnumerator() + { + foreach (JProperty property in _properties) + { + yield return new KeyValuePair(property.Name, property.Value); + } + } + + /// + /// Raises the event with the provided arguments. + /// + /// Name of the property. + protected virtual void OnPropertyChanged(string propertyName) + { + if (PropertyChanged != null) + PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + } #if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE || NET20) - /// - /// Raises the event with the provided arguments. - /// - /// Name of the property. - protected virtual void OnPropertyChanging(string propertyName) - { - if (PropertyChanging != null) - PropertyChanging(this, new PropertyChangingEventArgs(propertyName)); - } + /// + /// Raises the event with the provided arguments. + /// + /// Name of the property. + protected virtual void OnPropertyChanging(string propertyName) + { + if (PropertyChanging != null) + PropertyChanging(this, new PropertyChangingEventArgs(propertyName)); + } #endif #if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) - // include custom type descriptor on JObject rather than use a provider because the properties are specific to a type - #region ICustomTypeDescriptor - /// - /// Returns the properties for this instance of a component. - /// - /// - /// A that represents the properties for this component instance. - /// - PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties() - { - return ((ICustomTypeDescriptor) this).GetProperties(null); - } + // include custom type descriptor on JObject rather than use a provider because the properties are specific to a type - private static Type GetTokenPropertyType(JToken token) - { - if (token is JValue) - { - JValue v = (JValue)token; - return (v.Value != null) ? v.Value.GetType() : typeof(object); - } + #region ICustomTypeDescriptor + /// + /// Returns the properties for this instance of a component. + /// + /// + /// A that represents the properties for this component instance. + /// + PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties() + { + return ((ICustomTypeDescriptor)this).GetProperties(null); + } - return token.GetType(); - } + private static Type GetTokenPropertyType(JToken token) + { + if (token is JValue) + { + JValue v = (JValue)token; + return (v.Value != null) ? v.Value.GetType() : typeof(object); + } - /// - /// Returns the properties for this instance of a component using the attribute array as a filter. - /// - /// An array of type that is used as a filter. - /// - /// A that represents the filtered properties for this component instance. - /// - PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes) - { - PropertyDescriptorCollection descriptors = new PropertyDescriptorCollection(null); + return token.GetType(); + } - foreach (KeyValuePair propertyValue in this) - { - descriptors.Add(new JPropertyDescriptor(propertyValue.Key, GetTokenPropertyType(propertyValue.Value))); - } + /// + /// Returns the properties for this instance of a component using the attribute array as a filter. + /// + /// An array of type that is used as a filter. + /// + /// A that represents the filtered properties for this component instance. + /// + PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes) + { + PropertyDescriptorCollection descriptors = new PropertyDescriptorCollection(null); - return descriptors; - } + foreach (KeyValuePair propertyValue in this) + { + descriptors.Add(new JPropertyDescriptor(propertyValue.Key, GetTokenPropertyType(propertyValue.Value))); + } - /// - /// Returns a collection of custom attributes for this instance of a component. - /// - /// - /// An containing the attributes for this object. - /// - AttributeCollection ICustomTypeDescriptor.GetAttributes() - { - return AttributeCollection.Empty; - } + return descriptors; + } - /// - /// Returns the class name of this instance of a component. - /// - /// - /// The class name of the object, or null if the class does not have a name. - /// - string ICustomTypeDescriptor.GetClassName() - { - return null; - } + /// + /// Returns a collection of custom attributes for this instance of a component. + /// + /// + /// An containing the attributes for this object. + /// + AttributeCollection ICustomTypeDescriptor.GetAttributes() + { + return AttributeCollection.Empty; + } - /// - /// Returns the name of this instance of a component. - /// - /// - /// The name of the object, or null if the object does not have a name. - /// - string ICustomTypeDescriptor.GetComponentName() - { - return null; - } + /// + /// Returns the class name of this instance of a component. + /// + /// + /// The class name of the object, or null if the class does not have a name. + /// + string ICustomTypeDescriptor.GetClassName() + { + return null; + } - /// - /// Returns a type converter for this instance of a component. - /// - /// - /// A that is the converter for this object, or null if there is no for this object. - /// - TypeConverter ICustomTypeDescriptor.GetConverter() - { - return new TypeConverter(); - } + /// + /// Returns the name of this instance of a component. + /// + /// + /// The name of the object, or null if the object does not have a name. + /// + string ICustomTypeDescriptor.GetComponentName() + { + return null; + } - /// - /// Returns the default event for this instance of a component. - /// - /// - /// An that represents the default event for this object, or null if this object does not have events. - /// - EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() - { - return null; - } + /// + /// Returns a type converter for this instance of a component. + /// + /// + /// A that is the converter for this object, or null if there is no for this object. + /// + TypeConverter ICustomTypeDescriptor.GetConverter() + { + return new TypeConverter(); + } - /// - /// Returns the default property for this instance of a component. - /// - /// - /// A that represents the default property for this object, or null if this object does not have properties. - /// - PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() - { - return null; - } + /// + /// Returns the default event for this instance of a component. + /// + /// + /// An that represents the default event for this object, or null if this object does not have events. + /// + EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() + { + return null; + } - /// - /// Returns an editor of the specified type for this instance of a component. - /// - /// A that represents the editor for this object. - /// - /// An of the specified type that is the editor for this object, or null if the editor cannot be found. - /// - object ICustomTypeDescriptor.GetEditor(Type editorBaseType) - { - return null; - } + /// + /// Returns the default property for this instance of a component. + /// + /// + /// A that represents the default property for this object, or null if this object does not have properties. + /// + PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() + { + return null; + } - /// - /// Returns the events for this instance of a component using the specified attribute array as a filter. - /// - /// An array of type that is used as a filter. - /// - /// An that represents the filtered events for this component instance. - /// - EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes) - { - return EventDescriptorCollection.Empty; - } + /// + /// Returns an editor of the specified type for this instance of a component. + /// + /// A that represents the editor for this object. + /// + /// An of the specified type that is the editor for this object, or null if the editor cannot be found. + /// + object ICustomTypeDescriptor.GetEditor(Type editorBaseType) + { + return null; + } - /// - /// Returns the events for this instance of a component. - /// - /// - /// An that represents the events for this component instance. - /// - EventDescriptorCollection ICustomTypeDescriptor.GetEvents() - { - return EventDescriptorCollection.Empty; - } + /// + /// Returns the events for this instance of a component using the specified attribute array as a filter. + /// + /// An array of type that is used as a filter. + /// + /// An that represents the filtered events for this component instance. + /// + EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes) + { + return EventDescriptorCollection.Empty; + } + + /// + /// Returns the events for this instance of a component. + /// + /// + /// An that represents the events for this component instance. + /// + EventDescriptorCollection ICustomTypeDescriptor.GetEvents() + { + return EventDescriptorCollection.Empty; + } + + /// + /// Returns an object that contains the property described by the specified property descriptor. + /// + /// A that represents the property whose owner is to be found. + /// + /// An that represents the owner of the specified property. + /// + object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd) + { + return null; + } + #endregion - /// - /// Returns an object that contains the property described by the specified property descriptor. - /// - /// A that represents the property whose owner is to be found. - /// - /// An that represents the owner of the specified property. - /// - object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd) - { - return null; - } - #endregion #endif #if !(NET35 || NET20 || PORTABLE40) - /// - /// Returns the responsible for binding operations performed on this object. - /// - /// The expression tree representation of the runtime value. - /// - /// The to bind this object. - /// - protected override DynamicMetaObject GetMetaObject(Expression parameter) - { - return new DynamicProxyMetaObject(parameter, this, new JObjectDynamicProxy(), true); - } + /// + /// Returns the responsible for binding operations performed on this object. + /// + /// The expression tree representation of the runtime value. + /// + /// The to bind this object. + /// + protected override DynamicMetaObject GetMetaObject(Expression parameter) + { + return new DynamicProxyMetaObject(parameter, this, new JObjectDynamicProxy(), true); + } - private class JObjectDynamicProxy : DynamicProxy - { - public override bool TryGetMember(JObject instance, GetMemberBinder binder, out object result) - { - // result can be null - result = instance[binder.Name]; - return true; - } + private class JObjectDynamicProxy : DynamicProxy + { + public override bool TryGetMember(JObject instance, GetMemberBinder binder, out object result) + { + // result can be null + result = instance[binder.Name]; + return true; + } - public override bool TrySetMember(JObject instance, SetMemberBinder binder, object value) - { - JToken v = value as JToken; + public override bool TrySetMember(JObject instance, SetMemberBinder binder, object value) + { + JToken v = value as JToken; - // this can throw an error if value isn't a valid for a JValue - if (v == null) - v = new JValue(value); + // this can throw an error if value isn't a valid for a JValue + if (v == null) + v = new JValue(value); - instance[binder.Name] = v; - return true; - } + instance[binder.Name] = v; + return true; + } - public override IEnumerable GetDynamicMemberNames(JObject instance) - { - return instance.Properties().Select(p => p.Name); - } - } + public override IEnumerable GetDynamicMemberNames(JObject instance) + { + return instance.Properties().Select(p => p.Name); + } + } #endif - } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Linq/JPath.cs b/Src/Newtonsoft.Json/Linq/JPath.cs index bd8eb160..188ec6ca 100644 --- a/Src/Newtonsoft.Json/Linq/JPath.cs +++ b/Src/Newtonsoft.Json/Linq/JPath.cs @@ -30,179 +30,179 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Linq { - internal class JPath - { - private readonly string _expression; - public List Parts { get; private set; } - - private int _currentIndex; - - public JPath(string expression) + internal class JPath { - ValidationUtils.ArgumentNotNull(expression, "expression"); - _expression = expression; - Parts = new List(); + private readonly string _expression; + public List Parts { get; private set; } - ParseMain(); - } + private int _currentIndex; - private void ParseMain() - { - int currentPartStartIndex = _currentIndex; - bool followingIndexer = false; - - while (_currentIndex < _expression.Length) - { - char currentChar = _expression[_currentIndex]; - - switch (currentChar) + public JPath(string expression) { - case '[': - case '(': + ValidationUtils.ArgumentNotNull(expression, "expression"); + _expression = expression; + Parts = new List(); + + ParseMain(); + } + + private void ParseMain() + { + int currentPartStartIndex = _currentIndex; + bool followingIndexer = false; + + while (_currentIndex < _expression.Length) + { + char currentChar = _expression[_currentIndex]; + + switch (currentChar) + { + case '[': + case '(': + if (_currentIndex > currentPartStartIndex) + { + string member = _expression.Substring(currentPartStartIndex, _currentIndex - currentPartStartIndex); + Parts.Add(member); + } + + ParseIndexer(currentChar); + currentPartStartIndex = _currentIndex + 1; + followingIndexer = true; + break; + case ']': + case ')': + throw new JsonException("Unexpected character while parsing path: " + currentChar); + case '.': + if (_currentIndex > currentPartStartIndex) + { + string member = _expression.Substring(currentPartStartIndex, _currentIndex - currentPartStartIndex); + Parts.Add(member); + } + currentPartStartIndex = _currentIndex + 1; + followingIndexer = false; + break; + default: + if (followingIndexer) + throw new JsonException("Unexpected character following indexer: " + currentChar); + break; + } + + _currentIndex++; + } + if (_currentIndex > currentPartStartIndex) { - string member = _expression.Substring(currentPartStartIndex, _currentIndex - currentPartStartIndex); - Parts.Add(member); + string member = _expression.Substring(currentPartStartIndex, _currentIndex - currentPartStartIndex); + Parts.Add(member); } + } - ParseIndexer(currentChar); - currentPartStartIndex = _currentIndex + 1; - followingIndexer = true; - break; - case ']': - case ')': - throw new JsonException("Unexpected character while parsing path: " + currentChar); - case '.': - if (_currentIndex > currentPartStartIndex) + private void ParseIndexer(char indexerOpenChar) + { + _currentIndex++; + + char indexerCloseChar = (indexerOpenChar == '[') ? ']' : ')'; + int indexerStart = _currentIndex; + int indexerLength = 0; + bool indexerClosed = false; + + while (_currentIndex < _expression.Length) { - string member = _expression.Substring(currentPartStartIndex, _currentIndex - currentPartStartIndex); - Parts.Add(member); + char currentCharacter = _expression[_currentIndex]; + if (char.IsDigit(currentCharacter)) + { + indexerLength++; + } + else if (currentCharacter == indexerCloseChar) + { + indexerClosed = true; + break; + } + else + { + throw new JsonException("Unexpected character while parsing path indexer: " + currentCharacter); + } + + _currentIndex++; } - currentPartStartIndex = _currentIndex + 1; - followingIndexer = false; - break; - default: - if (followingIndexer) - throw new JsonException("Unexpected character following indexer: " + currentChar); - break; + + if (!indexerClosed) + throw new JsonException("Path ended with open indexer. Expected " + indexerCloseChar); + + if (indexerLength == 0) + throw new JsonException("Empty path indexer."); + + string indexer = _expression.Substring(indexerStart, indexerLength); + Parts.Add(Convert.ToInt32(indexer, CultureInfo.InvariantCulture)); } - _currentIndex++; - } - - if (_currentIndex > currentPartStartIndex) - { - string member = _expression.Substring(currentPartStartIndex, _currentIndex - currentPartStartIndex); - Parts.Add(member); - } - } - - private void ParseIndexer(char indexerOpenChar) - { - _currentIndex++; - - char indexerCloseChar = (indexerOpenChar == '[') ? ']' : ')'; - int indexerStart = _currentIndex; - int indexerLength = 0; - bool indexerClosed = false; - - while (_currentIndex < _expression.Length) - { - char currentCharacter = _expression[_currentIndex]; - if (char.IsDigit(currentCharacter)) + internal JToken Evaluate(JToken root, bool errorWhenNoMatch) { - indexerLength++; - } - else if (currentCharacter == indexerCloseChar) - { - indexerClosed = true; - break; - } - else - { - throw new JsonException("Unexpected character while parsing path indexer: " + currentCharacter); - } + JToken current = root; - _currentIndex++; - } - - if (!indexerClosed) - throw new JsonException("Path ended with open indexer. Expected " + indexerCloseChar); - - if (indexerLength == 0) - throw new JsonException("Empty path indexer."); - - string indexer = _expression.Substring(indexerStart, indexerLength); - Parts.Add(Convert.ToInt32(indexer, CultureInfo.InvariantCulture)); - } - - internal JToken Evaluate(JToken root, bool errorWhenNoMatch) - { - JToken current = root; - - foreach (object part in Parts) - { - string propertyName = part as string; - if (propertyName != null) - { - JObject o = current as JObject; - if (o != null) - { - current = o[propertyName]; - - if (current == null && errorWhenNoMatch) - throw new JsonException("Property '{0}' does not exist on JObject.".FormatWith(CultureInfo.InvariantCulture, propertyName)); - } - else - { - if (errorWhenNoMatch) - throw new JsonException("Property '{0}' not valid on {1}.".FormatWith(CultureInfo.InvariantCulture, propertyName, current.GetType().Name)); - - return null; - } - } - else - { - int index = (int) part; - - JArray a = current as JArray; - JConstructor c = current as JConstructor; - - if (a != null) - { - if (a.Count <= index) + foreach (object part in Parts) { - if (errorWhenNoMatch) - throw new JsonException("Index {0} outside the bounds of JArray.".FormatWith(CultureInfo.InvariantCulture, index)); - - return null; + string propertyName = part as string; + if (propertyName != null) + { + JObject o = current as JObject; + if (o != null) + { + current = o[propertyName]; + + if (current == null && errorWhenNoMatch) + throw new JsonException("Property '{0}' does not exist on JObject.".FormatWith(CultureInfo.InvariantCulture, propertyName)); + } + else + { + if (errorWhenNoMatch) + throw new JsonException("Property '{0}' not valid on {1}.".FormatWith(CultureInfo.InvariantCulture, propertyName, current.GetType().Name)); + + return null; + } + } + else + { + int index = (int)part; + + JArray a = current as JArray; + JConstructor c = current as JConstructor; + + if (a != null) + { + if (a.Count <= index) + { + if (errorWhenNoMatch) + throw new JsonException("Index {0} outside the bounds of JArray.".FormatWith(CultureInfo.InvariantCulture, index)); + + return null; + } + + current = a[index]; + } + else if (c != null) + { + if (c.Count <= index) + { + if (errorWhenNoMatch) + throw new JsonException("Index {0} outside the bounds of JConstructor.".FormatWith(CultureInfo.InvariantCulture, index)); + + return null; + } + + current = c[index]; + } + else + { + if (errorWhenNoMatch) + throw new JsonException("Index {0} not valid on {1}.".FormatWith(CultureInfo.InvariantCulture, index, current.GetType().Name)); + + return null; + } + } } - current = a[index]; - } - else if (c != null) - { - if (c.Count <= index) - { - if (errorWhenNoMatch) - throw new JsonException("Index {0} outside the bounds of JConstructor.".FormatWith(CultureInfo.InvariantCulture, index)); - - return null; - } - - current = c[index]; - } - else - { - if (errorWhenNoMatch) - throw new JsonException("Index {0} not valid on {1}.".FormatWith(CultureInfo.InvariantCulture, index, current.GetType().Name)); - - return null; - } + return current; } - } - - return current; } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Linq/JProperty.cs b/Src/Newtonsoft.Json/Linq/JProperty.cs index 3c187bf4..9d77ded3 100644 --- a/Src/Newtonsoft.Json/Linq/JProperty.cs +++ b/Src/Newtonsoft.Json/Linq/JProperty.cs @@ -31,224 +31,224 @@ using System.Globalization; namespace Newtonsoft.Json.Linq { - /// - /// Represents a JSON property. - /// - public class JProperty : JContainer - { - private readonly List _content = new List(); - private readonly string _name; - /// - /// Gets the container's children tokens. + /// Represents a JSON property. /// - /// The container's children tokens. - protected override IList ChildrenTokens + public class JProperty : JContainer { - get { return _content; } - } + private readonly List _content = new List(); + private readonly string _name; - /// - /// Gets the property name. - /// - /// The property name. - public string Name - { - [DebuggerStepThrough] - get { return _name; } - } - - /// - /// Gets or sets the property value. - /// - /// The property value. - public JToken Value - { - [DebuggerStepThrough] - get { return (_content.Count > 0) ? _content[0] : null; } - set - { - CheckReentrancy(); - - JToken newValue = value ?? new JValue((object) null); - - if (_content.Count == 0) + /// + /// Gets the container's children tokens. + /// + /// The container's children tokens. + protected override IList ChildrenTokens { - InsertItem(0, newValue, false); + get { return _content; } } - else + + /// + /// Gets the property name. + /// + /// The property name. + public string Name { - SetItem(0, newValue); + [DebuggerStepThrough] + get { return _name; } + } + + /// + /// Gets or sets the property value. + /// + /// The property value. + public JToken Value + { + [DebuggerStepThrough] + get { return (_content.Count > 0) ? _content[0] : null; } + set + { + CheckReentrancy(); + + JToken newValue = value ?? new JValue((object)null); + + if (_content.Count == 0) + { + InsertItem(0, newValue, false); + } + else + { + SetItem(0, newValue); + } + } + } + + /// + /// Initializes a new instance of the class from another object. + /// + /// A object to copy from. + public JProperty(JProperty other) + : base(other) + { + _name = other.Name; + } + + internal override JToken GetItem(int index) + { + if (index != 0) + throw new ArgumentOutOfRangeException(); + + return Value; + } + + internal override void SetItem(int index, JToken item) + { + if (index != 0) + throw new ArgumentOutOfRangeException(); + + if (IsTokenUnchanged(Value, item)) + return; + + if (Parent != null) + ((JObject)Parent).InternalPropertyChanging(this); + + base.SetItem(0, item); + + if (Parent != null) + ((JObject)Parent).InternalPropertyChanged(this); + } + + internal override bool RemoveItem(JToken item) + { + throw new JsonException("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty))); + } + + internal override void RemoveItemAt(int index) + { + throw new JsonException("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty))); + } + + internal override void InsertItem(int index, JToken item, bool skipParentCheck) + { + if (Value != null) + throw new JsonException("{0} cannot have multiple values.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty))); + + base.InsertItem(0, item, false); + } + + internal override bool ContainsItem(JToken item) + { + return (Value == item); + } + + internal override void ClearItems() + { + throw new JsonException("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty))); + } + + internal override bool DeepEquals(JToken node) + { + JProperty t = node as JProperty; + return (t != null && _name == t.Name && ContentsEqual(t)); + } + + internal override JToken CloneToken() + { + return new JProperty(this); + } + + /// + /// Gets the node type for this . + /// + /// The type. + public override JTokenType Type + { + [DebuggerStepThrough] + get { return JTokenType.Property; } + } + + internal JProperty(string name) + { + // called from JTokenWriter + ValidationUtils.ArgumentNotNull(name, "name"); + + _name = name; + } + + /// + /// Initializes a new instance of the class. + /// + /// The property name. + /// The property content. + public JProperty(string name, params object[] content) + : this(name, (object)content) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The property name. + /// The property content. + public JProperty(string name, object content) + { + ValidationUtils.ArgumentNotNull(name, "name"); + + _name = name; + + Value = IsMultiContent(content) + ? new JArray(content) + : CreateFromContent(content); + } + + /// + /// Writes this token to a . + /// + /// A into which this method will write. + /// A collection of which will be used when writing the token. + public override void WriteTo(JsonWriter writer, params JsonConverter[] converters) + { + writer.WritePropertyName(_name); + + JToken value = Value; + if (value != null) + value.WriteTo(writer, converters); + else + writer.WriteNull(); + } + + internal override int GetDeepHashCode() + { + return _name.GetHashCode() ^ ((Value != null) ? Value.GetDeepHashCode() : 0); + } + + /// + /// Loads an from a . + /// + /// A that will be read for the content of the . + /// A that contains the JSON that was read from the specified . + public new static JProperty Load(JsonReader reader) + { + if (reader.TokenType == JsonToken.None) + { + if (!reader.Read()) + throw JsonReaderException.Create(reader, "Error reading JProperty from JsonReader."); + } + + while (reader.TokenType == JsonToken.Comment) + { + reader.Read(); + } + + if (reader.TokenType != JsonToken.PropertyName) + throw JsonReaderException.Create(reader, "Error reading JProperty from JsonReader. Current JsonReader item is not a property: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); + + JProperty p = new JProperty((string)reader.Value); + p.SetLineInfo(reader as IJsonLineInfo); + + p.ReadTokenFrom(reader); + + return p; } - } } - - /// - /// Initializes a new instance of the class from another object. - /// - /// A object to copy from. - public JProperty(JProperty other) - : base(other) - { - _name = other.Name; - } - - internal override JToken GetItem(int index) - { - if (index != 0) - throw new ArgumentOutOfRangeException(); - - return Value; - } - - internal override void SetItem(int index, JToken item) - { - if (index != 0) - throw new ArgumentOutOfRangeException(); - - if (IsTokenUnchanged(Value, item)) - return; - - if (Parent != null) - ((JObject)Parent).InternalPropertyChanging(this); - - base.SetItem(0, item); - - if (Parent != null) - ((JObject)Parent).InternalPropertyChanged(this); - } - - internal override bool RemoveItem(JToken item) - { - throw new JsonException("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty))); - } - - internal override void RemoveItemAt(int index) - { - throw new JsonException("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty))); - } - - internal override void InsertItem(int index, JToken item, bool skipParentCheck) - { - if (Value != null) - throw new JsonException("{0} cannot have multiple values.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty))); - - base.InsertItem(0, item, false); - } - - internal override bool ContainsItem(JToken item) - { - return (Value == item); - } - - internal override void ClearItems() - { - throw new JsonException("Cannot add or remove items from {0}.".FormatWith(CultureInfo.InvariantCulture, typeof(JProperty))); - } - - internal override bool DeepEquals(JToken node) - { - JProperty t = node as JProperty; - return (t != null && _name == t.Name && ContentsEqual(t)); - } - - internal override JToken CloneToken() - { - return new JProperty(this); - } - - /// - /// Gets the node type for this . - /// - /// The type. - public override JTokenType Type - { - [DebuggerStepThrough] - get { return JTokenType.Property; } - } - - internal JProperty(string name) - { - // called from JTokenWriter - ValidationUtils.ArgumentNotNull(name, "name"); - - _name = name; - } - - /// - /// Initializes a new instance of the class. - /// - /// The property name. - /// The property content. - public JProperty(string name, params object[] content) - : this(name, (object)content) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The property name. - /// The property content. - public JProperty(string name, object content) - { - ValidationUtils.ArgumentNotNull(name, "name"); - - _name = name; - - Value = IsMultiContent(content) - ? new JArray(content) - : CreateFromContent(content); - } - - /// - /// Writes this token to a . - /// - /// A into which this method will write. - /// A collection of which will be used when writing the token. - public override void WriteTo(JsonWriter writer, params JsonConverter[] converters) - { - writer.WritePropertyName(_name); - - JToken value = Value; - if (value != null) - value.WriteTo(writer, converters); - else - writer.WriteNull(); - } - - internal override int GetDeepHashCode() - { - return _name.GetHashCode() ^ ((Value != null) ? Value.GetDeepHashCode() : 0); - } - - /// - /// Loads an from a . - /// - /// A that will be read for the content of the . - /// A that contains the JSON that was read from the specified . - public static new JProperty Load(JsonReader reader) - { - if (reader.TokenType == JsonToken.None) - { - if (!reader.Read()) - throw JsonReaderException.Create(reader, "Error reading JProperty from JsonReader."); - } - - while (reader.TokenType == JsonToken.Comment) - { - reader.Read(); - } - - if (reader.TokenType != JsonToken.PropertyName) - throw JsonReaderException.Create(reader, "Error reading JProperty from JsonReader. Current JsonReader item is not a property: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); - - JProperty p = new JProperty((string)reader.Value); - p.SetLineInfo(reader as IJsonLineInfo); - - p.ReadTokenFrom(reader); - - return p; - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Linq/JPropertyDescriptor.cs b/Src/Newtonsoft.Json/Linq/JPropertyDescriptor.cs index 377f6e8c..a0b80d8b 100644 --- a/Src/Newtonsoft.Json/Linq/JPropertyDescriptor.cs +++ b/Src/Newtonsoft.Json/Linq/JPropertyDescriptor.cs @@ -30,144 +30,145 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Linq { - /// - /// Represents a view of a . - /// - public class JPropertyDescriptor : PropertyDescriptor - { - private readonly Type _propertyType; - /// - /// Initializes a new instance of the class. + /// Represents a view of a . /// - /// The name. - /// Type of the property. - public JPropertyDescriptor(string name, Type propertyType) - : base(name, null) + public class JPropertyDescriptor : PropertyDescriptor { - ValidationUtils.ArgumentNotNull(name, "name"); - ValidationUtils.ArgumentNotNull(propertyType, "propertyType"); + private readonly Type _propertyType; - _propertyType = propertyType; + /// + /// Initializes a new instance of the class. + /// + /// The name. + /// Type of the property. + public JPropertyDescriptor(string name, Type propertyType) + : base(name, null) + { + ValidationUtils.ArgumentNotNull(name, "name"); + ValidationUtils.ArgumentNotNull(propertyType, "propertyType"); + + _propertyType = propertyType; + } + + private static JObject CastInstance(object instance) + { + return (JObject)instance; + } + + /// + /// When overridden in a derived class, returns whether resetting an object changes its value. + /// + /// + /// true if resetting the component changes its value; otherwise, false. + /// + /// The component to test for reset capability. + /// + public override bool CanResetValue(object component) + { + return false; + } + + /// + /// When overridden in a derived class, gets the current value of the property on a component. + /// + /// + /// The value of a property for a given component. + /// + /// The component with the property for which to retrieve the value. + /// + public override object GetValue(object component) + { + JToken token = CastInstance(component)[Name]; + + return token; + } + + /// + /// When overridden in a derived class, resets the value for this property of the component to the default value. + /// + /// The component with the property value that is to be reset to the default value. + /// + public override void ResetValue(object component) + { + } + + /// + /// When overridden in a derived class, sets the value of the component to a different value. + /// + /// The component with the property value that is to be set. + /// The new value. + /// + public override void SetValue(object component, object value) + { + JToken token = (value is JToken) ? (JToken)value : new JValue(value); + + CastInstance(component)[Name] = token; + } + + /// + /// When overridden in a derived class, determines a value indicating whether the value of this property needs to be persisted. + /// + /// + /// true if the property should be persisted; otherwise, false. + /// + /// The component with the property to be examined for persistence. + /// + public override bool ShouldSerializeValue(object component) + { + return false; + } + + /// + /// When overridden in a derived class, gets the type of the component this property is bound to. + /// + /// + /// A that represents the type of component this property is bound to. When the or methods are invoked, the object specified might be an instance of this type. + /// + public override Type ComponentType + { + get { return typeof(JObject); } + } + + /// + /// When overridden in a derived class, gets a value indicating whether this property is read-only. + /// + /// + /// true if the property is read-only; otherwise, false. + /// + public override bool IsReadOnly + { + get { return false; } + } + + /// + /// When overridden in a derived class, gets the type of the property. + /// + /// + /// A that represents the type of the property. + /// + public override Type PropertyType + { + get { return _propertyType; } + } + + /// + /// Gets the hash code for the name of the member. + /// + /// + /// + /// The hash code for the name of the member. + /// + protected override int NameHashCode + { + get + { + // override property to fix up an error in its documentation + int nameHashCode = base.NameHashCode; + return nameHashCode; + } + } } - - private static JObject CastInstance(object instance) - { - return (JObject)instance; - } - - /// - /// When overridden in a derived class, returns whether resetting an object changes its value. - /// - /// - /// true if resetting the component changes its value; otherwise, false. - /// - /// The component to test for reset capability. - /// - public override bool CanResetValue(object component) - { - return false; - } - - /// - /// When overridden in a derived class, gets the current value of the property on a component. - /// - /// - /// The value of a property for a given component. - /// - /// The component with the property for which to retrieve the value. - /// - public override object GetValue(object component) - { - JToken token = CastInstance(component)[Name]; - - return token; - } - - /// - /// When overridden in a derived class, resets the value for this property of the component to the default value. - /// - /// The component with the property value that is to be reset to the default value. - /// - public override void ResetValue(object component) - { - } - - /// - /// When overridden in a derived class, sets the value of the component to a different value. - /// - /// The component with the property value that is to be set. - /// The new value. - /// - public override void SetValue(object component, object value) - { - JToken token = (value is JToken) ? (JToken) value : new JValue(value); - - CastInstance(component)[Name] = token; - } - - /// - /// When overridden in a derived class, determines a value indicating whether the value of this property needs to be persisted. - /// - /// - /// true if the property should be persisted; otherwise, false. - /// - /// The component with the property to be examined for persistence. - /// - public override bool ShouldSerializeValue(object component) - { - return false; - } - - /// - /// When overridden in a derived class, gets the type of the component this property is bound to. - /// - /// - /// A that represents the type of component this property is bound to. When the or methods are invoked, the object specified might be an instance of this type. - /// - public override Type ComponentType - { - get { return typeof(JObject); } - } - - /// - /// When overridden in a derived class, gets a value indicating whether this property is read-only. - /// - /// - /// true if the property is read-only; otherwise, false. - /// - public override bool IsReadOnly - { - get { return false; } - } - - /// - /// When overridden in a derived class, gets the type of the property. - /// - /// - /// A that represents the type of the property. - /// - public override Type PropertyType - { - get { return _propertyType; } - } - - /// - /// Gets the hash code for the name of the member. - /// - /// - /// - /// The hash code for the name of the member. - /// - protected override int NameHashCode - { - get - { - // override property to fix up an error in its documentation - int nameHashCode = base.NameHashCode; - return nameHashCode; - } - } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Linq/JPropertyKeyedCollection.cs b/Src/Newtonsoft.Json/Linq/JPropertyKeyedCollection.cs index aa063c88..cb3b01b4 100644 --- a/Src/Newtonsoft.Json/Linq/JPropertyKeyedCollection.cs +++ b/Src/Newtonsoft.Json/Linq/JPropertyKeyedCollection.cs @@ -29,203 +29,203 @@ using System.Collections.ObjectModel; namespace Newtonsoft.Json.Linq { - internal class JPropertyKeyedCollection : Collection - { - private static readonly IEqualityComparer Comparer = StringComparer.Ordinal; - - private Dictionary _dictionary; - - private void AddKey(string key, JToken item) + internal class JPropertyKeyedCollection : Collection { - EnsureDictionary(); - _dictionary[key] = item; + private static readonly IEqualityComparer Comparer = StringComparer.Ordinal; + + private Dictionary _dictionary; + + private void AddKey(string key, JToken item) + { + EnsureDictionary(); + _dictionary[key] = item; + } + + protected void ChangeItemKey(JToken item, string newKey) + { + if (!ContainsItem(item)) + throw new ArgumentException("The specified item does not exist in this KeyedCollection."); + + string keyForItem = GetKeyForItem(item); + if (!Comparer.Equals(keyForItem, newKey)) + { + if (newKey != null) + AddKey(newKey, item); + + if (keyForItem != null) + RemoveKey(keyForItem); + } + } + + protected override void ClearItems() + { + base.ClearItems(); + + if (_dictionary != null) + _dictionary.Clear(); + } + + public bool Contains(string key) + { + if (key == null) + throw new ArgumentNullException("key"); + + if (_dictionary != null) + return _dictionary.ContainsKey(key); + + return false; + } + + private bool ContainsItem(JToken item) + { + if (_dictionary == null) + return false; + + string key = GetKeyForItem(item); + JToken value; + return _dictionary.TryGetValue(key, out value); + } + + private void EnsureDictionary() + { + if (_dictionary == null) + _dictionary = new Dictionary(Comparer); + } + + private string GetKeyForItem(JToken item) + { + return ((JProperty)item).Name; + } + + protected override void InsertItem(int index, JToken item) + { + AddKey(GetKeyForItem(item), item); + base.InsertItem(index, item); + } + + public bool Remove(string key) + { + if (key == null) + throw new ArgumentNullException("key"); + + if (_dictionary != null) + return _dictionary.ContainsKey(key) && Remove(_dictionary[key]); + + return false; + } + + protected override void RemoveItem(int index) + { + string keyForItem = GetKeyForItem(Items[index]); + RemoveKey(keyForItem); + base.RemoveItem(index); + } + + private void RemoveKey(string key) + { + if (_dictionary != null) + _dictionary.Remove(key); + } + + protected override void SetItem(int index, JToken item) + { + string keyForItem = GetKeyForItem(item); + string keyAtIndex = GetKeyForItem(Items[index]); + + if (Comparer.Equals(keyAtIndex, keyForItem)) + { + if (_dictionary != null) + _dictionary[keyForItem] = item; + } + else + { + AddKey(keyForItem, item); + + if (keyAtIndex != null) + RemoveKey(keyAtIndex); + } + base.SetItem(index, item); + } + + public JToken this[string key] + { + get + { + if (key == null) + throw new ArgumentNullException("key"); + + if (_dictionary != null) + return _dictionary[key]; + + throw new KeyNotFoundException(); + } + } + + public bool TryGetValue(string key, out JToken value) + { + if (_dictionary == null) + { + value = null; + return false; + } + + return _dictionary.TryGetValue(key, out value); + } + + public ICollection Keys + { + get + { + EnsureDictionary(); + return _dictionary.Keys; + } + } + + public ICollection Values + { + get + { + EnsureDictionary(); + return _dictionary.Values; + } + } + + public bool Compare(JPropertyKeyedCollection other) + { + if (this == other) + return true; + + // dictionaries in JavaScript aren't ordered + // ignore order when comparing properties + Dictionary d1 = _dictionary; + Dictionary d2 = other._dictionary; + + if (d1 == null && d2 == null) + return true; + + if (d1 == null) + return (d2.Count == 0); + + if (d2 == null) + return (d1.Count == 0); + + if (d1.Count != d2.Count) + return false; + + foreach (KeyValuePair keyAndProperty in d1) + { + JToken secondValue; + if (!d2.TryGetValue(keyAndProperty.Key, out secondValue)) + return false; + + JProperty p1 = (JProperty)keyAndProperty.Value; + JProperty p2 = (JProperty)secondValue; + + if (!p1.Value.DeepEquals(p2.Value)) + return false; + } + + return true; + } } - - protected void ChangeItemKey(JToken item, string newKey) - { - if (!ContainsItem(item)) - throw new ArgumentException("The specified item does not exist in this KeyedCollection."); - - string keyForItem = GetKeyForItem(item); - if (!Comparer.Equals(keyForItem, newKey)) - { - if (newKey != null) - AddKey(newKey, item); - - if (keyForItem != null) - RemoveKey(keyForItem); - } - } - - protected override void ClearItems() - { - base.ClearItems(); - - if (_dictionary != null) - _dictionary.Clear(); - } - - public bool Contains(string key) - { - if (key == null) - throw new ArgumentNullException("key"); - - if (_dictionary != null) - return _dictionary.ContainsKey(key); - - return false; - } - - private bool ContainsItem(JToken item) - { - if (_dictionary == null) - return false; - - string key = GetKeyForItem(item); - JToken value; - return _dictionary.TryGetValue(key, out value); - } - - private void EnsureDictionary() - { - if (_dictionary == null) - _dictionary = new Dictionary(Comparer); - } - - private string GetKeyForItem(JToken item) - { - return ((JProperty)item).Name; - } - - protected override void InsertItem(int index, JToken item) - { - AddKey(GetKeyForItem(item), item); - base.InsertItem(index, item); - } - - public bool Remove(string key) - { - if (key == null) - throw new ArgumentNullException("key"); - - if (_dictionary != null) - return _dictionary.ContainsKey(key) && Remove(_dictionary[key]); - - return false; - } - - protected override void RemoveItem(int index) - { - string keyForItem = GetKeyForItem(Items[index]); - RemoveKey(keyForItem); - base.RemoveItem(index); - } - - private void RemoveKey(string key) - { - if (_dictionary != null) - _dictionary.Remove(key); - } - - protected override void SetItem(int index, JToken item) - { - string keyForItem = GetKeyForItem(item); - string keyAtIndex = GetKeyForItem(Items[index]); - - if (Comparer.Equals(keyAtIndex, keyForItem)) - { - if (_dictionary != null) - _dictionary[keyForItem] = item; - } - else - { - AddKey(keyForItem, item); - - if (keyAtIndex != null) - RemoveKey(keyAtIndex); - } - base.SetItem(index, item); - } - - public JToken this[string key] - { - get - { - if (key == null) - throw new ArgumentNullException("key"); - - if (_dictionary != null) - return _dictionary[key]; - - throw new KeyNotFoundException(); - } - } - - public bool TryGetValue(string key, out JToken value) - { - if (_dictionary == null) - { - value = null; - return false; - } - - return _dictionary.TryGetValue(key, out value); - } - - public ICollection Keys - { - get - { - EnsureDictionary(); - return _dictionary.Keys; - } - } - - public ICollection Values - { - get - { - EnsureDictionary(); - return _dictionary.Values; - } - } - - public bool Compare(JPropertyKeyedCollection other) - { - if (this == other) - return true; - - // dictionaries in JavaScript aren't ordered - // ignore order when comparing properties - Dictionary d1 = _dictionary; - Dictionary d2 = other._dictionary; - - if (d1 == null && d2 == null) - return true; - - if (d1 == null) - return (d2.Count == 0); - - if (d2 == null) - return (d1.Count == 0); - - if (d1.Count != d2.Count) - return false; - - foreach (KeyValuePair keyAndProperty in d1) - { - JToken secondValue; - if (!d2.TryGetValue(keyAndProperty.Key, out secondValue)) - return false; - - JProperty p1 = (JProperty)keyAndProperty.Value; - JProperty p2 = (JProperty)secondValue; - - if (!p1.Value.DeepEquals(p2.Value)) - return false; - } - - return true; - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Linq/JRaw.cs b/Src/Newtonsoft.Json/Linq/JRaw.cs index b9c4860f..fec5a57d 100644 --- a/Src/Newtonsoft.Json/Linq/JRaw.cs +++ b/Src/Newtonsoft.Json/Linq/JRaw.cs @@ -28,48 +28,48 @@ using System.IO; namespace Newtonsoft.Json.Linq { - /// - /// Represents a raw JSON string. - /// - public class JRaw : JValue - { /// - /// Initializes a new instance of the class from another object. + /// Represents a raw JSON string. /// - /// A object to copy from. - public JRaw(JRaw other) - : base(other) + public class JRaw : JValue { - } + /// + /// Initializes a new instance of the class from another object. + /// + /// A object to copy from. + public JRaw(JRaw other) + : base(other) + { + } - /// - /// Initializes a new instance of the class. - /// - /// The raw json. - public JRaw(object rawJson) - : base(rawJson, JTokenType.Raw) - { - } + /// + /// Initializes a new instance of the class. + /// + /// The raw json. + public JRaw(object rawJson) + : base(rawJson, JTokenType.Raw) + { + } - /// - /// Creates an instance of with the content of the reader's current token. - /// - /// The reader. - /// An instance of with the content of the reader's current token. - public static JRaw Create(JsonReader reader) - { - using (StringWriter sw = new StringWriter(CultureInfo.InvariantCulture)) - using (JsonTextWriter jsonWriter = new JsonTextWriter(sw)) - { - jsonWriter.WriteToken(reader); + /// + /// Creates an instance of with the content of the reader's current token. + /// + /// The reader. + /// An instance of with the content of the reader's current token. + public static JRaw Create(JsonReader reader) + { + using (StringWriter sw = new StringWriter(CultureInfo.InvariantCulture)) + using (JsonTextWriter jsonWriter = new JsonTextWriter(sw)) + { + jsonWriter.WriteToken(reader); - return new JRaw(sw.ToString()); - } - } + return new JRaw(sw.ToString()); + } + } - internal override JToken CloneToken() - { - return new JRaw(this); + internal override JToken CloneToken() + { + return new JRaw(this); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Linq/JToken.cs b/Src/Newtonsoft.Json/Linq/JToken.cs index 61f4a97f..9832851a 100644 --- a/Src/Newtonsoft.Json/Linq/JToken.cs +++ b/Src/Newtonsoft.Json/Linq/JToken.cs @@ -42,1940 +42,1941 @@ using System.Collections; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json.Linq { - /// - /// Represents an abstract JSON token. - /// - public abstract class JToken : IJEnumerable, IJsonLineInfo + /// + /// Represents an abstract JSON token. + /// + public abstract class JToken : IJEnumerable, IJsonLineInfo #if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) - , ICloneable + , ICloneable #endif #if !(NET35 || NET20 || PORTABLE40) - , IDynamicMetaObjectProvider + , IDynamicMetaObjectProvider #endif - { - private JContainer _parent; - private JToken _previous; - private JToken _next; - private static JTokenEqualityComparer _equalityComparer; - - private int? _lineNumber; - private int? _linePosition; - - private static readonly JTokenType[] BooleanTypes = new[] { JTokenType.Integer, JTokenType.Float, JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.Boolean }; - private static readonly JTokenType[] NumberTypes = new[] { JTokenType.Integer, JTokenType.Float, JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.Boolean }; - private static readonly JTokenType[] BigIntegerTypes = new[] { JTokenType.Integer, JTokenType.Float, JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.Boolean, JTokenType.Bytes }; - private static readonly JTokenType[] StringTypes = new[] { JTokenType.Date, JTokenType.Integer, JTokenType.Float, JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.Boolean, JTokenType.Bytes, JTokenType.Guid, JTokenType.TimeSpan, JTokenType.Uri }; - private static readonly JTokenType[] GuidTypes = new[] { JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.Guid, JTokenType.Bytes }; - private static readonly JTokenType[] TimeSpanTypes = new[] { JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.TimeSpan }; - private static readonly JTokenType[] UriTypes = new[] { JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.Uri }; - private static readonly JTokenType[] CharTypes = new[] { JTokenType.Integer, JTokenType.Float, JTokenType.String, JTokenType.Comment, JTokenType.Raw }; - private static readonly JTokenType[] DateTimeTypes = new[] { JTokenType.Date, JTokenType.String, JTokenType.Comment, JTokenType.Raw }; - private static readonly JTokenType[] BytesTypes = new[] { JTokenType.Bytes, JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.Integer }; - - /// - /// Gets a comparer that can compare two tokens for value equality. - /// - /// A that can compare two nodes for value equality. - public static JTokenEqualityComparer EqualityComparer { - get - { - if (_equalityComparer == null) - _equalityComparer = new JTokenEqualityComparer(); + private JContainer _parent; + private JToken _previous; + private JToken _next; + private static JTokenEqualityComparer _equalityComparer; - return _equalityComparer; - } - } + private int? _lineNumber; + private int? _linePosition; - /// - /// Gets or sets the parent. - /// - /// The parent. - public JContainer Parent - { - [DebuggerStepThrough] - get { return _parent; } - internal set { _parent = value; } - } + private static readonly JTokenType[] BooleanTypes = new[] { JTokenType.Integer, JTokenType.Float, JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.Boolean }; + private static readonly JTokenType[] NumberTypes = new[] { JTokenType.Integer, JTokenType.Float, JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.Boolean }; + private static readonly JTokenType[] BigIntegerTypes = new[] { JTokenType.Integer, JTokenType.Float, JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.Boolean, JTokenType.Bytes }; + private static readonly JTokenType[] StringTypes = new[] { JTokenType.Date, JTokenType.Integer, JTokenType.Float, JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.Boolean, JTokenType.Bytes, JTokenType.Guid, JTokenType.TimeSpan, JTokenType.Uri }; + private static readonly JTokenType[] GuidTypes = new[] { JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.Guid, JTokenType.Bytes }; + private static readonly JTokenType[] TimeSpanTypes = new[] { JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.TimeSpan }; + private static readonly JTokenType[] UriTypes = new[] { JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.Uri }; + private static readonly JTokenType[] CharTypes = new[] { JTokenType.Integer, JTokenType.Float, JTokenType.String, JTokenType.Comment, JTokenType.Raw }; + private static readonly JTokenType[] DateTimeTypes = new[] { JTokenType.Date, JTokenType.String, JTokenType.Comment, JTokenType.Raw }; + private static readonly JTokenType[] BytesTypes = new[] { JTokenType.Bytes, JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.Integer }; - /// - /// Gets the root of this . - /// - /// The root of this . - public JToken Root - { - get - { - JContainer parent = Parent; - if (parent == null) - return this; - - while (parent.Parent != null) + /// + /// Gets a comparer that can compare two tokens for value equality. + /// + /// A that can compare two nodes for value equality. + public static JTokenEqualityComparer EqualityComparer { - parent = parent.Parent; - } - - return parent; - } - } - - internal abstract JToken CloneToken(); - internal abstract bool DeepEquals(JToken node); - - /// - /// Gets the node type for this . - /// - /// The type. - public abstract JTokenType Type { get; } - - /// - /// Gets a value indicating whether this token has child tokens. - /// - /// - /// true if this token has child values; otherwise, false. - /// - public abstract bool HasValues { get; } - - /// - /// Compares the values of two tokens, including the values of all descendant tokens. - /// - /// The first to compare. - /// The second to compare. - /// true if the tokens are equal; otherwise false. - public static bool DeepEquals(JToken t1, JToken t2) - { - return (t1 == t2 || (t1 != null && t2 != null && t1.DeepEquals(t2))); - } - - /// - /// Gets the next sibling token of this node. - /// - /// The that contains the next sibling token. - public JToken Next - { - get { return _next; } - internal set { _next = value; } - } - - /// - /// Gets the previous sibling token of this node. - /// - /// The that contains the previous sibling token. - public JToken Previous - { - get { return _previous; } - internal set { _previous = value; } - } - - /// - /// Gets the path of the JSON token. - /// - public string Path - { - get - { - if (Parent == null) - return string.Empty; - - IList ancestors = Ancestors().Reverse().ToList(); - ancestors.Add(this); - - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < ancestors.Count; i++) - { - JToken current = ancestors[i]; - JToken next = (i + 1 < ancestors.Count) ? ancestors[i + 1] : null; - - if (next != null) - { - switch (current.Type) + get { - case JTokenType.Property: - JProperty property = (JProperty)current; + if (_equalityComparer == null) + _equalityComparer = new JTokenEqualityComparer(); - if (sb.Length > 0) - sb.Append("."); - - sb.Append(property.Name); - break; - case JTokenType.Array: - case JTokenType.Constructor: - int index = ((IList)current).IndexOf(next); - - sb.Append("[" + index + "]"); - break; + return _equalityComparer; } - } } - return sb.ToString(); - } - } - - internal JToken() - { - } - - /// - /// Adds the specified content immediately after this token. - /// - /// A content object that contains simple content or a collection of content objects to be added after this token. - public void AddAfterSelf(object content) - { - if (_parent == null) - throw new InvalidOperationException("The parent is missing."); - - int index = _parent.IndexOfItem(this); - _parent.AddInternal(index + 1, content, false); - } - - /// - /// Adds the specified content immediately before this token. - /// - /// A content object that contains simple content or a collection of content objects to be added before this token. - public void AddBeforeSelf(object content) - { - if (_parent == null) - throw new InvalidOperationException("The parent is missing."); - - int index = _parent.IndexOfItem(this); - _parent.AddInternal(index, content, false); - } - - /// - /// Returns a collection of the ancestor tokens of this token. - /// - /// A collection of the ancestor tokens of this token. - public IEnumerable Ancestors() - { - for (JToken parent = Parent; parent != null; parent = parent.Parent) - { - yield return parent; - } - } - - /// - /// Returns a collection of the sibling tokens after this token, in document order. - /// - /// A collection of the sibling tokens after this tokens, in document order. - public IEnumerable AfterSelf() - { - if (Parent == null) - yield break; - - for (JToken o = Next; o != null; o = o.Next) - { - yield return o; - } - } - - /// - /// Returns a collection of the sibling tokens before this token, in document order. - /// - /// A collection of the sibling tokens before this token, in document order. - public IEnumerable BeforeSelf() - { - for (JToken o = Parent.First; o != this; o = o.Next) - { - yield return o; - } - } - - /// - /// Gets the with the specified key. - /// - /// The with the specified key. - public virtual JToken this[object key] - { - get { throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); } - set { throw new InvalidOperationException("Cannot set child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); } - } - - /// - /// Gets the with the specified key converted to the specified type. - /// - /// The type to convert the token to. - /// The token key. - /// The converted token value. - public virtual T Value(object key) - { - JToken token = this[key]; - - return Extensions.Convert(token); - } - - /// - /// Get the first child token of this token. - /// - /// A containing the first child token of the . - public virtual JToken First - { - get { throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); } - } - - /// - /// Get the last child token of this token. - /// - /// A containing the last child token of the . - public virtual JToken Last - { - get { throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); } - } - - /// - /// Returns a collection of the child tokens of this token, in document order. - /// - /// An of containing the child tokens of this , in document order. - public virtual JEnumerable Children() - { - return JEnumerable.Empty; - } - - /// - /// Returns a collection of the child tokens of this token, in document order, filtered by the specified type. - /// - /// The type to filter the child tokens on. - /// A containing the child tokens of this , in document order. - public JEnumerable Children() where T : JToken - { - return new JEnumerable(Children().OfType()); - } - - /// - /// Returns a collection of the child values of this token, in document order. - /// - /// The type to convert the values to. - /// A containing the child values of this , in document order. - public virtual IEnumerable Values() - { - throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); - } - - /// - /// Removes this token from its parent. - /// - public void Remove() - { - if (_parent == null) - throw new InvalidOperationException("The parent is missing."); - - _parent.RemoveItem(this); - } - - /// - /// Replaces this token with the specified token. - /// - /// The value. - public void Replace(JToken value) - { - if (_parent == null) - throw new InvalidOperationException("The parent is missing."); - - _parent.ReplaceItem(this, value); - } - - /// - /// Writes this token to a . - /// - /// A into which this method will write. - /// A collection of which will be used when writing the token. - public abstract void WriteTo(JsonWriter writer, params JsonConverter[] converters); - - /// - /// Returns the indented JSON for this token. - /// - /// - /// The indented JSON for this token. - /// - public override string ToString() - { - return ToString(Formatting.Indented); - } - - /// - /// Returns the JSON for this token using the given formatting and converters. - /// - /// Indicates how the output is formatted. - /// A collection of which will be used when writing the token. - /// The JSON for this token using the given formatting and converters. - public string ToString(Formatting formatting, params JsonConverter[] converters) - { - using (StringWriter sw = new StringWriter(CultureInfo.InvariantCulture)) - { - JsonTextWriter jw = new JsonTextWriter(sw); - jw.Formatting = formatting; - - WriteTo(jw, converters); - - return sw.ToString(); - } - } - - private static JValue EnsureValue(JToken value) - { - if (value == null) - throw new ArgumentNullException("value"); - - if (value is JProperty) - value = ((JProperty)value).Value; - - JValue v = value as JValue; - - return v; - } - - private static string GetType(JToken token) - { - ValidationUtils.ArgumentNotNull(token, "token"); - - if (token is JProperty) - token = ((JProperty)token).Value; - - return token.Type.ToString(); - } - - private static bool ValidateToken(JToken o, JTokenType[] validTypes, bool nullable) - { - return (Array.IndexOf(validTypes, o.Type) != -1) || (nullable && (o.Type == JTokenType.Null || o.Type == JTokenType.Undefined)); - } - - #region Cast from operators - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator bool(JToken value) - { - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, BooleanTypes, false)) - throw new ArgumentException("Can not convert {0} to Boolean.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (v.Value is BigInteger) - return Convert.ToBoolean((int)(BigInteger)v.Value); -#endif - - return Convert.ToBoolean(v.Value, CultureInfo.InvariantCulture); - } - -#if !NET20 - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator DateTimeOffset(JToken value) - { - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, DateTimeTypes, false)) - throw new ArgumentException("Can not convert {0} to DateTimeOffset.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - - if (v.Value is DateTimeOffset) - return (DateTimeOffset)v.Value; - if (v.Value is string) - return DateTimeOffset.Parse((string)v.Value, CultureInfo.InvariantCulture); - return new DateTimeOffset(Convert.ToDateTime(v.Value, CultureInfo.InvariantCulture)); - } -#endif - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator bool?(JToken value) - { - if (value == null) - return null; - - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, BooleanTypes, true)) - throw new ArgumentException("Can not convert {0} to Boolean.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (v.Value is BigInteger) - return Convert.ToBoolean((int)(BigInteger)v.Value); -#endif - - return (v.Value != null) ? (bool?)Convert.ToBoolean(v.Value, CultureInfo.InvariantCulture) : null; - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator long(JToken value) - { - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, NumberTypes, false)) - throw new ArgumentException("Can not convert {0} to Int64.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (v.Value is BigInteger) - return (long)(BigInteger)v.Value; -#endif - - return Convert.ToInt64(v.Value, CultureInfo.InvariantCulture); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator DateTime?(JToken value) - { - if (value == null) - return null; - - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, DateTimeTypes, true)) - throw new ArgumentException("Can not convert {0} to DateTime.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - -#if !NET20 - if (v.Value is DateTimeOffset) - return ((DateTimeOffset)v.Value).DateTime; -#endif - - return (v.Value != null) ? (DateTime?)Convert.ToDateTime(v.Value, CultureInfo.InvariantCulture) : null; - } - -#if !NET20 - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator DateTimeOffset?(JToken value) - { - if (value == null) - return null; - - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, DateTimeTypes, true)) - throw new ArgumentException("Can not convert {0} to DateTimeOffset.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - - if (v.Value == null) - return null; - if (v.Value is DateTimeOffset) - return (DateTimeOffset?)v.Value; - if (v.Value is string) - return DateTimeOffset.Parse((string)v.Value, CultureInfo.InvariantCulture); - return new DateTimeOffset(Convert.ToDateTime(v.Value, CultureInfo.InvariantCulture)); - } -#endif - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator decimal?(JToken value) - { - if (value == null) - return null; - - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, NumberTypes, true)) - throw new ArgumentException("Can not convert {0} to Decimal.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (v.Value is BigInteger) - return (decimal?)(BigInteger)v.Value; -#endif - - return (v.Value != null) ? (decimal?)Convert.ToDecimal(v.Value, CultureInfo.InvariantCulture) : null; - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator double?(JToken value) - { - if (value == null) - return null; - - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, NumberTypes, true)) - throw new ArgumentException("Can not convert {0} to Double.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (v.Value is BigInteger) - return (double?)(BigInteger)v.Value; -#endif - - return (v.Value != null) ? (double?)Convert.ToDouble(v.Value, CultureInfo.InvariantCulture) : null; - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator char?(JToken value) - { - if (value == null) - return null; - - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, CharTypes, true)) - throw new ArgumentException("Can not convert {0} to Char.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (v.Value is BigInteger) - return (char?)(BigInteger)v.Value; -#endif - - return (v.Value != null) ? (char?)Convert.ToChar(v.Value, CultureInfo.InvariantCulture) : null; - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator int(JToken value) - { - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, NumberTypes, false)) - throw new ArgumentException("Can not convert {0} to Int32.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (v.Value is BigInteger) - return (int)(BigInteger)v.Value; -#endif - - return Convert.ToInt32(v.Value, CultureInfo.InvariantCulture); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator short(JToken value) - { - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, NumberTypes, false)) - throw new ArgumentException("Can not convert {0} to Int16.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (v.Value is BigInteger) - return (short)(BigInteger)v.Value; -#endif - - return Convert.ToInt16(v.Value, CultureInfo.InvariantCulture); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - [CLSCompliant(false)] - public static explicit operator ushort(JToken value) - { - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, NumberTypes, false)) - throw new ArgumentException("Can not convert {0} to UInt16.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (v.Value is BigInteger) - return (ushort)(BigInteger)v.Value; -#endif - - return Convert.ToUInt16(v.Value, CultureInfo.InvariantCulture); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - [CLSCompliant(false)] - public static explicit operator char(JToken value) - { - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, CharTypes, false)) - throw new ArgumentException("Can not convert {0} to Char.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (v.Value is BigInteger) - return (char)(BigInteger)v.Value; -#endif - - return Convert.ToChar(v.Value, CultureInfo.InvariantCulture); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator byte(JToken value) - { - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, NumberTypes, false)) - throw new ArgumentException("Can not convert {0} to Byte.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (v.Value is BigInteger) - return (byte)(BigInteger)v.Value; -#endif - - return Convert.ToByte(v.Value, CultureInfo.InvariantCulture); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - [CLSCompliant(false)] - public static explicit operator sbyte(JToken value) - { - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, NumberTypes, false)) - throw new ArgumentException("Can not convert {0} to SByte.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (v.Value is BigInteger) - return (sbyte)(BigInteger)v.Value; -#endif - - return Convert.ToSByte(v.Value, CultureInfo.InvariantCulture); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator int?(JToken value) - { - if (value == null) - return null; - - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, NumberTypes, true)) - throw new ArgumentException("Can not convert {0} to Int32.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (v.Value is BigInteger) - return (int?)(BigInteger)v.Value; -#endif - - return (v.Value != null) ? (int?)Convert.ToInt32(v.Value, CultureInfo.InvariantCulture) : null; - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator short?(JToken value) - { - if (value == null) - return null; - - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, NumberTypes, true)) - throw new ArgumentException("Can not convert {0} to Int16.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (v.Value is BigInteger) - return (short?)(BigInteger)v.Value; -#endif - - return (v.Value != null) ? (short?)Convert.ToInt16(v.Value, CultureInfo.InvariantCulture) : null; - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - [CLSCompliant(false)] - public static explicit operator ushort?(JToken value) - { - if (value == null) - return null; - - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, NumberTypes, true)) - throw new ArgumentException("Can not convert {0} to UInt16.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (v.Value is BigInteger) - return (ushort?)(BigInteger)v.Value; -#endif - - return (v.Value != null) ? (ushort?)Convert.ToUInt16(v.Value, CultureInfo.InvariantCulture) : null; - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator byte?(JToken value) - { - if (value == null) - return null; - - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, NumberTypes, true)) - throw new ArgumentException("Can not convert {0} to Byte.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (v.Value is BigInteger) - return (byte?)(BigInteger)v.Value; -#endif - - return (v.Value != null) ? (byte?)Convert.ToByte(v.Value, CultureInfo.InvariantCulture) : null; - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - [CLSCompliant(false)] - public static explicit operator sbyte?(JToken value) - { - if (value == null) - return null; - - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, NumberTypes, true)) - throw new ArgumentException("Can not convert {0} to SByte.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (v.Value is BigInteger) - return (sbyte?)(BigInteger)v.Value; -#endif - - return (v.Value != null) ? (sbyte?)Convert.ToByte(v.Value, CultureInfo.InvariantCulture) : null; - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator DateTime(JToken value) - { - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, DateTimeTypes, false)) - throw new ArgumentException("Can not convert {0} to DateTime.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - -#if !NET20 - if (v.Value is DateTimeOffset) - return ((DateTimeOffset) v.Value).DateTime; -#endif - - return Convert.ToDateTime(v.Value, CultureInfo.InvariantCulture); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator long?(JToken value) - { - if (value == null) - return null; - - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, NumberTypes, true)) - throw new ArgumentException("Can not convert {0} to Int64.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (v.Value is BigInteger) - return (long?)(BigInteger)v.Value; -#endif - - return (v.Value != null) ? (long?)Convert.ToInt64(v.Value, CultureInfo.InvariantCulture) : null; - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator float?(JToken value) - { - if (value == null) - return null; - - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, NumberTypes, true)) - throw new ArgumentException("Can not convert {0} to Single.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (v.Value is BigInteger) - return (float?)(BigInteger)v.Value; -#endif - - return (v.Value != null) ? (float?)Convert.ToSingle(v.Value, CultureInfo.InvariantCulture) : null; - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator decimal(JToken value) - { - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, NumberTypes, false)) - throw new ArgumentException("Can not convert {0} to Decimal.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (v.Value is BigInteger) - return (decimal)(BigInteger)v.Value; -#endif - - return Convert.ToDecimal(v.Value, CultureInfo.InvariantCulture); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - [CLSCompliant(false)] - public static explicit operator uint?(JToken value) - { - if (value == null) - return null; - - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, NumberTypes, true)) - throw new ArgumentException("Can not convert {0} to UInt32.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (v.Value is BigInteger) - return (uint?)(BigInteger)v.Value; -#endif - - return (v.Value != null) ? (uint?)Convert.ToUInt32(v.Value, CultureInfo.InvariantCulture) : null; - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - [CLSCompliant(false)] - public static explicit operator ulong?(JToken value) - { - if (value == null) - return null; - - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, NumberTypes, true)) - throw new ArgumentException("Can not convert {0} to UInt64.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (v.Value is BigInteger) - return (ulong?)(BigInteger)v.Value; -#endif - - return (v.Value != null) ? (ulong?)Convert.ToUInt64(v.Value, CultureInfo.InvariantCulture) : null; - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator double(JToken value) - { - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, NumberTypes, false)) - throw new ArgumentException("Can not convert {0} to Double.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (v.Value is BigInteger) - return (double) (BigInteger) v.Value; -#endif - - return Convert.ToDouble(v.Value, CultureInfo.InvariantCulture); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator float(JToken value) - { - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, NumberTypes, false)) - throw new ArgumentException("Can not convert {0} to Single.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (v.Value is BigInteger) - return (float)(BigInteger)v.Value; -#endif - - return Convert.ToSingle(v.Value, CultureInfo.InvariantCulture); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator string(JToken value) - { - if (value == null) - return null; - - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, StringTypes, true)) - throw new ArgumentException("Can not convert {0} to String.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - - if (v.Value == null) - return null; - if (v.Value is byte[]) - return Convert.ToBase64String((byte[]) v.Value); -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (v.Value is BigInteger) - return ((BigInteger)v.Value).ToString(CultureInfo.InvariantCulture); -#endif - - return Convert.ToString(v.Value, CultureInfo.InvariantCulture); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - [CLSCompliant(false)] - public static explicit operator uint(JToken value) - { - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, NumberTypes, false)) - throw new ArgumentException("Can not convert {0} to UInt32.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (v.Value is BigInteger) - return (uint)(BigInteger)v.Value; -#endif - - return Convert.ToUInt32(v.Value, CultureInfo.InvariantCulture); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - [CLSCompliant(false)] - public static explicit operator ulong(JToken value) - { - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, NumberTypes, false)) - throw new ArgumentException("Can not convert {0} to UInt64.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (v.Value is BigInteger) - return (ulong)(BigInteger)v.Value; -#endif - - return Convert.ToUInt64(v.Value, CultureInfo.InvariantCulture); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator byte[](JToken value) - { - if (value == null) - return null; - - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, BytesTypes, false)) - throw new ArgumentException("Can not convert {0} to byte array.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - - if (v.Value is string) - return Convert.FromBase64String(Convert.ToString(v.Value, CultureInfo.InvariantCulture)); -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (v.Value is BigInteger) - return ((BigInteger)v.Value).ToByteArray(); -#endif - - if (v.Value is byte[]) - return (byte[])v.Value; - - throw new ArgumentException("Can not convert {0} to byte array.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Guid(JToken value) - { - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, GuidTypes, false)) - throw new ArgumentException("Can not convert {0} to Guid.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - - if (v.Value is byte[]) - return new Guid((byte[]) v.Value); - - return (v.Value is Guid) ? (Guid) v.Value : new Guid(Convert.ToString(v.Value, CultureInfo.InvariantCulture)); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Guid?(JToken value) - { - if (value == null) - return null; - - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, GuidTypes, true)) - throw new ArgumentException("Can not convert {0} to Guid.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - - if (v.Value == null) - return null; - - if (v.Value is byte[]) - return new Guid((byte[])v.Value); - - return (v.Value is Guid) ? (Guid)v.Value : new Guid(Convert.ToString(v.Value, CultureInfo.InvariantCulture)); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator TimeSpan(JToken value) - { - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, TimeSpanTypes, false)) - throw new ArgumentException("Can not convert {0} to TimeSpan.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - - return (v.Value is TimeSpan) ? (TimeSpan)v.Value : ConvertUtils.ParseTimeSpan(Convert.ToString(v.Value, CultureInfo.InvariantCulture)); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator TimeSpan?(JToken value) - { - if (value == null) - return null; - - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, TimeSpanTypes, true)) - throw new ArgumentException("Can not convert {0} to TimeSpan.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - - if (v.Value == null) - return null; - - return (v.Value is TimeSpan) ? (TimeSpan)v.Value : ConvertUtils.ParseTimeSpan(Convert.ToString(v.Value, CultureInfo.InvariantCulture)); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator Uri(JToken value) - { - if (value == null) - return null; - - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, UriTypes, true)) - throw new ArgumentException("Can not convert {0} to Uri.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - - if (v.Value == null) - return null; - - return (v.Value is Uri) ? (Uri)v.Value : new Uri(Convert.ToString(v.Value, CultureInfo.InvariantCulture)); - } - -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - private static BigInteger ToBigInteger(JToken value) - { - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, BigIntegerTypes, false)) - throw new ArgumentException("Can not convert {0} to BigInteger.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - - return ConvertUtils.ToBigInteger(v.Value); - } - - private static BigInteger? ToBigIntegerNullable(JToken value) - { - JValue v = EnsureValue(value); - if (v == null || !ValidateToken(v, BigIntegerTypes, true)) - throw new ArgumentException("Can not convert {0} to BigInteger.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); - - if (v.Value == null) - return null; - - return ConvertUtils.ToBigInteger(v.Value); - } -#endif - #endregion - - #region Cast to operators - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - public static implicit operator JToken(bool value) - { - return new JValue(value); - } - -#if !NET20 - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - public static implicit operator JToken(DateTimeOffset value) - { - return new JValue(value); - } -#endif - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - public static implicit operator JToken(byte value) - { - return new JValue(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - public static implicit operator JToken(byte? value) - { - return new JValue(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - [CLSCompliant(false)] - public static implicit operator JToken(sbyte value) - { - return new JValue(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - [CLSCompliant(false)] - public static implicit operator JToken(sbyte? value) - { - return new JValue(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - public static implicit operator JToken(bool? value) - { - return new JValue(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - public static implicit operator JToken(long value) - { - return new JValue(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - public static implicit operator JToken(DateTime? value) - { - return new JValue(value); - } - -#if !NET20 - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - public static implicit operator JToken(DateTimeOffset? value) - { - return new JValue(value); - } -#endif - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - public static implicit operator JToken(decimal? value) - { - return new JValue(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - public static implicit operator JToken(double? value) - { - return new JValue(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - [CLSCompliant(false)] - public static implicit operator JToken(short value) - { - return new JValue(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - [CLSCompliant(false)] - public static implicit operator JToken(ushort value) - { - return new JValue(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - public static implicit operator JToken(int value) - { - return new JValue(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - public static implicit operator JToken(int? value) - { - return new JValue(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - public static implicit operator JToken(DateTime value) - { - return new JValue(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - public static implicit operator JToken(long? value) - { - return new JValue(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - public static implicit operator JToken(float? value) - { - return new JValue(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - public static implicit operator JToken(decimal value) - { - return new JValue(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - [CLSCompliant(false)] - public static implicit operator JToken(short? value) - { - return new JValue(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - [CLSCompliant(false)] - public static implicit operator JToken(ushort? value) - { - return new JValue(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - [CLSCompliant(false)] - public static implicit operator JToken(uint? value) - { - return new JValue(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - [CLSCompliant(false)] - public static implicit operator JToken(ulong? value) - { - return new JValue(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - public static implicit operator JToken(double value) - { - return new JValue(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - public static implicit operator JToken(float value) - { - return new JValue(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - public static implicit operator JToken(string value) - { - return new JValue(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - [CLSCompliant(false)] - public static implicit operator JToken(uint value) - { - return new JValue(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - [CLSCompliant(false)] - public static implicit operator JToken(ulong value) - { - return new JValue(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - public static implicit operator JToken(byte[] value) - { - return new JValue(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - public static implicit operator JToken(Uri value) - { - return new JValue(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - public static implicit operator JToken(TimeSpan value) - { - return new JValue(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - public static implicit operator JToken(TimeSpan? value) - { - return new JValue(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - public static implicit operator JToken(Guid value) - { - return new JValue(value); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The value to create a from. - /// The initialized with the specified value. - public static implicit operator JToken(Guid? value) - { - return new JValue(value); - } - #endregion - - IEnumerator IEnumerable.GetEnumerator() - { - return ((IEnumerable)this).GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return Children().GetEnumerator(); - } - - internal abstract int GetDeepHashCode(); - - IJEnumerable IJEnumerable.this[object key] - { - get { return this[key]; } - } - - /// - /// Creates an for this token. - /// - /// An that can be used to read this token and its descendants. - public JsonReader CreateReader() - { - return new JTokenReader(this); - } - - internal static JToken FromObjectInternal(object o, JsonSerializer jsonSerializer) - { - ValidationUtils.ArgumentNotNull(o, "o"); - ValidationUtils.ArgumentNotNull(jsonSerializer, "jsonSerializer"); - - JToken token; - using (JTokenWriter jsonWriter = new JTokenWriter()) - { - jsonSerializer.Serialize(jsonWriter, o); - token = jsonWriter.Token; - } - - return token; - } - - /// - /// Creates a from an object. - /// - /// The object that will be used to create . - /// A with the value of the specified object - public static JToken FromObject(object o) - { - return FromObjectInternal(o, JsonSerializer.CreateDefault()); - } - - /// - /// Creates a from an object using the specified . - /// - /// The object that will be used to create . - /// The that will be used when reading the object. - /// A with the value of the specified object - public static JToken FromObject(object o, JsonSerializer jsonSerializer) - { - return FromObjectInternal(o, jsonSerializer); - } - - /// - /// Creates the specified .NET type from the . - /// - /// The object type that the token will be deserialized to. - /// The new object created from the JSON value. - public T ToObject() - { - return (T)ToObject(typeof(T)); - } - - /// - /// Creates the specified .NET type from the . - /// - /// The object type that the token will be deserialized to. - /// The new object created from the JSON value. - public object ToObject(Type objectType) - { - if (JsonConvert.DefaultSettings == null) - { - PrimitiveTypeCode typeCode = ConvertUtils.GetTypeCode(objectType); - - switch (typeCode) + /// + /// Gets or sets the parent. + /// + /// The parent. + public JContainer Parent { - 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; -#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; -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - case PrimitiveTypeCode.BigIntegerNullable: - return ToBigIntegerNullable(this); - case PrimitiveTypeCode.BigInteger: - return ToBigInteger(this); -#endif + [DebuggerStepThrough] + get { return _parent; } + internal set { _parent = value; } } - } - return ToObject(objectType, JsonSerializer.CreateDefault()); - } + /// + /// Gets the root of this . + /// + /// The root of this . + public JToken Root + { + get + { + JContainer parent = Parent; + if (parent == null) + return this; - /// - /// Creates the specified .NET type from the using the specified . - /// - /// The object type that the token will be deserialized to. - /// The that will be used when creating the object. - /// The new object created from the JSON value. - public T ToObject(JsonSerializer jsonSerializer) - { - return (T)ToObject(typeof(T), jsonSerializer); - } + while (parent.Parent != null) + { + parent = parent.Parent; + } - /// - /// Creates the specified .NET type from the using the specified . - /// - /// The object type that the token will be deserialized to. - /// The that will be used when creating the object. - /// The new object created from the JSON value. - public object ToObject(Type objectType, JsonSerializer jsonSerializer) - { - ValidationUtils.ArgumentNotNull(jsonSerializer, "jsonSerializer"); + return parent; + } + } - using (JTokenReader jsonReader = new JTokenReader(this)) - { - return jsonSerializer.Deserialize(jsonReader, objectType); - } - } + internal abstract JToken CloneToken(); + internal abstract bool DeepEquals(JToken node); - /// - /// Creates a from a . - /// - /// An positioned at the token to read into this . - /// - /// An that contains the token and its descendant tokens - /// that were read from the reader. The runtime type of the token is determined - /// by the token type of the first token encountered in the reader. - /// - public static JToken ReadFrom(JsonReader reader) - { - ValidationUtils.ArgumentNotNull(reader, "reader"); + /// + /// Gets the node type for this . + /// + /// The type. + public abstract JTokenType Type { get; } - if (reader.TokenType == JsonToken.None) - { - if (!reader.Read()) - throw JsonReaderException.Create(reader, "Error reading JToken from JsonReader."); - } + /// + /// Gets a value indicating whether this token has child tokens. + /// + /// + /// true if this token has child values; otherwise, false. + /// + public abstract bool HasValues { get; } - if (reader.TokenType == JsonToken.StartObject) - return JObject.Load(reader); + /// + /// Compares the values of two tokens, including the values of all descendant tokens. + /// + /// The first to compare. + /// The second to compare. + /// true if the tokens are equal; otherwise false. + public static bool DeepEquals(JToken t1, JToken t2) + { + return (t1 == t2 || (t1 != null && t2 != null && t1.DeepEquals(t2))); + } - if (reader.TokenType == JsonToken.StartArray) - return JArray.Load(reader); + /// + /// Gets the next sibling token of this node. + /// + /// The that contains the next sibling token. + public JToken Next + { + get { return _next; } + internal set { _next = value; } + } - if (reader.TokenType == JsonToken.PropertyName) - return JProperty.Load(reader); + /// + /// Gets the previous sibling token of this node. + /// + /// The that contains the previous sibling token. + public JToken Previous + { + get { return _previous; } + internal set { _previous = value; } + } - if (reader.TokenType == JsonToken.StartConstructor) - return JConstructor.Load(reader); + /// + /// Gets the path of the JSON token. + /// + public string Path + { + get + { + if (Parent == null) + return string.Empty; - if (!JsonReader.IsStartToken(reader.TokenType)) - return new JValue(reader.Value); + IList ancestors = Ancestors().Reverse().ToList(); + ancestors.Add(this); - throw JsonReaderException.Create(reader, "Error reading JToken from JsonReader. Unexpected token: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); - } + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < ancestors.Count; i++) + { + JToken current = ancestors[i]; + JToken next = (i + 1 < ancestors.Count) ? ancestors[i + 1] : null; - /// - /// Load a from a string that contains JSON. - /// - /// A that contains JSON. - /// A populated from the string that contains JSON. - public static JToken Parse(string json) - { - JsonReader reader = new JsonTextReader(new StringReader(json)); + if (next != null) + { + switch (current.Type) + { + case JTokenType.Property: + JProperty property = (JProperty)current; - JToken t = Load(reader); + if (sb.Length > 0) + sb.Append("."); - if (reader.Read() && reader.TokenType != JsonToken.Comment) - throw JsonReaderException.Create(reader, "Additional text found in JSON string after parsing content."); + sb.Append(property.Name); + break; + case JTokenType.Array: + case JTokenType.Constructor: + int index = ((IList)current).IndexOf(next); - return t; - } + sb.Append("[" + index + "]"); + break; + } + } + } - /// - /// Creates a from a . - /// - /// An positioned at the token to read into this . - /// - /// An that contains the token and its descendant tokens - /// that were read from the reader. The runtime type of the token is determined - /// by the token type of the first token encountered in the reader. - /// - public static JToken Load(JsonReader reader) - { - return ReadFrom(reader); - } + return sb.ToString(); + } + } - internal void SetLineInfo(IJsonLineInfo lineInfo) - { - if (lineInfo == null || !lineInfo.HasLineInfo()) - return; + internal JToken() + { + } - SetLineInfo(lineInfo.LineNumber, lineInfo.LinePosition); - } + /// + /// Adds the specified content immediately after this token. + /// + /// A content object that contains simple content or a collection of content objects to be added after this token. + public void AddAfterSelf(object content) + { + if (_parent == null) + throw new InvalidOperationException("The parent is missing."); - internal void SetLineInfo(int lineNumber, int linePosition) - { - _lineNumber = lineNumber; - _linePosition = linePosition; - } + int index = _parent.IndexOfItem(this); + _parent.AddInternal(index + 1, content, false); + } - bool IJsonLineInfo.HasLineInfo() - { - return (_lineNumber != null && _linePosition != null); - } + /// + /// Adds the specified content immediately before this token. + /// + /// A content object that contains simple content or a collection of content objects to be added before this token. + public void AddBeforeSelf(object content) + { + if (_parent == null) + throw new InvalidOperationException("The parent is missing."); - int IJsonLineInfo.LineNumber - { - get { return _lineNumber ?? 0; } - } + int index = _parent.IndexOfItem(this); + _parent.AddInternal(index, content, false); + } - int IJsonLineInfo.LinePosition - { - get { return _linePosition ?? 0; } - } + /// + /// Returns a collection of the ancestor tokens of this token. + /// + /// A collection of the ancestor tokens of this token. + public IEnumerable Ancestors() + { + for (JToken parent = Parent; parent != null; parent = parent.Parent) + { + yield return parent; + } + } - /// - /// Selects the token that matches the object path. - /// - /// - /// The object path from the current to the - /// to be returned. This must be a string of property names or array indexes separated - /// by periods, such as Tables[0].DefaultView[0].Price in C# or - /// Tables(0).DefaultView(0).Price in Visual Basic. - /// - /// The that matches the object path or a null reference if no matching token is found. - public JToken SelectToken(string path) - { - return SelectToken(path, false); - } + /// + /// Returns a collection of the sibling tokens after this token, in document order. + /// + /// A collection of the sibling tokens after this tokens, in document order. + public IEnumerable AfterSelf() + { + if (Parent == null) + yield break; - /// - /// Selects the token that matches the object path. - /// - /// - /// The object path from the current to the - /// to be returned. This must be a string of property names or array indexes separated - /// by periods, such as Tables[0].DefaultView[0].Price in C# or - /// Tables(0).DefaultView(0).Price in Visual Basic. - /// - /// A flag to indicate whether an error should be thrown if no token is found. - /// The that matches the object path. - public JToken SelectToken(string path, bool errorWhenNoMatch) - { - JPath p = new JPath(path); - return p.Evaluate(this, errorWhenNoMatch); - } + for (JToken o = Next; o != null; o = o.Next) + { + yield return o; + } + } + + /// + /// Returns a collection of the sibling tokens before this token, in document order. + /// + /// A collection of the sibling tokens before this token, in document order. + public IEnumerable BeforeSelf() + { + for (JToken o = Parent.First; o != this; o = o.Next) + { + yield return o; + } + } + + /// + /// Gets the with the specified key. + /// + /// The with the specified key. + public virtual JToken this[object key] + { + get { throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); } + set { throw new InvalidOperationException("Cannot set child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); } + } + + /// + /// Gets the with the specified key converted to the specified type. + /// + /// The type to convert the token to. + /// The token key. + /// The converted token value. + public virtual T Value(object key) + { + JToken token = this[key]; + + return Extensions.Convert(token); + } + + /// + /// Get the first child token of this token. + /// + /// A containing the first child token of the . + public virtual JToken First + { + get { throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); } + } + + /// + /// Get the last child token of this token. + /// + /// A containing the last child token of the . + public virtual JToken Last + { + get { throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); } + } + + /// + /// Returns a collection of the child tokens of this token, in document order. + /// + /// An of containing the child tokens of this , in document order. + public virtual JEnumerable Children() + { + return JEnumerable.Empty; + } + + /// + /// Returns a collection of the child tokens of this token, in document order, filtered by the specified type. + /// + /// The type to filter the child tokens on. + /// A containing the child tokens of this , in document order. + public JEnumerable Children() where T : JToken + { + return new JEnumerable(Children().OfType()); + } + + /// + /// Returns a collection of the child values of this token, in document order. + /// + /// The type to convert the values to. + /// A containing the child values of this , in document order. + public virtual IEnumerable Values() + { + throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType())); + } + + /// + /// Removes this token from its parent. + /// + public void Remove() + { + if (_parent == null) + throw new InvalidOperationException("The parent is missing."); + + _parent.RemoveItem(this); + } + + /// + /// Replaces this token with the specified token. + /// + /// The value. + public void Replace(JToken value) + { + if (_parent == null) + throw new InvalidOperationException("The parent is missing."); + + _parent.ReplaceItem(this, value); + } + + /// + /// Writes this token to a . + /// + /// A into which this method will write. + /// A collection of which will be used when writing the token. + public abstract void WriteTo(JsonWriter writer, params JsonConverter[] converters); + + /// + /// Returns the indented JSON for this token. + /// + /// + /// The indented JSON for this token. + /// + public override string ToString() + { + return ToString(Formatting.Indented); + } + + /// + /// Returns the JSON for this token using the given formatting and converters. + /// + /// Indicates how the output is formatted. + /// A collection of which will be used when writing the token. + /// The JSON for this token using the given formatting and converters. + public string ToString(Formatting formatting, params JsonConverter[] converters) + { + using (StringWriter sw = new StringWriter(CultureInfo.InvariantCulture)) + { + JsonTextWriter jw = new JsonTextWriter(sw); + jw.Formatting = formatting; + + WriteTo(jw, converters); + + return sw.ToString(); + } + } + + private static JValue EnsureValue(JToken value) + { + if (value == null) + throw new ArgumentNullException("value"); + + if (value is JProperty) + value = ((JProperty)value).Value; + + JValue v = value as JValue; + + return v; + } + + private static string GetType(JToken token) + { + ValidationUtils.ArgumentNotNull(token, "token"); + + if (token is JProperty) + token = ((JProperty)token).Value; + + return token.Type.ToString(); + } + + private static bool ValidateToken(JToken o, JTokenType[] validTypes, bool nullable) + { + return (Array.IndexOf(validTypes, o.Type) != -1) || (nullable && (o.Type == JTokenType.Null || o.Type == JTokenType.Undefined)); + } + + #region Cast from operators + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static explicit operator bool(JToken value) + { + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, BooleanTypes, false)) + throw new ArgumentException("Can not convert {0} to Boolean.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (v.Value is BigInteger) + return Convert.ToBoolean((int)(BigInteger)v.Value); +#endif + + return Convert.ToBoolean(v.Value, CultureInfo.InvariantCulture); + } + +#if !NET20 + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static explicit operator DateTimeOffset(JToken value) + { + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, DateTimeTypes, false)) + throw new ArgumentException("Can not convert {0} to DateTimeOffset.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + + if (v.Value is DateTimeOffset) + return (DateTimeOffset)v.Value; + if (v.Value is string) + return DateTimeOffset.Parse((string)v.Value, CultureInfo.InvariantCulture); + return new DateTimeOffset(Convert.ToDateTime(v.Value, CultureInfo.InvariantCulture)); + } +#endif + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static explicit operator bool?(JToken value) + { + if (value == null) + return null; + + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, BooleanTypes, true)) + throw new ArgumentException("Can not convert {0} to Boolean.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (v.Value is BigInteger) + return Convert.ToBoolean((int)(BigInteger)v.Value); +#endif + + return (v.Value != null) ? (bool?)Convert.ToBoolean(v.Value, CultureInfo.InvariantCulture) : null; + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static explicit operator long(JToken value) + { + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, NumberTypes, false)) + throw new ArgumentException("Can not convert {0} to Int64.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (v.Value is BigInteger) + return (long)(BigInteger)v.Value; +#endif + + return Convert.ToInt64(v.Value, CultureInfo.InvariantCulture); + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static explicit operator DateTime?(JToken value) + { + if (value == null) + return null; + + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, DateTimeTypes, true)) + throw new ArgumentException("Can not convert {0} to DateTime.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + +#if !NET20 + if (v.Value is DateTimeOffset) + return ((DateTimeOffset)v.Value).DateTime; +#endif + + return (v.Value != null) ? (DateTime?)Convert.ToDateTime(v.Value, CultureInfo.InvariantCulture) : null; + } + +#if !NET20 + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static explicit operator DateTimeOffset?(JToken value) + { + if (value == null) + return null; + + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, DateTimeTypes, true)) + throw new ArgumentException("Can not convert {0} to DateTimeOffset.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + + if (v.Value == null) + return null; + if (v.Value is DateTimeOffset) + return (DateTimeOffset?)v.Value; + if (v.Value is string) + return DateTimeOffset.Parse((string)v.Value, CultureInfo.InvariantCulture); + return new DateTimeOffset(Convert.ToDateTime(v.Value, CultureInfo.InvariantCulture)); + } +#endif + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static explicit operator decimal?(JToken value) + { + if (value == null) + return null; + + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, NumberTypes, true)) + throw new ArgumentException("Can not convert {0} to Decimal.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (v.Value is BigInteger) + return (decimal?)(BigInteger)v.Value; +#endif + + return (v.Value != null) ? (decimal?)Convert.ToDecimal(v.Value, CultureInfo.InvariantCulture) : null; + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static explicit operator double?(JToken value) + { + if (value == null) + return null; + + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, NumberTypes, true)) + throw new ArgumentException("Can not convert {0} to Double.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (v.Value is BigInteger) + return (double?)(BigInteger)v.Value; +#endif + + return (v.Value != null) ? (double?)Convert.ToDouble(v.Value, CultureInfo.InvariantCulture) : null; + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static explicit operator char?(JToken value) + { + if (value == null) + return null; + + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, CharTypes, true)) + throw new ArgumentException("Can not convert {0} to Char.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (v.Value is BigInteger) + return (char?)(BigInteger)v.Value; +#endif + + return (v.Value != null) ? (char?)Convert.ToChar(v.Value, CultureInfo.InvariantCulture) : null; + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static explicit operator int(JToken value) + { + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, NumberTypes, false)) + throw new ArgumentException("Can not convert {0} to Int32.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (v.Value is BigInteger) + return (int)(BigInteger)v.Value; +#endif + + return Convert.ToInt32(v.Value, CultureInfo.InvariantCulture); + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static explicit operator short(JToken value) + { + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, NumberTypes, false)) + throw new ArgumentException("Can not convert {0} to Int16.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (v.Value is BigInteger) + return (short)(BigInteger)v.Value; +#endif + + return Convert.ToInt16(v.Value, CultureInfo.InvariantCulture); + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + [CLSCompliant(false)] + public static explicit operator ushort(JToken value) + { + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, NumberTypes, false)) + throw new ArgumentException("Can not convert {0} to UInt16.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (v.Value is BigInteger) + return (ushort)(BigInteger)v.Value; +#endif + + return Convert.ToUInt16(v.Value, CultureInfo.InvariantCulture); + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + [CLSCompliant(false)] + public static explicit operator char(JToken value) + { + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, CharTypes, false)) + throw new ArgumentException("Can not convert {0} to Char.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (v.Value is BigInteger) + return (char)(BigInteger)v.Value; +#endif + + return Convert.ToChar(v.Value, CultureInfo.InvariantCulture); + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static explicit operator byte(JToken value) + { + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, NumberTypes, false)) + throw new ArgumentException("Can not convert {0} to Byte.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (v.Value is BigInteger) + return (byte)(BigInteger)v.Value; +#endif + + return Convert.ToByte(v.Value, CultureInfo.InvariantCulture); + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + [CLSCompliant(false)] + public static explicit operator sbyte(JToken value) + { + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, NumberTypes, false)) + throw new ArgumentException("Can not convert {0} to SByte.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (v.Value is BigInteger) + return (sbyte)(BigInteger)v.Value; +#endif + + return Convert.ToSByte(v.Value, CultureInfo.InvariantCulture); + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static explicit operator int?(JToken value) + { + if (value == null) + return null; + + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, NumberTypes, true)) + throw new ArgumentException("Can not convert {0} to Int32.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (v.Value is BigInteger) + return (int?)(BigInteger)v.Value; +#endif + + return (v.Value != null) ? (int?)Convert.ToInt32(v.Value, CultureInfo.InvariantCulture) : null; + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static explicit operator short?(JToken value) + { + if (value == null) + return null; + + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, NumberTypes, true)) + throw new ArgumentException("Can not convert {0} to Int16.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (v.Value is BigInteger) + return (short?)(BigInteger)v.Value; +#endif + + return (v.Value != null) ? (short?)Convert.ToInt16(v.Value, CultureInfo.InvariantCulture) : null; + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + [CLSCompliant(false)] + public static explicit operator ushort?(JToken value) + { + if (value == null) + return null; + + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, NumberTypes, true)) + throw new ArgumentException("Can not convert {0} to UInt16.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (v.Value is BigInteger) + return (ushort?)(BigInteger)v.Value; +#endif + + return (v.Value != null) ? (ushort?)Convert.ToUInt16(v.Value, CultureInfo.InvariantCulture) : null; + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static explicit operator byte?(JToken value) + { + if (value == null) + return null; + + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, NumberTypes, true)) + throw new ArgumentException("Can not convert {0} to Byte.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (v.Value is BigInteger) + return (byte?)(BigInteger)v.Value; +#endif + + return (v.Value != null) ? (byte?)Convert.ToByte(v.Value, CultureInfo.InvariantCulture) : null; + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + [CLSCompliant(false)] + public static explicit operator sbyte?(JToken value) + { + if (value == null) + return null; + + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, NumberTypes, true)) + throw new ArgumentException("Can not convert {0} to SByte.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (v.Value is BigInteger) + return (sbyte?)(BigInteger)v.Value; +#endif + + return (v.Value != null) ? (sbyte?)Convert.ToByte(v.Value, CultureInfo.InvariantCulture) : null; + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static explicit operator DateTime(JToken value) + { + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, DateTimeTypes, false)) + throw new ArgumentException("Can not convert {0} to DateTime.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + +#if !NET20 + if (v.Value is DateTimeOffset) + return ((DateTimeOffset)v.Value).DateTime; +#endif + + return Convert.ToDateTime(v.Value, CultureInfo.InvariantCulture); + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static explicit operator long?(JToken value) + { + if (value == null) + return null; + + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, NumberTypes, true)) + throw new ArgumentException("Can not convert {0} to Int64.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (v.Value is BigInteger) + return (long?)(BigInteger)v.Value; +#endif + + return (v.Value != null) ? (long?)Convert.ToInt64(v.Value, CultureInfo.InvariantCulture) : null; + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static explicit operator float?(JToken value) + { + if (value == null) + return null; + + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, NumberTypes, true)) + throw new ArgumentException("Can not convert {0} to Single.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (v.Value is BigInteger) + return (float?)(BigInteger)v.Value; +#endif + + return (v.Value != null) ? (float?)Convert.ToSingle(v.Value, CultureInfo.InvariantCulture) : null; + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static explicit operator decimal(JToken value) + { + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, NumberTypes, false)) + throw new ArgumentException("Can not convert {0} to Decimal.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (v.Value is BigInteger) + return (decimal)(BigInteger)v.Value; +#endif + + return Convert.ToDecimal(v.Value, CultureInfo.InvariantCulture); + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + [CLSCompliant(false)] + public static explicit operator uint?(JToken value) + { + if (value == null) + return null; + + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, NumberTypes, true)) + throw new ArgumentException("Can not convert {0} to UInt32.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (v.Value is BigInteger) + return (uint?)(BigInteger)v.Value; +#endif + + return (v.Value != null) ? (uint?)Convert.ToUInt32(v.Value, CultureInfo.InvariantCulture) : null; + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + [CLSCompliant(false)] + public static explicit operator ulong?(JToken value) + { + if (value == null) + return null; + + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, NumberTypes, true)) + throw new ArgumentException("Can not convert {0} to UInt64.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (v.Value is BigInteger) + return (ulong?)(BigInteger)v.Value; +#endif + + return (v.Value != null) ? (ulong?)Convert.ToUInt64(v.Value, CultureInfo.InvariantCulture) : null; + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static explicit operator double(JToken value) + { + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, NumberTypes, false)) + throw new ArgumentException("Can not convert {0} to Double.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (v.Value is BigInteger) + return (double)(BigInteger)v.Value; +#endif + + return Convert.ToDouble(v.Value, CultureInfo.InvariantCulture); + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static explicit operator float(JToken value) + { + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, NumberTypes, false)) + throw new ArgumentException("Can not convert {0} to Single.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (v.Value is BigInteger) + return (float)(BigInteger)v.Value; +#endif + + return Convert.ToSingle(v.Value, CultureInfo.InvariantCulture); + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static explicit operator string(JToken value) + { + if (value == null) + return null; + + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, StringTypes, true)) + throw new ArgumentException("Can not convert {0} to String.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + + if (v.Value == null) + return null; + if (v.Value is byte[]) + return Convert.ToBase64String((byte[])v.Value); +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (v.Value is BigInteger) + return ((BigInteger)v.Value).ToString(CultureInfo.InvariantCulture); +#endif + + return Convert.ToString(v.Value, CultureInfo.InvariantCulture); + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + [CLSCompliant(false)] + public static explicit operator uint(JToken value) + { + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, NumberTypes, false)) + throw new ArgumentException("Can not convert {0} to UInt32.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (v.Value is BigInteger) + return (uint)(BigInteger)v.Value; +#endif + + return Convert.ToUInt32(v.Value, CultureInfo.InvariantCulture); + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + [CLSCompliant(false)] + public static explicit operator ulong(JToken value) + { + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, NumberTypes, false)) + throw new ArgumentException("Can not convert {0} to UInt64.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (v.Value is BigInteger) + return (ulong)(BigInteger)v.Value; +#endif + + return Convert.ToUInt64(v.Value, CultureInfo.InvariantCulture); + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static explicit operator byte[](JToken value) + { + if (value == null) + return null; + + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, BytesTypes, false)) + throw new ArgumentException("Can not convert {0} to byte array.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + + if (v.Value is string) + return Convert.FromBase64String(Convert.ToString(v.Value, CultureInfo.InvariantCulture)); +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (v.Value is BigInteger) + return ((BigInteger)v.Value).ToByteArray(); +#endif + + if (v.Value is byte[]) + return (byte[])v.Value; + + throw new ArgumentException("Can not convert {0} to byte array.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static explicit operator Guid(JToken value) + { + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, GuidTypes, false)) + throw new ArgumentException("Can not convert {0} to Guid.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + + if (v.Value is byte[]) + return new Guid((byte[])v.Value); + + return (v.Value is Guid) ? (Guid)v.Value : new Guid(Convert.ToString(v.Value, CultureInfo.InvariantCulture)); + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static explicit operator Guid?(JToken value) + { + if (value == null) + return null; + + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, GuidTypes, true)) + throw new ArgumentException("Can not convert {0} to Guid.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + + if (v.Value == null) + return null; + + if (v.Value is byte[]) + return new Guid((byte[])v.Value); + + return (v.Value is Guid) ? (Guid)v.Value : new Guid(Convert.ToString(v.Value, CultureInfo.InvariantCulture)); + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static explicit operator TimeSpan(JToken value) + { + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, TimeSpanTypes, false)) + throw new ArgumentException("Can not convert {0} to TimeSpan.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + + return (v.Value is TimeSpan) ? (TimeSpan)v.Value : ConvertUtils.ParseTimeSpan(Convert.ToString(v.Value, CultureInfo.InvariantCulture)); + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static explicit operator TimeSpan?(JToken value) + { + if (value == null) + return null; + + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, TimeSpanTypes, true)) + throw new ArgumentException("Can not convert {0} to TimeSpan.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + + if (v.Value == null) + return null; + + return (v.Value is TimeSpan) ? (TimeSpan)v.Value : ConvertUtils.ParseTimeSpan(Convert.ToString(v.Value, CultureInfo.InvariantCulture)); + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static explicit operator Uri(JToken value) + { + if (value == null) + return null; + + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, UriTypes, true)) + throw new ArgumentException("Can not convert {0} to Uri.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + + if (v.Value == null) + return null; + + return (v.Value is Uri) ? (Uri)v.Value : new Uri(Convert.ToString(v.Value, CultureInfo.InvariantCulture)); + } + +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + private static BigInteger ToBigInteger(JToken value) + { + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, BigIntegerTypes, false)) + throw new ArgumentException("Can not convert {0} to BigInteger.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + + return ConvertUtils.ToBigInteger(v.Value); + } + + private static BigInteger? ToBigIntegerNullable(JToken value) + { + JValue v = EnsureValue(value); + if (v == null || !ValidateToken(v, BigIntegerTypes, true)) + throw new ArgumentException("Can not convert {0} to BigInteger.".FormatWith(CultureInfo.InvariantCulture, GetType(value))); + + if (v.Value == null) + return null; + + return ConvertUtils.ToBigInteger(v.Value); + } +#endif + #endregion + + #region Cast to operators + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + public static implicit operator JToken(bool value) + { + return new JValue(value); + } + +#if !NET20 + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + public static implicit operator JToken(DateTimeOffset value) + { + return new JValue(value); + } +#endif + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + public static implicit operator JToken(byte value) + { + return new JValue(value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + public static implicit operator JToken(byte? value) + { + return new JValue(value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + [CLSCompliant(false)] + public static implicit operator JToken(sbyte value) + { + return new JValue(value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + [CLSCompliant(false)] + public static implicit operator JToken(sbyte? value) + { + return new JValue(value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + public static implicit operator JToken(bool? value) + { + return new JValue(value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + public static implicit operator JToken(long value) + { + return new JValue(value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + public static implicit operator JToken(DateTime? value) + { + return new JValue(value); + } + +#if !NET20 + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + public static implicit operator JToken(DateTimeOffset? value) + { + return new JValue(value); + } +#endif + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + public static implicit operator JToken(decimal? value) + { + return new JValue(value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + public static implicit operator JToken(double? value) + { + return new JValue(value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + [CLSCompliant(false)] + public static implicit operator JToken(short value) + { + return new JValue(value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + [CLSCompliant(false)] + public static implicit operator JToken(ushort value) + { + return new JValue(value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + public static implicit operator JToken(int value) + { + return new JValue(value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + public static implicit operator JToken(int? value) + { + return new JValue(value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + public static implicit operator JToken(DateTime value) + { + return new JValue(value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + public static implicit operator JToken(long? value) + { + return new JValue(value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + public static implicit operator JToken(float? value) + { + return new JValue(value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + public static implicit operator JToken(decimal value) + { + return new JValue(value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + [CLSCompliant(false)] + public static implicit operator JToken(short? value) + { + return new JValue(value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + [CLSCompliant(false)] + public static implicit operator JToken(ushort? value) + { + return new JValue(value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + [CLSCompliant(false)] + public static implicit operator JToken(uint? value) + { + return new JValue(value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + [CLSCompliant(false)] + public static implicit operator JToken(ulong? value) + { + return new JValue(value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + public static implicit operator JToken(double value) + { + return new JValue(value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + public static implicit operator JToken(float value) + { + return new JValue(value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + public static implicit operator JToken(string value) + { + return new JValue(value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + [CLSCompliant(false)] + public static implicit operator JToken(uint value) + { + return new JValue(value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + [CLSCompliant(false)] + public static implicit operator JToken(ulong value) + { + return new JValue(value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + public static implicit operator JToken(byte[] value) + { + return new JValue(value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + public static implicit operator JToken(Uri value) + { + return new JValue(value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + public static implicit operator JToken(TimeSpan value) + { + return new JValue(value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + public static implicit operator JToken(TimeSpan? value) + { + return new JValue(value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + public static implicit operator JToken(Guid value) + { + return new JValue(value); + } + + /// + /// Performs an implicit conversion from to . + /// + /// The value to create a from. + /// The initialized with the specified value. + public static implicit operator JToken(Guid? value) + { + return new JValue(value); + } + #endregion + + IEnumerator IEnumerable.GetEnumerator() + { + return ((IEnumerable)this).GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return Children().GetEnumerator(); + } + + internal abstract int GetDeepHashCode(); + + IJEnumerable IJEnumerable.this[object key] + { + get { return this[key]; } + } + + /// + /// Creates an for this token. + /// + /// An that can be used to read this token and its descendants. + public JsonReader CreateReader() + { + return new JTokenReader(this); + } + + internal static JToken FromObjectInternal(object o, JsonSerializer jsonSerializer) + { + ValidationUtils.ArgumentNotNull(o, "o"); + ValidationUtils.ArgumentNotNull(jsonSerializer, "jsonSerializer"); + + JToken token; + using (JTokenWriter jsonWriter = new JTokenWriter()) + { + jsonSerializer.Serialize(jsonWriter, o); + token = jsonWriter.Token; + } + + return token; + } + + /// + /// Creates a from an object. + /// + /// The object that will be used to create . + /// A with the value of the specified object + public static JToken FromObject(object o) + { + return FromObjectInternal(o, JsonSerializer.CreateDefault()); + } + + /// + /// Creates a from an object using the specified . + /// + /// The object that will be used to create . + /// The that will be used when reading the object. + /// A with the value of the specified object + public static JToken FromObject(object o, JsonSerializer jsonSerializer) + { + return FromObjectInternal(o, jsonSerializer); + } + + /// + /// Creates the specified .NET type from the . + /// + /// The object type that the token will be deserialized to. + /// The new object created from the JSON value. + public T ToObject() + { + return (T)ToObject(typeof(T)); + } + + /// + /// Creates the specified .NET type from the . + /// + /// The object type that the token will be deserialized to. + /// The new object created from the JSON value. + public object ToObject(Type objectType) + { + if (JsonConvert.DefaultSettings == null) + { + 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; +#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; +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + case PrimitiveTypeCode.BigIntegerNullable: + return ToBigIntegerNullable(this); + case PrimitiveTypeCode.BigInteger: + return ToBigInteger(this); +#endif + } + } + + return ToObject(objectType, JsonSerializer.CreateDefault()); + } + + /// + /// Creates the specified .NET type from the using the specified . + /// + /// The object type that the token will be deserialized to. + /// The that will be used when creating the object. + /// The new object created from the JSON value. + public T ToObject(JsonSerializer jsonSerializer) + { + return (T)ToObject(typeof(T), jsonSerializer); + } + + /// + /// Creates the specified .NET type from the using the specified . + /// + /// The object type that the token will be deserialized to. + /// The that will be used when creating the object. + /// The new object created from the JSON value. + public object ToObject(Type objectType, JsonSerializer jsonSerializer) + { + ValidationUtils.ArgumentNotNull(jsonSerializer, "jsonSerializer"); + + using (JTokenReader jsonReader = new JTokenReader(this)) + { + return jsonSerializer.Deserialize(jsonReader, objectType); + } + } + + /// + /// Creates a from a . + /// + /// An positioned at the token to read into this . + /// + /// An that contains the token and its descendant tokens + /// that were read from the reader. The runtime type of the token is determined + /// by the token type of the first token encountered in the reader. + /// + public static JToken ReadFrom(JsonReader reader) + { + ValidationUtils.ArgumentNotNull(reader, "reader"); + + if (reader.TokenType == JsonToken.None) + { + if (!reader.Read()) + throw JsonReaderException.Create(reader, "Error reading JToken from JsonReader."); + } + + if (reader.TokenType == JsonToken.StartObject) + return JObject.Load(reader); + + if (reader.TokenType == JsonToken.StartArray) + return JArray.Load(reader); + + if (reader.TokenType == JsonToken.PropertyName) + return JProperty.Load(reader); + + if (reader.TokenType == JsonToken.StartConstructor) + return JConstructor.Load(reader); + + if (!JsonReader.IsStartToken(reader.TokenType)) + return new JValue(reader.Value); + + throw JsonReaderException.Create(reader, "Error reading JToken from JsonReader. Unexpected token: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); + } + + /// + /// Load a from a string that contains JSON. + /// + /// A that contains JSON. + /// A populated from the string that contains JSON. + public static JToken Parse(string json) + { + JsonReader reader = new JsonTextReader(new StringReader(json)); + + JToken t = Load(reader); + + if (reader.Read() && reader.TokenType != JsonToken.Comment) + throw JsonReaderException.Create(reader, "Additional text found in JSON string after parsing content."); + + return t; + } + + /// + /// Creates a from a . + /// + /// An positioned at the token to read into this . + /// + /// An that contains the token and its descendant tokens + /// that were read from the reader. The runtime type of the token is determined + /// by the token type of the first token encountered in the reader. + /// + public static JToken Load(JsonReader reader) + { + return ReadFrom(reader); + } + + internal void SetLineInfo(IJsonLineInfo lineInfo) + { + if (lineInfo == null || !lineInfo.HasLineInfo()) + return; + + SetLineInfo(lineInfo.LineNumber, lineInfo.LinePosition); + } + + internal void SetLineInfo(int lineNumber, int linePosition) + { + _lineNumber = lineNumber; + _linePosition = linePosition; + } + + bool IJsonLineInfo.HasLineInfo() + { + return (_lineNumber != null && _linePosition != null); + } + + int IJsonLineInfo.LineNumber + { + get { return _lineNumber ?? 0; } + } + + int IJsonLineInfo.LinePosition + { + get { return _linePosition ?? 0; } + } + + /// + /// Selects the token that matches the object path. + /// + /// + /// The object path from the current to the + /// to be returned. This must be a string of property names or array indexes separated + /// by periods, such as Tables[0].DefaultView[0].Price in C# or + /// Tables(0).DefaultView(0).Price in Visual Basic. + /// + /// The that matches the object path or a null reference if no matching token is found. + public JToken SelectToken(string path) + { + return SelectToken(path, false); + } + + /// + /// Selects the token that matches the object path. + /// + /// + /// The object path from the current to the + /// to be returned. This must be a string of property names or array indexes separated + /// by periods, such as Tables[0].DefaultView[0].Price in C# or + /// Tables(0).DefaultView(0).Price in Visual Basic. + /// + /// A flag to indicate whether an error should be thrown if no token is found. + /// The that matches the object path. + public JToken SelectToken(string path, bool errorWhenNoMatch) + { + JPath p = new JPath(path); + return p.Evaluate(this, errorWhenNoMatch); + } #if !(NET35 || NET20 || PORTABLE40) - /// - /// Returns the responsible for binding operations performed on this object. - /// - /// The expression tree representation of the runtime value. - /// - /// The to bind this object. - /// - protected virtual DynamicMetaObject GetMetaObject(Expression parameter) - { - return new DynamicProxyMetaObject(parameter, this, new DynamicProxy(), true); - } + /// + /// Returns the responsible for binding operations performed on this object. + /// + /// The expression tree representation of the runtime value. + /// + /// The to bind this object. + /// + protected virtual DynamicMetaObject GetMetaObject(Expression parameter) + { + return new DynamicProxyMetaObject(parameter, this, new DynamicProxy(), true); + } - /// - /// Returns the responsible for binding operations performed on this object. - /// - /// The expression tree representation of the runtime value. - /// - /// The to bind this object. - /// - DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter) - { - return GetMetaObject(parameter); - } + /// + /// Returns the responsible for binding operations performed on this object. + /// + /// The expression tree representation of the runtime value. + /// + /// The to bind this object. + /// + DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter) + { + return GetMetaObject(parameter); + } #endif #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - object ICloneable.Clone() - { - return DeepClone(); - } + object ICloneable.Clone() + { + return DeepClone(); + } #endif - /// - /// Creates a new instance of the . All child tokens are recursively cloned. - /// - /// A new instance of the . - public JToken DeepClone() - { - return CloneToken(); + /// + /// Creates a new instance of the . All child tokens are recursively cloned. + /// + /// A new instance of the . + public JToken DeepClone() + { + return CloneToken(); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Linq/JTokenEqualityComparer.cs b/Src/Newtonsoft.Json/Linq/JTokenEqualityComparer.cs index 25a2eeba..8665b7ca 100644 --- a/Src/Newtonsoft.Json/Linq/JTokenEqualityComparer.cs +++ b/Src/Newtonsoft.Json/Linq/JTokenEqualityComparer.cs @@ -27,36 +27,36 @@ using System.Collections.Generic; namespace Newtonsoft.Json.Linq { - /// - /// Compares tokens to determine whether they are equal. - /// - public class JTokenEqualityComparer : IEqualityComparer - { /// - /// Determines whether the specified objects are equal. + /// Compares tokens to determine whether they are equal. /// - /// The first object of type to compare. - /// The second object of type to compare. - /// - /// true if the specified objects are equal; otherwise, false. - /// - public bool Equals(JToken x, JToken y) + public class JTokenEqualityComparer : IEqualityComparer { - return JToken.DeepEquals(x, y); - } + /// + /// Determines whether the specified objects are equal. + /// + /// The first object of type to compare. + /// The second object of type to compare. + /// + /// true if the specified objects are equal; otherwise, false. + /// + public bool Equals(JToken x, JToken y) + { + return JToken.DeepEquals(x, y); + } - /// - /// Returns a hash code for the specified object. - /// - /// The for which a hash code is to be returned. - /// A hash code for the specified object. - /// The type of is a reference type and is null. - public int GetHashCode(JToken obj) - { - if (obj == null) - return 0; + /// + /// Returns a hash code for the specified object. + /// + /// The for which a hash code is to be returned. + /// A hash code for the specified object. + /// The type of is a reference type and is null. + public int GetHashCode(JToken obj) + { + if (obj == null) + return 0; - return obj.GetDeepHashCode(); + return obj.GetDeepHashCode(); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Linq/JTokenReader.cs b/Src/Newtonsoft.Json/Linq/JTokenReader.cs index 0198d660..dfdbf7dd 100644 --- a/Src/Newtonsoft.Json/Linq/JTokenReader.cs +++ b/Src/Newtonsoft.Json/Linq/JTokenReader.cs @@ -28,296 +28,296 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Linq { - /// - /// Represents a reader that provides fast, non-cached, forward-only access to serialized Json data. - /// - public class JTokenReader : JsonReader, IJsonLineInfo - { - private readonly JToken _root; - private JToken _parent; - private JToken _current; - /// - /// Initializes a new instance of the class. + /// Represents a reader that provides fast, non-cached, forward-only access to serialized Json data. /// - /// The token to read from. - public JTokenReader(JToken token) + public class JTokenReader : JsonReader, IJsonLineInfo { - ValidationUtils.ArgumentNotNull(token, "token"); + private readonly JToken _root; + private JToken _parent; + private JToken _current; - _root = token; - _current = token; - } + /// + /// Initializes a new instance of the class. + /// + /// The token to read from. + public JTokenReader(JToken token) + { + ValidationUtils.ArgumentNotNull(token, "token"); - /// - /// Reads the next JSON token from the stream as a . - /// - /// - /// A or a null reference if the next JSON token is null. This method will return null at the end of an array. - /// - public override byte[] ReadAsBytes() - { - return ReadAsBytesInternal(); - } + _root = token; + _current = token; + } - /// - /// Reads the next JSON token from the stream as a . - /// - /// A . This method will return null at the end of an array. - public override decimal? ReadAsDecimal() - { - return ReadAsDecimalInternal(); - } + /// + /// Reads the next JSON token from the stream as a . + /// + /// + /// A or a null reference if the next JSON token is null. This method will return null at the end of an array. + /// + public override byte[] ReadAsBytes() + { + return ReadAsBytesInternal(); + } - /// - /// Reads the next JSON token from the stream as a . - /// - /// A . This method will return null at the end of an array. - public override int? ReadAsInt32() - { - return ReadAsInt32Internal(); - } + /// + /// Reads the next JSON token from the stream as a . + /// + /// A . This method will return null at the end of an array. + public override decimal? ReadAsDecimal() + { + return ReadAsDecimalInternal(); + } - /// - /// Reads the next JSON token from the stream as a . - /// - /// A . This method will return null at the end of an array. - public override string ReadAsString() - { - return ReadAsStringInternal(); - } + /// + /// Reads the next JSON token from the stream as a . + /// + /// A . This method will return null at the end of an array. + public override int? ReadAsInt32() + { + return ReadAsInt32Internal(); + } - /// - /// Reads the next JSON token from the stream as a . - /// - /// A . This method will return null at the end of an array. - public override DateTime? ReadAsDateTime() - { - return ReadAsDateTimeInternal(); - } + /// + /// Reads the next JSON token from the stream as a . + /// + /// A . This method will return null at the end of an array. + public override string ReadAsString() + { + return ReadAsStringInternal(); + } + + /// + /// Reads the next JSON token from the stream as a . + /// + /// A . This method will return null at the end of an array. + public override DateTime? ReadAsDateTime() + { + return ReadAsDateTimeInternal(); + } #if !NET20 - /// - /// Reads the next JSON token from the stream as a . - /// - /// A . This method will return null at the end of an array. - public override DateTimeOffset? ReadAsDateTimeOffset() - { - return ReadAsDateTimeOffsetInternal(); - } + /// + /// Reads the next JSON token from the stream as a . + /// + /// A . This method will return null at the end of an array. + public override DateTimeOffset? ReadAsDateTimeOffset() + { + return ReadAsDateTimeOffsetInternal(); + } #endif - internal override bool ReadInternal() - { - if (CurrentState != State.Start) - { - JContainer container = _current as JContainer; - if (container != null && _parent != container) - return ReadInto(container); - else - return ReadOver(_current); - } + internal override bool ReadInternal() + { + if (CurrentState != State.Start) + { + JContainer container = _current as JContainer; + if (container != null && _parent != container) + return ReadInto(container); + else + return ReadOver(_current); + } - SetToken(_current); - return true; + SetToken(_current); + return true; + } + + /// + /// Reads the next JSON token from the stream. + /// + /// + /// true if the next token was read successfully; false if there are no more tokens to read. + /// + public override bool Read() + { + _readType = ReadType.Read; + + return ReadInternal(); + } + + private bool ReadOver(JToken t) + { + if (t == _root) + return ReadToEnd(); + + JToken next = t.Next; + if ((next == null || next == t) || t == t.Parent.Last) + { + if (t.Parent == null) + return ReadToEnd(); + + return SetEnd(t.Parent); + } + else + { + _current = next; + SetToken(_current); + return true; + } + } + + private bool ReadToEnd() + { + SetToken(JsonToken.None); + return false; + } + + private bool IsEndElement + { + get { return (_current == _parent); } + } + + private JsonToken? GetEndToken(JContainer c) + { + switch (c.Type) + { + case JTokenType.Object: + return JsonToken.EndObject; + case JTokenType.Array: + return JsonToken.EndArray; + case JTokenType.Constructor: + return JsonToken.EndConstructor; + case JTokenType.Property: + return null; + default: + throw MiscellaneousUtils.CreateArgumentOutOfRangeException("Type", c.Type, "Unexpected JContainer type."); + } + } + + private bool ReadInto(JContainer c) + { + JToken firstChild = c.First; + if (firstChild == null) + { + return SetEnd(c); + } + else + { + SetToken(firstChild); + _current = firstChild; + _parent = c; + return true; + } + } + + private bool SetEnd(JContainer c) + { + JsonToken? endToken = GetEndToken(c); + if (endToken != null) + { + SetToken(endToken.Value); + _current = c; + _parent = c; + return true; + } + else + { + return ReadOver(c); + } + } + + private void SetToken(JToken token) + { + switch (token.Type) + { + case JTokenType.Object: + SetToken(JsonToken.StartObject); + break; + case JTokenType.Array: + SetToken(JsonToken.StartArray); + break; + case JTokenType.Constructor: + SetToken(JsonToken.StartConstructor); + break; + case JTokenType.Property: + SetToken(JsonToken.PropertyName, ((JProperty)token).Name); + break; + case JTokenType.Comment: + SetToken(JsonToken.Comment, ((JValue)token).Value); + break; + case JTokenType.Integer: + SetToken(JsonToken.Integer, ((JValue)token).Value); + break; + case JTokenType.Float: + SetToken(JsonToken.Float, ((JValue)token).Value); + break; + case JTokenType.String: + SetToken(JsonToken.String, ((JValue)token).Value); + break; + case JTokenType.Boolean: + SetToken(JsonToken.Boolean, ((JValue)token).Value); + break; + case JTokenType.Null: + SetToken(JsonToken.Null, ((JValue)token).Value); + break; + case JTokenType.Undefined: + SetToken(JsonToken.Undefined, ((JValue)token).Value); + break; + case JTokenType.Date: + SetToken(JsonToken.Date, ((JValue)token).Value); + break; + case JTokenType.Raw: + SetToken(JsonToken.Raw, ((JValue)token).Value); + break; + case JTokenType.Bytes: + SetToken(JsonToken.Bytes, ((JValue)token).Value); + break; + case JTokenType.Guid: + SetToken(JsonToken.String, SafeToString(((JValue)token).Value)); + break; + case JTokenType.Uri: + SetToken(JsonToken.String, SafeToString(((JValue)token).Value)); + break; + case JTokenType.TimeSpan: + SetToken(JsonToken.String, SafeToString(((JValue)token).Value)); + break; + default: + throw MiscellaneousUtils.CreateArgumentOutOfRangeException("Type", token.Type, "Unexpected JTokenType."); + } + } + + private string SafeToString(object value) + { + return (value != null) ? value.ToString() : null; + } + + bool IJsonLineInfo.HasLineInfo() + { + if (CurrentState == State.Start) + return false; + + IJsonLineInfo info = IsEndElement ? null : _current; + return (info != null && info.HasLineInfo()); + } + + int IJsonLineInfo.LineNumber + { + get + { + if (CurrentState == State.Start) + return 0; + + IJsonLineInfo info = IsEndElement ? null : _current; + if (info != null) + return info.LineNumber; + + return 0; + } + } + + int IJsonLineInfo.LinePosition + { + get + { + if (CurrentState == State.Start) + return 0; + + IJsonLineInfo info = IsEndElement ? null : _current; + if (info != null) + return info.LinePosition; + + return 0; + } + } } - - /// - /// Reads the next JSON token from the stream. - /// - /// - /// true if the next token was read successfully; false if there are no more tokens to read. - /// - public override bool Read() - { - _readType = ReadType.Read; - - return ReadInternal(); - } - - private bool ReadOver(JToken t) - { - if (t == _root) - return ReadToEnd(); - - JToken next = t.Next; - if ((next == null || next == t) || t == t.Parent.Last) - { - if (t.Parent == null) - return ReadToEnd(); - - return SetEnd(t.Parent); - } - else - { - _current = next; - SetToken(_current); - return true; - } - } - - private bool ReadToEnd() - { - SetToken(JsonToken.None); - return false; - } - - private bool IsEndElement - { - get { return (_current == _parent); } - } - - private JsonToken? GetEndToken(JContainer c) - { - switch (c.Type) - { - case JTokenType.Object: - return JsonToken.EndObject; - case JTokenType.Array: - return JsonToken.EndArray; - case JTokenType.Constructor: - return JsonToken.EndConstructor; - case JTokenType.Property: - return null; - default: - throw MiscellaneousUtils.CreateArgumentOutOfRangeException("Type", c.Type, "Unexpected JContainer type."); - } - } - - private bool ReadInto(JContainer c) - { - JToken firstChild = c.First; - if (firstChild == null) - { - return SetEnd(c); - } - else - { - SetToken(firstChild); - _current = firstChild; - _parent = c; - return true; - } - } - - private bool SetEnd(JContainer c) - { - JsonToken? endToken = GetEndToken(c); - if (endToken != null) - { - SetToken(endToken.Value); - _current = c; - _parent = c; - return true; - } - else - { - return ReadOver(c); - } - } - - private void SetToken(JToken token) - { - switch (token.Type) - { - case JTokenType.Object: - SetToken(JsonToken.StartObject); - break; - case JTokenType.Array: - SetToken(JsonToken.StartArray); - break; - case JTokenType.Constructor: - SetToken(JsonToken.StartConstructor); - break; - case JTokenType.Property: - SetToken(JsonToken.PropertyName, ((JProperty)token).Name); - break; - case JTokenType.Comment: - SetToken(JsonToken.Comment, ((JValue)token).Value); - break; - case JTokenType.Integer: - SetToken(JsonToken.Integer, ((JValue)token).Value); - break; - case JTokenType.Float: - SetToken(JsonToken.Float, ((JValue)token).Value); - break; - case JTokenType.String: - SetToken(JsonToken.String, ((JValue)token).Value); - break; - case JTokenType.Boolean: - SetToken(JsonToken.Boolean, ((JValue)token).Value); - break; - case JTokenType.Null: - SetToken(JsonToken.Null, ((JValue)token).Value); - break; - case JTokenType.Undefined: - SetToken(JsonToken.Undefined, ((JValue)token).Value); - break; - case JTokenType.Date: - SetToken(JsonToken.Date, ((JValue)token).Value); - break; - case JTokenType.Raw: - SetToken(JsonToken.Raw, ((JValue)token).Value); - break; - case JTokenType.Bytes: - SetToken(JsonToken.Bytes, ((JValue)token).Value); - break; - case JTokenType.Guid: - SetToken(JsonToken.String, SafeToString(((JValue)token).Value)); - break; - case JTokenType.Uri: - SetToken(JsonToken.String, SafeToString(((JValue)token).Value)); - break; - case JTokenType.TimeSpan: - SetToken(JsonToken.String, SafeToString(((JValue)token).Value)); - break; - default: - throw MiscellaneousUtils.CreateArgumentOutOfRangeException("Type", token.Type, "Unexpected JTokenType."); - } - } - - private string SafeToString(object value) - { - return (value != null) ? value.ToString() : null; - } - - bool IJsonLineInfo.HasLineInfo() - { - if (CurrentState == State.Start) - return false; - - IJsonLineInfo info = IsEndElement ? null : _current; - return (info != null && info.HasLineInfo()); - } - - int IJsonLineInfo.LineNumber - { - get - { - if (CurrentState == State.Start) - return 0; - - IJsonLineInfo info = IsEndElement ? null : _current; - if (info != null) - return info.LineNumber; - - return 0; - } - } - - int IJsonLineInfo.LinePosition - { - get - { - if (CurrentState == State.Start) - return 0; - - IJsonLineInfo info = IsEndElement ? null : _current; - if (info != null) - return info.LinePosition; - - return 0; - } - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Linq/JTokenType.cs b/Src/Newtonsoft.Json/Linq/JTokenType.cs index 20585ba8..00e04a40 100644 --- a/Src/Newtonsoft.Json/Linq/JTokenType.cs +++ b/Src/Newtonsoft.Json/Linq/JTokenType.cs @@ -25,82 +25,99 @@ namespace Newtonsoft.Json.Linq { - /// - /// Specifies the type of token. - /// - public enum JTokenType - { /// - /// No token type has been set. + /// Specifies the type of token. /// - None, - /// - /// A JSON object. - /// - Object, - /// - /// A JSON array. - /// - Array, - /// - /// A JSON constructor. - /// - Constructor, - /// - /// A JSON object property. - /// - Property, - /// - /// A comment. - /// - Comment, - /// - /// An integer value. - /// - Integer, - /// - /// A float value. - /// - Float, - /// - /// A string value. - /// - String, - /// - /// A boolean value. - /// - Boolean, - /// - /// A null value. - /// - Null, - /// - /// An undefined value. - /// - Undefined, - /// - /// A date value. - /// - Date, - /// - /// A raw JSON value. - /// - Raw, - /// - /// A collection of bytes value. - /// - Bytes, - /// - /// A Guid value. - /// - Guid, - /// - /// A Uri value. - /// - Uri, - /// - /// A TimeSpan value. - /// - TimeSpan - } + public enum JTokenType + { + /// + /// No token type has been set. + /// + None, + + /// + /// A JSON object. + /// + Object, + + /// + /// A JSON array. + /// + Array, + + /// + /// A JSON constructor. + /// + Constructor, + + /// + /// A JSON object property. + /// + Property, + + /// + /// A comment. + /// + Comment, + + /// + /// An integer value. + /// + Integer, + + /// + /// A float value. + /// + Float, + + /// + /// A string value. + /// + String, + + /// + /// A boolean value. + /// + Boolean, + + /// + /// A null value. + /// + Null, + + /// + /// An undefined value. + /// + Undefined, + + /// + /// A date value. + /// + Date, + + /// + /// A raw JSON value. + /// + Raw, + + /// + /// A collection of bytes value. + /// + Bytes, + + /// + /// A Guid value. + /// + Guid, + + /// + /// A Uri value. + /// + Uri, + + /// + /// A TimeSpan value. + /// + TimeSpan + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Linq/JTokenWriter.cs b/Src/Newtonsoft.Json/Linq/JTokenWriter.cs index 759020ce..c40547ce 100644 --- a/Src/Newtonsoft.Json/Linq/JTokenWriter.cs +++ b/Src/Newtonsoft.Json/Linq/JTokenWriter.cs @@ -32,425 +32,425 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Linq { - /// - /// Represents a writer that provides a fast, non-cached, forward-only way of generating Json data. - /// - public class JTokenWriter : JsonWriter - { - private JContainer _token; - private JContainer _parent; - // used when writer is writing single value and the value has no containing parent - private JValue _value; - /// - /// Gets the token being writen. + /// Represents a writer that provides a fast, non-cached, forward-only way of generating Json data. /// - /// The token being writen. - public JToken Token + public class JTokenWriter : JsonWriter { - get - { - if (_token != null) - return _token; + private JContainer _token; + private JContainer _parent; + // used when writer is writing single value and the value has no containing parent + private JValue _value; - return _value; - } - } + /// + /// Gets the token being writen. + /// + /// The token being writen. + public JToken Token + { + get + { + if (_token != null) + return _token; - /// - /// Initializes a new instance of the class writing to the given . - /// - /// The container being written to. - public JTokenWriter(JContainer container) - { - ValidationUtils.ArgumentNotNull(container, "container"); + return _value; + } + } - _token = container; - _parent = container; - } + /// + /// Initializes a new instance of the class writing to the given . + /// + /// The container being written to. + public JTokenWriter(JContainer container) + { + ValidationUtils.ArgumentNotNull(container, "container"); - /// - /// Initializes a new instance of the class. - /// - public JTokenWriter() - { - } + _token = container; + _parent = container; + } - /// - /// Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. - /// - public override void Flush() - { - } + /// + /// Initializes a new instance of the class. + /// + public JTokenWriter() + { + } - /// - /// Closes this stream and the underlying stream. - /// - public override void Close() - { - base.Close(); - } + /// + /// Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. + /// + public override void Flush() + { + } - /// - /// Writes the beginning of a Json object. - /// - public override void WriteStartObject() - { - base.WriteStartObject(); + /// + /// Closes this stream and the underlying stream. + /// + public override void Close() + { + base.Close(); + } - AddParent(new JObject()); - } + /// + /// Writes the beginning of a Json object. + /// + public override void WriteStartObject() + { + base.WriteStartObject(); - private void AddParent(JContainer container) - { - if (_parent == null) - _token = container; - else - _parent.AddAndSkipParentCheck(container); + AddParent(new JObject()); + } - _parent = container; - } + private void AddParent(JContainer container) + { + if (_parent == null) + _token = container; + else + _parent.AddAndSkipParentCheck(container); - private void RemoveParent() - { - _parent = _parent.Parent; + _parent = container; + } - if (_parent != null && _parent.Type == JTokenType.Property) - _parent = _parent.Parent; - } + private void RemoveParent() + { + _parent = _parent.Parent; - /// - /// Writes the beginning of a Json array. - /// - public override void WriteStartArray() - { - base.WriteStartArray(); + if (_parent != null && _parent.Type == JTokenType.Property) + _parent = _parent.Parent; + } - AddParent(new JArray()); - } + /// + /// Writes the beginning of a Json array. + /// + public override void WriteStartArray() + { + base.WriteStartArray(); - /// - /// Writes the start of a constructor with the given name. - /// - /// The name of the constructor. - public override void WriteStartConstructor(string name) - { - base.WriteStartConstructor(name); + AddParent(new JArray()); + } - AddParent(new JConstructor(name)); - } + /// + /// Writes the start of a constructor with the given name. + /// + /// The name of the constructor. + public override void WriteStartConstructor(string name) + { + base.WriteStartConstructor(name); - /// - /// Writes the end. - /// - /// The token. - protected override void WriteEnd(JsonToken token) - { - RemoveParent(); - } + AddParent(new JConstructor(name)); + } - /// - /// Writes the property name of a name/value pair on a Json object. - /// - /// The name of the property. - public override void WritePropertyName(string name) - { - base.WritePropertyName(name); + /// + /// Writes the end. + /// + /// The token. + protected override void WriteEnd(JsonToken token) + { + RemoveParent(); + } - AddParent(new JProperty(name)); - } + /// + /// Writes the property name of a name/value pair on a Json object. + /// + /// The name of the property. + public override void WritePropertyName(string name) + { + base.WritePropertyName(name); - private void AddValue(object value, JsonToken token) - { - AddValue(new JValue(value), token); - } + AddParent(new JProperty(name)); + } - internal void AddValue(JValue value, JsonToken token) - { - if (_parent != null) - { - _parent.Add(value); + private void AddValue(object value, JsonToken token) + { + AddValue(new JValue(value), token); + } - if (_parent.Type == JTokenType.Property) - _parent = _parent.Parent; - } - else - { - _value = value ?? new JValue((object)null); - } - } + internal void AddValue(JValue value, JsonToken token) + { + if (_parent != null) + { + _parent.Add(value); - #region WriteValue methods - /// - /// Writes a value. - /// An error will raised if the value cannot be written as a single JSON token. - /// - /// The value to write. - public override void WriteValue(object value) - { + if (_parent.Type == JTokenType.Property) + _parent = _parent.Parent; + } + else + { + _value = value ?? new JValue((object)null); + } + } + + #region WriteValue methods + /// + /// Writes a value. + /// An error will raised if the value cannot be written as a single JSON token. + /// + /// The value to write. + public override void WriteValue(object value) + { #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE || PORTABLE40) - if (value is BigInteger) - { - InternalWriteValue(JsonToken.Integer); - AddValue(value, JsonToken.Integer); - } - else + if (value is BigInteger) + { + InternalWriteValue(JsonToken.Integer); + AddValue(value, JsonToken.Integer); + } + else #endif - { - base.WriteValue(value); - } - } + { + base.WriteValue(value); + } + } - /// - /// Writes a null value. - /// - public override void WriteNull() - { - base.WriteNull(); - AddValue(null, JsonToken.Null); - } + /// + /// Writes a null value. + /// + public override void WriteNull() + { + base.WriteNull(); + AddValue(null, JsonToken.Null); + } - /// - /// Writes an undefined value. - /// - public override void WriteUndefined() - { - base.WriteUndefined(); - AddValue(null, JsonToken.Undefined); - } + /// + /// Writes an undefined value. + /// + public override void WriteUndefined() + { + base.WriteUndefined(); + AddValue(null, JsonToken.Undefined); + } - /// - /// Writes raw JSON. - /// - /// The raw JSON to write. - public override void WriteRaw(string json) - { - base.WriteRaw(json); - AddValue(new JRaw(json), JsonToken.Raw); - } + /// + /// Writes raw JSON. + /// + /// The raw JSON to write. + public override void WriteRaw(string json) + { + base.WriteRaw(json); + AddValue(new JRaw(json), JsonToken.Raw); + } - /// - /// Writes out a comment /*...*/ containing the specified text. - /// - /// Text to place inside the comment. - public override void WriteComment(string text) - { - base.WriteComment(text); - AddValue(JValue.CreateComment(text), JsonToken.Comment); - } + /// + /// Writes out a comment /*...*/ containing the specified text. + /// + /// Text to place inside the comment. + public override void WriteComment(string text) + { + base.WriteComment(text); + AddValue(JValue.CreateComment(text), JsonToken.Comment); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(string value) - { - base.WriteValue(value); - AddValue(value ?? string.Empty, JsonToken.String); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(string value) + { + base.WriteValue(value); + AddValue(value ?? string.Empty, JsonToken.String); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(int value) - { - base.WriteValue(value); - AddValue(value, JsonToken.Integer); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(int value) + { + base.WriteValue(value); + AddValue(value, JsonToken.Integer); + } - /// - /// Writes a value. - /// - /// The value to write. - [CLSCompliant(false)] - public override void WriteValue(uint value) - { - base.WriteValue(value); - AddValue(value, JsonToken.Integer); - } + /// + /// Writes a value. + /// + /// The value to write. + [CLSCompliant(false)] + public override void WriteValue(uint value) + { + base.WriteValue(value); + AddValue(value, JsonToken.Integer); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(long value) - { - base.WriteValue(value); - AddValue(value, JsonToken.Integer); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(long value) + { + base.WriteValue(value); + AddValue(value, JsonToken.Integer); + } - /// - /// Writes a value. - /// - /// The value to write. - [CLSCompliant(false)] - public override void WriteValue(ulong value) - { - base.WriteValue(value); - AddValue(value, JsonToken.Integer); - } + /// + /// Writes a value. + /// + /// The value to write. + [CLSCompliant(false)] + public override void WriteValue(ulong value) + { + base.WriteValue(value); + AddValue(value, JsonToken.Integer); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(float value) - { - base.WriteValue(value); - AddValue(value, JsonToken.Float); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(float value) + { + base.WriteValue(value); + AddValue(value, JsonToken.Float); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(double value) - { - base.WriteValue(value); - AddValue(value, JsonToken.Float); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(double value) + { + base.WriteValue(value); + AddValue(value, JsonToken.Float); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(bool value) - { - base.WriteValue(value); - AddValue(value, JsonToken.Boolean); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(bool value) + { + base.WriteValue(value); + AddValue(value, JsonToken.Boolean); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(short value) - { - base.WriteValue(value); - AddValue(value, JsonToken.Integer); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(short value) + { + base.WriteValue(value); + AddValue(value, JsonToken.Integer); + } - /// - /// Writes a value. - /// - /// The value to write. - [CLSCompliant(false)] - public override void WriteValue(ushort value) - { - base.WriteValue(value); - AddValue(value, JsonToken.Integer); - } + /// + /// Writes a value. + /// + /// The value to write. + [CLSCompliant(false)] + public override void WriteValue(ushort value) + { + base.WriteValue(value); + AddValue(value, JsonToken.Integer); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(char value) - { - base.WriteValue(value); - string s = null; + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(char value) + { + base.WriteValue(value); + string s = null; #if !(NETFX_CORE || PORTABLE40 || PORTABLE) - s = value.ToString(CultureInfo.InvariantCulture); + s = value.ToString(CultureInfo.InvariantCulture); #else - s = value.ToString(); + s = value.ToString(); #endif - AddValue(s, JsonToken.String); - } + AddValue(s, JsonToken.String); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(byte value) - { - base.WriteValue(value); - AddValue(value, JsonToken.Integer); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(byte value) + { + base.WriteValue(value); + AddValue(value, JsonToken.Integer); + } - /// - /// Writes a value. - /// - /// The value to write. - [CLSCompliant(false)] - public override void WriteValue(sbyte value) - { - base.WriteValue(value); - AddValue(value, JsonToken.Integer); - } + /// + /// Writes a value. + /// + /// The value to write. + [CLSCompliant(false)] + public override void WriteValue(sbyte value) + { + base.WriteValue(value); + AddValue(value, JsonToken.Integer); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(decimal value) - { - base.WriteValue(value); - AddValue(value, JsonToken.Float); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(decimal value) + { + base.WriteValue(value); + AddValue(value, JsonToken.Float); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(DateTime value) - { - base.WriteValue(value); - value = DateTimeUtils.EnsureDateTime(value, DateTimeZoneHandling); - AddValue(value, JsonToken.Date); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(DateTime value) + { + base.WriteValue(value); + value = DateTimeUtils.EnsureDateTime(value, DateTimeZoneHandling); + AddValue(value, JsonToken.Date); + } #if !NET20 - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(DateTimeOffset value) - { - base.WriteValue(value); - AddValue(value, JsonToken.Date); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(DateTimeOffset value) + { + base.WriteValue(value); + AddValue(value, JsonToken.Date); + } #endif - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(byte[] value) - { - base.WriteValue(value); - AddValue(value, JsonToken.Bytes); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(byte[] value) + { + base.WriteValue(value); + AddValue(value, JsonToken.Bytes); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(TimeSpan value) - { - base.WriteValue(value); - AddValue(value, JsonToken.String); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(TimeSpan value) + { + base.WriteValue(value); + AddValue(value, JsonToken.String); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(Guid value) - { - base.WriteValue(value); - AddValue(value, JsonToken.String); - } + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(Guid value) + { + base.WriteValue(value); + AddValue(value, JsonToken.String); + } - /// - /// Writes a value. - /// - /// The value to write. - public override void WriteValue(Uri value) - { - base.WriteValue(value); - AddValue(value, JsonToken.String); + /// + /// Writes a value. + /// + /// The value to write. + public override void WriteValue(Uri value) + { + base.WriteValue(value); + AddValue(value, JsonToken.String); + } + #endregion } - #endregion - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Linq/JValue.cs b/Src/Newtonsoft.Json/Linq/JValue.cs index 28402d99..1b676263 100644 --- a/Src/Newtonsoft.Json/Linq/JValue.cs +++ b/Src/Newtonsoft.Json/Linq/JValue.cs @@ -33,984 +33,985 @@ using System.Linq.Expressions; #endif #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) using System.Numerics; + #endif namespace Newtonsoft.Json.Linq { - /// - /// Represents a value in JSON (string, integer, date, etc). - /// - public class JValue : JToken, IEquatable, IFormattable, IComparable, IComparable + /// + /// Represents a value in JSON (string, integer, date, etc). + /// + public class JValue : JToken, IEquatable, IFormattable, IComparable, IComparable #if !(NETFX_CORE || PORTABLE) - , IConvertible + , IConvertible #endif - { - private JTokenType _valueType; - private object _value; - - internal JValue(object value, JTokenType type) { - _value = value; - _valueType = type; - } + private JTokenType _valueType; + private object _value; - /// - /// Initializes a new instance of the class from another object. - /// - /// A object to copy from. - public JValue(JValue other) - : this(other.Value, other.Type) - { - } + internal JValue(object value, JTokenType type) + { + _value = value; + _valueType = type; + } - /// - /// Initializes a new instance of the class with the given value. - /// - /// The value. - public JValue(long value) - : this(value, JTokenType.Integer) - { - } + /// + /// Initializes a new instance of the class from another object. + /// + /// A object to copy from. + public JValue(JValue other) + : this(other.Value, other.Type) + { + } - /// - /// Initializes a new instance of the class with the given value. - /// - /// The value. - public JValue(char value) - : this(value, JTokenType.String) - { - } + /// + /// Initializes a new instance of the class with the given value. + /// + /// The value. + public JValue(long value) + : this(value, JTokenType.Integer) + { + } - /// - /// Initializes a new instance of the class with the given value. - /// - /// The value. - [CLSCompliant(false)] - public JValue(ulong value) - : this(value, JTokenType.Integer) - { - } + /// + /// Initializes a new instance of the class with the given value. + /// + /// The value. + public JValue(char value) + : this(value, JTokenType.String) + { + } - /// - /// Initializes a new instance of the class with the given value. - /// - /// The value. - public JValue(double value) - : this(value, JTokenType.Float) - { - } + /// + /// Initializes a new instance of the class with the given value. + /// + /// The value. + [CLSCompliant(false)] + public JValue(ulong value) + : this(value, JTokenType.Integer) + { + } - /// - /// Initializes a new instance of the class with the given value. - /// - /// The value. - public JValue(float value) - : this(value, JTokenType.Float) - { - } + /// + /// Initializes a new instance of the class with the given value. + /// + /// The value. + public JValue(double value) + : this(value, JTokenType.Float) + { + } - /// - /// Initializes a new instance of the class with the given value. - /// - /// The value. - public JValue(DateTime value) - : this(value, JTokenType.Date) - { - } + /// + /// Initializes a new instance of the class with the given value. + /// + /// The value. + public JValue(float value) + : this(value, JTokenType.Float) + { + } - /// - /// Initializes a new instance of the class with the given value. - /// - /// The value. - public JValue(bool value) - : this(value, JTokenType.Boolean) - { - } + /// + /// Initializes a new instance of the class with the given value. + /// + /// The value. + public JValue(DateTime value) + : this(value, JTokenType.Date) + { + } - /// - /// Initializes a new instance of the class with the given value. - /// - /// The value. - public JValue(string value) - : this(value, JTokenType.String) - { - } + /// + /// Initializes a new instance of the class with the given value. + /// + /// The value. + public JValue(bool value) + : this(value, JTokenType.Boolean) + { + } - /// - /// Initializes a new instance of the class with the given value. - /// - /// The value. - public JValue(Guid value) - : this(value, JTokenType.Guid) - { - } + /// + /// Initializes a new instance of the class with the given value. + /// + /// The value. + public JValue(string value) + : this(value, JTokenType.String) + { + } - /// - /// Initializes a new instance of the class with the given value. - /// - /// The value. - public JValue(Uri value) - : this(value, (value != null) ? JTokenType.Uri : JTokenType.Null) - { - } + /// + /// Initializes a new instance of the class with the given value. + /// + /// The value. + public JValue(Guid value) + : this(value, JTokenType.Guid) + { + } - /// - /// Initializes a new instance of the class with the given value. - /// - /// The value. - public JValue(TimeSpan value) - : this(value, JTokenType.TimeSpan) - { - } + /// + /// Initializes a new instance of the class with the given value. + /// + /// The value. + public JValue(Uri value) + : this(value, (value != null) ? JTokenType.Uri : JTokenType.Null) + { + } - /// - /// Initializes a new instance of the class with the given value. - /// - /// The value. - public JValue(object value) - : this(value, GetValueType(null, value)) - { - } + /// + /// Initializes a new instance of the class with the given value. + /// + /// The value. + public JValue(TimeSpan value) + : this(value, JTokenType.TimeSpan) + { + } - internal override bool DeepEquals(JToken node) - { - JValue other = node as JValue; - if (other == null) - return false; - if (other == this) - return true; + /// + /// Initializes a new instance of the class with the given value. + /// + /// The value. + public JValue(object value) + : this(value, GetValueType(null, value)) + { + } - return ValuesEquals(this, other); - } + internal override bool DeepEquals(JToken node) + { + JValue other = node as JValue; + if (other == null) + return false; + if (other == this) + return true; - /// - /// Gets a value indicating whether this token has child tokens. - /// - /// - /// true if this token has child values; otherwise, false. - /// - public override bool HasValues - { - get { return false; } - } + return ValuesEquals(this, other); + } + + /// + /// Gets a value indicating whether this token has child tokens. + /// + /// + /// true if this token has child values; otherwise, false. + /// + public override bool HasValues + { + get { return false; } + } #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - private static int CompareBigInteger(BigInteger i1, object i2) - { - int result = i1.CompareTo(ConvertUtils.ToBigInteger(i2)); - - if (result != 0) - return result; - - // converting a fractional number to a BigInteger will lose the fraction - // check for fraction if result is two numbers are equal - if (i2 is decimal) - { - decimal d = (decimal) i2; - return (0m).CompareTo(Math.Abs(d - Math.Truncate(d))); - } - else if (i2 is double || i2 is float) - { - double d = Convert.ToDouble(i2, CultureInfo.InvariantCulture); - return (0d).CompareTo(Math.Abs(d - Math.Truncate(d))); - } - - return result; - } -#endif - - internal static int Compare(JTokenType valueType, object objA, object objB) - { - if (objA == null && objB == null) - return 0; - if (objA != null && objB == null) - return 1; - if (objA == null && objB != null) - return -1; - - switch (valueType) - { - case JTokenType.Integer: -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (objA is BigInteger) - return CompareBigInteger((BigInteger)objA, objB); - if (objB is BigInteger) - return -CompareBigInteger((BigInteger)objB, objA); -#endif - if (objA is ulong || objB is ulong || objA is decimal || objB is decimal) - return Convert.ToDecimal(objA, CultureInfo.InvariantCulture).CompareTo(Convert.ToDecimal(objB, CultureInfo.InvariantCulture)); - else if (objA is float || objB is float || objA is double || objB is double) - return CompareFloat(objA, objB); - else - return Convert.ToInt64(objA, CultureInfo.InvariantCulture).CompareTo(Convert.ToInt64(objB, CultureInfo.InvariantCulture)); - case JTokenType.Float: -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (objA is BigInteger) - return CompareBigInteger((BigInteger)objA, objB); - if (objB is BigInteger) - return -CompareBigInteger((BigInteger)objB, objA); -#endif - return CompareFloat(objA, objB); - case JTokenType.Comment: - case JTokenType.String: - case JTokenType.Raw: - string s1 = Convert.ToString(objA, CultureInfo.InvariantCulture); - string s2 = Convert.ToString(objB, CultureInfo.InvariantCulture); - - return string.CompareOrdinal(s1, s2); - case JTokenType.Boolean: - bool b1 = Convert.ToBoolean(objA, CultureInfo.InvariantCulture); - bool b2 = Convert.ToBoolean(objB, CultureInfo.InvariantCulture); - - return b1.CompareTo(b2); - case JTokenType.Date: -#if !NET20 - if (objA is DateTime) - { -#endif - DateTime date1 = (DateTime)objA; - DateTime date2; - -#if !NET20 - if (objB is DateTimeOffset) - date2 = ((DateTimeOffset)objB).DateTime; - else -#endif - date2 = Convert.ToDateTime(objB, CultureInfo.InvariantCulture); - - return date1.CompareTo(date2); -#if !NET20 - } - else - { - DateTimeOffset date1 = (DateTimeOffset) objA; - DateTimeOffset date2; - - if (objB is DateTimeOffset) - date2 = (DateTimeOffset)objB; - else - date2 = new DateTimeOffset(Convert.ToDateTime(objB, CultureInfo.InvariantCulture)); - - return date1.CompareTo(date2); - } -#endif - case JTokenType.Bytes: - if (!(objB is byte[])) - throw new ArgumentException("Object must be of type byte[]."); - - byte[] bytes1 = objA as byte[]; - byte[] bytes2 = objB as byte[]; - if (bytes1 == null) - return -1; - if (bytes2 == null) - return 1; - - return MiscellaneousUtils.ByteArrayCompare(bytes1, bytes2); - case JTokenType.Guid: - if (!(objB is Guid)) - throw new ArgumentException("Object must be of type Guid."); - - Guid guid1 = (Guid) objA; - Guid guid2 = (Guid) objB; - - return guid1.CompareTo(guid2); - case JTokenType.Uri: - if (!(objB is Uri)) - throw new ArgumentException("Object must be of type Uri."); - - Uri uri1 = (Uri)objA; - Uri uri2 = (Uri)objB; - - return Comparer.Default.Compare(uri1.ToString(), uri2.ToString()); - case JTokenType.TimeSpan: - if (!(objB is TimeSpan)) - throw new ArgumentException("Object must be of type TimeSpan."); - - TimeSpan ts1 = (TimeSpan)objA; - TimeSpan ts2 = (TimeSpan)objB; - - return ts1.CompareTo(ts2); - default: - throw MiscellaneousUtils.CreateArgumentOutOfRangeException("valueType", valueType, "Unexpected value type: {0}".FormatWith(CultureInfo.InvariantCulture, valueType)); - } - } - - private static int CompareFloat(object objA, object objB) - { - double d1 = Convert.ToDouble(objA, CultureInfo.InvariantCulture); - double d2 = Convert.ToDouble(objB, CultureInfo.InvariantCulture); - - // take into account possible floating point errors - if (MathUtils.ApproxEquals(d1, d2)) - return 0; - - return d1.CompareTo(d2); - } - -#if !(NET35 || NET20 || PORTABLE40) - private static bool Operation(ExpressionType operation, object objA, object objB, out object result) - { - if (objA is string || objB is string) - { - if (operation == ExpressionType.Add || operation == ExpressionType.AddAssign) + private static int CompareBigInteger(BigInteger i1, object i2) { - result = ((objA != null) ? objA.ToString() : null) + ((objB != null) ? objB.ToString() : null); - return true; - } - } + int result = i1.CompareTo(ConvertUtils.ToBigInteger(i2)); -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (objA is BigInteger || objB is BigInteger) - { - if (objA == null || objB == null) - { - result = null; - return true; - } + if (result != 0) + return result; - // not that this will lose the fraction - // BigInteger doesn't have operators with non-integer types - BigInteger i1 = ConvertUtils.ToBigInteger(objA); - BigInteger i2 = ConvertUtils.ToBigInteger(objB); - - switch (operation) - { - case ExpressionType.Add: - case ExpressionType.AddAssign: - result = i1 + i2; - return true; - case ExpressionType.Subtract: - case ExpressionType.SubtractAssign: - result = i1 - i2; - return true; - case ExpressionType.Multiply: - case ExpressionType.MultiplyAssign: - result = i1 * i2; - return true; - case ExpressionType.Divide: - case ExpressionType.DivideAssign: - result = i1 / i2; - return true; - } - } - else -#endif - if (objA is ulong || objB is ulong || objA is decimal || objB is decimal) - { - if (objA == null || objB == null) - { - result = null; - return true; - } - - decimal d1 = Convert.ToDecimal(objA, CultureInfo.InvariantCulture); - decimal d2 = Convert.ToDecimal(objB, CultureInfo.InvariantCulture); - - switch (operation) - { - case ExpressionType.Add: - case ExpressionType.AddAssign: - result = d1 + d2; - return true; - case ExpressionType.Subtract: - case ExpressionType.SubtractAssign: - result = d1 - d2; - return true; - case ExpressionType.Multiply: - case ExpressionType.MultiplyAssign: - result = d1 * d2; - return true; - case ExpressionType.Divide: - case ExpressionType.DivideAssign: - result = d1 / d2; - return true; - } - } - else if (objA is float || objB is float || objA is double || objB is double) - { - if (objA == null || objB == null) - { - result = null; - return true; - } - - double d1 = Convert.ToDouble(objA, CultureInfo.InvariantCulture); - double d2 = Convert.ToDouble(objB, CultureInfo.InvariantCulture); - - switch (operation) - { - case ExpressionType.Add: - case ExpressionType.AddAssign: - result = d1 + d2; - return true; - case ExpressionType.Subtract: - case ExpressionType.SubtractAssign: - result = d1 - d2; - return true; - case ExpressionType.Multiply: - case ExpressionType.MultiplyAssign: - result = d1 * d2; - return true; - case ExpressionType.Divide: - case ExpressionType.DivideAssign: - result = d1 / d2; - return true; - } - } - else if (objA is int || objA is uint || objA is long || objA is short || objA is ushort || objA is sbyte || objA is byte || - objB is int || objB is uint || objB is long || objB is short || objB is ushort || objB is sbyte || objB is byte) - { - if (objA == null || objB == null) - { - result = null; - return true; - } - - long l1 = Convert.ToInt64(objA, CultureInfo.InvariantCulture); - long l2 = Convert.ToInt64(objB, CultureInfo.InvariantCulture); - - switch (operation) - { - case ExpressionType.Add: - case ExpressionType.AddAssign: - result = l1 + l2; - return true; - case ExpressionType.Subtract: - case ExpressionType.SubtractAssign: - result = l1 - l2; - return true; - case ExpressionType.Multiply: - case ExpressionType.MultiplyAssign: - result = l1 * l2; - return true; - case ExpressionType.Divide: - case ExpressionType.DivideAssign: - result = l1 / l2; - return true; - } - } - - result = null; - return false; - } -#endif - - internal override JToken CloneToken() - { - return new JValue(this); - } - - /// - /// Creates a comment with the given value. - /// - /// The value. - /// A comment with the given value. - public static JValue CreateComment(string value) - { - return new JValue(value, JTokenType.Comment); - } - - /// - /// Creates a string with the given value. - /// - /// The value. - /// A string with the given value. - public static JValue CreateString(string value) - { - return new JValue(value, JTokenType.String); - } - - private static JTokenType GetValueType(JTokenType? current, object value) - { - if (value == null) - return JTokenType.Null; -#if !(NETFX_CORE || PORTABLE40 || PORTABLE) - else if (value == DBNull.Value) - return JTokenType.Null; -#endif - else if (value is string) - return GetStringValueType(current); - else if (value is long || value is int || value is short || value is sbyte - || value is ulong || value is uint || value is ushort || value is byte) - return JTokenType.Integer; - else if (value is Enum) - return JTokenType.Integer; -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - else if (value is BigInteger) - return JTokenType.Integer; -#endif - else if (value is double || value is float || value is decimal) - return JTokenType.Float; - else if (value is DateTime) - return JTokenType.Date; -#if !NET20 - else if (value is DateTimeOffset) - return JTokenType.Date; -#endif - else if (value is byte[]) - return JTokenType.Bytes; - else if (value is bool) - return JTokenType.Boolean; - else if (value is Guid) - return JTokenType.Guid; - else if (value is Uri) - return JTokenType.Uri; - else if (value is TimeSpan) - return JTokenType.TimeSpan; - - throw new ArgumentException("Could not determine JSON object type for type {0}.".FormatWith(CultureInfo.InvariantCulture, value.GetType())); - } - - private static JTokenType GetStringValueType(JTokenType? current) - { - if (current == null) - return JTokenType.String; - - switch (current.Value) - { - case JTokenType.Comment: - case JTokenType.String: - case JTokenType.Raw: - return current.Value; - default: - return JTokenType.String; - } - } - - /// - /// Gets the node type for this . - /// - /// The type. - public override JTokenType Type - { - get { return _valueType; } - } - - /// - /// Gets or sets the underlying token value. - /// - /// The underlying token value. - public object Value - { - get { return _value; } - set - { - Type currentType = (_value != null) ? _value.GetType() : null; - Type newType = (value != null) ? value.GetType() : null; - - if (currentType != newType) - _valueType = GetValueType(_valueType, value); - - _value = value; - } - } - - /// - /// Writes this token to a . - /// - /// A into which this method will write. - /// A collection of which will be used when writing the token. - public override void WriteTo(JsonWriter writer, params JsonConverter[] converters) - { - if (converters != null && converters.Length > 0 && _value != null) - { - JsonConverter matchingConverter = JsonSerializer.GetMatchingConverter(converters, _value.GetType()); - if (matchingConverter != null) - { - matchingConverter.WriteJson(writer, _value, JsonSerializer.CreateDefault()); - return; - } - } - - switch (_valueType) - { - case JTokenType.Comment: - writer.WriteComment((_value != null) ? _value.ToString() : null); - return; - case JTokenType.Raw: - writer.WriteRawValue((_value != null) ? _value.ToString() : null); - return; - case JTokenType.Null: - writer.WriteNull(); - return; - case JTokenType.Undefined: - writer.WriteUndefined(); - return; - case JTokenType.Integer: -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (_value is BigInteger) - writer.WriteValue((BigInteger)_value); - else -#endif - writer.WriteValue(Convert.ToInt64(_value, CultureInfo.InvariantCulture)); - return; - case JTokenType.Float: - if (_value is decimal) - writer.WriteValue((decimal)_value); - else if (_value is double) - writer.WriteValue((double)_value); - else if (_value is float) - writer.WriteValue((float)_value); - else - writer.WriteValue(Convert.ToDouble(_value, CultureInfo.InvariantCulture)); - return; - case JTokenType.String: - writer.WriteValue((_value != null) ? _value.ToString() : null); - return; - case JTokenType.Boolean: - writer.WriteValue(Convert.ToBoolean(_value, CultureInfo.InvariantCulture)); - return; - case JTokenType.Date: -#if !NET20 - if (_value is DateTimeOffset) - writer.WriteValue((DateTimeOffset)_value); - else -#endif - writer.WriteValue(Convert.ToDateTime(_value, CultureInfo.InvariantCulture)); - return; - case JTokenType.Bytes: - writer.WriteValue((byte[])_value); - return; - case JTokenType.Guid: - case JTokenType.Uri: - case JTokenType.TimeSpan: - writer.WriteValue((_value != null) ? _value.ToString() : null); - return; - } - - throw MiscellaneousUtils.CreateArgumentOutOfRangeException("TokenType", _valueType, "Unexpected token type."); - } - - internal override int GetDeepHashCode() - { - int valueHashCode = (_value != null) ? _value.GetHashCode() : 0; - - return _valueType.GetHashCode() ^ valueHashCode; - } - - private static bool ValuesEquals(JValue v1, JValue v2) - { - return (v1 == v2 || (v1._valueType == v2._valueType && Compare(v1._valueType, v1._value, v2._value) == 0)); - } - - /// - /// Indicates whether the current object is equal to another object of the same type. - /// - /// - /// true if the current object is equal to the parameter; otherwise, false. - /// - /// An object to compare with this object. - public bool Equals(JValue other) - { - if (other == null) - return false; - - return ValuesEquals(this, other); - } - - /// - /// Determines whether the specified is equal to the current . - /// - /// The to compare with the current . - /// - /// true if the specified is equal to the current ; otherwise, false. - /// - /// - /// The parameter is null. - /// - public override bool Equals(object obj) - { - if (obj == null) - return false; - - JValue otherValue = obj as JValue; - if (otherValue != null) - return Equals(otherValue); - - return base.Equals(obj); - } - - /// - /// Serves as a hash function for a particular type. - /// - /// - /// A hash code for the current . - /// - public override int GetHashCode() - { - if (_value == null) - return 0; - - return _value.GetHashCode(); - } - - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override string ToString() - { - if (_value == null) - return string.Empty; - - return _value.ToString(); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// - /// A that represents this instance. - /// - public string ToString(string format) - { - return ToString(format, CultureInfo.CurrentCulture); - } - - /// - /// Returns a that represents this instance. - /// - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(IFormatProvider formatProvider) - { - return ToString(null, formatProvider); - } - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// The format provider. - /// - /// A that represents this instance. - /// - public string ToString(string format, IFormatProvider formatProvider) - { - if (_value == null) - return string.Empty; - - IFormattable formattable = _value as IFormattable; - if (formattable != null) - return formattable.ToString(format, formatProvider); - else - return _value.ToString(); - } - -#if !(NET35 || NET20 || PORTABLE40) - /// - /// Returns the responsible for binding operations performed on this object. - /// - /// The expression tree representation of the runtime value. - /// - /// The to bind this object. - /// - protected override DynamicMetaObject GetMetaObject(Expression parameter) - { - return new DynamicProxyMetaObject(parameter, this, new JValueDynamicProxy(), true); - } - - private class JValueDynamicProxy : DynamicProxy - { - public override bool TryConvert(JValue instance, ConvertBinder binder, out object result) - { - if (binder.Type == typeof(JValue)) - { - result = instance; - return true; - } - - object value = instance.Value; - - if (value == null) - { - result = null; - return ReflectionUtils.IsNullable(binder.Type); - } - - result = ConvertUtils.Convert(instance.Value, CultureInfo.InvariantCulture, binder.Type); - return true; - } - - public override bool TryBinaryOperation(JValue instance, BinaryOperationBinder binder, object arg, out object result) - { - object compareValue = (arg is JValue) ? ((JValue) arg).Value : arg; - - switch (binder.Operation) - { - case ExpressionType.Equal: - result = (Compare(instance.Type, instance.Value, compareValue) == 0); - return true; - case ExpressionType.NotEqual: - result = (Compare(instance.Type, instance.Value, compareValue) != 0); - return true; - case ExpressionType.GreaterThan: - result = (Compare(instance.Type, instance.Value, compareValue) > 0); - return true; - case ExpressionType.GreaterThanOrEqual: - result = (Compare(instance.Type, instance.Value, compareValue) >= 0); - return true; - case ExpressionType.LessThan: - result = (Compare(instance.Type, instance.Value, compareValue) < 0); - return true; - case ExpressionType.LessThanOrEqual: - result = (Compare(instance.Type, instance.Value, compareValue) <= 0); - return true; - case ExpressionType.Add: - case ExpressionType.AddAssign: - case ExpressionType.Subtract: - case ExpressionType.SubtractAssign: - case ExpressionType.Multiply: - case ExpressionType.MultiplyAssign: - case ExpressionType.Divide: - case ExpressionType.DivideAssign: - if (Operation(binder.Operation, instance.Value, compareValue, out result)) + // converting a fractional number to a BigInteger will lose the fraction + // check for fraction if result is two numbers are equal + if (i2 is decimal) { - result = new JValue(result); - return true; + decimal d = (decimal)i2; + return (0m).CompareTo(Math.Abs(d - Math.Truncate(d))); + } + else if (i2 is double || i2 is float) + { + double d = Convert.ToDouble(i2, CultureInfo.InvariantCulture); + return (0d).CompareTo(Math.Abs(d - Math.Truncate(d))); } - break; - } - result = null; - return false; - } - } + return result; + } #endif - int IComparable.CompareTo(object obj) - { - if (obj == null) - return 1; + internal static int Compare(JTokenType valueType, object objA, object objB) + { + if (objA == null && objB == null) + return 0; + if (objA != null && objB == null) + return 1; + if (objA == null && objB != null) + return -1; - object otherValue = (obj is JValue) ? ((JValue) obj).Value : obj; + switch (valueType) + { + case JTokenType.Integer: +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (objA is BigInteger) + return CompareBigInteger((BigInteger)objA, objB); + if (objB is BigInteger) + return -CompareBigInteger((BigInteger)objB, objA); +#endif + if (objA is ulong || objB is ulong || objA is decimal || objB is decimal) + return Convert.ToDecimal(objA, CultureInfo.InvariantCulture).CompareTo(Convert.ToDecimal(objB, CultureInfo.InvariantCulture)); + else if (objA is float || objB is float || objA is double || objB is double) + return CompareFloat(objA, objB); + else + return Convert.ToInt64(objA, CultureInfo.InvariantCulture).CompareTo(Convert.ToInt64(objB, CultureInfo.InvariantCulture)); + case JTokenType.Float: +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (objA is BigInteger) + return CompareBigInteger((BigInteger)objA, objB); + if (objB is BigInteger) + return -CompareBigInteger((BigInteger)objB, objA); +#endif + return CompareFloat(objA, objB); + case JTokenType.Comment: + case JTokenType.String: + case JTokenType.Raw: + string s1 = Convert.ToString(objA, CultureInfo.InvariantCulture); + string s2 = Convert.ToString(objB, CultureInfo.InvariantCulture); - return Compare(_valueType, _value, otherValue); - } + return string.CompareOrdinal(s1, s2); + case JTokenType.Boolean: + bool b1 = Convert.ToBoolean(objA, CultureInfo.InvariantCulture); + bool b2 = Convert.ToBoolean(objB, CultureInfo.InvariantCulture); - /// - /// Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance precedes, follows, or occurs in the same position in the sort order as the other object. - /// - /// An object to compare with this instance. - /// - /// A 32-bit signed integer that indicates the relative order of the objects being compared. The return value has these meanings: - /// Value - /// Meaning - /// Less than zero - /// This instance is less than . - /// Zero - /// This instance is equal to . - /// Greater than zero - /// This instance is greater than . - /// - /// - /// is not the same type as this instance. - /// - public int CompareTo(JValue obj) - { - if (obj == null) - return 1; - - return Compare(_valueType, _value, obj._value); - } - -#if !(NETFX_CORE || PORTABLE) - TypeCode IConvertible.GetTypeCode() - { - if (_value == null) - return TypeCode.Empty; + return b1.CompareTo(b2); + case JTokenType.Date: +#if !NET20 + if (objA is DateTime) + { +#endif + DateTime date1 = (DateTime)objA; + DateTime date2; #if !NET20 - if (_value is DateTimeOffset) - return TypeCode.DateTime; + if (objB is DateTimeOffset) + date2 = ((DateTimeOffset)objB).DateTime; + else +#endif + date2 = Convert.ToDateTime(objB, CultureInfo.InvariantCulture); + + return date1.CompareTo(date2); +#if !NET20 + } + else + { + DateTimeOffset date1 = (DateTimeOffset)objA; + DateTimeOffset date2; + + if (objB is DateTimeOffset) + date2 = (DateTimeOffset)objB; + else + date2 = new DateTimeOffset(Convert.ToDateTime(objB, CultureInfo.InvariantCulture)); + + return date1.CompareTo(date2); + } +#endif + case JTokenType.Bytes: + if (!(objB is byte[])) + throw new ArgumentException("Object must be of type byte[]."); + + byte[] bytes1 = objA as byte[]; + byte[] bytes2 = objB as byte[]; + if (bytes1 == null) + return -1; + if (bytes2 == null) + return 1; + + return MiscellaneousUtils.ByteArrayCompare(bytes1, bytes2); + case JTokenType.Guid: + if (!(objB is Guid)) + throw new ArgumentException("Object must be of type Guid."); + + Guid guid1 = (Guid)objA; + Guid guid2 = (Guid)objB; + + return guid1.CompareTo(guid2); + case JTokenType.Uri: + if (!(objB is Uri)) + throw new ArgumentException("Object must be of type Uri."); + + Uri uri1 = (Uri)objA; + Uri uri2 = (Uri)objB; + + return Comparer.Default.Compare(uri1.ToString(), uri2.ToString()); + case JTokenType.TimeSpan: + if (!(objB is TimeSpan)) + throw new ArgumentException("Object must be of type TimeSpan."); + + TimeSpan ts1 = (TimeSpan)objA; + TimeSpan ts2 = (TimeSpan)objB; + + return ts1.CompareTo(ts2); + default: + throw MiscellaneousUtils.CreateArgumentOutOfRangeException("valueType", valueType, "Unexpected value type: {0}".FormatWith(CultureInfo.InvariantCulture, valueType)); + } + } + + private static int CompareFloat(object objA, object objB) + { + double d1 = Convert.ToDouble(objA, CultureInfo.InvariantCulture); + double d2 = Convert.ToDouble(objB, CultureInfo.InvariantCulture); + + // take into account possible floating point errors + if (MathUtils.ApproxEquals(d1, d2)) + return 0; + + return d1.CompareTo(d2); + } + +#if !(NET35 || NET20 || PORTABLE40) + private static bool Operation(ExpressionType operation, object objA, object objB, out object result) + { + if (objA is string || objB is string) + { + if (operation == ExpressionType.Add || operation == ExpressionType.AddAssign) + { + result = ((objA != null) ? objA.ToString() : null) + ((objB != null) ? objB.ToString() : null); + return true; + } + } + +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (objA is BigInteger || objB is BigInteger) + { + if (objA == null || objB == null) + { + result = null; + return true; + } + + // not that this will lose the fraction + // BigInteger doesn't have operators with non-integer types + BigInteger i1 = ConvertUtils.ToBigInteger(objA); + BigInteger i2 = ConvertUtils.ToBigInteger(objB); + + switch (operation) + { + case ExpressionType.Add: + case ExpressionType.AddAssign: + result = i1 + i2; + return true; + case ExpressionType.Subtract: + case ExpressionType.SubtractAssign: + result = i1 - i2; + return true; + case ExpressionType.Multiply: + case ExpressionType.MultiplyAssign: + result = i1 * i2; + return true; + case ExpressionType.Divide: + case ExpressionType.DivideAssign: + result = i1 / i2; + return true; + } + } + else +#endif + if (objA is ulong || objB is ulong || objA is decimal || objB is decimal) + { + if (objA == null || objB == null) + { + result = null; + return true; + } + + decimal d1 = Convert.ToDecimal(objA, CultureInfo.InvariantCulture); + decimal d2 = Convert.ToDecimal(objB, CultureInfo.InvariantCulture); + + switch (operation) + { + case ExpressionType.Add: + case ExpressionType.AddAssign: + result = d1 + d2; + return true; + case ExpressionType.Subtract: + case ExpressionType.SubtractAssign: + result = d1 - d2; + return true; + case ExpressionType.Multiply: + case ExpressionType.MultiplyAssign: + result = d1 * d2; + return true; + case ExpressionType.Divide: + case ExpressionType.DivideAssign: + result = d1 / d2; + return true; + } + } + else if (objA is float || objB is float || objA is double || objB is double) + { + if (objA == null || objB == null) + { + result = null; + return true; + } + + double d1 = Convert.ToDouble(objA, CultureInfo.InvariantCulture); + double d2 = Convert.ToDouble(objB, CultureInfo.InvariantCulture); + + switch (operation) + { + case ExpressionType.Add: + case ExpressionType.AddAssign: + result = d1 + d2; + return true; + case ExpressionType.Subtract: + case ExpressionType.SubtractAssign: + result = d1 - d2; + return true; + case ExpressionType.Multiply: + case ExpressionType.MultiplyAssign: + result = d1 * d2; + return true; + case ExpressionType.Divide: + case ExpressionType.DivideAssign: + result = d1 / d2; + return true; + } + } + else if (objA is int || objA is uint || objA is long || objA is short || objA is ushort || objA is sbyte || objA is byte || + objB is int || objB is uint || objB is long || objB is short || objB is ushort || objB is sbyte || objB is byte) + { + if (objA == null || objB == null) + { + result = null; + return true; + } + + long l1 = Convert.ToInt64(objA, CultureInfo.InvariantCulture); + long l2 = Convert.ToInt64(objB, CultureInfo.InvariantCulture); + + switch (operation) + { + case ExpressionType.Add: + case ExpressionType.AddAssign: + result = l1 + l2; + return true; + case ExpressionType.Subtract: + case ExpressionType.SubtractAssign: + result = l1 - l2; + return true; + case ExpressionType.Multiply: + case ExpressionType.MultiplyAssign: + result = l1 * l2; + return true; + case ExpressionType.Divide: + case ExpressionType.DivideAssign: + result = l1 / l2; + return true; + } + } + + result = null; + return false; + } +#endif + + internal override JToken CloneToken() + { + return new JValue(this); + } + + /// + /// Creates a comment with the given value. + /// + /// The value. + /// A comment with the given value. + public static JValue CreateComment(string value) + { + return new JValue(value, JTokenType.Comment); + } + + /// + /// Creates a string with the given value. + /// + /// The value. + /// A string with the given value. + public static JValue CreateString(string value) + { + return new JValue(value, JTokenType.String); + } + + private static JTokenType GetValueType(JTokenType? current, object value) + { + if (value == null) + return JTokenType.Null; +#if !(NETFX_CORE || PORTABLE40 || PORTABLE) + else if (value == DBNull.Value) + return JTokenType.Null; +#endif + else if (value is string) + return GetStringValueType(current); + else if (value is long || value is int || value is short || value is sbyte + || value is ulong || value is uint || value is ushort || value is byte) + return JTokenType.Integer; + else if (value is Enum) + return JTokenType.Integer; +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + else if (value is BigInteger) + return JTokenType.Integer; +#endif + else if (value is double || value is float || value is decimal) + return JTokenType.Float; + else if (value is DateTime) + return JTokenType.Date; +#if !NET20 + else if (value is DateTimeOffset) + return JTokenType.Date; +#endif + else if (value is byte[]) + return JTokenType.Bytes; + else if (value is bool) + return JTokenType.Boolean; + else if (value is Guid) + return JTokenType.Guid; + else if (value is Uri) + return JTokenType.Uri; + else if (value is TimeSpan) + return JTokenType.TimeSpan; + + throw new ArgumentException("Could not determine JSON object type for type {0}.".FormatWith(CultureInfo.InvariantCulture, value.GetType())); + } + + private static JTokenType GetStringValueType(JTokenType? current) + { + if (current == null) + return JTokenType.String; + + switch (current.Value) + { + case JTokenType.Comment: + case JTokenType.String: + case JTokenType.Raw: + return current.Value; + default: + return JTokenType.String; + } + } + + /// + /// Gets the node type for this . + /// + /// The type. + public override JTokenType Type + { + get { return _valueType; } + } + + /// + /// Gets or sets the underlying token value. + /// + /// The underlying token value. + public object Value + { + get { return _value; } + set + { + Type currentType = (_value != null) ? _value.GetType() : null; + Type newType = (value != null) ? value.GetType() : null; + + if (currentType != newType) + _valueType = GetValueType(_valueType, value); + + _value = value; + } + } + + /// + /// Writes this token to a . + /// + /// A into which this method will write. + /// A collection of which will be used when writing the token. + public override void WriteTo(JsonWriter writer, params JsonConverter[] converters) + { + if (converters != null && converters.Length > 0 && _value != null) + { + JsonConverter matchingConverter = JsonSerializer.GetMatchingConverter(converters, _value.GetType()); + if (matchingConverter != null) + { + matchingConverter.WriteJson(writer, _value, JsonSerializer.CreateDefault()); + return; + } + } + + switch (_valueType) + { + case JTokenType.Comment: + writer.WriteComment((_value != null) ? _value.ToString() : null); + return; + case JTokenType.Raw: + writer.WriteRawValue((_value != null) ? _value.ToString() : null); + return; + case JTokenType.Null: + writer.WriteNull(); + return; + case JTokenType.Undefined: + writer.WriteUndefined(); + return; + case JTokenType.Integer: +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) + if (_value is BigInteger) + writer.WriteValue((BigInteger)_value); + else +#endif + writer.WriteValue(Convert.ToInt64(_value, CultureInfo.InvariantCulture)); + return; + case JTokenType.Float: + if (_value is decimal) + writer.WriteValue((decimal)_value); + else if (_value is double) + writer.WriteValue((double)_value); + else if (_value is float) + writer.WriteValue((float)_value); + else + writer.WriteValue(Convert.ToDouble(_value, CultureInfo.InvariantCulture)); + return; + case JTokenType.String: + writer.WriteValue((_value != null) ? _value.ToString() : null); + return; + case JTokenType.Boolean: + writer.WriteValue(Convert.ToBoolean(_value, CultureInfo.InvariantCulture)); + return; + case JTokenType.Date: +#if !NET20 + if (_value is DateTimeOffset) + writer.WriteValue((DateTimeOffset)_value); + else +#endif + writer.WriteValue(Convert.ToDateTime(_value, CultureInfo.InvariantCulture)); + return; + case JTokenType.Bytes: + writer.WriteValue((byte[])_value); + return; + case JTokenType.Guid: + case JTokenType.Uri: + case JTokenType.TimeSpan: + writer.WriteValue((_value != null) ? _value.ToString() : null); + return; + } + + throw MiscellaneousUtils.CreateArgumentOutOfRangeException("TokenType", _valueType, "Unexpected token type."); + } + + internal override int GetDeepHashCode() + { + int valueHashCode = (_value != null) ? _value.GetHashCode() : 0; + + return _valueType.GetHashCode() ^ valueHashCode; + } + + private static bool ValuesEquals(JValue v1, JValue v2) + { + return (v1 == v2 || (v1._valueType == v2._valueType && Compare(v1._valueType, v1._value, v2._value) == 0)); + } + + /// + /// Indicates whether the current object is equal to another object of the same type. + /// + /// + /// true if the current object is equal to the parameter; otherwise, false. + /// + /// An object to compare with this object. + public bool Equals(JValue other) + { + if (other == null) + return false; + + return ValuesEquals(this, other); + } + + /// + /// Determines whether the specified is equal to the current . + /// + /// The to compare with the current . + /// + /// true if the specified is equal to the current ; otherwise, false. + /// + /// + /// The parameter is null. + /// + public override bool Equals(object obj) + { + if (obj == null) + return false; + + JValue otherValue = obj as JValue; + if (otherValue != null) + return Equals(otherValue); + + return base.Equals(obj); + } + + /// + /// Serves as a hash function for a particular type. + /// + /// + /// A hash code for the current . + /// + public override int GetHashCode() + { + if (_value == null) + return 0; + + return _value.GetHashCode(); + } + + /// + /// Returns a that represents this instance. + /// + /// + /// A that represents this instance. + /// + public override string ToString() + { + if (_value == null) + return string.Empty; + + return _value.ToString(); + } + + /// + /// Returns a that represents this instance. + /// + /// The format. + /// + /// A that represents this instance. + /// + public string ToString(string format) + { + return ToString(format, CultureInfo.CurrentCulture); + } + + /// + /// Returns a that represents this instance. + /// + /// The format provider. + /// + /// A that represents this instance. + /// + public string ToString(IFormatProvider formatProvider) + { + return ToString(null, formatProvider); + } + + /// + /// Returns a that represents this instance. + /// + /// The format. + /// The format provider. + /// + /// A that represents this instance. + /// + public string ToString(string format, IFormatProvider formatProvider) + { + if (_value == null) + return string.Empty; + + IFormattable formattable = _value as IFormattable; + if (formattable != null) + return formattable.ToString(format, formatProvider); + else + return _value.ToString(); + } + +#if !(NET35 || NET20 || PORTABLE40) + /// + /// Returns the responsible for binding operations performed on this object. + /// + /// The expression tree representation of the runtime value. + /// + /// The to bind this object. + /// + protected override DynamicMetaObject GetMetaObject(Expression parameter) + { + return new DynamicProxyMetaObject(parameter, this, new JValueDynamicProxy(), true); + } + + private class JValueDynamicProxy : DynamicProxy + { + public override bool TryConvert(JValue instance, ConvertBinder binder, out object result) + { + if (binder.Type == typeof(JValue)) + { + result = instance; + return true; + } + + object value = instance.Value; + + if (value == null) + { + result = null; + return ReflectionUtils.IsNullable(binder.Type); + } + + result = ConvertUtils.Convert(instance.Value, CultureInfo.InvariantCulture, binder.Type); + return true; + } + + public override bool TryBinaryOperation(JValue instance, BinaryOperationBinder binder, object arg, out object result) + { + object compareValue = (arg is JValue) ? ((JValue)arg).Value : arg; + + switch (binder.Operation) + { + case ExpressionType.Equal: + result = (Compare(instance.Type, instance.Value, compareValue) == 0); + return true; + case ExpressionType.NotEqual: + result = (Compare(instance.Type, instance.Value, compareValue) != 0); + return true; + case ExpressionType.GreaterThan: + result = (Compare(instance.Type, instance.Value, compareValue) > 0); + return true; + case ExpressionType.GreaterThanOrEqual: + result = (Compare(instance.Type, instance.Value, compareValue) >= 0); + return true; + case ExpressionType.LessThan: + result = (Compare(instance.Type, instance.Value, compareValue) < 0); + return true; + case ExpressionType.LessThanOrEqual: + result = (Compare(instance.Type, instance.Value, compareValue) <= 0); + return true; + case ExpressionType.Add: + case ExpressionType.AddAssign: + case ExpressionType.Subtract: + case ExpressionType.SubtractAssign: + case ExpressionType.Multiply: + case ExpressionType.MultiplyAssign: + case ExpressionType.Divide: + case ExpressionType.DivideAssign: + if (Operation(binder.Operation, instance.Value, compareValue, out result)) + { + result = new JValue(result); + return true; + } + break; + } + + result = null; + return false; + } + } +#endif + + int IComparable.CompareTo(object obj) + { + if (obj == null) + return 1; + + object otherValue = (obj is JValue) ? ((JValue)obj).Value : obj; + + return Compare(_valueType, _value, otherValue); + } + + /// + /// Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance precedes, follows, or occurs in the same position in the sort order as the other object. + /// + /// An object to compare with this instance. + /// + /// A 32-bit signed integer that indicates the relative order of the objects being compared. The return value has these meanings: + /// Value + /// Meaning + /// Less than zero + /// This instance is less than . + /// Zero + /// This instance is equal to . + /// Greater than zero + /// This instance is greater than . + /// + /// + /// is not the same type as this instance. + /// + public int CompareTo(JValue obj) + { + if (obj == null) + return 1; + + return Compare(_valueType, _value, obj._value); + } + +#if !(NETFX_CORE || PORTABLE) + TypeCode IConvertible.GetTypeCode() + { + if (_value == null) + return TypeCode.Empty; + +#if !NET20 + if (_value is DateTimeOffset) + return TypeCode.DateTime; #endif #if !(NET20 || NET35 || PORTABLE40 || SILVERLIGHT) - if (_value is BigInteger) - return TypeCode.Object; + if (_value is BigInteger) + return TypeCode.Object; #endif - return System.Type.GetTypeCode(_value.GetType()); - } + return System.Type.GetTypeCode(_value.GetType()); + } - bool IConvertible.ToBoolean(IFormatProvider provider) - { - return (bool) this; - } + bool IConvertible.ToBoolean(IFormatProvider provider) + { + return (bool)this; + } - char IConvertible.ToChar(IFormatProvider provider) - { - return (char) this; - } + char IConvertible.ToChar(IFormatProvider provider) + { + return (char)this; + } - sbyte IConvertible.ToSByte(IFormatProvider provider) - { - return (sbyte) this; - } + sbyte IConvertible.ToSByte(IFormatProvider provider) + { + return (sbyte)this; + } - byte IConvertible.ToByte(IFormatProvider provider) - { - return (byte) this; - } + byte IConvertible.ToByte(IFormatProvider provider) + { + return (byte)this; + } - short IConvertible.ToInt16(IFormatProvider provider) - { - return (short) this; - } + short IConvertible.ToInt16(IFormatProvider provider) + { + return (short)this; + } - ushort IConvertible.ToUInt16(IFormatProvider provider) - { - return (ushort) this; - } + ushort IConvertible.ToUInt16(IFormatProvider provider) + { + return (ushort)this; + } - int IConvertible.ToInt32(IFormatProvider provider) - { - return (int) this; - } + int IConvertible.ToInt32(IFormatProvider provider) + { + return (int)this; + } - uint IConvertible.ToUInt32(IFormatProvider provider) - { - return (uint) this; - } + uint IConvertible.ToUInt32(IFormatProvider provider) + { + return (uint)this; + } - long IConvertible.ToInt64(IFormatProvider provider) - { - return (long) this; - } + long IConvertible.ToInt64(IFormatProvider provider) + { + return (long)this; + } - ulong IConvertible.ToUInt64(IFormatProvider provider) - { - return (ulong) this; - } + ulong IConvertible.ToUInt64(IFormatProvider provider) + { + return (ulong)this; + } - float IConvertible.ToSingle(IFormatProvider provider) - { - return (float) this; - } + float IConvertible.ToSingle(IFormatProvider provider) + { + return (float)this; + } - double IConvertible.ToDouble(IFormatProvider provider) - { - return (double) this; - } + double IConvertible.ToDouble(IFormatProvider provider) + { + return (double)this; + } - decimal IConvertible.ToDecimal(IFormatProvider provider) - { - return (decimal) this; - } + decimal IConvertible.ToDecimal(IFormatProvider provider) + { + return (decimal)this; + } - DateTime IConvertible.ToDateTime(IFormatProvider provider) - { - return (DateTime) this; - } + DateTime IConvertible.ToDateTime(IFormatProvider provider) + { + return (DateTime)this; + } - object IConvertible.ToType(Type conversionType, IFormatProvider provider) - { - return ToObject(conversionType); - } + object IConvertible.ToType(Type conversionType, IFormatProvider provider) + { + return ToObject(conversionType); + } #endif - } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/MemberSerialization.cs b/Src/Newtonsoft.Json/MemberSerialization.cs index b4dcf2cd..8ed52304 100644 --- a/Src/Newtonsoft.Json/MemberSerialization.cs +++ b/Src/Newtonsoft.Json/MemberSerialization.cs @@ -29,28 +29,30 @@ using Newtonsoft.Json.Serialization; namespace Newtonsoft.Json { - /// - /// Specifies the member serialization options for the . - /// - public enum MemberSerialization - { + /// + /// Specifies the member serialization options for the . + /// + public enum MemberSerialization + { #pragma warning disable 1584,1711,1572,1581,1580,1574 - /// - /// All public members are serialized by default. Members can be excluded using or . - /// This is the default member serialization mode. - /// - OptOut, - /// - /// Only members must be marked with or are serialized. - /// This member serialization mode can also be set by marking the class with . - /// - OptIn, - /// - /// All public and private fields are serialized. Members can be excluded using or . - /// This member serialization mode can also be set by marking the class with - /// and setting IgnoreSerializableAttribute on to false. - /// - Fields + /// + /// All public members are serialized by default. Members can be excluded using or . + /// This is the default member serialization mode. + /// + OptOut, + + /// + /// Only members must be marked with or are serialized. + /// This member serialization mode can also be set by marking the class with . + /// + OptIn, + + /// + /// All public and private fields are serialized. Members can be excluded using or . + /// This member serialization mode can also be set by marking the class with + /// and setting IgnoreSerializableAttribute on to false. + /// + Fields #pragma warning restore 1584,1711,1572,1581,1580,1574 - } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/MissingMemberHandling.cs b/Src/Newtonsoft.Json/MissingMemberHandling.cs index d61e1e68..4e35081b 100644 --- a/Src/Newtonsoft.Json/MissingMemberHandling.cs +++ b/Src/Newtonsoft.Json/MissingMemberHandling.cs @@ -29,18 +29,19 @@ using System.Text; namespace Newtonsoft.Json { - /// - /// Specifies missing member handling options for the . - /// - public enum MissingMemberHandling - { /// - /// Ignore a missing member and do not attempt to deserialize it. + /// Specifies missing member handling options for the . /// - Ignore = 0, - /// - /// Throw a when a missing member is encountered during deserialization. - /// - Error = 1 - } -} + public enum MissingMemberHandling + { + /// + /// Ignore a missing member and do not attempt to deserialize it. + /// + Ignore = 0, + + /// + /// Throw a when a missing member is encountered during deserialization. + /// + Error = 1 + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Portable40.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Portable40.csproj index 0bbddf3f..2c6f5ed6 100644 --- a/Src/Newtonsoft.Json/Newtonsoft.Json.Portable40.csproj +++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Portable40.csproj @@ -9,10 +9,15 @@ Newtonsoft.Json Newtonsoft.Json v4.0 - Profile2 + Profile136 512 {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 10.0 + + + + + 4.0 true diff --git a/Src/Newtonsoft.Json/NullValueHandling.cs b/Src/Newtonsoft.Json/NullValueHandling.cs index 08c4f831..8a88c163 100644 --- a/Src/Newtonsoft.Json/NullValueHandling.cs +++ b/Src/Newtonsoft.Json/NullValueHandling.cs @@ -25,22 +25,23 @@ namespace Newtonsoft.Json { - /// - /// Specifies null value handling options for the . - /// - /// - /// - /// - /// - public enum NullValueHandling - { /// - /// Include null values when serializing and deserializing objects. + /// Specifies null value handling options for the . /// - Include = 0, - /// - /// Ignore null values when serializing and deserializing objects. - /// - Ignore = 1 - } + /// + /// + /// + /// + public enum NullValueHandling + { + /// + /// Include null values when serializing and deserializing objects. + /// + Include = 0, + + /// + /// Ignore null values when serializing and deserializing objects. + /// + Ignore = 1 + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/ObjectCreationHandling.cs b/Src/Newtonsoft.Json/ObjectCreationHandling.cs index a3be502a..cc53b142 100644 --- a/Src/Newtonsoft.Json/ObjectCreationHandling.cs +++ b/Src/Newtonsoft.Json/ObjectCreationHandling.cs @@ -25,22 +25,24 @@ namespace Newtonsoft.Json { - /// - /// Specifies how object creation is handled by the . - /// - public enum ObjectCreationHandling - { /// - /// Reuse existing objects, create new objects when needed. + /// Specifies how object creation is handled by the . /// - Auto = 0, - /// - /// Only reuse existing objects. - /// - Reuse = 1, - /// - /// Always create new objects. - /// - Replace = 2 - } + public enum ObjectCreationHandling + { + /// + /// Reuse existing objects, create new objects when needed. + /// + Auto = 0, + + /// + /// Only reuse existing objects. + /// + Reuse = 1, + + /// + /// Always create new objects. + /// + Replace = 2 + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/PreserveReferencesHandling.cs b/Src/Newtonsoft.Json/PreserveReferencesHandling.cs index 051f0e0e..61fcbd47 100644 --- a/Src/Newtonsoft.Json/PreserveReferencesHandling.cs +++ b/Src/Newtonsoft.Json/PreserveReferencesHandling.cs @@ -29,31 +29,34 @@ using System.Text; namespace Newtonsoft.Json { - /// - /// Specifies reference handling options for the . - /// Note that references cannot be preserved when a value is set via a non-default constructor such as types that implement ISerializable. - /// - /// - /// - /// - [Flags] - public enum PreserveReferencesHandling - { /// - /// Do not preserve references when serializing types. + /// Specifies reference handling options for the . + /// Note that references cannot be preserved when a value is set via a non-default constructor such as types that implement ISerializable. /// - None = 0, - /// - /// Preserve references when serializing into a JSON object structure. - /// - Objects = 1, - /// - /// Preserve references when serializing into a JSON array structure. - /// - Arrays = 2, - /// - /// Preserve references when serializing. - /// - All = Objects | Arrays - } -} + /// + /// + /// + [Flags] + public enum PreserveReferencesHandling + { + /// + /// Do not preserve references when serializing types. + /// + None = 0, + + /// + /// Preserve references when serializing into a JSON object structure. + /// + Objects = 1, + + /// + /// Preserve references when serializing into a JSON array structure. + /// + Arrays = 2, + + /// + /// Preserve references when serializing. + /// + All = Objects | Arrays + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs index 546866a2..7721fb4f 100644 --- a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs +++ b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs @@ -37,6 +37,7 @@ using System.Security; #elif SILVERLIGHT [assembly: AssemblyTitle("Json.NET Silverlight")] #elif PORTABLE40 + [assembly: AssemblyTitle("Json.NET Portable .NET 4.0")] #elif PORTABLE [assembly: AssemblyTitle("Json.NET Portable")] @@ -52,18 +53,19 @@ using System.Security; [assembly: AssemblyTitle("Json.NET .NET 4.0")] [assembly: AllowPartiallyTrustedCallers] #else + [assembly: AssemblyTitle("Json.NET")] [assembly: AllowPartiallyTrustedCallers] #endif #if !SIGNED + [assembly: InternalsVisibleTo("Newtonsoft.Json.Tests")] #else [assembly: InternalsVisibleTo("Newtonsoft.Json.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")] #endif [assembly: InternalsVisibleTo("Newtonsoft.Json.Dynamic, PublicKey=0024000004800000940000000602000000240000525341310004000001000100cbd8d53b9d7de30f1f1278f636ec462cf9c254991291e66ebb157a885638a517887633b898ccbcf0d5c5ff7be85a6abe9e765d0ac7cd33c68dac67e7e64530e8222101109f154ab14a941c490ac155cd1d4fcba0fabb49016b4ef28593b015cab5937da31172f03f67d09edda404b88a60023f062ae71d0b2e4438b74cc11dc9")] - [assembly: AssemblyDescription("Json.NET is a popular high-performance JSON framework for .NET")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Newtonsoft")] @@ -76,9 +78,11 @@ using System.Security; // Setting ComVisible to false makes the types in this assembly not visible // to COM componenets. If you need to access a type in this assembly from // COM, set the ComVisible attribute to true on that type. + [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM + [assembly: Guid("9ca358aa-317b-4925-8ada-4a29e943a363")] #endif @@ -91,7 +95,7 @@ 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.8.16617")] -[assembly: CLSCompliant(true)] +[assembly: AssemblyVersion("4.5.0.0")] +[assembly: AssemblyFileVersion("5.0.8.16620")] +[assembly: CLSCompliant(true)] \ No newline at end of file diff --git a/Src/Newtonsoft.Json/ReferenceLoopHandling.cs b/Src/Newtonsoft.Json/ReferenceLoopHandling.cs index 01d03b18..bfa5133f 100644 --- a/Src/Newtonsoft.Json/ReferenceLoopHandling.cs +++ b/Src/Newtonsoft.Json/ReferenceLoopHandling.cs @@ -29,22 +29,24 @@ using System.Text; namespace Newtonsoft.Json { - /// - /// Specifies reference loop handling options for the . - /// - public enum ReferenceLoopHandling - { /// - /// Throw a when a loop is encountered. + /// Specifies reference loop handling options for the . /// - Error = 0, - /// - /// Ignore loop references and do not serialize. - /// - Ignore = 1, - /// - /// Serialize loop references. - /// - Serialize = 2 - } -} + public enum ReferenceLoopHandling + { + /// + /// Throw a when a loop is encountered. + /// + Error = 0, + + /// + /// Ignore loop references and do not serialize. + /// + Ignore = 1, + + /// + /// Serialize loop references. + /// + Serialize = 2 + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Required.cs b/Src/Newtonsoft.Json/Required.cs index 22c86d5d..889aa6d0 100644 --- a/Src/Newtonsoft.Json/Required.cs +++ b/Src/Newtonsoft.Json/Required.cs @@ -25,22 +25,24 @@ namespace Newtonsoft.Json { - /// - /// Indicating whether a property is required. - /// - public enum Required - { /// - /// The property is not required. The default state. + /// Indicating whether a property is required. /// - Default, - /// - /// The property must be defined in JSON but can be a null value. - /// - AllowNull, - /// - /// The property must be defined in JSON and cannot be a null value. - /// - Always - } + public enum Required + { + /// + /// The property is not required. The default state. + /// + Default, + + /// + /// The property must be defined in JSON but can be a null value. + /// + AllowNull, + + /// + /// The property must be defined in JSON and cannot be a null value. + /// + Always + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Schema/Extensions.cs b/Src/Newtonsoft.Json/Schema/Extensions.cs index 04bac5a2..2532dff8 100644 --- a/Src/Newtonsoft.Json/Schema/Extensions.cs +++ b/Src/Newtonsoft.Json/Schema/Extensions.cs @@ -29,76 +29,76 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Schema { - /// - /// Contains the JSON schema extension methods. - /// - public static class Extensions - { /// - /// Determines whether the is valid. + /// Contains the JSON schema extension methods. /// - /// The source to test. - /// The schema to test with. - /// - /// true if the specified is valid; otherwise, false. - /// - public static bool IsValid(this JToken source, JsonSchema schema) + public static class Extensions { - bool valid = true; - source.Validate(schema, (sender, args) => { valid = false; }); - return valid; - } - - /// - /// Determines whether the is valid. - /// - /// The source to test. - /// The schema to test with. - /// When this method returns, contains any error messages generated while validating. - /// - /// true if the specified is valid; otherwise, false. - /// - public static bool IsValid(this JToken source, JsonSchema schema, out IList errorMessages) - { - IList errors = new List(); - - source.Validate(schema, (sender, args) => errors.Add(args.Message)); - - errorMessages = errors; - return (errorMessages.Count == 0); - } - - /// - /// Validates the specified . - /// - /// The source to test. - /// The schema to test with. - public static void Validate(this JToken source, JsonSchema schema) - { - source.Validate(schema, null); - } - - /// - /// Validates the specified . - /// - /// The source to test. - /// The schema to test with. - /// The validation event handler. - public static void Validate(this JToken source, JsonSchema schema, ValidationEventHandler validationEventHandler) - { - ValidationUtils.ArgumentNotNull(source, "source"); - ValidationUtils.ArgumentNotNull(schema, "schema"); - - using (JsonValidatingReader reader = new JsonValidatingReader(source.CreateReader())) - { - reader.Schema = schema; - if (validationEventHandler != null) - reader.ValidationEventHandler += validationEventHandler; - - while (reader.Read()) + /// + /// Determines whether the is valid. + /// + /// The source to test. + /// The schema to test with. + /// + /// true if the specified is valid; otherwise, false. + /// + public static bool IsValid(this JToken source, JsonSchema schema) { + bool valid = true; + source.Validate(schema, (sender, args) => { valid = false; }); + return valid; + } + + /// + /// Determines whether the is valid. + /// + /// The source to test. + /// The schema to test with. + /// When this method returns, contains any error messages generated while validating. + /// + /// true if the specified is valid; otherwise, false. + /// + public static bool IsValid(this JToken source, JsonSchema schema, out IList errorMessages) + { + IList errors = new List(); + + source.Validate(schema, (sender, args) => errors.Add(args.Message)); + + errorMessages = errors; + return (errorMessages.Count == 0); + } + + /// + /// Validates the specified . + /// + /// The source to test. + /// The schema to test with. + public static void Validate(this JToken source, JsonSchema schema) + { + source.Validate(schema, null); + } + + /// + /// Validates the specified . + /// + /// The source to test. + /// The schema to test with. + /// The validation event handler. + public static void Validate(this JToken source, JsonSchema schema, ValidationEventHandler validationEventHandler) + { + ValidationUtils.ArgumentNotNull(source, "source"); + ValidationUtils.ArgumentNotNull(schema, "schema"); + + using (JsonValidatingReader reader = new JsonValidatingReader(source.CreateReader())) + { + reader.Schema = schema; + if (validationEventHandler != null) + reader.ValidationEventHandler += validationEventHandler; + + while (reader.Read()) + { + } + } } - } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Schema/JsonSchema.cs b/Src/Newtonsoft.Json/Schema/JsonSchema.cs index d4a3b36d..0084a6f1 100644 --- a/Src/Newtonsoft.Json/Schema/JsonSchema.cs +++ b/Src/Newtonsoft.Json/Schema/JsonSchema.cs @@ -32,286 +32,318 @@ using System.Globalization; namespace Newtonsoft.Json.Schema { - /// - /// An in-memory representation of a JSON Schema. - /// - public class JsonSchema - { /// - /// Gets or sets the id. + /// An in-memory representation of a JSON Schema. /// - public string Id { get; set; } - /// - /// Gets or sets the title. - /// - public string Title { get; set; } - /// - /// Gets or sets whether the object is required. - /// - public bool? Required { get; set; } - /// - /// Gets or sets whether the object is read only. - /// - public bool? ReadOnly { get; set; } - /// - /// Gets or sets whether the object is visible to users. - /// - public bool? Hidden { get; set; } - /// - /// Gets or sets whether the object is transient. - /// - public bool? Transient { get; set; } - /// - /// Gets or sets the description of the object. - /// - public string Description { get; set; } - /// - /// Gets or sets the types of values allowed by the object. - /// - /// The type. - public JsonSchemaType? Type { get; set; } - /// - /// Gets or sets the pattern. - /// - /// The pattern. - public string Pattern { get; set; } - /// - /// Gets or sets the minimum length. - /// - /// The minimum length. - public int? MinimumLength { get; set; } - /// - /// Gets or sets the maximum length. - /// - /// The maximum length. - public int? MaximumLength { get; set; } - /// - /// Gets or sets a number that the value should be divisble by. - /// - /// A number that the value should be divisble by. - public double? DivisibleBy { get; set; } - /// - /// Gets or sets the minimum. - /// - /// The minimum. - public double? Minimum { get; set; } - /// - /// Gets or sets the maximum. - /// - /// The maximum. - public double? Maximum { get; set; } - /// - /// Gets or sets a flag indicating whether the value can not equal the number defined by the "minimum" attribute. - /// - /// A flag indicating whether the value can not equal the number defined by the "minimum" attribute. - public bool? ExclusiveMinimum { get; set; } - /// - /// Gets or sets a flag indicating whether the value can not equal the number defined by the "maximum" attribute. - /// - /// A flag indicating whether the value can not equal the number defined by the "maximum" attribute. - public bool? ExclusiveMaximum { get; set; } - /// - /// Gets or sets the minimum number of items. - /// - /// The minimum number of items. - public int? MinimumItems { get; set; } - /// - /// Gets or sets the maximum number of items. - /// - /// The maximum number of items. - public int? MaximumItems { get; set; } - /// - /// Gets or sets the of items. - /// - /// The of items. - public IList Items { get; set; } - /// - /// Gets or sets a value indicating whether items in an array are validated using the instance at their array position from . - /// - /// - /// true if items are validated using their array position; otherwise, false. - /// - public bool PositionalItemsValidation { get; set; } - /// - /// Gets or sets the of additional items. - /// - /// The of additional items. - public JsonSchema AdditionalItems { get; set; } - /// - /// Gets or sets a value indicating whether additional items are allowed. - /// - /// - /// true if additional items are allowed; otherwise, false. - /// - public bool AllowAdditionalItems { get; set; } - /// - /// Gets or sets whether the array items must be unique. - /// - public bool UniqueItems { get; set; } - /// - /// Gets or sets the of properties. - /// - /// The of properties. - public IDictionary Properties { get; set; } - /// - /// Gets or sets the of additional properties. - /// - /// The of additional properties. - public JsonSchema AdditionalProperties { get; set; } - /// - /// Gets or sets the pattern properties. - /// - /// The pattern properties. - public IDictionary PatternProperties { get; set; } - /// - /// Gets or sets a value indicating whether additional properties are allowed. - /// - /// - /// true if additional properties are allowed; otherwise, false. - /// - public bool AllowAdditionalProperties { get; set; } - /// - /// Gets or sets the required property if this property is present. - /// - /// The required property if this property is present. - public string Requires { get; set; } - /// - /// Gets or sets the a collection of valid enum values allowed. - /// - /// A collection of valid enum values allowed. - public IList Enum { get; set; } - /// - /// Gets or sets disallowed types. - /// - /// The disallow types. - public JsonSchemaType? Disallow { get; set; } - /// - /// Gets or sets the default value. - /// - /// The default value. - public JToken Default { get; set; } - /// - /// Gets or sets the collection of that this schema extends. - /// - /// The collection of that this schema extends. - public IList Extends { get; set; } - /// - /// Gets or sets the format. - /// - /// The format. - public string Format { get; set; } - - internal string Location { get; set; } - - private readonly string _internalId = Guid.NewGuid().ToString("N"); - - internal string InternalId + public class JsonSchema { - get { return _internalId; } + /// + /// Gets or sets the id. + /// + public string Id { get; set; } + + /// + /// Gets or sets the title. + /// + public string Title { get; set; } + + /// + /// Gets or sets whether the object is required. + /// + public bool? Required { get; set; } + + /// + /// Gets or sets whether the object is read only. + /// + public bool? ReadOnly { get; set; } + + /// + /// Gets or sets whether the object is visible to users. + /// + public bool? Hidden { get; set; } + + /// + /// Gets or sets whether the object is transient. + /// + public bool? Transient { get; set; } + + /// + /// Gets or sets the description of the object. + /// + public string Description { get; set; } + + /// + /// Gets or sets the types of values allowed by the object. + /// + /// The type. + public JsonSchemaType? Type { get; set; } + + /// + /// Gets or sets the pattern. + /// + /// The pattern. + public string Pattern { get; set; } + + /// + /// Gets or sets the minimum length. + /// + /// The minimum length. + public int? MinimumLength { get; set; } + + /// + /// Gets or sets the maximum length. + /// + /// The maximum length. + public int? MaximumLength { get; set; } + + /// + /// Gets or sets a number that the value should be divisble by. + /// + /// A number that the value should be divisble by. + public double? DivisibleBy { get; set; } + + /// + /// Gets or sets the minimum. + /// + /// The minimum. + public double? Minimum { get; set; } + + /// + /// Gets or sets the maximum. + /// + /// The maximum. + public double? Maximum { get; set; } + + /// + /// Gets or sets a flag indicating whether the value can not equal the number defined by the "minimum" attribute. + /// + /// A flag indicating whether the value can not equal the number defined by the "minimum" attribute. + public bool? ExclusiveMinimum { get; set; } + + /// + /// Gets or sets a flag indicating whether the value can not equal the number defined by the "maximum" attribute. + /// + /// A flag indicating whether the value can not equal the number defined by the "maximum" attribute. + public bool? ExclusiveMaximum { get; set; } + + /// + /// Gets or sets the minimum number of items. + /// + /// The minimum number of items. + public int? MinimumItems { get; set; } + + /// + /// Gets or sets the maximum number of items. + /// + /// The maximum number of items. + public int? MaximumItems { get; set; } + + /// + /// Gets or sets the of items. + /// + /// The of items. + public IList Items { get; set; } + + /// + /// Gets or sets a value indicating whether items in an array are validated using the instance at their array position from . + /// + /// + /// true if items are validated using their array position; otherwise, false. + /// + public bool PositionalItemsValidation { get; set; } + + /// + /// Gets or sets the of additional items. + /// + /// The of additional items. + public JsonSchema AdditionalItems { get; set; } + + /// + /// Gets or sets a value indicating whether additional items are allowed. + /// + /// + /// true if additional items are allowed; otherwise, false. + /// + public bool AllowAdditionalItems { get; set; } + + /// + /// Gets or sets whether the array items must be unique. + /// + public bool UniqueItems { get; set; } + + /// + /// Gets or sets the of properties. + /// + /// The of properties. + public IDictionary Properties { get; set; } + + /// + /// Gets or sets the of additional properties. + /// + /// The of additional properties. + public JsonSchema AdditionalProperties { get; set; } + + /// + /// Gets or sets the pattern properties. + /// + /// The pattern properties. + public IDictionary PatternProperties { get; set; } + + /// + /// Gets or sets a value indicating whether additional properties are allowed. + /// + /// + /// true if additional properties are allowed; otherwise, false. + /// + public bool AllowAdditionalProperties { get; set; } + + /// + /// Gets or sets the required property if this property is present. + /// + /// The required property if this property is present. + public string Requires { get; set; } + + /// + /// Gets or sets the a collection of valid enum values allowed. + /// + /// A collection of valid enum values allowed. + public IList Enum { get; set; } + + /// + /// Gets or sets disallowed types. + /// + /// The disallow types. + public JsonSchemaType? Disallow { get; set; } + + /// + /// Gets or sets the default value. + /// + /// The default value. + public JToken Default { get; set; } + + /// + /// Gets or sets the collection of that this schema extends. + /// + /// The collection of that this schema extends. + public IList Extends { get; set; } + + /// + /// Gets or sets the format. + /// + /// The format. + public string Format { get; set; } + + internal string Location { get; set; } + + private readonly string _internalId = Guid.NewGuid().ToString("N"); + + internal string InternalId + { + get { return _internalId; } + } + + // if this is set then this schema instance is just a deferred reference + // and will be replaced when the schema reference is resolved + internal string DeferredReference { get; set; } + internal bool ReferencesResolved { get; set; } + + /// + /// Initializes a new instance of the class. + /// + public JsonSchema() + { + AllowAdditionalProperties = true; + AllowAdditionalItems = true; + } + + /// + /// Reads a from the specified . + /// + /// The containing the JSON Schema to read. + /// The object representing the JSON Schema. + public static JsonSchema Read(JsonReader reader) + { + return Read(reader, new JsonSchemaResolver()); + } + + /// + /// Reads a from the specified . + /// + /// The containing the JSON Schema to read. + /// The to use when resolving schema references. + /// The object representing the JSON Schema. + public static JsonSchema Read(JsonReader reader, JsonSchemaResolver resolver) + { + ValidationUtils.ArgumentNotNull(reader, "reader"); + ValidationUtils.ArgumentNotNull(resolver, "resolver"); + + JsonSchemaBuilder builder = new JsonSchemaBuilder(resolver); + return builder.Read(reader); + } + + /// + /// Load a from a string that contains schema JSON. + /// + /// A that contains JSON. + /// A populated from the string that contains JSON. + public static JsonSchema Parse(string json) + { + return Parse(json, new JsonSchemaResolver()); + } + + /// + /// Parses the specified json. + /// + /// The json. + /// The resolver. + /// A populated from the string that contains JSON. + public static JsonSchema Parse(string json, JsonSchemaResolver resolver) + { + ValidationUtils.ArgumentNotNull(json, "json"); + + JsonReader reader = new JsonTextReader(new StringReader(json)); + + return Read(reader, resolver); + } + + /// + /// Writes this schema to a . + /// + /// A into which this method will write. + public void WriteTo(JsonWriter writer) + { + WriteTo(writer, new JsonSchemaResolver()); + } + + /// + /// Writes this schema to a using the specified . + /// + /// A into which this method will write. + /// The resolver used. + public void WriteTo(JsonWriter writer, JsonSchemaResolver resolver) + { + ValidationUtils.ArgumentNotNull(writer, "writer"); + ValidationUtils.ArgumentNotNull(resolver, "resolver"); + + JsonSchemaWriter schemaWriter = new JsonSchemaWriter(writer, resolver); + schemaWriter.WriteSchema(this); + } + + /// + /// Returns a that represents the current . + /// + /// + /// A that represents the current . + /// + public override string ToString() + { + StringWriter writer = new StringWriter(CultureInfo.InvariantCulture); + JsonTextWriter jsonWriter = new JsonTextWriter(writer); + jsonWriter.Formatting = Formatting.Indented; + + WriteTo(jsonWriter); + + return writer.ToString(); + } } - - // if this is set then this schema instance is just a deferred reference - // and will be replaced when the schema reference is resolved - internal string DeferredReference { get; set; } - internal bool ReferencesResolved { get; set; } - - /// - /// Initializes a new instance of the class. - /// - public JsonSchema() - { - AllowAdditionalProperties = true; - AllowAdditionalItems = true; - } - - /// - /// Reads a from the specified . - /// - /// The containing the JSON Schema to read. - /// The object representing the JSON Schema. - public static JsonSchema Read(JsonReader reader) - { - return Read(reader, new JsonSchemaResolver()); - } - - /// - /// Reads a from the specified . - /// - /// The containing the JSON Schema to read. - /// The to use when resolving schema references. - /// The object representing the JSON Schema. - public static JsonSchema Read(JsonReader reader, JsonSchemaResolver resolver) - { - ValidationUtils.ArgumentNotNull(reader, "reader"); - ValidationUtils.ArgumentNotNull(resolver, "resolver"); - - JsonSchemaBuilder builder = new JsonSchemaBuilder(resolver); - return builder.Read(reader); - } - - /// - /// Load a from a string that contains schema JSON. - /// - /// A that contains JSON. - /// A populated from the string that contains JSON. - public static JsonSchema Parse(string json) - { - return Parse(json, new JsonSchemaResolver()); - } - - /// - /// Parses the specified json. - /// - /// The json. - /// The resolver. - /// A populated from the string that contains JSON. - public static JsonSchema Parse(string json, JsonSchemaResolver resolver) - { - ValidationUtils.ArgumentNotNull(json, "json"); - - JsonReader reader = new JsonTextReader(new StringReader(json)); - - return Read(reader, resolver); - } - - /// - /// Writes this schema to a . - /// - /// A into which this method will write. - public void WriteTo(JsonWriter writer) - { - WriteTo(writer, new JsonSchemaResolver()); - } - - /// - /// Writes this schema to a using the specified . - /// - /// A into which this method will write. - /// The resolver used. - public void WriteTo(JsonWriter writer, JsonSchemaResolver resolver) - { - ValidationUtils.ArgumentNotNull(writer, "writer"); - ValidationUtils.ArgumentNotNull(resolver, "resolver"); - - JsonSchemaWriter schemaWriter = new JsonSchemaWriter(writer, resolver); - schemaWriter.WriteSchema(this); - } - - /// - /// Returns a that represents the current . - /// - /// - /// A that represents the current . - /// - public override string ToString() - { - StringWriter writer = new StringWriter(CultureInfo.InvariantCulture); - JsonTextWriter jsonWriter = new JsonTextWriter(writer); - jsonWriter.Formatting = Formatting.Indented; - - WriteTo(jsonWriter); - - return writer.ToString(); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Schema/JsonSchemaBuilder.cs b/Src/Newtonsoft.Json/Schema/JsonSchemaBuilder.cs index 08b4fd4e..8b150289 100644 --- a/Src/Newtonsoft.Json/Schema/JsonSchemaBuilder.cs +++ b/Src/Newtonsoft.Json/Schema/JsonSchemaBuilder.cs @@ -36,412 +36,412 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Schema { - internal class JsonSchemaBuilder - { - private readonly IList _stack; - private readonly JsonSchemaResolver _resolver; - private readonly IDictionary _documentSchemas; - private JsonSchema _currentSchema; - private JObject _rootSchema; - - public JsonSchemaBuilder(JsonSchemaResolver resolver) + internal class JsonSchemaBuilder { - _stack = new List(); - _documentSchemas = new Dictionary(); - _resolver = resolver; - } + private readonly IList _stack; + private readonly JsonSchemaResolver _resolver; + private readonly IDictionary _documentSchemas; + private JsonSchema _currentSchema; + private JObject _rootSchema; - private void Push(JsonSchema value) - { - _currentSchema = value; - _stack.Add(value); - _resolver.LoadedSchemas.Add(value); - _documentSchemas.Add(value.Location, value); - } - - private JsonSchema Pop() - { - JsonSchema poppedSchema = _currentSchema; - _stack.RemoveAt(_stack.Count - 1); - _currentSchema = _stack.LastOrDefault(); - - return poppedSchema; - } - - private JsonSchema CurrentSchema - { - get { return _currentSchema; } - } - - internal JsonSchema Read(JsonReader reader) - { - JToken schemaToken = JToken.ReadFrom(reader); - - _rootSchema = schemaToken as JObject; - - JsonSchema schema = BuildSchema(schemaToken); - - ResolveReferences(schema); - - return schema; - } - - private string UnescapeReference(string reference) - { - return Uri.UnescapeDataString(reference).Replace("~1", "/").Replace("~0", "~"); - } - - private JsonSchema ResolveReferences(JsonSchema schema) - { - if (schema.DeferredReference != null) - { - string reference = schema.DeferredReference; - - bool locationReference = (reference.StartsWith("#", StringComparison.OrdinalIgnoreCase)); - if (locationReference) - reference = UnescapeReference(reference); - - JsonSchema resolvedSchema = _resolver.GetSchema(reference); - - if (resolvedSchema == null) + public JsonSchemaBuilder(JsonSchemaResolver resolver) { - if (locationReference) - { - string[] escapedParts = schema.DeferredReference.TrimStart('#').Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); - JToken currentToken = _rootSchema; - foreach (string escapedPart in escapedParts) + _stack = new List(); + _documentSchemas = new Dictionary(); + _resolver = resolver; + } + + private void Push(JsonSchema value) + { + _currentSchema = value; + _stack.Add(value); + _resolver.LoadedSchemas.Add(value); + _documentSchemas.Add(value.Location, value); + } + + private JsonSchema Pop() + { + JsonSchema poppedSchema = _currentSchema; + _stack.RemoveAt(_stack.Count - 1); + _currentSchema = _stack.LastOrDefault(); + + return poppedSchema; + } + + private JsonSchema CurrentSchema + { + get { return _currentSchema; } + } + + internal JsonSchema Read(JsonReader reader) + { + JToken schemaToken = JToken.ReadFrom(reader); + + _rootSchema = schemaToken as JObject; + + JsonSchema schema = BuildSchema(schemaToken); + + ResolveReferences(schema); + + return schema; + } + + private string UnescapeReference(string reference) + { + return Uri.UnescapeDataString(reference).Replace("~1", "/").Replace("~0", "~"); + } + + private JsonSchema ResolveReferences(JsonSchema schema) + { + if (schema.DeferredReference != null) { - string part = UnescapeReference(escapedPart); + string reference = schema.DeferredReference; - if (currentToken.Type == JTokenType.Object) - { - currentToken = currentToken[part]; - } - else if (currentToken.Type == JTokenType.Array || currentToken.Type == JTokenType.Constructor) - { - int index; - if (int.TryParse(part, out index) && index >= 0 && index < currentToken.Count()) - currentToken = currentToken[index]; - else - currentToken = null; - } + bool locationReference = (reference.StartsWith("#", StringComparison.OrdinalIgnoreCase)); + if (locationReference) + reference = UnescapeReference(reference); - if (currentToken == null) - break; + JsonSchema resolvedSchema = _resolver.GetSchema(reference); + + if (resolvedSchema == null) + { + if (locationReference) + { + string[] escapedParts = schema.DeferredReference.TrimStart('#').Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); + JToken currentToken = _rootSchema; + foreach (string escapedPart in escapedParts) + { + string part = UnescapeReference(escapedPart); + + if (currentToken.Type == JTokenType.Object) + { + currentToken = currentToken[part]; + } + else if (currentToken.Type == JTokenType.Array || currentToken.Type == JTokenType.Constructor) + { + int index; + if (int.TryParse(part, out index) && index >= 0 && index < currentToken.Count()) + currentToken = currentToken[index]; + else + currentToken = null; + } + + if (currentToken == null) + break; + } + + if (currentToken != null) + resolvedSchema = BuildSchema(currentToken); + } + + if (resolvedSchema == null) + throw new JsonException("Could not resolve schema reference '{0}'.".FormatWith(CultureInfo.InvariantCulture, schema.DeferredReference)); + } + + schema = resolvedSchema; } - if (currentToken != null) - resolvedSchema = BuildSchema(currentToken); - } + if (schema.ReferencesResolved) + return schema; - if (resolvedSchema == null) - throw new JsonException("Could not resolve schema reference '{0}'.".FormatWith(CultureInfo.InvariantCulture, schema.DeferredReference)); + schema.ReferencesResolved = true; + + if (schema.Extends != null) + { + for (int i = 0; i < schema.Extends.Count; i++) + { + schema.Extends[i] = ResolveReferences(schema.Extends[i]); + } + } + + if (schema.Items != null) + { + for (int i = 0; i < schema.Items.Count; i++) + { + schema.Items[i] = ResolveReferences(schema.Items[i]); + } + } + + if (schema.AdditionalItems != null) + schema.AdditionalItems = ResolveReferences(schema.AdditionalItems); + + if (schema.PatternProperties != null) + { + foreach (KeyValuePair patternProperty in schema.PatternProperties.ToList()) + { + schema.PatternProperties[patternProperty.Key] = ResolveReferences(patternProperty.Value); + } + } + + if (schema.Properties != null) + { + foreach (KeyValuePair property in schema.Properties.ToList()) + { + schema.Properties[property.Key] = ResolveReferences(property.Value); + } + } + + if (schema.AdditionalProperties != null) + schema.AdditionalProperties = ResolveReferences(schema.AdditionalProperties); + + return schema; } - schema = resolvedSchema; - } - - if (schema.ReferencesResolved) - return schema; - - schema.ReferencesResolved = true; - - if (schema.Extends != null) - { - for (int i = 0; i < schema.Extends.Count; i++) + private JsonSchema BuildSchema(JToken token) { - schema.Extends[i] = ResolveReferences(schema.Extends[i]); + JObject schemaObject = token as JObject; + if (schemaObject == null) + throw JsonException.Create(token, token.Path, "Expected object while parsing schema object, got {0}.".FormatWith(CultureInfo.InvariantCulture, token.Type)); + + JToken referenceToken; + if (schemaObject.TryGetValue(JsonSchemaConstants.ReferencePropertyName, out referenceToken)) + { + JsonSchema deferredSchema = new JsonSchema(); + deferredSchema.DeferredReference = (string)referenceToken; + + return deferredSchema; + } + + string location = token.Path.Replace(".", "/").Replace("[", "/").Replace("]", string.Empty); + if (!string.IsNullOrEmpty(location)) + location = "/" + location; + location = "#" + location; + + JsonSchema existingSchema; + if (_documentSchemas.TryGetValue(location, out existingSchema)) + return existingSchema; + + Push(new JsonSchema { Location = location }); + + ProcessSchemaProperties(schemaObject); + + return Pop(); } - } - if (schema.Items != null) - { - for (int i = 0; i < schema.Items.Count; i++) + private void ProcessSchemaProperties(JObject schemaObject) { - schema.Items[i] = ResolveReferences(schema.Items[i]); + foreach (KeyValuePair property in schemaObject) + { + switch (property.Key) + { + case JsonSchemaConstants.TypePropertyName: + CurrentSchema.Type = ProcessType(property.Value); + break; + case JsonSchemaConstants.IdPropertyName: + CurrentSchema.Id = (string)property.Value; + break; + case JsonSchemaConstants.TitlePropertyName: + CurrentSchema.Title = (string)property.Value; + break; + case JsonSchemaConstants.DescriptionPropertyName: + CurrentSchema.Description = (string)property.Value; + break; + case JsonSchemaConstants.PropertiesPropertyName: + CurrentSchema.Properties = ProcessProperties(property.Value); + break; + case JsonSchemaConstants.ItemsPropertyName: + ProcessItems(property.Value); + break; + case JsonSchemaConstants.AdditionalPropertiesPropertyName: + ProcessAdditionalProperties(property.Value); + break; + case JsonSchemaConstants.AdditionalItemsPropertyName: + ProcessAdditionalItems(property.Value); + break; + case JsonSchemaConstants.PatternPropertiesPropertyName: + CurrentSchema.PatternProperties = ProcessProperties(property.Value); + break; + case JsonSchemaConstants.RequiredPropertyName: + CurrentSchema.Required = (bool)property.Value; + break; + case JsonSchemaConstants.RequiresPropertyName: + CurrentSchema.Requires = (string)property.Value; + break; + case JsonSchemaConstants.MinimumPropertyName: + CurrentSchema.Minimum = (double)property.Value; + break; + case JsonSchemaConstants.MaximumPropertyName: + CurrentSchema.Maximum = (double)property.Value; + break; + case JsonSchemaConstants.ExclusiveMinimumPropertyName: + CurrentSchema.ExclusiveMinimum = (bool)property.Value; + break; + case JsonSchemaConstants.ExclusiveMaximumPropertyName: + CurrentSchema.ExclusiveMaximum = (bool)property.Value; + break; + case JsonSchemaConstants.MaximumLengthPropertyName: + CurrentSchema.MaximumLength = (int)property.Value; + break; + case JsonSchemaConstants.MinimumLengthPropertyName: + CurrentSchema.MinimumLength = (int)property.Value; + break; + case JsonSchemaConstants.MaximumItemsPropertyName: + CurrentSchema.MaximumItems = (int)property.Value; + break; + case JsonSchemaConstants.MinimumItemsPropertyName: + CurrentSchema.MinimumItems = (int)property.Value; + break; + case JsonSchemaConstants.DivisibleByPropertyName: + CurrentSchema.DivisibleBy = (double)property.Value; + break; + case JsonSchemaConstants.DisallowPropertyName: + CurrentSchema.Disallow = ProcessType(property.Value); + break; + case JsonSchemaConstants.DefaultPropertyName: + CurrentSchema.Default = property.Value.DeepClone(); + break; + case JsonSchemaConstants.HiddenPropertyName: + CurrentSchema.Hidden = (bool)property.Value; + break; + case JsonSchemaConstants.ReadOnlyPropertyName: + CurrentSchema.ReadOnly = (bool)property.Value; + break; + case JsonSchemaConstants.FormatPropertyName: + CurrentSchema.Format = (string)property.Value; + break; + case JsonSchemaConstants.PatternPropertyName: + CurrentSchema.Pattern = (string)property.Value; + break; + case JsonSchemaConstants.EnumPropertyName: + ProcessEnum(property.Value); + break; + case JsonSchemaConstants.ExtendsPropertyName: + ProcessExtends(property.Value); + break; + case JsonSchemaConstants.UniqueItemsPropertyName: + CurrentSchema.UniqueItems = (bool)property.Value; + break; + } + } } - } - if (schema.AdditionalItems != null) - schema.AdditionalItems = ResolveReferences(schema.AdditionalItems); - - if (schema.PatternProperties != null) - { - foreach (KeyValuePair patternProperty in schema.PatternProperties.ToList()) + private void ProcessExtends(JToken token) { - schema.PatternProperties[patternProperty.Key] = ResolveReferences(patternProperty.Value); + IList schemas = new List(); + + if (token.Type == JTokenType.Array) + { + foreach (JToken schemaObject in token) + { + schemas.Add(BuildSchema(schemaObject)); + } + } + else + { + JsonSchema schema = BuildSchema(token); + if (schema != null) + schemas.Add(schema); + } + + if (schemas.Count > 0) + CurrentSchema.Extends = schemas; } - } - if (schema.Properties != null) - { - foreach (KeyValuePair property in schema.Properties.ToList()) + private void ProcessEnum(JToken token) { - schema.Properties[property.Key] = ResolveReferences(property.Value); + if (token.Type != JTokenType.Array) + throw JsonException.Create(token, token.Path, "Expected Array token while parsing enum values, got {0}.".FormatWith(CultureInfo.InvariantCulture, token.Type)); + + CurrentSchema.Enum = new List(); + + foreach (JToken enumValue in token) + { + CurrentSchema.Enum.Add(enumValue.DeepClone()); + } } - } - if (schema.AdditionalProperties != null) - schema.AdditionalProperties = ResolveReferences(schema.AdditionalProperties); - - return schema; - } - - private JsonSchema BuildSchema(JToken token) - { - JObject schemaObject = token as JObject; - if (schemaObject == null) - throw JsonException.Create(token, token.Path, "Expected object while parsing schema object, got {0}.".FormatWith(CultureInfo.InvariantCulture, token.Type)); - - JToken referenceToken; - if (schemaObject.TryGetValue(JsonSchemaConstants.ReferencePropertyName, out referenceToken)) - { - JsonSchema deferredSchema = new JsonSchema(); - deferredSchema.DeferredReference = (string)referenceToken; - - return deferredSchema; - } - - string location = token.Path.Replace(".", "/").Replace("[", "/").Replace("]", string.Empty); - if (!string.IsNullOrEmpty(location)) - location = "/" + location; - location = "#" + location; - - JsonSchema existingSchema; - if (_documentSchemas.TryGetValue(location, out existingSchema)) - return existingSchema; - - Push(new JsonSchema { Location = location }); - - ProcessSchemaProperties(schemaObject); - - return Pop(); - } - - private void ProcessSchemaProperties(JObject schemaObject) - { - foreach (KeyValuePair property in schemaObject) - { - switch (property.Key) + private void ProcessAdditionalProperties(JToken token) { - case JsonSchemaConstants.TypePropertyName: - CurrentSchema.Type = ProcessType(property.Value); - break; - case JsonSchemaConstants.IdPropertyName: - CurrentSchema.Id = (string)property.Value; - break; - case JsonSchemaConstants.TitlePropertyName: - CurrentSchema.Title = (string)property.Value; - break; - case JsonSchemaConstants.DescriptionPropertyName: - CurrentSchema.Description = (string)property.Value; - break; - case JsonSchemaConstants.PropertiesPropertyName: - CurrentSchema.Properties = ProcessProperties(property.Value); - break; - case JsonSchemaConstants.ItemsPropertyName: - ProcessItems(property.Value); - break; - case JsonSchemaConstants.AdditionalPropertiesPropertyName: - ProcessAdditionalProperties(property.Value); - break; - case JsonSchemaConstants.AdditionalItemsPropertyName: - ProcessAdditionalItems(property.Value); - break; - case JsonSchemaConstants.PatternPropertiesPropertyName: - CurrentSchema.PatternProperties = ProcessProperties(property.Value); - break; - case JsonSchemaConstants.RequiredPropertyName: - CurrentSchema.Required = (bool)property.Value; - break; - case JsonSchemaConstants.RequiresPropertyName: - CurrentSchema.Requires = (string)property.Value; - break; - case JsonSchemaConstants.MinimumPropertyName: - CurrentSchema.Minimum = (double)property.Value; - break; - case JsonSchemaConstants.MaximumPropertyName: - CurrentSchema.Maximum = (double)property.Value; - break; - case JsonSchemaConstants.ExclusiveMinimumPropertyName: - CurrentSchema.ExclusiveMinimum = (bool)property.Value; - break; - case JsonSchemaConstants.ExclusiveMaximumPropertyName: - CurrentSchema.ExclusiveMaximum = (bool)property.Value; - break; - case JsonSchemaConstants.MaximumLengthPropertyName: - CurrentSchema.MaximumLength = (int)property.Value; - break; - case JsonSchemaConstants.MinimumLengthPropertyName: - CurrentSchema.MinimumLength = (int)property.Value; - break; - case JsonSchemaConstants.MaximumItemsPropertyName: - CurrentSchema.MaximumItems = (int)property.Value; - break; - case JsonSchemaConstants.MinimumItemsPropertyName: - CurrentSchema.MinimumItems = (int)property.Value; - break; - case JsonSchemaConstants.DivisibleByPropertyName: - CurrentSchema.DivisibleBy = (double)property.Value; - break; - case JsonSchemaConstants.DisallowPropertyName: - CurrentSchema.Disallow = ProcessType(property.Value); - break; - case JsonSchemaConstants.DefaultPropertyName: - CurrentSchema.Default = property.Value.DeepClone(); - break; - case JsonSchemaConstants.HiddenPropertyName: - CurrentSchema.Hidden = (bool)property.Value; - break; - case JsonSchemaConstants.ReadOnlyPropertyName: - CurrentSchema.ReadOnly = (bool)property.Value; - break; - case JsonSchemaConstants.FormatPropertyName: - CurrentSchema.Format = (string)property.Value; - break; - case JsonSchemaConstants.PatternPropertyName: - CurrentSchema.Pattern = (string)property.Value; - break; - case JsonSchemaConstants.EnumPropertyName: - ProcessEnum(property.Value); - break; - case JsonSchemaConstants.ExtendsPropertyName: - ProcessExtends(property.Value); - break; - case JsonSchemaConstants.UniqueItemsPropertyName: - CurrentSchema.UniqueItems = (bool)property.Value; - break; - } - } - } - - private void ProcessExtends(JToken token) - { - IList schemas = new List(); - - if (token.Type == JTokenType.Array) - { - foreach (JToken schemaObject in token) - { - schemas.Add(BuildSchema(schemaObject)); + if (token.Type == JTokenType.Boolean) + CurrentSchema.AllowAdditionalProperties = (bool)token; + else + CurrentSchema.AdditionalProperties = BuildSchema(token); } - } - else - { - JsonSchema schema = BuildSchema(token); - if (schema != null) - schemas.Add(schema); - } - if (schemas.Count > 0) - CurrentSchema.Extends = schemas; + private void ProcessAdditionalItems(JToken token) + { + if (token.Type == JTokenType.Boolean) + CurrentSchema.AllowAdditionalItems = (bool)token; + else + CurrentSchema.AdditionalItems = BuildSchema(token); + } + + private IDictionary ProcessProperties(JToken token) + { + IDictionary properties = new Dictionary(); + + if (token.Type != JTokenType.Object) + throw JsonException.Create(token, token.Path, "Expected Object token while parsing schema properties, got {0}.".FormatWith(CultureInfo.InvariantCulture, token.Type)); + + foreach (JProperty propertyToken in token) + { + if (properties.ContainsKey(propertyToken.Name)) + throw new JsonException("Property {0} has already been defined in schema.".FormatWith(CultureInfo.InvariantCulture, propertyToken.Name)); + + properties.Add(propertyToken.Name, BuildSchema(propertyToken.Value)); + } + + return properties; + } + + private void ProcessItems(JToken token) + { + CurrentSchema.Items = new List(); + + switch (token.Type) + { + case JTokenType.Object: + CurrentSchema.Items.Add(BuildSchema(token)); + CurrentSchema.PositionalItemsValidation = false; + break; + case JTokenType.Array: + CurrentSchema.PositionalItemsValidation = true; + foreach (JToken schemaToken in token) + { + CurrentSchema.Items.Add(BuildSchema(schemaToken)); + } + break; + default: + throw JsonException.Create(token, token.Path, "Expected array or JSON schema object, got {0}.".FormatWith(CultureInfo.InvariantCulture, token.Type)); + } + } + + private JsonSchemaType? ProcessType(JToken token) + { + switch (token.Type) + { + case JTokenType.Array: + // ensure type is in blank state before ORing values + JsonSchemaType? type = JsonSchemaType.None; + + foreach (JToken typeToken in token) + { + if (typeToken.Type != JTokenType.String) + throw JsonException.Create(typeToken, typeToken.Path, "Exception JSON schema type string token, got {0}.".FormatWith(CultureInfo.InvariantCulture, token.Type)); + + type = type | MapType((string)typeToken); + } + + return type; + case JTokenType.String: + return MapType((string)token); + default: + throw JsonException.Create(token, token.Path, "Expected array or JSON schema type string token, got {0}.".FormatWith(CultureInfo.InvariantCulture, token.Type)); + } + } + + internal static JsonSchemaType MapType(string type) + { + JsonSchemaType mappedType; + if (!JsonSchemaConstants.JsonSchemaTypeMapping.TryGetValue(type, out mappedType)) + throw new JsonException("Invalid JSON schema type: {0}".FormatWith(CultureInfo.InvariantCulture, type)); + + return mappedType; + } + + internal static string MapType(JsonSchemaType type) + { + return JsonSchemaConstants.JsonSchemaTypeMapping.Single(kv => kv.Value == type).Key; + } } - - private void ProcessEnum(JToken token) - { - if (token.Type != JTokenType.Array) - throw JsonException.Create(token, token.Path, "Expected Array token while parsing enum values, got {0}.".FormatWith(CultureInfo.InvariantCulture, token.Type)); - - CurrentSchema.Enum = new List(); - - foreach (JToken enumValue in token) - { - CurrentSchema.Enum.Add(enumValue.DeepClone()); - } - } - - private void ProcessAdditionalProperties(JToken token) - { - if (token.Type == JTokenType.Boolean) - CurrentSchema.AllowAdditionalProperties = (bool)token; - else - CurrentSchema.AdditionalProperties = BuildSchema(token); - } - - private void ProcessAdditionalItems(JToken token) - { - if (token.Type == JTokenType.Boolean) - CurrentSchema.AllowAdditionalItems = (bool)token; - else - CurrentSchema.AdditionalItems = BuildSchema(token); - } - - private IDictionary ProcessProperties(JToken token) - { - IDictionary properties = new Dictionary(); - - if (token.Type != JTokenType.Object) - throw JsonException.Create(token, token.Path, "Expected Object token while parsing schema properties, got {0}.".FormatWith(CultureInfo.InvariantCulture, token.Type)); - - foreach (JProperty propertyToken in token) - { - if (properties.ContainsKey(propertyToken.Name)) - throw new JsonException("Property {0} has already been defined in schema.".FormatWith(CultureInfo.InvariantCulture, propertyToken.Name)); - - properties.Add(propertyToken.Name, BuildSchema(propertyToken.Value)); - } - - return properties; - } - - private void ProcessItems(JToken token) - { - CurrentSchema.Items = new List(); - - switch (token.Type) - { - case JTokenType.Object: - CurrentSchema.Items.Add(BuildSchema(token)); - CurrentSchema.PositionalItemsValidation = false; - break; - case JTokenType.Array: - CurrentSchema.PositionalItemsValidation = true; - foreach (JToken schemaToken in token) - { - CurrentSchema.Items.Add(BuildSchema(schemaToken)); - } - break; - default: - throw JsonException.Create(token, token.Path, "Expected array or JSON schema object, got {0}.".FormatWith(CultureInfo.InvariantCulture, token.Type)); - } - } - - private JsonSchemaType? ProcessType(JToken token) - { - switch (token.Type) - { - case JTokenType.Array: - // ensure type is in blank state before ORing values - JsonSchemaType? type = JsonSchemaType.None; - - foreach (JToken typeToken in token) - { - if (typeToken.Type != JTokenType.String) - throw JsonException.Create(typeToken, typeToken.Path, "Exception JSON schema type string token, got {0}.".FormatWith(CultureInfo.InvariantCulture, token.Type)); - - type = type | MapType((string) typeToken); - } - - return type; - case JTokenType.String: - return MapType((string)token); - default: - throw JsonException.Create(token, token.Path, "Expected array or JSON schema type string token, got {0}.".FormatWith(CultureInfo.InvariantCulture, token.Type)); - } - } - - internal static JsonSchemaType MapType(string type) - { - JsonSchemaType mappedType; - if (!JsonSchemaConstants.JsonSchemaTypeMapping.TryGetValue(type, out mappedType)) - throw new JsonException("Invalid JSON schema type: {0}".FormatWith(CultureInfo.InvariantCulture, type)); - - return mappedType; - } - - internal static string MapType(JsonSchemaType type) - { - return JsonSchemaConstants.JsonSchemaTypeMapping.Single(kv => kv.Value == type).Key; - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Schema/JsonSchemaConstants.cs b/Src/Newtonsoft.Json/Schema/JsonSchemaConstants.cs index 22161692..692517ad 100644 --- a/Src/Newtonsoft.Json/Schema/JsonSchemaConstants.cs +++ b/Src/Newtonsoft.Json/Schema/JsonSchemaConstants.cs @@ -27,54 +27,54 @@ using System.Collections.Generic; namespace Newtonsoft.Json.Schema { - internal static class JsonSchemaConstants - { - public const string TypePropertyName = "type"; - public const string PropertiesPropertyName = "properties"; - public const string ItemsPropertyName = "items"; - public const string AdditionalItemsPropertyName = "additionalItems"; - public const string RequiredPropertyName = "required"; - public const string PatternPropertiesPropertyName = "patternProperties"; - public const string AdditionalPropertiesPropertyName = "additionalProperties"; - public const string RequiresPropertyName = "requires"; - public const string MinimumPropertyName = "minimum"; - public const string MaximumPropertyName = "maximum"; - public const string ExclusiveMinimumPropertyName = "exclusiveMinimum"; - public const string ExclusiveMaximumPropertyName = "exclusiveMaximum"; - public const string MinimumItemsPropertyName = "minItems"; - public const string MaximumItemsPropertyName = "maxItems"; - public const string PatternPropertyName = "pattern"; - public const string MaximumLengthPropertyName = "maxLength"; - public const string MinimumLengthPropertyName = "minLength"; - public const string EnumPropertyName = "enum"; - public const string ReadOnlyPropertyName = "readonly"; - public const string TitlePropertyName = "title"; - public const string DescriptionPropertyName = "description"; - public const string FormatPropertyName = "format"; - public const string DefaultPropertyName = "default"; - public const string TransientPropertyName = "transient"; - public const string DivisibleByPropertyName = "divisibleBy"; - public const string HiddenPropertyName = "hidden"; - public const string DisallowPropertyName = "disallow"; - public const string ExtendsPropertyName = "extends"; - public const string IdPropertyName = "id"; - public const string UniqueItemsPropertyName = "uniqueItems"; - - public const string OptionValuePropertyName = "value"; - public const string OptionLabelPropertyName = "label"; - - public const string ReferencePropertyName = "$ref"; - - public static readonly IDictionary JsonSchemaTypeMapping = new Dictionary + internal static class JsonSchemaConstants { - {"string", JsonSchemaType.String}, - {"object", JsonSchemaType.Object}, - {"integer", JsonSchemaType.Integer}, - {"number", JsonSchemaType.Float}, - {"null", JsonSchemaType.Null}, - {"boolean", JsonSchemaType.Boolean}, - {"array", JsonSchemaType.Array}, - {"any", JsonSchemaType.Any} - }; - } -} + public const string TypePropertyName = "type"; + public const string PropertiesPropertyName = "properties"; + public const string ItemsPropertyName = "items"; + public const string AdditionalItemsPropertyName = "additionalItems"; + public const string RequiredPropertyName = "required"; + public const string PatternPropertiesPropertyName = "patternProperties"; + public const string AdditionalPropertiesPropertyName = "additionalProperties"; + public const string RequiresPropertyName = "requires"; + public const string MinimumPropertyName = "minimum"; + public const string MaximumPropertyName = "maximum"; + public const string ExclusiveMinimumPropertyName = "exclusiveMinimum"; + public const string ExclusiveMaximumPropertyName = "exclusiveMaximum"; + public const string MinimumItemsPropertyName = "minItems"; + public const string MaximumItemsPropertyName = "maxItems"; + public const string PatternPropertyName = "pattern"; + public const string MaximumLengthPropertyName = "maxLength"; + public const string MinimumLengthPropertyName = "minLength"; + public const string EnumPropertyName = "enum"; + public const string ReadOnlyPropertyName = "readonly"; + public const string TitlePropertyName = "title"; + public const string DescriptionPropertyName = "description"; + public const string FormatPropertyName = "format"; + public const string DefaultPropertyName = "default"; + public const string TransientPropertyName = "transient"; + public const string DivisibleByPropertyName = "divisibleBy"; + public const string HiddenPropertyName = "hidden"; + public const string DisallowPropertyName = "disallow"; + public const string ExtendsPropertyName = "extends"; + public const string IdPropertyName = "id"; + public const string UniqueItemsPropertyName = "uniqueItems"; + + public const string OptionValuePropertyName = "value"; + public const string OptionLabelPropertyName = "label"; + + public const string ReferencePropertyName = "$ref"; + + public static readonly IDictionary JsonSchemaTypeMapping = new Dictionary + { + { "string", JsonSchemaType.String }, + { "object", JsonSchemaType.Object }, + { "integer", JsonSchemaType.Integer }, + { "number", JsonSchemaType.Float }, + { "null", JsonSchemaType.Null }, + { "boolean", JsonSchemaType.Boolean }, + { "array", JsonSchemaType.Array }, + { "any", JsonSchemaType.Any } + }; + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Schema/JsonSchemaException.cs b/Src/Newtonsoft.Json/Schema/JsonSchemaException.cs index 448bd4a4..94c93d59 100644 --- a/Src/Newtonsoft.Json/Schema/JsonSchemaException.cs +++ b/Src/Newtonsoft.Json/Schema/JsonSchemaException.cs @@ -28,81 +28,81 @@ using System.Runtime.Serialization; namespace Newtonsoft.Json.Schema { - /// - /// Returns detailed information about the schema exception. - /// + /// + /// Returns detailed information about the schema exception. + /// #if !(SILVERLIGHT || WINDOWS_PHONE || NETFX_CORE || PORTABLE40 || PORTABLE) - [Serializable] + [Serializable] #endif - public class JsonSchemaException : JsonException - { - /// - /// Gets the line number indicating where the error occurred. - /// - /// The line number indicating where the error occurred. - public int LineNumber { get; private set; } - - - /// - /// Gets the line position indicating where the error occurred. - /// - /// The line position indicating where the error occurred. - public int LinePosition { get; private set; } - - /// - /// Gets the path to the JSON where the error occurred. - /// - /// The path to the JSON where the error occurred. - public string Path { get; private set; } - - /// - /// Initializes a new instance of the class. - /// - public JsonSchemaException() + public class JsonSchemaException : JsonException { - } + /// + /// Gets the line number indicating where the error occurred. + /// + /// The line number indicating where the error occurred. + public int LineNumber { get; private set; } - /// - /// Initializes a new instance of the class - /// with a specified error message. - /// - /// The error message that explains the reason for the exception. - public JsonSchemaException(string message) - : base(message) - { - } - /// - /// Initializes a new instance of the class - /// with a specified error message and a reference to the inner exception that is the cause of this exception. - /// - /// The error message that explains the reason for the exception. - /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - public JsonSchemaException(string message, Exception innerException) - : base(message, innerException) - { - } + /// + /// Gets the line position indicating where the error occurred. + /// + /// The line position indicating where the error occurred. + public int LinePosition { get; private set; } + + /// + /// Gets the path to the JSON where the error occurred. + /// + /// The path to the JSON where the error occurred. + public string Path { get; private set; } + + /// + /// Initializes a new instance of the class. + /// + public JsonSchemaException() + { + } + + /// + /// Initializes a new instance of the class + /// with a specified error message. + /// + /// The error message that explains the reason for the exception. + public JsonSchemaException(string message) + : base(message) + { + } + + /// + /// Initializes a new instance of the class + /// with a specified error message and a reference to the inner exception that is the cause of this exception. + /// + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + public JsonSchemaException(string message, Exception innerException) + : base(message, innerException) + { + } #if !(WINDOWS_PHONE || SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) - /// - /// Initializes a new instance of the class. - /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. - /// The parameter is null. - /// The class name is null or is zero (0). - public JsonSchemaException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } + /// + /// Initializes a new instance of the class. + /// + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. + /// The parameter is null. + /// The class name is null or is zero (0). + public JsonSchemaException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } #endif - internal JsonSchemaException(string message, Exception innerException, string path, int lineNumber, int linePosition) - : base(message, innerException) - { - Path = path; - LineNumber = lineNumber; - LinePosition = linePosition; + internal JsonSchemaException(string message, Exception innerException, string path, int lineNumber, int linePosition) + : base(message, innerException) + { + Path = path; + LineNumber = lineNumber; + LinePosition = linePosition; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Schema/JsonSchemaGenerator.cs b/Src/Newtonsoft.Json/Schema/JsonSchemaGenerator.cs index beb78b1e..9a6aae73 100644 --- a/Src/Newtonsoft.Json/Schema/JsonSchemaGenerator.cs +++ b/Src/Newtonsoft.Json/Schema/JsonSchemaGenerator.cs @@ -34,438 +34,440 @@ using Newtonsoft.Json.Serialization; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json.Schema { - /// - /// Generates a from a specified . - /// - public class JsonSchemaGenerator - { /// - /// Gets or sets how undefined schemas are handled by the serializer. + /// Generates a from a specified . /// - public UndefinedSchemaIdHandling UndefinedSchemaIdHandling { get; set; } - - private IContractResolver _contractResolver; - /// - /// Gets or sets the contract resolver. - /// - /// The contract resolver. - public IContractResolver ContractResolver + public class JsonSchemaGenerator { - get - { - if (_contractResolver == null) - return DefaultContractResolver.Instance; + /// + /// Gets or sets how undefined schemas are handled by the serializer. + /// + public UndefinedSchemaIdHandling UndefinedSchemaIdHandling { get; set; } - return _contractResolver; - } - set { _contractResolver = value; } - } + private IContractResolver _contractResolver; - private class TypeSchema - { - public Type Type { get; private set; } - public JsonSchema Schema { get; private set;} + /// + /// Gets or sets the contract resolver. + /// + /// The contract resolver. + public IContractResolver ContractResolver + { + get + { + if (_contractResolver == null) + return DefaultContractResolver.Instance; - public TypeSchema(Type type, JsonSchema schema) - { - ValidationUtils.ArgumentNotNull(type, "type"); - ValidationUtils.ArgumentNotNull(schema, "schema"); + return _contractResolver; + } + set { _contractResolver = value; } + } - Type = type; - Schema = schema; - } - } + private class TypeSchema + { + public Type Type { get; private set; } + public JsonSchema Schema { get; private set; } - private JsonSchemaResolver _resolver; - private readonly IList _stack = new List(); - private JsonSchema _currentSchema; + public TypeSchema(Type type, JsonSchema schema) + { + ValidationUtils.ArgumentNotNull(type, "type"); + ValidationUtils.ArgumentNotNull(schema, "schema"); - private JsonSchema CurrentSchema - { - get { return _currentSchema; } - } + Type = type; + Schema = schema; + } + } - private void Push(TypeSchema typeSchema) - { - _currentSchema = typeSchema.Schema; - _stack.Add(typeSchema); - _resolver.LoadedSchemas.Add(typeSchema.Schema); - } + private JsonSchemaResolver _resolver; + private readonly IList _stack = new List(); + private JsonSchema _currentSchema; - private TypeSchema Pop() - { - TypeSchema popped = _stack[_stack.Count - 1]; - _stack.RemoveAt(_stack.Count - 1); - TypeSchema newValue = _stack.LastOrDefault(); - if (newValue != null) - { - _currentSchema = newValue.Schema; - } - else - { - _currentSchema = null; - } + private JsonSchema CurrentSchema + { + get { return _currentSchema; } + } - return popped; - } + private void Push(TypeSchema typeSchema) + { + _currentSchema = typeSchema.Schema; + _stack.Add(typeSchema); + _resolver.LoadedSchemas.Add(typeSchema.Schema); + } - /// - /// Generate a from the specified type. - /// - /// The type to generate a from. - /// A generated from the specified type. - public JsonSchema Generate(Type type) - { - return Generate(type, new JsonSchemaResolver(), false); - } + private TypeSchema Pop() + { + TypeSchema popped = _stack[_stack.Count - 1]; + _stack.RemoveAt(_stack.Count - 1); + TypeSchema newValue = _stack.LastOrDefault(); + if (newValue != null) + { + _currentSchema = newValue.Schema; + } + else + { + _currentSchema = null; + } - /// - /// Generate a from the specified type. - /// - /// The type to generate a from. - /// The used to resolve schema references. - /// A generated from the specified type. - public JsonSchema Generate(Type type, JsonSchemaResolver resolver) - { - return Generate(type, resolver, false); - } + return popped; + } - /// - /// Generate a from the specified type. - /// - /// The type to generate a from. - /// Specify whether the generated root will be nullable. - /// A generated from the specified type. - public JsonSchema Generate(Type type, bool rootSchemaNullable) - { - return Generate(type, new JsonSchemaResolver(), rootSchemaNullable); - } + /// + /// Generate a from the specified type. + /// + /// The type to generate a from. + /// A generated from the specified type. + public JsonSchema Generate(Type type) + { + return Generate(type, new JsonSchemaResolver(), false); + } - /// - /// Generate a from the specified type. - /// - /// The type to generate a from. - /// The used to resolve schema references. - /// Specify whether the generated root will be nullable. - /// A generated from the specified type. - public JsonSchema Generate(Type type, JsonSchemaResolver resolver, bool rootSchemaNullable) - { - ValidationUtils.ArgumentNotNull(type, "type"); - ValidationUtils.ArgumentNotNull(resolver, "resolver"); + /// + /// Generate a from the specified type. + /// + /// The type to generate a from. + /// The used to resolve schema references. + /// A generated from the specified type. + public JsonSchema Generate(Type type, JsonSchemaResolver resolver) + { + return Generate(type, resolver, false); + } - _resolver = resolver; + /// + /// Generate a from the specified type. + /// + /// The type to generate a from. + /// Specify whether the generated root will be nullable. + /// A generated from the specified type. + public JsonSchema Generate(Type type, bool rootSchemaNullable) + { + return Generate(type, new JsonSchemaResolver(), rootSchemaNullable); + } - return GenerateInternal(type, (!rootSchemaNullable) ? Required.Always : Required.Default, false); - } + /// + /// Generate a from the specified type. + /// + /// The type to generate a from. + /// The used to resolve schema references. + /// Specify whether the generated root will be nullable. + /// A generated from the specified type. + public JsonSchema Generate(Type type, JsonSchemaResolver resolver, bool rootSchemaNullable) + { + ValidationUtils.ArgumentNotNull(type, "type"); + ValidationUtils.ArgumentNotNull(resolver, "resolver"); - private string GetTitle(Type type) - { - JsonContainerAttribute containerAttribute = JsonTypeReflector.GetJsonContainerAttribute(type); + _resolver = resolver; - if (containerAttribute != null && !string.IsNullOrEmpty(containerAttribute.Title)) - return containerAttribute.Title; + return GenerateInternal(type, (!rootSchemaNullable) ? Required.Always : Required.Default, false); + } - return null; - } + private string GetTitle(Type type) + { + JsonContainerAttribute containerAttribute = JsonTypeReflector.GetJsonContainerAttribute(type); - private string GetDescription(Type type) - { - JsonContainerAttribute containerAttribute = JsonTypeReflector.GetJsonContainerAttribute(type); + if (containerAttribute != null && !string.IsNullOrEmpty(containerAttribute.Title)) + return containerAttribute.Title; - if (containerAttribute != null && !string.IsNullOrEmpty(containerAttribute.Description)) - return containerAttribute.Description; + return null; + } + + private string GetDescription(Type type) + { + JsonContainerAttribute containerAttribute = JsonTypeReflector.GetJsonContainerAttribute(type); + + if (containerAttribute != null && !string.IsNullOrEmpty(containerAttribute.Description)) + return containerAttribute.Description; #if !(NETFX_CORE || PORTABLE40 || PORTABLE) - DescriptionAttribute descriptionAttribute = ReflectionUtils.GetAttribute(type); - if (descriptionAttribute != null) - return descriptionAttribute.Description; + DescriptionAttribute descriptionAttribute = ReflectionUtils.GetAttribute(type); + if (descriptionAttribute != null) + return descriptionAttribute.Description; #endif - return null; - } - - private string GetTypeId(Type type, bool explicitOnly) - { - JsonContainerAttribute containerAttribute = JsonTypeReflector.GetJsonContainerAttribute(type); - - if (containerAttribute != null && !string.IsNullOrEmpty(containerAttribute.Id)) - return containerAttribute.Id; - - if (explicitOnly) - return null; - - switch (UndefinedSchemaIdHandling) - { - case UndefinedSchemaIdHandling.UseTypeName: - return type.FullName; - case UndefinedSchemaIdHandling.UseAssemblyQualifiedName: - return type.AssemblyQualifiedName; - default: - return null; - } - } - - private JsonSchema GenerateInternal(Type type, Required valueRequired, bool required) - { - ValidationUtils.ArgumentNotNull(type, "type"); - - string resolvedId = GetTypeId(type, false); - string explicitId = GetTypeId(type, true); - - if (!string.IsNullOrEmpty(resolvedId)) - { - JsonSchema resolvedSchema = _resolver.GetSchema(resolvedId); - if (resolvedSchema != null) - { - // resolved schema is not null but referencing member allows nulls - // change resolved schema to allow nulls. hacky but what are ya gonna do? - if (valueRequired != Required.Always && !HasFlag(resolvedSchema.Type, JsonSchemaType.Null)) - resolvedSchema.Type |= JsonSchemaType.Null; - if (required && resolvedSchema.Required != true) - resolvedSchema.Required = true; - - return resolvedSchema; + return null; } - } - // test for unresolved circular reference - if (_stack.Any(tc => tc.Type == type)) - { - throw new JsonException("Unresolved circular reference for type '{0}'. Explicitly define an Id for the type using a JsonObject/JsonArray attribute or automatically generate a type Id using the UndefinedSchemaIdHandling property.".FormatWith(CultureInfo.InvariantCulture, type)); - } - - JsonContract contract = ContractResolver.ResolveContract(type); - JsonConverter converter; - if ((converter = contract.Converter) != null || (converter = contract.InternalConverter) != null) - { - JsonSchema converterSchema = converter.GetSchema(); - if (converterSchema != null) - return converterSchema; - } - - Push(new TypeSchema(type, new JsonSchema())); - - if (explicitId != null) - CurrentSchema.Id = explicitId; - - if (required) - CurrentSchema.Required = true; - CurrentSchema.Title = GetTitle(type); - CurrentSchema.Description = GetDescription(type); - - if (converter != null) - { - // todo: Add GetSchema to JsonConverter and use here? - CurrentSchema.Type = JsonSchemaType.Any; - } - else - { - switch (contract.ContractType) + private string GetTypeId(Type type, bool explicitOnly) { - case JsonContractType.Object: - CurrentSchema.Type = AddNullType(JsonSchemaType.Object, valueRequired); - CurrentSchema.Id = GetTypeId(type, false); - GenerateObjectSchema(type, (JsonObjectContract) contract); - break; - case JsonContractType.Array: - CurrentSchema.Type = AddNullType(JsonSchemaType.Array, valueRequired); + JsonContainerAttribute containerAttribute = JsonTypeReflector.GetJsonContainerAttribute(type); - CurrentSchema.Id = GetTypeId(type, false); + if (containerAttribute != null && !string.IsNullOrEmpty(containerAttribute.Id)) + return containerAttribute.Id; - JsonArrayAttribute arrayAttribute = JsonTypeReflector.GetJsonContainerAttribute(type) as JsonArrayAttribute; - bool allowNullItem = (arrayAttribute == null || arrayAttribute.AllowNullItems); + if (explicitOnly) + return null; - Type collectionItemType = ReflectionUtils.GetCollectionItemType(type); - if (collectionItemType != null) + switch (UndefinedSchemaIdHandling) { - CurrentSchema.Items = new List(); - CurrentSchema.Items.Add(GenerateInternal(collectionItemType, (!allowNullItem) ? Required.Always : Required.Default, false)); + case UndefinedSchemaIdHandling.UseTypeName: + return type.FullName; + case UndefinedSchemaIdHandling.UseAssemblyQualifiedName: + return type.AssemblyQualifiedName; + default: + return null; } - break; - case JsonContractType.Primitive: - CurrentSchema.Type = GetJsonSchemaType(type, valueRequired); + } - if (CurrentSchema.Type == JsonSchemaType.Integer && type.IsEnum() && !type.IsDefined(typeof (FlagsAttribute), true)) + private JsonSchema GenerateInternal(Type type, Required valueRequired, bool required) + { + ValidationUtils.ArgumentNotNull(type, "type"); + + string resolvedId = GetTypeId(type, false); + string explicitId = GetTypeId(type, true); + + if (!string.IsNullOrEmpty(resolvedId)) { - CurrentSchema.Enum = new List(); + JsonSchema resolvedSchema = _resolver.GetSchema(resolvedId); + if (resolvedSchema != null) + { + // resolved schema is not null but referencing member allows nulls + // change resolved schema to allow nulls. hacky but what are ya gonna do? + if (valueRequired != Required.Always && !HasFlag(resolvedSchema.Type, JsonSchemaType.Null)) + resolvedSchema.Type |= JsonSchemaType.Null; + if (required && resolvedSchema.Required != true) + resolvedSchema.Required = true; - EnumValues enumValues = EnumUtils.GetNamesAndValues(type); - foreach (EnumValue enumValue in enumValues) - { - JToken value = JToken.FromObject(enumValue.Value); - - CurrentSchema.Enum.Add(value); - } + return resolvedSchema; + } } - break; - case JsonContractType.String: - JsonSchemaType schemaType = (!ReflectionUtils.IsNullable(contract.UnderlyingType)) - ? JsonSchemaType.String - : AddNullType(JsonSchemaType.String, valueRequired); - CurrentSchema.Type = schemaType; - break; - case JsonContractType.Dictionary: - CurrentSchema.Type = AddNullType(JsonSchemaType.Object, valueRequired); - - Type keyType; - Type valueType; - ReflectionUtils.GetDictionaryKeyValueTypes(type, out keyType, out valueType); - - if (keyType != null) + // test for unresolved circular reference + if (_stack.Any(tc => tc.Type == type)) { - JsonContract keyContract = ContractResolver.ResolveContract(keyType); - - // can be converted to a string - if (keyContract.ContractType == JsonContractType.Primitive) - { - CurrentSchema.AdditionalProperties = GenerateInternal(valueType, Required.Default, false); - } + throw new JsonException("Unresolved circular reference for type '{0}'. Explicitly define an Id for the type using a JsonObject/JsonArray attribute or automatically generate a type Id using the UndefinedSchemaIdHandling property.".FormatWith(CultureInfo.InvariantCulture, type)); } - break; + + JsonContract contract = ContractResolver.ResolveContract(type); + JsonConverter converter; + if ((converter = contract.Converter) != null || (converter = contract.InternalConverter) != null) + { + JsonSchema converterSchema = converter.GetSchema(); + if (converterSchema != null) + return converterSchema; + } + + Push(new TypeSchema(type, new JsonSchema())); + + if (explicitId != null) + CurrentSchema.Id = explicitId; + + if (required) + CurrentSchema.Required = true; + CurrentSchema.Title = GetTitle(type); + CurrentSchema.Description = GetDescription(type); + + if (converter != null) + { + // todo: Add GetSchema to JsonConverter and use here? + CurrentSchema.Type = JsonSchemaType.Any; + } + else + { + switch (contract.ContractType) + { + case JsonContractType.Object: + CurrentSchema.Type = AddNullType(JsonSchemaType.Object, valueRequired); + CurrentSchema.Id = GetTypeId(type, false); + GenerateObjectSchema(type, (JsonObjectContract)contract); + break; + case JsonContractType.Array: + CurrentSchema.Type = AddNullType(JsonSchemaType.Array, valueRequired); + + CurrentSchema.Id = GetTypeId(type, false); + + JsonArrayAttribute arrayAttribute = JsonTypeReflector.GetJsonContainerAttribute(type) as JsonArrayAttribute; + bool allowNullItem = (arrayAttribute == null || arrayAttribute.AllowNullItems); + + Type collectionItemType = ReflectionUtils.GetCollectionItemType(type); + if (collectionItemType != null) + { + CurrentSchema.Items = new List(); + CurrentSchema.Items.Add(GenerateInternal(collectionItemType, (!allowNullItem) ? Required.Always : Required.Default, false)); + } + break; + case JsonContractType.Primitive: + CurrentSchema.Type = GetJsonSchemaType(type, valueRequired); + + if (CurrentSchema.Type == JsonSchemaType.Integer && type.IsEnum() && !type.IsDefined(typeof(FlagsAttribute), true)) + { + CurrentSchema.Enum = new List(); + + EnumValues enumValues = EnumUtils.GetNamesAndValues(type); + foreach (EnumValue enumValue in enumValues) + { + JToken value = JToken.FromObject(enumValue.Value); + + CurrentSchema.Enum.Add(value); + } + } + break; + case JsonContractType.String: + JsonSchemaType schemaType = (!ReflectionUtils.IsNullable(contract.UnderlyingType)) + ? JsonSchemaType.String + : AddNullType(JsonSchemaType.String, valueRequired); + + CurrentSchema.Type = schemaType; + break; + case JsonContractType.Dictionary: + CurrentSchema.Type = AddNullType(JsonSchemaType.Object, valueRequired); + + Type keyType; + Type valueType; + ReflectionUtils.GetDictionaryKeyValueTypes(type, out keyType, out valueType); + + if (keyType != null) + { + JsonContract keyContract = ContractResolver.ResolveContract(keyType); + + // can be converted to a string + if (keyContract.ContractType == JsonContractType.Primitive) + { + CurrentSchema.AdditionalProperties = GenerateInternal(valueType, Required.Default, false); + } + } + break; #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - case JsonContractType.Serializable: - CurrentSchema.Type = AddNullType(JsonSchemaType.Object, valueRequired); - CurrentSchema.Id = GetTypeId(type, false); - GenerateISerializableContract(type, (JsonISerializableContract) contract); - break; + case JsonContractType.Serializable: + CurrentSchema.Type = AddNullType(JsonSchemaType.Object, valueRequired); + CurrentSchema.Id = GetTypeId(type, false); + GenerateISerializableContract(type, (JsonISerializableContract)contract); + break; #endif #if !(NET35 || NET20 || WINDOWS_PHONE || PORTABLE40) - case JsonContractType.Dynamic: + case JsonContractType.Dynamic: #endif - case JsonContractType.Linq: - CurrentSchema.Type = JsonSchemaType.Any; - break; - default: - throw new JsonException("Unexpected contract type: {0}".FormatWith(CultureInfo.InvariantCulture, contract)); + case JsonContractType.Linq: + CurrentSchema.Type = JsonSchemaType.Any; + break; + default: + throw new JsonException("Unexpected contract type: {0}".FormatWith(CultureInfo.InvariantCulture, contract)); + } + } + + return Pop().Schema; } - } - return Pop().Schema; - } - - private JsonSchemaType AddNullType(JsonSchemaType type, Required valueRequired) - { - if (valueRequired != Required.Always) - return type | JsonSchemaType.Null; - - return type; - } - - private bool HasFlag(DefaultValueHandling value, DefaultValueHandling flag) - { - return ((value & flag) == flag); - } - - private void GenerateObjectSchema(Type type, JsonObjectContract contract) - { - CurrentSchema.Properties = new Dictionary(); - foreach (JsonProperty property in contract.Properties) - { - if (!property.Ignored) + private JsonSchemaType AddNullType(JsonSchemaType type, Required valueRequired) { - bool optional = property.NullValueHandling == NullValueHandling.Ignore || - HasFlag(property.DefaultValueHandling.GetValueOrDefault(), DefaultValueHandling.Ignore) || - property.ShouldSerialize != null || - property.GetIsSpecified != null; + if (valueRequired != Required.Always) + return type | JsonSchemaType.Null; - JsonSchema propertySchema = GenerateInternal(property.PropertyType, property.Required, !optional); - - if (property.DefaultValue != null) - propertySchema.Default = JToken.FromObject(property.DefaultValue); - - CurrentSchema.Properties.Add(property.PropertyName, propertySchema); + return type; } - } - if (type.IsSealed()) - CurrentSchema.AllowAdditionalProperties = false; - } + private bool HasFlag(DefaultValueHandling value, DefaultValueHandling flag) + { + return ((value & flag) == flag); + } + + private void GenerateObjectSchema(Type type, JsonObjectContract contract) + { + CurrentSchema.Properties = new Dictionary(); + foreach (JsonProperty property in contract.Properties) + { + if (!property.Ignored) + { + bool optional = property.NullValueHandling == NullValueHandling.Ignore || + HasFlag(property.DefaultValueHandling.GetValueOrDefault(), DefaultValueHandling.Ignore) || + property.ShouldSerialize != null || + property.GetIsSpecified != null; + + JsonSchema propertySchema = GenerateInternal(property.PropertyType, property.Required, !optional); + + if (property.DefaultValue != null) + propertySchema.Default = JToken.FromObject(property.DefaultValue); + + CurrentSchema.Properties.Add(property.PropertyName, propertySchema); + } + } + + if (type.IsSealed()) + CurrentSchema.AllowAdditionalProperties = false; + } #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - private void GenerateISerializableContract(Type type, JsonISerializableContract contract) - { - CurrentSchema.AllowAdditionalProperties = true; - } + private void GenerateISerializableContract(Type type, JsonISerializableContract contract) + { + CurrentSchema.AllowAdditionalProperties = true; + } #endif - internal static bool HasFlag(JsonSchemaType? value, JsonSchemaType flag) - { - // default value is Any - if (value == null) - return true; + internal static bool HasFlag(JsonSchemaType? value, JsonSchemaType flag) + { + // default value is Any + if (value == null) + return true; - bool match = ((value & flag) == flag); - if (match) - return true; + bool match = ((value & flag) == flag); + if (match) + return true; - // integer is a subset of float - if (flag == JsonSchemaType.Integer && (value & JsonSchemaType.Float) == JsonSchemaType.Float) - return true; + // integer is a subset of float + if (flag == JsonSchemaType.Integer && (value & JsonSchemaType.Float) == JsonSchemaType.Float) + return true; - return false; - } + return false; + } - private JsonSchemaType GetJsonSchemaType(Type type, Required valueRequired) - { - JsonSchemaType schemaType = JsonSchemaType.None; - if (valueRequired != Required.Always && ReflectionUtils.IsNullable(type)) - { - schemaType = JsonSchemaType.Null; - if (ReflectionUtils.IsNullableType(type)) - type = Nullable.GetUnderlyingType(type); - } + private JsonSchemaType GetJsonSchemaType(Type type, Required valueRequired) + { + JsonSchemaType schemaType = JsonSchemaType.None; + if (valueRequired != Required.Always && ReflectionUtils.IsNullable(type)) + { + schemaType = JsonSchemaType.Null; + if (ReflectionUtils.IsNullableType(type)) + type = Nullable.GetUnderlyingType(type); + } - PrimitiveTypeCode typeCode = ConvertUtils.GetTypeCode(type); + PrimitiveTypeCode typeCode = ConvertUtils.GetTypeCode(type); - switch (typeCode) - { - case PrimitiveTypeCode.Empty: - case PrimitiveTypeCode.Object: - return schemaType | JsonSchemaType.String; + switch (typeCode) + { + case PrimitiveTypeCode.Empty: + case PrimitiveTypeCode.Object: + return schemaType | JsonSchemaType.String; #if !(NETFX_CORE || PORTABLE) - case PrimitiveTypeCode.DBNull: - return schemaType | JsonSchemaType.Null; + case PrimitiveTypeCode.DBNull: + return schemaType | JsonSchemaType.Null; #endif - case PrimitiveTypeCode.Boolean: - return schemaType | JsonSchemaType.Boolean; - case PrimitiveTypeCode.Char: - return schemaType | JsonSchemaType.String; - case PrimitiveTypeCode.SByte: - case PrimitiveTypeCode.Byte: - case PrimitiveTypeCode.Int16: - case PrimitiveTypeCode.UInt16: - case PrimitiveTypeCode.Int32: - case PrimitiveTypeCode.UInt32: - case PrimitiveTypeCode.Int64: - case PrimitiveTypeCode.UInt64: + case PrimitiveTypeCode.Boolean: + return schemaType | JsonSchemaType.Boolean; + case PrimitiveTypeCode.Char: + return schemaType | JsonSchemaType.String; + case PrimitiveTypeCode.SByte: + case PrimitiveTypeCode.Byte: + case PrimitiveTypeCode.Int16: + case PrimitiveTypeCode.UInt16: + case PrimitiveTypeCode.Int32: + case PrimitiveTypeCode.UInt32: + case PrimitiveTypeCode.Int64: + case PrimitiveTypeCode.UInt64: #if !(PORTABLE || NET35 || NET20 || WINDOWS_PHONE || SILVERLIGHT) - case PrimitiveTypeCode.BigInteger: + case PrimitiveTypeCode.BigInteger: #endif - return schemaType | JsonSchemaType.Integer; - case PrimitiveTypeCode.Single: - case PrimitiveTypeCode.Double: - case PrimitiveTypeCode.Decimal: - return schemaType | JsonSchemaType.Float; - // convert to string? - case PrimitiveTypeCode.DateTime: + return schemaType | JsonSchemaType.Integer; + case PrimitiveTypeCode.Single: + case PrimitiveTypeCode.Double: + case PrimitiveTypeCode.Decimal: + return schemaType | JsonSchemaType.Float; + // convert to string? + case PrimitiveTypeCode.DateTime: #if !NET20 - case PrimitiveTypeCode.DateTimeOffset: + case PrimitiveTypeCode.DateTimeOffset: #endif - return schemaType | JsonSchemaType.String; - case PrimitiveTypeCode.String: - case PrimitiveTypeCode.Uri: - case PrimitiveTypeCode.Guid: - case PrimitiveTypeCode.TimeSpan: - case PrimitiveTypeCode.Bytes: - return schemaType | JsonSchemaType.String; - default: - throw new JsonException("Unexpected type code '{0}' for type '{1}'.".FormatWith(CultureInfo.InvariantCulture, typeCode, type)); - } + return schemaType | JsonSchemaType.String; + case PrimitiveTypeCode.String: + case PrimitiveTypeCode.Uri: + case PrimitiveTypeCode.Guid: + case PrimitiveTypeCode.TimeSpan: + case PrimitiveTypeCode.Bytes: + return schemaType | JsonSchemaType.String; + default: + throw new JsonException("Unexpected type code '{0}' for type '{1}'.".FormatWith(CultureInfo.InvariantCulture, typeCode, type)); + } + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Schema/JsonSchemaModel.cs b/Src/Newtonsoft.Json/Schema/JsonSchemaModel.cs index fddc4c13..5a369fcc 100644 --- a/Src/Newtonsoft.Json/Schema/JsonSchemaModel.cs +++ b/Src/Newtonsoft.Json/Schema/JsonSchemaModel.cs @@ -29,91 +29,91 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Schema { - internal class JsonSchemaModel - { - public bool Required { get; set; } - public JsonSchemaType Type { get; set; } - public int? MinimumLength { get; set; } - public int? MaximumLength { get; set; } - public double? DivisibleBy { get; set; } - public double? Minimum { get; set; } - public double? Maximum { get; set; } - public bool ExclusiveMinimum { get; set; } - public bool ExclusiveMaximum { get; set; } - public int? MinimumItems { get; set; } - public int? MaximumItems { get; set; } - public IList Patterns { get; set; } - public IList Items { get; set; } - public IDictionary Properties { get; set; } - public IDictionary PatternProperties { get; set; } - public JsonSchemaModel AdditionalProperties { get; set; } - public JsonSchemaModel AdditionalItems { get; set; } - public bool PositionalItemsValidation { get; set; } - public bool AllowAdditionalProperties { get; set; } - public bool AllowAdditionalItems { get; set; } - public bool UniqueItems { get; set; } - public IList Enum { get; set; } - public JsonSchemaType Disallow { get; set; } - - public JsonSchemaModel() + internal class JsonSchemaModel { - Type = JsonSchemaType.Any; - AllowAdditionalProperties = true; - AllowAdditionalItems = true; - Required = false; + public bool Required { get; set; } + public JsonSchemaType Type { get; set; } + public int? MinimumLength { get; set; } + public int? MaximumLength { get; set; } + public double? DivisibleBy { get; set; } + public double? Minimum { get; set; } + public double? Maximum { get; set; } + public bool ExclusiveMinimum { get; set; } + public bool ExclusiveMaximum { get; set; } + public int? MinimumItems { get; set; } + public int? MaximumItems { get; set; } + public IList Patterns { get; set; } + public IList Items { get; set; } + public IDictionary Properties { get; set; } + public IDictionary PatternProperties { get; set; } + public JsonSchemaModel AdditionalProperties { get; set; } + public JsonSchemaModel AdditionalItems { get; set; } + public bool PositionalItemsValidation { get; set; } + public bool AllowAdditionalProperties { get; set; } + public bool AllowAdditionalItems { get; set; } + public bool UniqueItems { get; set; } + public IList Enum { get; set; } + public JsonSchemaType Disallow { get; set; } + + public JsonSchemaModel() + { + Type = JsonSchemaType.Any; + AllowAdditionalProperties = true; + AllowAdditionalItems = true; + Required = false; + } + + public static JsonSchemaModel Create(IList schemata) + { + JsonSchemaModel model = new JsonSchemaModel(); + + foreach (JsonSchema schema in schemata) + { + Combine(model, schema); + } + + return model; + } + + private static void Combine(JsonSchemaModel model, JsonSchema schema) + { + // Version 3 of the Draft JSON Schema has the default value of Not Required + model.Required = model.Required || (schema.Required ?? false); + model.Type = model.Type & (schema.Type ?? JsonSchemaType.Any); + + model.MinimumLength = MathUtils.Max(model.MinimumLength, schema.MinimumLength); + model.MaximumLength = MathUtils.Min(model.MaximumLength, schema.MaximumLength); + + // not sure what is the best way to combine divisibleBy + model.DivisibleBy = MathUtils.Max(model.DivisibleBy, schema.DivisibleBy); + + model.Minimum = MathUtils.Max(model.Minimum, schema.Minimum); + model.Maximum = MathUtils.Max(model.Maximum, schema.Maximum); + model.ExclusiveMinimum = model.ExclusiveMinimum || (schema.ExclusiveMinimum ?? false); + model.ExclusiveMaximum = model.ExclusiveMaximum || (schema.ExclusiveMaximum ?? false); + + model.MinimumItems = MathUtils.Max(model.MinimumItems, schema.MinimumItems); + model.MaximumItems = MathUtils.Min(model.MaximumItems, schema.MaximumItems); + model.PositionalItemsValidation = model.PositionalItemsValidation || schema.PositionalItemsValidation; + model.AllowAdditionalProperties = model.AllowAdditionalProperties && schema.AllowAdditionalProperties; + model.AllowAdditionalItems = model.AllowAdditionalItems && schema.AllowAdditionalItems; + model.UniqueItems = model.UniqueItems || schema.UniqueItems; + if (schema.Enum != null) + { + if (model.Enum == null) + model.Enum = new List(); + + model.Enum.AddRangeDistinct(schema.Enum, JToken.EqualityComparer); + } + model.Disallow = model.Disallow | (schema.Disallow ?? JsonSchemaType.None); + + if (schema.Pattern != null) + { + if (model.Patterns == null) + model.Patterns = new List(); + + model.Patterns.AddDistinct(schema.Pattern); + } + } } - - public static JsonSchemaModel Create(IList schemata) - { - JsonSchemaModel model = new JsonSchemaModel(); - - foreach (JsonSchema schema in schemata) - { - Combine(model, schema); - } - - return model; - } - - private static void Combine(JsonSchemaModel model, JsonSchema schema) - { - // Version 3 of the Draft JSON Schema has the default value of Not Required - model.Required = model.Required || (schema.Required ?? false); - model.Type = model.Type & (schema.Type ?? JsonSchemaType.Any); - - model.MinimumLength = MathUtils.Max(model.MinimumLength, schema.MinimumLength); - model.MaximumLength = MathUtils.Min(model.MaximumLength, schema.MaximumLength); - - // not sure what is the best way to combine divisibleBy - model.DivisibleBy = MathUtils.Max(model.DivisibleBy, schema.DivisibleBy); - - model.Minimum = MathUtils.Max(model.Minimum, schema.Minimum); - model.Maximum = MathUtils.Max(model.Maximum, schema.Maximum); - model.ExclusiveMinimum = model.ExclusiveMinimum || (schema.ExclusiveMinimum ?? false); - model.ExclusiveMaximum = model.ExclusiveMaximum || (schema.ExclusiveMaximum ?? false); - - model.MinimumItems = MathUtils.Max(model.MinimumItems, schema.MinimumItems); - model.MaximumItems = MathUtils.Min(model.MaximumItems, schema.MaximumItems); - model.PositionalItemsValidation = model.PositionalItemsValidation || schema.PositionalItemsValidation; - model.AllowAdditionalProperties = model.AllowAdditionalProperties && schema.AllowAdditionalProperties; - model.AllowAdditionalItems = model.AllowAdditionalItems && schema.AllowAdditionalItems; - model.UniqueItems = model.UniqueItems || schema.UniqueItems; - if (schema.Enum != null) - { - if (model.Enum == null) - model.Enum = new List(); - - model.Enum.AddRangeDistinct(schema.Enum, JToken.EqualityComparer); - } - model.Disallow = model.Disallow | (schema.Disallow ?? JsonSchemaType.None); - - if (schema.Pattern != null) - { - if (model.Patterns == null) - model.Patterns = new List(); - - model.Patterns.AddDistinct(schema.Pattern); - } - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Schema/JsonSchemaModelBuilder.cs b/Src/Newtonsoft.Json/Schema/JsonSchemaModelBuilder.cs index 19f8ea35..4f17e3aa 100644 --- a/Src/Newtonsoft.Json/Schema/JsonSchemaModelBuilder.cs +++ b/Src/Newtonsoft.Json/Schema/JsonSchemaModelBuilder.cs @@ -28,163 +28,164 @@ using System.Collections.Generic; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json.Schema { - internal class JsonSchemaModelBuilder - { - private JsonSchemaNodeCollection _nodes = new JsonSchemaNodeCollection(); - private Dictionary _nodeModels = new Dictionary(); - private JsonSchemaNode _node ; - - public JsonSchemaModel Build(JsonSchema schema) + internal class JsonSchemaModelBuilder { - _nodes = new JsonSchemaNodeCollection(); - _node = AddSchema(null, schema); + private JsonSchemaNodeCollection _nodes = new JsonSchemaNodeCollection(); + private Dictionary _nodeModels = new Dictionary(); + private JsonSchemaNode _node; - _nodeModels = new Dictionary(); - JsonSchemaModel model = BuildNodeModel(_node); - - return model; - } - - public JsonSchemaNode AddSchema(JsonSchemaNode existingNode, JsonSchema schema) - { - string newId; - if (existingNode != null) - { - if (existingNode.Schemas.Contains(schema)) - return existingNode; - - newId = JsonSchemaNode.GetId(existingNode.Schemas.Union(new[] { schema })); - } - else - { - newId = JsonSchemaNode.GetId(new[] { schema }); - } - - if (_nodes.Contains(newId)) - return _nodes[newId]; - - JsonSchemaNode currentNode = (existingNode != null) - ? existingNode.Combine(schema) - : new JsonSchemaNode(schema); - - _nodes.Add(currentNode); - - AddProperties(schema.Properties, currentNode.Properties); - - AddProperties(schema.PatternProperties, currentNode.PatternProperties); - - if (schema.Items != null) - { - for (int i = 0; i < schema.Items.Count; i++) + public JsonSchemaModel Build(JsonSchema schema) { - AddItem(currentNode, i, schema.Items[i]); + _nodes = new JsonSchemaNodeCollection(); + _node = AddSchema(null, schema); + + _nodeModels = new Dictionary(); + JsonSchemaModel model = BuildNodeModel(_node); + + return model; } - } - if (schema.AdditionalItems != null) - AddAdditionalItems(currentNode, schema.AdditionalItems); - - if (schema.AdditionalProperties != null) - AddAdditionalProperties(currentNode, schema.AdditionalProperties); - - if (schema.Extends != null) - { - foreach (JsonSchema jsonSchema in schema.Extends) + public JsonSchemaNode AddSchema(JsonSchemaNode existingNode, JsonSchema schema) { - currentNode = AddSchema(currentNode, jsonSchema); + string newId; + if (existingNode != null) + { + if (existingNode.Schemas.Contains(schema)) + return existingNode; + + newId = JsonSchemaNode.GetId(existingNode.Schemas.Union(new[] { schema })); + } + else + { + newId = JsonSchemaNode.GetId(new[] { schema }); + } + + if (_nodes.Contains(newId)) + return _nodes[newId]; + + JsonSchemaNode currentNode = (existingNode != null) + ? existingNode.Combine(schema) + : new JsonSchemaNode(schema); + + _nodes.Add(currentNode); + + AddProperties(schema.Properties, currentNode.Properties); + + AddProperties(schema.PatternProperties, currentNode.PatternProperties); + + if (schema.Items != null) + { + for (int i = 0; i < schema.Items.Count; i++) + { + AddItem(currentNode, i, schema.Items[i]); + } + } + + if (schema.AdditionalItems != null) + AddAdditionalItems(currentNode, schema.AdditionalItems); + + if (schema.AdditionalProperties != null) + AddAdditionalProperties(currentNode, schema.AdditionalProperties); + + if (schema.Extends != null) + { + foreach (JsonSchema jsonSchema in schema.Extends) + { + currentNode = AddSchema(currentNode, jsonSchema); + } + } + + return currentNode; } - } - return currentNode; - } - - public void AddProperties(IDictionary source, IDictionary target) - { - if (source != null) - { - foreach (KeyValuePair property in source) + public void AddProperties(IDictionary source, IDictionary target) { - AddProperty(target, property.Key, property.Value); + if (source != null) + { + foreach (KeyValuePair property in source) + { + AddProperty(target, property.Key, property.Value); + } + } + } + + public void AddProperty(IDictionary target, string propertyName, JsonSchema schema) + { + JsonSchemaNode propertyNode; + target.TryGetValue(propertyName, out propertyNode); + + target[propertyName] = AddSchema(propertyNode, schema); + } + + public void AddItem(JsonSchemaNode parentNode, int index, JsonSchema schema) + { + JsonSchemaNode existingItemNode = (parentNode.Items.Count > index) + ? parentNode.Items[index] + : null; + + JsonSchemaNode newItemNode = AddSchema(existingItemNode, schema); + + if (!(parentNode.Items.Count > index)) + { + parentNode.Items.Add(newItemNode); + } + else + { + parentNode.Items[index] = newItemNode; + } + } + + public void AddAdditionalProperties(JsonSchemaNode parentNode, JsonSchema schema) + { + parentNode.AdditionalProperties = AddSchema(parentNode.AdditionalProperties, schema); + } + + public void AddAdditionalItems(JsonSchemaNode parentNode, JsonSchema schema) + { + parentNode.AdditionalItems = AddSchema(parentNode.AdditionalItems, schema); + } + + private JsonSchemaModel BuildNodeModel(JsonSchemaNode node) + { + JsonSchemaModel model; + if (_nodeModels.TryGetValue(node, out model)) + return model; + + model = JsonSchemaModel.Create(node.Schemas); + _nodeModels[node] = model; + + foreach (KeyValuePair property in node.Properties) + { + if (model.Properties == null) + model.Properties = new Dictionary(); + + model.Properties[property.Key] = BuildNodeModel(property.Value); + } + foreach (KeyValuePair property in node.PatternProperties) + { + if (model.PatternProperties == null) + model.PatternProperties = new Dictionary(); + + model.PatternProperties[property.Key] = BuildNodeModel(property.Value); + } + foreach (JsonSchemaNode t in node.Items) + { + if (model.Items == null) + model.Items = new List(); + + model.Items.Add(BuildNodeModel(t)); + } + if (node.AdditionalProperties != null) + model.AdditionalProperties = BuildNodeModel(node.AdditionalProperties); + if (node.AdditionalItems != null) + model.AdditionalItems = BuildNodeModel(node.AdditionalItems); + + return model; } - } } - - public void AddProperty(IDictionary target, string propertyName, JsonSchema schema) - { - JsonSchemaNode propertyNode; - target.TryGetValue(propertyName, out propertyNode); - - target[propertyName] = AddSchema(propertyNode, schema); - } - - public void AddItem(JsonSchemaNode parentNode, int index, JsonSchema schema) - { - JsonSchemaNode existingItemNode = (parentNode.Items.Count > index) - ? parentNode.Items[index] - : null; - - JsonSchemaNode newItemNode = AddSchema(existingItemNode, schema); - - if (!(parentNode.Items.Count > index)) - { - parentNode.Items.Add(newItemNode); - } - else - { - parentNode.Items[index] = newItemNode; - } - } - - public void AddAdditionalProperties(JsonSchemaNode parentNode, JsonSchema schema) - { - parentNode.AdditionalProperties = AddSchema(parentNode.AdditionalProperties, schema); - } - - public void AddAdditionalItems(JsonSchemaNode parentNode, JsonSchema schema) - { - parentNode.AdditionalItems = AddSchema(parentNode.AdditionalItems, schema); - } - - private JsonSchemaModel BuildNodeModel(JsonSchemaNode node) - { - JsonSchemaModel model; - if (_nodeModels.TryGetValue(node, out model)) - return model; - - model = JsonSchemaModel.Create(node.Schemas); - _nodeModels[node] = model; - - foreach (KeyValuePair property in node.Properties) - { - if (model.Properties == null) - model.Properties = new Dictionary(); - - model.Properties[property.Key] = BuildNodeModel(property.Value); - } - foreach (KeyValuePair property in node.PatternProperties) - { - if (model.PatternProperties == null) - model.PatternProperties = new Dictionary(); - - model.PatternProperties[property.Key] = BuildNodeModel(property.Value); - } - foreach (JsonSchemaNode t in node.Items) - { - if (model.Items == null) - model.Items = new List(); - - model.Items.Add(BuildNodeModel(t)); - } - if (node.AdditionalProperties != null) - model.AdditionalProperties = BuildNodeModel(node.AdditionalProperties); - if (node.AdditionalItems != null) - model.AdditionalItems = BuildNodeModel(node.AdditionalItems); - - return model; - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Schema/JsonSchemaNode.cs b/Src/Newtonsoft.Json/Schema/JsonSchemaNode.cs index 2b75313d..3cd2c333 100644 --- a/Src/Newtonsoft.Json/Schema/JsonSchemaNode.cs +++ b/Src/Newtonsoft.Json/Schema/JsonSchemaNode.cs @@ -30,50 +30,51 @@ using System.Collections.ObjectModel; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json.Schema { - internal class JsonSchemaNode - { - public string Id { get; private set; } - public ReadOnlyCollection Schemas { get; private set; } - public Dictionary Properties { get; private set; } - public Dictionary PatternProperties { get; private set; } - public List Items { get; private set; } - public JsonSchemaNode AdditionalProperties { get; set; } - public JsonSchemaNode AdditionalItems { get; set; } - - public JsonSchemaNode(JsonSchema schema) + internal class JsonSchemaNode { - Schemas = new ReadOnlyCollection(new []{ schema }); - Properties = new Dictionary(); - PatternProperties = new Dictionary(); - Items = new List(); + public string Id { get; private set; } + public ReadOnlyCollection Schemas { get; private set; } + public Dictionary Properties { get; private set; } + public Dictionary PatternProperties { get; private set; } + public List Items { get; private set; } + public JsonSchemaNode AdditionalProperties { get; set; } + public JsonSchemaNode AdditionalItems { get; set; } - Id = GetId(Schemas); + public JsonSchemaNode(JsonSchema schema) + { + Schemas = new ReadOnlyCollection(new[] { schema }); + Properties = new Dictionary(); + PatternProperties = new Dictionary(); + Items = new List(); + + Id = GetId(Schemas); + } + + private JsonSchemaNode(JsonSchemaNode source, JsonSchema schema) + { + Schemas = new ReadOnlyCollection(source.Schemas.Union(new[] { schema }).ToList()); + Properties = new Dictionary(source.Properties); + PatternProperties = new Dictionary(source.PatternProperties); + Items = new List(source.Items); + AdditionalProperties = source.AdditionalProperties; + AdditionalItems = source.AdditionalItems; + + Id = GetId(Schemas); + } + + public JsonSchemaNode Combine(JsonSchema schema) + { + return new JsonSchemaNode(this, schema); + } + + public static string GetId(IEnumerable schemata) + { + return string.Join("-", schemata.Select(s => s.InternalId).OrderBy(id => id, StringComparer.Ordinal).ToArray()); + } } - - private JsonSchemaNode(JsonSchemaNode source, JsonSchema schema) - { - Schemas = new ReadOnlyCollection(source.Schemas.Union(new[] { schema }).ToList()); - Properties = new Dictionary(source.Properties); - PatternProperties = new Dictionary(source.PatternProperties); - Items = new List(source.Items); - AdditionalProperties = source.AdditionalProperties; - AdditionalItems = source.AdditionalItems; - - Id = GetId(Schemas); - } - - public JsonSchemaNode Combine(JsonSchema schema) - { - return new JsonSchemaNode(this, schema); - } - - public static string GetId(IEnumerable schemata) - { - return string.Join("-", schemata.Select(s => s.InternalId).OrderBy(id => id, StringComparer.Ordinal).ToArray()); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Schema/JsonSchemaNodeCollection.cs b/Src/Newtonsoft.Json/Schema/JsonSchemaNodeCollection.cs index 5f2ef01e..008919a8 100644 --- a/Src/Newtonsoft.Json/Schema/JsonSchemaNodeCollection.cs +++ b/Src/Newtonsoft.Json/Schema/JsonSchemaNodeCollection.cs @@ -27,11 +27,11 @@ using System.Collections.ObjectModel; namespace Newtonsoft.Json.Schema { - internal class JsonSchemaNodeCollection : KeyedCollection - { - protected override string GetKeyForItem(JsonSchemaNode item) + internal class JsonSchemaNodeCollection : KeyedCollection { - return item.Id; + protected override string GetKeyForItem(JsonSchemaNode item) + { + return item.Id; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Schema/JsonSchemaResolver.cs b/Src/Newtonsoft.Json/Schema/JsonSchemaResolver.cs index 14b16f2d..d38121d6 100644 --- a/Src/Newtonsoft.Json/Schema/JsonSchemaResolver.cs +++ b/Src/Newtonsoft.Json/Schema/JsonSchemaResolver.cs @@ -29,42 +29,43 @@ using System.Collections.Generic; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json.Schema { - /// - /// Resolves from an id. - /// - public class JsonSchemaResolver - { /// - /// Gets or sets the loaded schemas. + /// Resolves from an id. /// - /// The loaded schemas. - public IList LoadedSchemas { get; protected set; } - - /// - /// Initializes a new instance of the class. - /// - public JsonSchemaResolver() + public class JsonSchemaResolver { - LoadedSchemas = new List(); + /// + /// Gets or sets the loaded schemas. + /// + /// The loaded schemas. + public IList LoadedSchemas { get; protected set; } + + /// + /// Initializes a new instance of the class. + /// + public JsonSchemaResolver() + { + LoadedSchemas = new List(); + } + + /// + /// Gets a for the specified reference. + /// + /// The id. + /// A for the specified reference. + public virtual JsonSchema GetSchema(string reference) + { + JsonSchema schema = LoadedSchemas.SingleOrDefault(s => string.Equals(s.Id, reference, StringComparison.Ordinal)); + + if (schema == null) + schema = LoadedSchemas.SingleOrDefault(s => string.Equals(s.Location, reference, StringComparison.Ordinal)); + + return schema; + } } - - /// - /// Gets a for the specified reference. - /// - /// The id. - /// A for the specified reference. - public virtual JsonSchema GetSchema(string reference) - { - JsonSchema schema = LoadedSchemas.SingleOrDefault(s => string.Equals(s.Id, reference, StringComparison.Ordinal)); - - if (schema == null) - schema = LoadedSchemas.SingleOrDefault(s => string.Equals(s.Location, reference, StringComparison.Ordinal)); - - return schema; - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Schema/JsonSchemaType.cs b/Src/Newtonsoft.Json/Schema/JsonSchemaType.cs index 160a4fcf..5b32805d 100644 --- a/Src/Newtonsoft.Json/Schema/JsonSchemaType.cs +++ b/Src/Newtonsoft.Json/Schema/JsonSchemaType.cs @@ -27,47 +27,55 @@ using System; namespace Newtonsoft.Json.Schema { - /// - /// The value types allowed by the . - /// - [Flags] - public enum JsonSchemaType - { /// - /// No type specified. + /// The value types allowed by the . /// - None = 0, - /// - /// String type. - /// - String = 1, - /// - /// Float type. - /// - Float = 2, - /// - /// Integer type. - /// - Integer = 4, - /// - /// Boolean type. - /// - Boolean = 8, - /// - /// Object type. - /// - Object = 16, - /// - /// Array type. - /// - Array = 32, - /// - /// Null type. - /// - Null = 64, - /// - /// Any type. - /// - Any = String | Float | Integer | Boolean | Object | Array | Null - } + [Flags] + public enum JsonSchemaType + { + /// + /// No type specified. + /// + None = 0, + + /// + /// String type. + /// + String = 1, + + /// + /// Float type. + /// + Float = 2, + + /// + /// Integer type. + /// + Integer = 4, + + /// + /// Boolean type. + /// + Boolean = 8, + + /// + /// Object type. + /// + Object = 16, + + /// + /// Array type. + /// + Array = 32, + + /// + /// Null type. + /// + Null = 64, + + /// + /// Any type. + /// + Any = String | Float | Integer | Boolean | Object | Array | Null + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Schema/JsonSchemaWriter.cs b/Src/Newtonsoft.Json/Schema/JsonSchemaWriter.cs index 5d486423..2ca437cc 100644 --- a/Src/Newtonsoft.Json/Schema/JsonSchemaWriter.cs +++ b/Src/Newtonsoft.Json/Schema/JsonSchemaWriter.cs @@ -30,212 +30,213 @@ using Newtonsoft.Json.Utilities; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json.Schema { - internal class JsonSchemaWriter - { - private readonly JsonWriter _writer; - private readonly JsonSchemaResolver _resolver; - - public JsonSchemaWriter(JsonWriter writer, JsonSchemaResolver resolver) + internal class JsonSchemaWriter { - ValidationUtils.ArgumentNotNull(writer, "writer"); - _writer = writer; - _resolver = resolver; + private readonly JsonWriter _writer; + private readonly JsonSchemaResolver _resolver; + + public JsonSchemaWriter(JsonWriter writer, JsonSchemaResolver resolver) + { + ValidationUtils.ArgumentNotNull(writer, "writer"); + _writer = writer; + _resolver = resolver; + } + + private void ReferenceOrWriteSchema(JsonSchema schema) + { + if (schema.Id != null && _resolver.GetSchema(schema.Id) != null) + { + _writer.WriteStartObject(); + _writer.WritePropertyName(JsonSchemaConstants.ReferencePropertyName); + _writer.WriteValue(schema.Id); + _writer.WriteEndObject(); + } + else + { + WriteSchema(schema); + } + } + + public void WriteSchema(JsonSchema schema) + { + ValidationUtils.ArgumentNotNull(schema, "schema"); + + if (!_resolver.LoadedSchemas.Contains(schema)) + _resolver.LoadedSchemas.Add(schema); + + _writer.WriteStartObject(); + WritePropertyIfNotNull(_writer, JsonSchemaConstants.IdPropertyName, schema.Id); + WritePropertyIfNotNull(_writer, JsonSchemaConstants.TitlePropertyName, schema.Title); + WritePropertyIfNotNull(_writer, JsonSchemaConstants.DescriptionPropertyName, schema.Description); + WritePropertyIfNotNull(_writer, JsonSchemaConstants.RequiredPropertyName, schema.Required); + WritePropertyIfNotNull(_writer, JsonSchemaConstants.ReadOnlyPropertyName, schema.ReadOnly); + WritePropertyIfNotNull(_writer, JsonSchemaConstants.HiddenPropertyName, schema.Hidden); + WritePropertyIfNotNull(_writer, JsonSchemaConstants.TransientPropertyName, schema.Transient); + if (schema.Type != null) + WriteType(JsonSchemaConstants.TypePropertyName, _writer, schema.Type.Value); + if (!schema.AllowAdditionalProperties) + { + _writer.WritePropertyName(JsonSchemaConstants.AdditionalPropertiesPropertyName); + _writer.WriteValue(schema.AllowAdditionalProperties); + } + else + { + if (schema.AdditionalProperties != null) + { + _writer.WritePropertyName(JsonSchemaConstants.AdditionalPropertiesPropertyName); + ReferenceOrWriteSchema(schema.AdditionalProperties); + } + } + if (!schema.AllowAdditionalItems) + { + _writer.WritePropertyName(JsonSchemaConstants.AdditionalItemsPropertyName); + _writer.WriteValue(schema.AllowAdditionalItems); + } + else + { + if (schema.AdditionalItems != null) + { + _writer.WritePropertyName(JsonSchemaConstants.AdditionalItemsPropertyName); + ReferenceOrWriteSchema(schema.AdditionalItems); + } + } + WriteSchemaDictionaryIfNotNull(_writer, JsonSchemaConstants.PropertiesPropertyName, schema.Properties); + WriteSchemaDictionaryIfNotNull(_writer, JsonSchemaConstants.PatternPropertiesPropertyName, schema.PatternProperties); + WriteItems(schema); + WritePropertyIfNotNull(_writer, JsonSchemaConstants.MinimumPropertyName, schema.Minimum); + WritePropertyIfNotNull(_writer, JsonSchemaConstants.MaximumPropertyName, schema.Maximum); + WritePropertyIfNotNull(_writer, JsonSchemaConstants.ExclusiveMinimumPropertyName, schema.ExclusiveMinimum); + WritePropertyIfNotNull(_writer, JsonSchemaConstants.ExclusiveMaximumPropertyName, schema.ExclusiveMaximum); + WritePropertyIfNotNull(_writer, JsonSchemaConstants.MinimumLengthPropertyName, schema.MinimumLength); + WritePropertyIfNotNull(_writer, JsonSchemaConstants.MaximumLengthPropertyName, schema.MaximumLength); + WritePropertyIfNotNull(_writer, JsonSchemaConstants.MinimumItemsPropertyName, schema.MinimumItems); + WritePropertyIfNotNull(_writer, JsonSchemaConstants.MaximumItemsPropertyName, schema.MaximumItems); + WritePropertyIfNotNull(_writer, JsonSchemaConstants.DivisibleByPropertyName, schema.DivisibleBy); + WritePropertyIfNotNull(_writer, JsonSchemaConstants.FormatPropertyName, schema.Format); + WritePropertyIfNotNull(_writer, JsonSchemaConstants.PatternPropertyName, schema.Pattern); + if (schema.Enum != null) + { + _writer.WritePropertyName(JsonSchemaConstants.EnumPropertyName); + _writer.WriteStartArray(); + foreach (JToken token in schema.Enum) + { + token.WriteTo(_writer); + } + _writer.WriteEndArray(); + } + if (schema.Default != null) + { + _writer.WritePropertyName(JsonSchemaConstants.DefaultPropertyName); + schema.Default.WriteTo(_writer); + } + if (schema.Disallow != null) + WriteType(JsonSchemaConstants.DisallowPropertyName, _writer, schema.Disallow.Value); + if (schema.Extends != null && schema.Extends.Count > 0) + { + _writer.WritePropertyName(JsonSchemaConstants.ExtendsPropertyName); + if (schema.Extends.Count == 1) + { + ReferenceOrWriteSchema(schema.Extends[0]); + } + else + { + _writer.WriteStartArray(); + foreach (JsonSchema jsonSchema in schema.Extends) + { + ReferenceOrWriteSchema(jsonSchema); + } + _writer.WriteEndArray(); + } + } + _writer.WriteEndObject(); + } + + private void WriteSchemaDictionaryIfNotNull(JsonWriter writer, string propertyName, IDictionary properties) + { + if (properties != null) + { + writer.WritePropertyName(propertyName); + writer.WriteStartObject(); + foreach (KeyValuePair property in properties) + { + writer.WritePropertyName(property.Key); + ReferenceOrWriteSchema(property.Value); + } + writer.WriteEndObject(); + } + } + + private void WriteItems(JsonSchema schema) + { + if (schema.Items == null && !schema.PositionalItemsValidation) + return; + + _writer.WritePropertyName(JsonSchemaConstants.ItemsPropertyName); + + if (!schema.PositionalItemsValidation) + { + if (schema.Items != null && schema.Items.Count > 0) + { + ReferenceOrWriteSchema(schema.Items[0]); + } + else + { + _writer.WriteStartObject(); + _writer.WriteEndObject(); + } + return; + } + + _writer.WriteStartArray(); + if (schema.Items != null) + { + foreach (JsonSchema itemSchema in schema.Items) + { + ReferenceOrWriteSchema(itemSchema); + } + } + _writer.WriteEndArray(); + } + + private void WriteType(string propertyName, JsonWriter writer, JsonSchemaType type) + { + IList types; + if (System.Enum.IsDefined(typeof(JsonSchemaType), type)) + types = new List { type }; + else + types = EnumUtils.GetFlagsValues(type).Where(v => v != JsonSchemaType.None).ToList(); + + if (types.Count == 0) + return; + + writer.WritePropertyName(propertyName); + + if (types.Count == 1) + { + writer.WriteValue(JsonSchemaBuilder.MapType(types[0])); + return; + } + + writer.WriteStartArray(); + foreach (JsonSchemaType jsonSchemaType in types) + { + writer.WriteValue(JsonSchemaBuilder.MapType(jsonSchemaType)); + } + writer.WriteEndArray(); + } + + private void WritePropertyIfNotNull(JsonWriter writer, string propertyName, object value) + { + if (value != null) + { + writer.WritePropertyName(propertyName); + writer.WriteValue(value); + } + } } - - private void ReferenceOrWriteSchema(JsonSchema schema) - { - if (schema.Id != null && _resolver.GetSchema(schema.Id) != null) - { - _writer.WriteStartObject(); - _writer.WritePropertyName(JsonSchemaConstants.ReferencePropertyName); - _writer.WriteValue(schema.Id); - _writer.WriteEndObject(); - } - else - { - WriteSchema(schema); - } - } - - public void WriteSchema(JsonSchema schema) - { - ValidationUtils.ArgumentNotNull(schema, "schema"); - - if (!_resolver.LoadedSchemas.Contains(schema)) - _resolver.LoadedSchemas.Add(schema); - - _writer.WriteStartObject(); - WritePropertyIfNotNull(_writer, JsonSchemaConstants.IdPropertyName, schema.Id); - WritePropertyIfNotNull(_writer, JsonSchemaConstants.TitlePropertyName, schema.Title); - WritePropertyIfNotNull(_writer, JsonSchemaConstants.DescriptionPropertyName, schema.Description); - WritePropertyIfNotNull(_writer, JsonSchemaConstants.RequiredPropertyName, schema.Required); - WritePropertyIfNotNull(_writer, JsonSchemaConstants.ReadOnlyPropertyName, schema.ReadOnly); - WritePropertyIfNotNull(_writer, JsonSchemaConstants.HiddenPropertyName, schema.Hidden); - WritePropertyIfNotNull(_writer, JsonSchemaConstants.TransientPropertyName, schema.Transient); - if (schema.Type != null) - WriteType(JsonSchemaConstants.TypePropertyName, _writer, schema.Type.Value); - if (!schema.AllowAdditionalProperties) - { - _writer.WritePropertyName(JsonSchemaConstants.AdditionalPropertiesPropertyName); - _writer.WriteValue(schema.AllowAdditionalProperties); - } - else - { - if (schema.AdditionalProperties != null) - { - _writer.WritePropertyName(JsonSchemaConstants.AdditionalPropertiesPropertyName); - ReferenceOrWriteSchema(schema.AdditionalProperties); - } - } - if (!schema.AllowAdditionalItems) - { - _writer.WritePropertyName(JsonSchemaConstants.AdditionalItemsPropertyName); - _writer.WriteValue(schema.AllowAdditionalItems); - } - else - { - if (schema.AdditionalItems != null) - { - _writer.WritePropertyName(JsonSchemaConstants.AdditionalItemsPropertyName); - ReferenceOrWriteSchema(schema.AdditionalItems); - } - } - WriteSchemaDictionaryIfNotNull(_writer, JsonSchemaConstants.PropertiesPropertyName, schema.Properties); - WriteSchemaDictionaryIfNotNull(_writer, JsonSchemaConstants.PatternPropertiesPropertyName, schema.PatternProperties); - WriteItems(schema); - WritePropertyIfNotNull(_writer, JsonSchemaConstants.MinimumPropertyName, schema.Minimum); - WritePropertyIfNotNull(_writer, JsonSchemaConstants.MaximumPropertyName, schema.Maximum); - WritePropertyIfNotNull(_writer, JsonSchemaConstants.ExclusiveMinimumPropertyName, schema.ExclusiveMinimum); - WritePropertyIfNotNull(_writer, JsonSchemaConstants.ExclusiveMaximumPropertyName, schema.ExclusiveMaximum); - WritePropertyIfNotNull(_writer, JsonSchemaConstants.MinimumLengthPropertyName, schema.MinimumLength); - WritePropertyIfNotNull(_writer, JsonSchemaConstants.MaximumLengthPropertyName, schema.MaximumLength); - WritePropertyIfNotNull(_writer, JsonSchemaConstants.MinimumItemsPropertyName, schema.MinimumItems); - WritePropertyIfNotNull(_writer, JsonSchemaConstants.MaximumItemsPropertyName, schema.MaximumItems); - WritePropertyIfNotNull(_writer, JsonSchemaConstants.DivisibleByPropertyName, schema.DivisibleBy); - WritePropertyIfNotNull(_writer, JsonSchemaConstants.FormatPropertyName, schema.Format); - WritePropertyIfNotNull(_writer, JsonSchemaConstants.PatternPropertyName, schema.Pattern); - if (schema.Enum != null) - { - _writer.WritePropertyName(JsonSchemaConstants.EnumPropertyName); - _writer.WriteStartArray(); - foreach (JToken token in schema.Enum) - { - token.WriteTo(_writer); - } - _writer.WriteEndArray(); - } - if (schema.Default != null) - { - _writer.WritePropertyName(JsonSchemaConstants.DefaultPropertyName); - schema.Default.WriteTo(_writer); - } - if (schema.Disallow != null) - WriteType(JsonSchemaConstants.DisallowPropertyName, _writer, schema.Disallow.Value); - if (schema.Extends != null && schema.Extends.Count > 0) - { - _writer.WritePropertyName(JsonSchemaConstants.ExtendsPropertyName); - if (schema.Extends.Count == 1) - { - ReferenceOrWriteSchema(schema.Extends[0]); - } - else - { - _writer.WriteStartArray(); - foreach (JsonSchema jsonSchema in schema.Extends) - { - ReferenceOrWriteSchema(jsonSchema); - } - _writer.WriteEndArray(); - } - } - _writer.WriteEndObject(); - } - - private void WriteSchemaDictionaryIfNotNull(JsonWriter writer, string propertyName, IDictionary properties) - { - if (properties != null) - { - writer.WritePropertyName(propertyName); - writer.WriteStartObject(); - foreach (KeyValuePair property in properties) - { - writer.WritePropertyName(property.Key); - ReferenceOrWriteSchema(property.Value); - } - writer.WriteEndObject(); - } - } - - private void WriteItems(JsonSchema schema) - { - if (schema.Items == null && !schema.PositionalItemsValidation) - return; - - _writer.WritePropertyName(JsonSchemaConstants.ItemsPropertyName); - - if (!schema.PositionalItemsValidation) - { - if (schema.Items != null && schema.Items.Count > 0) - { - ReferenceOrWriteSchema(schema.Items[0]); - } - else - { - _writer.WriteStartObject(); - _writer.WriteEndObject(); - } - return; - } - - _writer.WriteStartArray(); - if (schema.Items != null) - { - foreach (JsonSchema itemSchema in schema.Items) - { - ReferenceOrWriteSchema(itemSchema); - } - } - _writer.WriteEndArray(); - } - - private void WriteType(string propertyName, JsonWriter writer, JsonSchemaType type) - { - IList types; - if (System.Enum.IsDefined(typeof(JsonSchemaType), type)) - types = new List { type }; - else - types = EnumUtils.GetFlagsValues(type).Where(v => v != JsonSchemaType.None).ToList(); - - if (types.Count == 0) - return; - - writer.WritePropertyName(propertyName); - - if (types.Count == 1) - { - writer.WriteValue(JsonSchemaBuilder.MapType(types[0])); - return; - } - - writer.WriteStartArray(); - foreach (JsonSchemaType jsonSchemaType in types) - { - writer.WriteValue(JsonSchemaBuilder.MapType(jsonSchemaType)); - } - writer.WriteEndArray(); - } - - private void WritePropertyIfNotNull(JsonWriter writer, string propertyName, object value) - { - if (value != null) - { - writer.WritePropertyName(propertyName); - writer.WriteValue(value); - } - } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Schema/UndefinedSchemaIdHandling.cs b/Src/Newtonsoft.Json/Schema/UndefinedSchemaIdHandling.cs index 34bbbee5..43c76536 100644 --- a/Src/Newtonsoft.Json/Schema/UndefinedSchemaIdHandling.cs +++ b/Src/Newtonsoft.Json/Schema/UndefinedSchemaIdHandling.cs @@ -25,22 +25,24 @@ namespace Newtonsoft.Json.Schema { - /// - /// Specifies undefined schema Id handling options for the . - /// - public enum UndefinedSchemaIdHandling - { /// - /// Do not infer a schema Id. + /// Specifies undefined schema Id handling options for the . /// - None = 0, - /// - /// Use the .NET type name as the schema Id. - /// - UseTypeName = 1, - /// - /// Use the assembly qualified .NET type name as the schema Id. - /// - UseAssemblyQualifiedName = 2, - } + public enum UndefinedSchemaIdHandling + { + /// + /// Do not infer a schema Id. + /// + None = 0, + + /// + /// Use the .NET type name as the schema Id. + /// + UseTypeName = 1, + + /// + /// Use the assembly qualified .NET type name as the schema Id. + /// + UseAssemblyQualifiedName = 2, + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Schema/ValidationEventArgs.cs b/Src/Newtonsoft.Json/Schema/ValidationEventArgs.cs index b6b94f21..86173a9a 100644 --- a/Src/Newtonsoft.Json/Schema/ValidationEventArgs.cs +++ b/Src/Newtonsoft.Json/Schema/ValidationEventArgs.cs @@ -28,44 +28,44 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Schema { - /// - /// Returns detailed information related to the . - /// - public class ValidationEventArgs : EventArgs - { - private readonly JsonSchemaException _ex; - - internal ValidationEventArgs(JsonSchemaException ex) - { - ValidationUtils.ArgumentNotNull(ex, "ex"); - _ex = ex; - } - /// - /// Gets the associated with the validation error. + /// Returns detailed information related to the . /// - /// The JsonSchemaException associated with the validation error. - public JsonSchemaException Exception + public class ValidationEventArgs : EventArgs { - get { return _ex; } - } + private readonly JsonSchemaException _ex; - /// - /// Gets the path of the JSON location where the validation error occurred. - /// - /// The path of the JSON location where the validation error occurred. - public string Path - { - get { return _ex.Path; } - } + internal ValidationEventArgs(JsonSchemaException ex) + { + ValidationUtils.ArgumentNotNull(ex, "ex"); + _ex = ex; + } - /// - /// Gets the text description corresponding to the validation error. - /// - /// The text description. - public string Message - { - get { return _ex.Message; } + /// + /// Gets the associated with the validation error. + /// + /// The JsonSchemaException associated with the validation error. + public JsonSchemaException Exception + { + get { return _ex; } + } + + /// + /// Gets the path of the JSON location where the validation error occurred. + /// + /// The path of the JSON location where the validation error occurred. + public string Path + { + get { return _ex.Path; } + } + + /// + /// Gets the text description corresponding to the validation error. + /// + /// The text description. + public string Message + { + get { return _ex.Message; } + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Schema/ValidationEventHandler.cs b/Src/Newtonsoft.Json/Schema/ValidationEventHandler.cs index 95d213d4..80294f13 100644 --- a/Src/Newtonsoft.Json/Schema/ValidationEventHandler.cs +++ b/Src/Newtonsoft.Json/Schema/ValidationEventHandler.cs @@ -25,8 +25,8 @@ namespace Newtonsoft.Json.Schema { - /// - /// Represents the callback method that will handle JSON schema validation events and the . - /// - public delegate void ValidationEventHandler(object sender, ValidationEventArgs e); + /// + /// Represents the callback method that will handle JSON schema validation events and the . + /// + public delegate void ValidationEventHandler(object sender, ValidationEventArgs e); } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/CachedAttributeGetter.cs b/Src/Newtonsoft.Json/Serialization/CachedAttributeGetter.cs index c216ce53..0645631d 100644 --- a/Src/Newtonsoft.Json/Serialization/CachedAttributeGetter.cs +++ b/Src/Newtonsoft.Json/Serialization/CachedAttributeGetter.cs @@ -29,13 +29,13 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Serialization { - internal static class CachedAttributeGetter where T : Attribute - { - private static readonly ThreadSafeStore TypeAttributeCache = new ThreadSafeStore(JsonTypeReflector.GetAttribute); - - public static T GetAttribute(object type) + internal static class CachedAttributeGetter where T : Attribute { - return TypeAttributeCache.Get(type); + private static readonly ThreadSafeStore TypeAttributeCache = new ThreadSafeStore(JsonTypeReflector.GetAttribute); + + public static T GetAttribute(object type) + { + return TypeAttributeCache.Get(type); + } } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/CamelCasePropertyNamesContractResolver.cs b/Src/Newtonsoft.Json/Serialization/CamelCasePropertyNamesContractResolver.cs index e853ec1e..bbeb23de 100644 --- a/Src/Newtonsoft.Json/Serialization/CamelCasePropertyNamesContractResolver.cs +++ b/Src/Newtonsoft.Json/Serialization/CamelCasePropertyNamesContractResolver.cs @@ -28,28 +28,28 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Serialization { - /// - /// Resolves member mappings for a type, camel casing property names. - /// - public class CamelCasePropertyNamesContractResolver : DefaultContractResolver - { /// - /// Initializes a new instance of the class. + /// Resolves member mappings for a type, camel casing property names. /// - public CamelCasePropertyNamesContractResolver() - : base(true) + public class CamelCasePropertyNamesContractResolver : DefaultContractResolver { - } + /// + /// Initializes a new instance of the class. + /// + public CamelCasePropertyNamesContractResolver() + : base(true) + { + } - /// - /// Resolves the name of the property. - /// - /// Name of the property. - /// The property name camel cased. - protected internal override string ResolvePropertyName(string propertyName) - { - // lower case the first letter of the passed in name - return StringUtils.ToCamelCase(propertyName); + /// + /// Resolves the name of the property. + /// + /// Name of the property. + /// The property name camel cased. + protected internal override string ResolvePropertyName(string propertyName) + { + // lower case the first letter of the passed in name + return StringUtils.ToCamelCase(propertyName); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs index 0ac1470a..e02de4f3 100644 --- a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs +++ b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs @@ -48,1277 +48,1280 @@ using System.Runtime.CompilerServices; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json.Serialization { - internal struct ResolverContractKey : IEquatable - { - private readonly Type _resolverType; - private readonly Type _contractType; - - public ResolverContractKey(Type resolverType, Type contractType) + internal struct ResolverContractKey : IEquatable { - _resolverType = resolverType; - _contractType = contractType; + private readonly Type _resolverType; + private readonly Type _contractType; + + public ResolverContractKey(Type resolverType, Type contractType) + { + _resolverType = resolverType; + _contractType = contractType; + } + + public override int GetHashCode() + { + return _resolverType.GetHashCode() ^ _contractType.GetHashCode(); + } + + public override bool Equals(object obj) + { + if (!(obj is ResolverContractKey)) + return false; + + return Equals((ResolverContractKey)obj); + } + + public bool Equals(ResolverContractKey other) + { + return (_resolverType == other._resolverType && _contractType == other._contractType); + } } - public override int GetHashCode() + /// + /// Used by to resolves a for a given . + /// + public class DefaultContractResolver : IContractResolver { - return _resolverType.GetHashCode() ^ _contractType.GetHashCode(); - } + private static readonly IContractResolver _instance = new DefaultContractResolver(true); - public override bool Equals(object obj) - { - if (!(obj is ResolverContractKey)) - return false; + internal static IContractResolver Instance + { + get { return _instance; } + } - return Equals((ResolverContractKey)obj); - } - - public bool Equals(ResolverContractKey other) - { - return (_resolverType == other._resolverType && _contractType == other._contractType); - } - } - - /// - /// Used by to resolves a for a given . - /// - public class DefaultContractResolver : IContractResolver - { - private static readonly IContractResolver _instance = new DefaultContractResolver(true); - internal static IContractResolver Instance - { - get { return _instance; } - } - private static readonly IList BuiltInConverters = new List - { + private static readonly IList BuiltInConverters = new List + { #if !(SILVERLIGHT || NET20 || NETFX_CORE || PORTABLE40 || PORTABLE) - new EntityKeyMemberConverter(), + new EntityKeyMemberConverter(), #endif #if !(NET35 || NET20 || PORTABLE40) - new ExpandoObjectConverter(), + new ExpandoObjectConverter(), #endif #if (!(SILVERLIGHT || PORTABLE40) || WINDOWS_PHONE) - new XmlNodeConverter(), + new XmlNodeConverter(), #endif #if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) - new BinaryConverter(), - new DataSetConverter(), - new DataTableConverter(), + new BinaryConverter(), + new DataSetConverter(), + new DataTableConverter(), #endif #if NETFX_CORE new JsonValueConverter(), #endif - new KeyValuePairConverter(), - new BsonObjectIdConverter(), - new RegexConverter() - }; + new KeyValuePairConverter(), + new BsonObjectIdConverter(), + new RegexConverter() + }; - private static Dictionary _sharedContractCache; - private static readonly object _typeContractCacheLock = new object(); + private static Dictionary _sharedContractCache; + private static readonly object _typeContractCacheLock = new object(); - private Dictionary _instanceContractCache; - private readonly bool _sharedCache; + private Dictionary _instanceContractCache; + private readonly bool _sharedCache; - /// - /// Gets a value indicating whether members are being get and set using dynamic code generation. - /// This value is determined by the runtime permissions available. - /// - /// - /// true if using dynamic code generation; otherwise, false. - /// - public bool DynamicCodeGeneration - { - get { return JsonTypeReflector.DynamicCodeGeneration; } - } + /// + /// Gets a value indicating whether members are being get and set using dynamic code generation. + /// This value is determined by the runtime permissions available. + /// + /// + /// true if using dynamic code generation; otherwise, false. + /// + public bool DynamicCodeGeneration + { + get { return JsonTypeReflector.DynamicCodeGeneration; } + } #if !(NETFX_CORE || PORTABLE) - /// - /// Gets or sets the default members search flags. - /// - /// The default members search flags. - public BindingFlags DefaultMembersSearchFlags { get; set; } + /// + /// Gets or sets the default members search flags. + /// + /// The default members search flags. + public BindingFlags DefaultMembersSearchFlags { get; set; } #else private BindingFlags DefaultMembersSearchFlags = BindingFlags.Instance | BindingFlags.Public; #endif - /// - /// Gets or sets a value indicating whether compiler generated members should be serialized. - /// - /// - /// true if serialized compiler generated members; otherwise, false. - /// - public bool SerializeCompilerGeneratedMembers { get; set; } + /// + /// Gets or sets a value indicating whether compiler generated members should be serialized. + /// + /// + /// true if serialized compiler generated members; otherwise, false. + /// + public bool SerializeCompilerGeneratedMembers { get; set; } #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - /// - /// Gets or sets a value indicating whether to ignore the interface when serializing and deserializing types. - /// - /// - /// true if the interface will be ignored when serializing and deserializing types; otherwise, false. - /// - public bool IgnoreSerializableInterface { get; set; } + /// + /// Gets or sets a value indicating whether to ignore the interface when serializing and deserializing types. + /// + /// + /// true if the interface will be ignored when serializing and deserializing types; otherwise, false. + /// + public bool IgnoreSerializableInterface { get; set; } - /// - /// Gets or sets a value indicating whether to ignore the attribute when serializing and deserializing types. - /// - /// - /// true if the attribute will be ignored when serializing and deserializing types; otherwise, false. - /// - public bool IgnoreSerializableAttribute { get; set; } + /// + /// Gets or sets a value indicating whether to ignore the attribute when serializing and deserializing types. + /// + /// + /// true if the attribute will be ignored when serializing and deserializing types; otherwise, false. + /// + public bool IgnoreSerializableAttribute { get; set; } #endif - /// - /// Initializes a new instance of the class. - /// - public DefaultContractResolver() - : this(false) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// If set to true the will use a cached shared with other resolvers of the same type. - /// Sharing the cache will significantly performance because expensive reflection will only happen once but could cause unexpected - /// behavior if different instances of the resolver are suppose to produce different results. When set to false it is highly - /// recommended to reuse instances with the . - /// - public DefaultContractResolver(bool shareCache) - { -#if !NETFX_CORE - DefaultMembersSearchFlags = BindingFlags.Public | BindingFlags.Instance; -#endif -#if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - IgnoreSerializableAttribute = true; -#endif - - _sharedCache = shareCache; - } - - private Dictionary GetCache() - { - if (_sharedCache) - return _sharedContractCache; - else - return _instanceContractCache; - } - - private void UpdateCache(Dictionary cache) - { - if (_sharedCache) - _sharedContractCache = cache; - else - _instanceContractCache = cache; - } - - /// - /// Resolves the contract for a given type. - /// - /// The type to resolve a contract for. - /// The contract for a given type. - public virtual JsonContract ResolveContract(Type type) - { - if (type == null) - throw new ArgumentNullException("type"); - - JsonContract contract; - ResolverContractKey key = new ResolverContractKey(GetType(), type); - Dictionary cache = GetCache(); - if (cache == null || !cache.TryGetValue(key, out contract)) - { - contract = CreateContract(type); - - // avoid the possibility of modifying the cache dictionary while another thread is accessing it - lock (_typeContractCacheLock) + /// + /// Initializes a new instance of the class. + /// + public DefaultContractResolver() + : this(false) { - cache = GetCache(); - Dictionary updatedCache = - (cache != null) - ? new Dictionary(cache) - : new Dictionary(); - updatedCache[key] = contract; - - UpdateCache(updatedCache); } - } - return contract; - } - - /// - /// Gets the serializable members for the type. - /// - /// The type to get serializable members for. - /// The serializable members for the type. - protected virtual List GetSerializableMembers(Type objectType) - { - bool ignoreSerializableAttribute; -#if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - ignoreSerializableAttribute = IgnoreSerializableAttribute; -#else - ignoreSerializableAttribute = true; -#endif - - MemberSerialization memberSerialization = JsonTypeReflector.GetObjectMemberSerialization(objectType, ignoreSerializableAttribute); - - List allMembers = ReflectionUtils.GetFieldsAndProperties(objectType, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static) - .Where(m => !ReflectionUtils.IsIndexedProperty(m)).ToList(); - - List serializableMembers = new List(); - - if (memberSerialization != MemberSerialization.Fields) - { -#if !NET20 - DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(objectType); -#endif - - List defaultMembers = ReflectionUtils.GetFieldsAndProperties(objectType, DefaultMembersSearchFlags) - .Where(m => !ReflectionUtils.IsIndexedProperty(m)).ToList(); - - foreach (MemberInfo member in allMembers) + /// + /// Initializes a new instance of the class. + /// + /// + /// If set to true the will use a cached shared with other resolvers of the same type. + /// Sharing the cache will significantly performance because expensive reflection will only happen once but could cause unexpected + /// behavior if different instances of the resolver are suppose to produce different results. When set to false it is highly + /// recommended to reuse instances with the . + /// + public DefaultContractResolver(bool shareCache) { - // exclude members that are compiler generated if set - if (SerializeCompilerGeneratedMembers || !member.IsDefined(typeof (CompilerGeneratedAttribute), true)) - { - if (defaultMembers.Contains(member)) +#if !NETFX_CORE + DefaultMembersSearchFlags = BindingFlags.Public | BindingFlags.Instance; +#endif +#if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) + IgnoreSerializableAttribute = true; +#endif + + _sharedCache = shareCache; + } + + private Dictionary GetCache() + { + if (_sharedCache) + return _sharedContractCache; + else + return _instanceContractCache; + } + + private void UpdateCache(Dictionary cache) + { + if (_sharedCache) + _sharedContractCache = cache; + else + _instanceContractCache = cache; + } + + /// + /// Resolves the contract for a given type. + /// + /// The type to resolve a contract for. + /// The contract for a given type. + public virtual JsonContract ResolveContract(Type type) + { + if (type == null) + throw new ArgumentNullException("type"); + + JsonContract contract; + ResolverContractKey key = new ResolverContractKey(GetType(), type); + Dictionary cache = GetCache(); + if (cache == null || !cache.TryGetValue(key, out contract)) { - // add all members that are found by default member search - serializableMembers.Add(member); + contract = CreateContract(type); + + // avoid the possibility of modifying the cache dictionary while another thread is accessing it + lock (_typeContractCacheLock) + { + cache = GetCache(); + Dictionary updatedCache = + (cache != null) + ? new Dictionary(cache) + : new Dictionary(); + updatedCache[key] = contract; + + UpdateCache(updatedCache); + } + } + + return contract; + } + + /// + /// Gets the serializable members for the type. + /// + /// The type to get serializable members for. + /// The serializable members for the type. + protected virtual List GetSerializableMembers(Type objectType) + { + bool ignoreSerializableAttribute; +#if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) + ignoreSerializableAttribute = IgnoreSerializableAttribute; +#else + ignoreSerializableAttribute = true; +#endif + + MemberSerialization memberSerialization = JsonTypeReflector.GetObjectMemberSerialization(objectType, ignoreSerializableAttribute); + + List allMembers = ReflectionUtils.GetFieldsAndProperties(objectType, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static) + .Where(m => !ReflectionUtils.IsIndexedProperty(m)).ToList(); + + List serializableMembers = new List(); + + if (memberSerialization != MemberSerialization.Fields) + { +#if !NET20 + DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(objectType); +#endif + + List defaultMembers = ReflectionUtils.GetFieldsAndProperties(objectType, DefaultMembersSearchFlags) + .Where(m => !ReflectionUtils.IsIndexedProperty(m)).ToList(); + + foreach (MemberInfo member in allMembers) + { + // exclude members that are compiler generated if set + if (SerializeCompilerGeneratedMembers || !member.IsDefined(typeof(CompilerGeneratedAttribute), true)) + { + if (defaultMembers.Contains(member)) + { + // add all members that are found by default member search + serializableMembers.Add(member); + } + else + { + // add members that are explicitly marked with JsonProperty/DataMember attribute + // or are a field if serializing just fields + if (JsonTypeReflector.GetAttribute(member) != null) + serializableMembers.Add(member); +#if !NET20 + else if (dataContractAttribute != null && JsonTypeReflector.GetAttribute(member) != null) + serializableMembers.Add(member); +#endif + else if (memberSerialization == MemberSerialization.Fields && member.MemberType() == MemberTypes.Field) + serializableMembers.Add(member); + } + } + } + +#if !SILVERLIGHT && !NET20 + Type match; + // don't include EntityKey on entities objects... this is a bit hacky + if (objectType.AssignableToTypeName("System.Data.Objects.DataClasses.EntityObject", out match)) + serializableMembers = serializableMembers.Where(ShouldSerializeEntityMember).ToList(); +#endif } else { - // add members that are explicitly marked with JsonProperty/DataMember attribute - // or are a field if serializing just fields - if (JsonTypeReflector.GetAttribute(member) != null) - serializableMembers.Add(member); -#if !NET20 - else if (dataContractAttribute != null && JsonTypeReflector.GetAttribute(member) != null) - serializableMembers.Add(member); -#endif - else if (memberSerialization == MemberSerialization.Fields && member.MemberType() == MemberTypes.Field) - serializableMembers.Add(member); + // serialize all fields + foreach (MemberInfo member in allMembers) + { + FieldInfo field = member as FieldInfo; + if (field != null && !field.IsStatic) + serializableMembers.Add(member); + } } - } + + return serializableMembers; } #if !SILVERLIGHT && !NET20 - Type match; - // don't include EntityKey on entities objects... this is a bit hacky - if (objectType.AssignableToTypeName("System.Data.Objects.DataClasses.EntityObject", out match)) - serializableMembers = serializableMembers.Where(ShouldSerializeEntityMember).ToList(); -#endif - } - else - { - // serialize all fields - foreach (MemberInfo member in allMembers) + private bool ShouldSerializeEntityMember(MemberInfo memberInfo) { - FieldInfo field = member as FieldInfo; - if (field != null && !field.IsStatic) - serializableMembers.Add(member); + PropertyInfo propertyInfo = memberInfo as PropertyInfo; + if (propertyInfo != null) + { + if (propertyInfo.PropertyType.IsGenericType() && propertyInfo.PropertyType.GetGenericTypeDefinition().FullName == "System.Data.Objects.DataClasses.EntityReference`1") + return false; + } + + return true; } - } - - return serializableMembers; - } - -#if !SILVERLIGHT && !NET20 - private bool ShouldSerializeEntityMember(MemberInfo memberInfo) - { - PropertyInfo propertyInfo = memberInfo as PropertyInfo; - if (propertyInfo != null) - { - if (propertyInfo.PropertyType.IsGenericType() && propertyInfo.PropertyType.GetGenericTypeDefinition().FullName == "System.Data.Objects.DataClasses.EntityReference`1") - return false; - } - - return true; - } #endif - /// - /// Creates a for the given type. - /// - /// Type of the object. - /// A for the given type. - protected virtual JsonObjectContract CreateObjectContract(Type objectType) - { - JsonObjectContract contract = new JsonObjectContract(objectType); - InitializeContract(contract); + /// + /// Creates a for the given type. + /// + /// Type of the object. + /// A for the given type. + protected virtual JsonObjectContract CreateObjectContract(Type objectType) + { + JsonObjectContract contract = new JsonObjectContract(objectType); + InitializeContract(contract); - bool ignoreSerializableAttribute; + bool ignoreSerializableAttribute; #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - ignoreSerializableAttribute = IgnoreSerializableAttribute; + ignoreSerializableAttribute = IgnoreSerializableAttribute; #else - ignoreSerializableAttribute = true; + ignoreSerializableAttribute = true; #endif - contract.MemberSerialization = JsonTypeReflector.GetObjectMemberSerialization(contract.NonNullableUnderlyingType, ignoreSerializableAttribute); - contract.Properties.AddRange(CreateProperties(contract.NonNullableUnderlyingType, contract.MemberSerialization)); + contract.MemberSerialization = JsonTypeReflector.GetObjectMemberSerialization(contract.NonNullableUnderlyingType, ignoreSerializableAttribute); + contract.Properties.AddRange(CreateProperties(contract.NonNullableUnderlyingType, contract.MemberSerialization)); - JsonObjectAttribute attribute = JsonTypeReflector.GetJsonObjectAttribute(contract.NonNullableUnderlyingType); - if (attribute != null) - contract.ItemRequired = attribute._itemRequired; + JsonObjectAttribute attribute = JsonTypeReflector.GetJsonObjectAttribute(contract.NonNullableUnderlyingType); + if (attribute != null) + contract.ItemRequired = attribute._itemRequired; - ConstructorInfo overrideConstructor = GetAttributeConstructor(contract.NonNullableUnderlyingType); - - // check if a JsonConstructorAttribute has been defined and use that - if (overrideConstructor != null) - { - contract.OverrideConstructor = overrideConstructor; - contract.ConstructorParameters.AddRange(CreateConstructorParameters(overrideConstructor, contract.Properties)); - } - else if (contract.MemberSerialization == MemberSerialization.Fields) - { + ConstructorInfo overrideConstructor = GetAttributeConstructor(contract.NonNullableUnderlyingType); + + // check if a JsonConstructorAttribute has been defined and use that + if (overrideConstructor != null) + { + contract.OverrideConstructor = overrideConstructor; + contract.ConstructorParameters.AddRange(CreateConstructorParameters(overrideConstructor, contract.Properties)); + } + else if (contract.MemberSerialization == MemberSerialization.Fields) + { #if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) - // mimic DataContractSerializer behaviour when populating fields by overriding default creator to create an uninitialized object - // note that this is only possible when the application is fully trusted so fall back to using the default constructor (if available) in partial trust - if (JsonTypeReflector.FullyTrusted) - contract.DefaultCreator = contract.GetUninitializedObject; + // mimic DataContractSerializer behaviour when populating fields by overriding default creator to create an uninitialized object + // note that this is only possible when the application is fully trusted so fall back to using the default constructor (if available) in partial trust + if (JsonTypeReflector.FullyTrusted) + contract.DefaultCreator = contract.GetUninitializedObject; #endif - } - else if (contract.DefaultCreator == null || contract.DefaultCreatorNonPublic) - { - ConstructorInfo constructor = GetParametrizedConstructor(contract.NonNullableUnderlyingType); - if (constructor != null) - { - contract.ParametrizedConstructor = constructor; - contract.ConstructorParameters.AddRange(CreateConstructorParameters(constructor, contract.Properties)); + } + else if (contract.DefaultCreator == null || contract.DefaultCreatorNonPublic) + { + ConstructorInfo constructor = GetParametrizedConstructor(contract.NonNullableUnderlyingType); + if (constructor != null) + { + contract.ParametrizedConstructor = constructor; + contract.ConstructorParameters.AddRange(CreateConstructorParameters(constructor, contract.Properties)); + } + } + + MemberInfo extensionDataMember = GetExtensionDataMemberForType(contract.NonNullableUnderlyingType); + if (extensionDataMember != null) + SetExtensionDataDelegates(contract, extensionDataMember); + + return contract; } - } - MemberInfo extensionDataMember = GetExtensionDataMemberForType(contract.NonNullableUnderlyingType); - if (extensionDataMember != null) - SetExtensionDataDelegates(contract, extensionDataMember); - - return contract; - } - - private MemberInfo GetExtensionDataMemberForType(Type type) - { - IEnumerable members = GetClassHierarchyForType(type).SelectMany(baseType => + private MemberInfo GetExtensionDataMemberForType(Type type) { - IList m = new List(); - m.AddRange(baseType.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); - m.AddRange(baseType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + IEnumerable members = GetClassHierarchyForType(type).SelectMany(baseType => + { + IList m = new List(); + m.AddRange(baseType.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); + m.AddRange(baseType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)); - return m; - }); + return m; + }); - MemberInfo extensionDataMember = members.LastOrDefault(m => + MemberInfo extensionDataMember = members.LastOrDefault(m => + { + MemberTypes memberType = m.MemberType(); + if (memberType != MemberTypes.Property && memberType != MemberTypes.Field) + return false; + + // last instance of attribute wins on type if there are multiple + if (!m.IsDefined(typeof(JsonExtensionDataAttribute), false)) + return false; + + Type t = ReflectionUtils.GetMemberUnderlyingType(m); + + Type dictionaryType; + if (ReflectionUtils.ImplementsGenericDefinition(t, typeof(IDictionary<,>), out dictionaryType)) + { + Type keyType = dictionaryType.GetGenericArguments()[0]; + Type valueType = dictionaryType.GetGenericArguments()[1]; + + if (keyType.IsAssignableFrom(typeof(string)) && valueType.IsAssignableFrom(typeof(JToken))) + return true; + } + + throw new JsonException("Invalid extension data attribute on '{0}'. Member '{1}' type must implement IDictionary.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(m.DeclaringType), m.Name)); + }); + + return extensionDataMember; + } + + private static void SetExtensionDataDelegates(JsonObjectContract contract, MemberInfo member) { - MemberTypes memberType = m.MemberType(); - if (memberType != MemberTypes.Property && memberType != MemberTypes.Field) - return false; + JsonExtensionDataAttribute extensionDataAttribute = ReflectionUtils.GetAttribute(member); + if (extensionDataAttribute == null) + return; - // last instance of attribute wins on type if there are multiple - if (!m.IsDefined(typeof(JsonExtensionDataAttribute), false)) - return false; + Type t = ReflectionUtils.GetMemberUnderlyingType(member); - Type t = ReflectionUtils.GetMemberUnderlyingType(m); + Type dictionaryType; + ReflectionUtils.ImplementsGenericDefinition(t, typeof(IDictionary<,>), out dictionaryType); - Type dictionaryType; - if (ReflectionUtils.ImplementsGenericDefinition(t, typeof(IDictionary<,>), out dictionaryType)) - { Type keyType = dictionaryType.GetGenericArguments()[0]; Type valueType = dictionaryType.GetGenericArguments()[1]; + bool isJTokenValueType = typeof(JToken).IsAssignableFrom(valueType); - if (keyType.IsAssignableFrom(typeof(string)) && valueType.IsAssignableFrom(typeof(JToken))) - return true; - } + // change type to a class if it is the base interface so it can be instantiated if needed + if (ReflectionUtils.IsGenericDefinition(t, typeof(IDictionary<,>))) + t = typeof(Dictionary<,>).MakeGenericType(keyType, valueType); - throw new JsonException("Invalid extension data attribute on '{0}'. Member '{1}' type must implement IDictionary.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(m.DeclaringType), m.Name)); - }); + MethodInfo addMethod = t.GetMethod("Add", new[] { keyType, valueType }); + Func getExtensionDataDictionary = JsonTypeReflector.ReflectionDelegateFactory.CreateGet(member); + Action setExtensionDataDictionary = JsonTypeReflector.ReflectionDelegateFactory.CreateSet(member); + Func createExtensionDataDictionary = JsonTypeReflector.ReflectionDelegateFactory.CreateDefaultConstructor(t); + MethodCall setExtensionDataDictionaryValue = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(addMethod); - return extensionDataMember; - } + ExtensionDataSetter extensionDataSetter = (o, key, value) => + { + object dictionary = getExtensionDataDictionary(o); + if (dictionary == null) + { + dictionary = createExtensionDataDictionary(); + setExtensionDataDictionary(o, dictionary); + } - private static void SetExtensionDataDelegates(JsonObjectContract contract, MemberInfo member) - { - JsonExtensionDataAttribute extensionDataAttribute = ReflectionUtils.GetAttribute(member); - if (extensionDataAttribute == null) - return; + // convert object value to JToken so it is compatible with dictionary + // could happen because of primitive types, type name handling and references + if (isJTokenValueType && !(value is JToken)) + value = JToken.FromObject(value); - Type t = ReflectionUtils.GetMemberUnderlyingType(member); + setExtensionDataDictionaryValue(dictionary, key, value); + }; - Type dictionaryType; - ReflectionUtils.ImplementsGenericDefinition(t, typeof(IDictionary<,>), out dictionaryType); + Type enumerableWrapper = typeof(DictionaryEnumerator<,>).MakeGenericType(keyType, valueType); + ConstructorInfo constructors = enumerableWrapper.GetConstructors().First(); + MethodCall createEnumerableWrapper = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(constructors); - Type keyType = dictionaryType.GetGenericArguments()[0]; - Type valueType = dictionaryType.GetGenericArguments()[1]; - bool isJTokenValueType = typeof(JToken).IsAssignableFrom(valueType); + ExtensionDataGetter extensionDataGetter = o => + { + object dictionary = getExtensionDataDictionary(o); + if (dictionary == null) + return null; - // change type to a class if it is the base interface so it can be instantiated if needed - if (ReflectionUtils.IsGenericDefinition(t, typeof(IDictionary<,>))) - t = typeof(Dictionary<,>).MakeGenericType(keyType, valueType); + return (IEnumerable>)createEnumerableWrapper(null, dictionary); + }; - MethodInfo addMethod = t.GetMethod("Add", new[] { keyType, valueType }); - Func getExtensionDataDictionary = JsonTypeReflector.ReflectionDelegateFactory.CreateGet(member); - Action setExtensionDataDictionary = JsonTypeReflector.ReflectionDelegateFactory.CreateSet(member); - Func createExtensionDataDictionary = JsonTypeReflector.ReflectionDelegateFactory.CreateDefaultConstructor(t); - MethodCall setExtensionDataDictionaryValue = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(addMethod); + if (extensionDataAttribute.ReadData) + contract.ExtensionDataSetter = extensionDataSetter; - ExtensionDataSetter extensionDataSetter = (o, key, value) => - { - object dictionary = getExtensionDataDictionary(o); - if (dictionary == null) - { - dictionary = createExtensionDataDictionary(); - setExtensionDataDictionary(o, dictionary); - } - - // convert object value to JToken so it is compatible with dictionary - // could happen because of primitive types, type name handling and references - if (isJTokenValueType && !(value is JToken)) - value = JToken.FromObject(value); - - setExtensionDataDictionaryValue(dictionary, key, value); - }; - - Type enumerableWrapper = typeof(DictionaryEnumerator<,>).MakeGenericType(keyType, valueType); - ConstructorInfo constructors = enumerableWrapper.GetConstructors().First(); - MethodCall createEnumerableWrapper = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(constructors); - - ExtensionDataGetter extensionDataGetter = o => - { - object dictionary = getExtensionDataDictionary(o); - if (dictionary == null) - return null; - - return (IEnumerable>)createEnumerableWrapper(null, dictionary); - }; - - if (extensionDataAttribute.ReadData) - contract.ExtensionDataSetter = extensionDataSetter; - - if (extensionDataAttribute.WriteData) - contract.ExtensionDataGetter = extensionDataGetter; - } - - internal struct DictionaryEnumerator : IEnumerable>, IEnumerator> - { - private readonly IEnumerator> _e; - - public DictionaryEnumerator(IEnumerable> e) - { - ValidationUtils.ArgumentNotNull(e, "e"); - _e = e.GetEnumerator(); - } - - public bool MoveNext() - { - return _e.MoveNext(); - } - - public void Reset() - { - _e.Reset(); - } - - public KeyValuePair Current - { - get { return new KeyValuePair(_e.Current.Key, _e.Current.Value); } - } - - public void Dispose() - { - _e.Dispose(); - } - - object IEnumerator.Current - { - get { return Current; } - } - - public IEnumerator> GetEnumerator() - { - return this; - } - - IEnumerator IEnumerable.GetEnumerator() - { - return this; - } - } - - private ConstructorInfo GetAttributeConstructor(Type objectType) - { - IList markedConstructors = objectType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Where(c => c.IsDefined(typeof(JsonConstructorAttribute), true)).ToList(); - - if (markedConstructors.Count > 1) - throw new JsonException("Multiple constructors with the JsonConstructorAttribute."); - else if (markedConstructors.Count == 1) - return markedConstructors[0]; - - // little hack to get Version objects to deserialize correctly - if (objectType == typeof(Version)) - return objectType.GetConstructor(new [] { typeof(int), typeof(int), typeof(int), typeof(int) }); - - return null; - } - - private ConstructorInfo GetParametrizedConstructor(Type objectType) - { - IList constructors = objectType.GetConstructors(BindingFlags.Public | BindingFlags.Instance).ToList(); - - if (constructors.Count == 1) - return constructors[0]; - else - return null; - } - - /// - /// Creates the constructor parameters. - /// - /// The constructor to create properties for. - /// The type's member properties. - /// Properties for the given . - protected virtual IList CreateConstructorParameters(ConstructorInfo constructor, JsonPropertyCollection memberProperties) - { - var constructorParameters = constructor.GetParameters(); - - JsonPropertyCollection parameterCollection = new JsonPropertyCollection(constructor.DeclaringType); - - foreach (ParameterInfo parameterInfo in constructorParameters) - { - // it is possible to generate a ParameterInfo with a null name using Reflection.Emit - // protect against an ArgumentNullException from GetClosestMatchProperty by testing for null here - JsonProperty matchingMemberProperty = (parameterInfo.Name != null) ? memberProperties.GetClosestMatchProperty(parameterInfo.Name) : null; - - // type must match as well as name - if (matchingMemberProperty != null && matchingMemberProperty.PropertyType != parameterInfo.ParameterType) - matchingMemberProperty = null; - - // ensure that property will have a name from matching property or from parameterinfo - // parameterinfo could have no name if generated by a proxy (I'm looking at you Castle) - if (matchingMemberProperty != null || parameterInfo.Name != null) - { - JsonProperty property = CreatePropertyFromConstructorParameter(matchingMemberProperty, parameterInfo); - - if (property != null) - { - parameterCollection.AddProperty(property); - } + if (extensionDataAttribute.WriteData) + contract.ExtensionDataGetter = extensionDataGetter; } - } - return parameterCollection; - } + internal struct DictionaryEnumerator : IEnumerable>, IEnumerator> + { + private readonly IEnumerator> _e; - /// - /// Creates a for the given . - /// - /// The matching member property. - /// The constructor parameter. - /// A created for the given . - protected virtual JsonProperty CreatePropertyFromConstructorParameter(JsonProperty matchingMemberProperty, ParameterInfo parameterInfo) - { - JsonProperty property = new JsonProperty(); - property.PropertyType = parameterInfo.ParameterType; + public DictionaryEnumerator(IEnumerable> e) + { + ValidationUtils.ArgumentNotNull(e, "e"); + _e = e.GetEnumerator(); + } - bool allowNonPublicAccess; - SetPropertySettingsFromAttributes(property, parameterInfo, parameterInfo.Name, parameterInfo.Member.DeclaringType, MemberSerialization.OptOut, out allowNonPublicAccess); + public bool MoveNext() + { + return _e.MoveNext(); + } - property.Readable = false; - property.Writable = true; + public void Reset() + { + _e.Reset(); + } - // "inherit" values from matching member property if unset on parameter - if (matchingMemberProperty != null) - { - property.PropertyName = (property.PropertyName != parameterInfo.Name) ? property.PropertyName : matchingMemberProperty.PropertyName; - property.Converter = property.Converter ?? matchingMemberProperty.Converter; - property.MemberConverter = property.MemberConverter ?? matchingMemberProperty.MemberConverter; + public KeyValuePair Current + { + get { return new KeyValuePair(_e.Current.Key, _e.Current.Value); } + } - if (!property._hasExplicitDefaultValue && matchingMemberProperty._hasExplicitDefaultValue) - property.DefaultValue = matchingMemberProperty.DefaultValue; + public void Dispose() + { + _e.Dispose(); + } - property._required = property._required ?? matchingMemberProperty._required; - property.IsReference = property.IsReference ?? matchingMemberProperty.IsReference; - property.NullValueHandling = property.NullValueHandling ?? matchingMemberProperty.NullValueHandling; - property.DefaultValueHandling = property.DefaultValueHandling ?? matchingMemberProperty.DefaultValueHandling; - property.ReferenceLoopHandling = property.ReferenceLoopHandling ?? matchingMemberProperty.ReferenceLoopHandling; - property.ObjectCreationHandling = property.ObjectCreationHandling ?? matchingMemberProperty.ObjectCreationHandling; - property.TypeNameHandling = property.TypeNameHandling ?? matchingMemberProperty.TypeNameHandling; - } + object IEnumerator.Current + { + get { return Current; } + } - return property; - } + public IEnumerator> GetEnumerator() + { + return this; + } - /// - /// Resolves the default for the contract. - /// - /// Type of the object. - /// The contract's default . - protected virtual JsonConverter ResolveContractConverter(Type objectType) - { - return JsonTypeReflector.GetJsonConverter(objectType, objectType); - } + IEnumerator IEnumerable.GetEnumerator() + { + return this; + } + } - private Func GetDefaultCreator(Type createdType) - { - return JsonTypeReflector.ReflectionDelegateFactory.CreateDefaultConstructor(createdType); - } + private ConstructorInfo GetAttributeConstructor(Type objectType) + { + IList markedConstructors = objectType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Where(c => c.IsDefined(typeof(JsonConstructorAttribute), true)).ToList(); + + if (markedConstructors.Count > 1) + throw new JsonException("Multiple constructors with the JsonConstructorAttribute."); + else if (markedConstructors.Count == 1) + return markedConstructors[0]; + + // little hack to get Version objects to deserialize correctly + if (objectType == typeof(Version)) + return objectType.GetConstructor(new[] { typeof(int), typeof(int), typeof(int), typeof(int) }); + + return null; + } + + private ConstructorInfo GetParametrizedConstructor(Type objectType) + { + IList constructors = objectType.GetConstructors(BindingFlags.Public | BindingFlags.Instance).ToList(); + + if (constructors.Count == 1) + return constructors[0]; + else + return null; + } + + /// + /// Creates the constructor parameters. + /// + /// The constructor to create properties for. + /// The type's member properties. + /// Properties for the given . + protected virtual IList CreateConstructorParameters(ConstructorInfo constructor, JsonPropertyCollection memberProperties) + { + var constructorParameters = constructor.GetParameters(); + + JsonPropertyCollection parameterCollection = new JsonPropertyCollection(constructor.DeclaringType); + + foreach (ParameterInfo parameterInfo in constructorParameters) + { + // it is possible to generate a ParameterInfo with a null name using Reflection.Emit + // protect against an ArgumentNullException from GetClosestMatchProperty by testing for null here + JsonProperty matchingMemberProperty = (parameterInfo.Name != null) ? memberProperties.GetClosestMatchProperty(parameterInfo.Name) : null; + + // type must match as well as name + if (matchingMemberProperty != null && matchingMemberProperty.PropertyType != parameterInfo.ParameterType) + matchingMemberProperty = null; + + // ensure that property will have a name from matching property or from parameterinfo + // parameterinfo could have no name if generated by a proxy (I'm looking at you Castle) + if (matchingMemberProperty != null || parameterInfo.Name != null) + { + JsonProperty property = CreatePropertyFromConstructorParameter(matchingMemberProperty, parameterInfo); + + if (property != null) + { + parameterCollection.AddProperty(property); + } + } + } + + return parameterCollection; + } + + /// + /// Creates a for the given . + /// + /// The matching member property. + /// The constructor parameter. + /// A created for the given . + protected virtual JsonProperty CreatePropertyFromConstructorParameter(JsonProperty matchingMemberProperty, ParameterInfo parameterInfo) + { + JsonProperty property = new JsonProperty(); + property.PropertyType = parameterInfo.ParameterType; + + bool allowNonPublicAccess; + SetPropertySettingsFromAttributes(property, parameterInfo, parameterInfo.Name, parameterInfo.Member.DeclaringType, MemberSerialization.OptOut, out allowNonPublicAccess); + + property.Readable = false; + property.Writable = true; + + // "inherit" values from matching member property if unset on parameter + if (matchingMemberProperty != null) + { + property.PropertyName = (property.PropertyName != parameterInfo.Name) ? property.PropertyName : matchingMemberProperty.PropertyName; + property.Converter = property.Converter ?? matchingMemberProperty.Converter; + property.MemberConverter = property.MemberConverter ?? matchingMemberProperty.MemberConverter; + + if (!property._hasExplicitDefaultValue && matchingMemberProperty._hasExplicitDefaultValue) + property.DefaultValue = matchingMemberProperty.DefaultValue; + + property._required = property._required ?? matchingMemberProperty._required; + property.IsReference = property.IsReference ?? matchingMemberProperty.IsReference; + property.NullValueHandling = property.NullValueHandling ?? matchingMemberProperty.NullValueHandling; + property.DefaultValueHandling = property.DefaultValueHandling ?? matchingMemberProperty.DefaultValueHandling; + property.ReferenceLoopHandling = property.ReferenceLoopHandling ?? matchingMemberProperty.ReferenceLoopHandling; + property.ObjectCreationHandling = property.ObjectCreationHandling ?? matchingMemberProperty.ObjectCreationHandling; + property.TypeNameHandling = property.TypeNameHandling ?? matchingMemberProperty.TypeNameHandling; + } + + return property; + } + + /// + /// Resolves the default for the contract. + /// + /// Type of the object. + /// The contract's default . + protected virtual JsonConverter ResolveContractConverter(Type objectType) + { + return JsonTypeReflector.GetJsonConverter(objectType, objectType); + } + + private Func GetDefaultCreator(Type createdType) + { + return JsonTypeReflector.ReflectionDelegateFactory.CreateDefaultConstructor(createdType); + } #if !NET20 - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Portability", "CA1903:UseOnlyApiFromTargetedFramework", MessageId = "System.Runtime.Serialization.DataContractAttribute.#get_IsReference()")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Portability", "CA1903:UseOnlyApiFromTargetedFramework", MessageId = "System.Runtime.Serialization.DataContractAttribute.#get_IsReference()")] #endif - private void InitializeContract(JsonContract contract) - { - JsonContainerAttribute containerAttribute = JsonTypeReflector.GetJsonContainerAttribute(contract.NonNullableUnderlyingType); - if (containerAttribute != null) - { - contract.IsReference = containerAttribute._isReference; - } + private void InitializeContract(JsonContract contract) + { + JsonContainerAttribute containerAttribute = JsonTypeReflector.GetJsonContainerAttribute(contract.NonNullableUnderlyingType); + if (containerAttribute != null) + { + contract.IsReference = containerAttribute._isReference; + } #if !NET20 - else - { - DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(contract.NonNullableUnderlyingType); - // doesn't have a null value - if (dataContractAttribute != null && dataContractAttribute.IsReference) - contract.IsReference = true; - } + else + { + DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(contract.NonNullableUnderlyingType); + // doesn't have a null value + if (dataContractAttribute != null && dataContractAttribute.IsReference) + contract.IsReference = true; + } #endif - contract.Converter = ResolveContractConverter(contract.NonNullableUnderlyingType); + contract.Converter = ResolveContractConverter(contract.NonNullableUnderlyingType); - // then see whether object is compadible with any of the built in converters - contract.InternalConverter = JsonSerializer.GetMatchingConverter(BuiltInConverters, contract.NonNullableUnderlyingType); + // then see whether object is compadible with any of the built in converters + contract.InternalConverter = JsonSerializer.GetMatchingConverter(BuiltInConverters, contract.NonNullableUnderlyingType); - if (ReflectionUtils.HasDefaultConstructor(contract.CreatedType, true) - || contract.CreatedType.IsValueType()) - { - contract.DefaultCreator = GetDefaultCreator(contract.CreatedType); + if (ReflectionUtils.HasDefaultConstructor(contract.CreatedType, true) + || contract.CreatedType.IsValueType()) + { + contract.DefaultCreator = GetDefaultCreator(contract.CreatedType); - contract.DefaultCreatorNonPublic = (!contract.CreatedType.IsValueType() && - ReflectionUtils.GetDefaultConstructor(contract.CreatedType) == null); - } + contract.DefaultCreatorNonPublic = (!contract.CreatedType.IsValueType() && + ReflectionUtils.GetDefaultConstructor(contract.CreatedType) == null); + } - ResolveCallbackMethods(contract, contract.NonNullableUnderlyingType); - } + ResolveCallbackMethods(contract, contract.NonNullableUnderlyingType); + } - private void ResolveCallbackMethods(JsonContract contract, Type t) - { - List onSerializing; - List onSerialized; - List onDeserializing; - List onDeserialized; - List onError; + private void ResolveCallbackMethods(JsonContract contract, Type t) + { + List onSerializing; + List onSerialized; + List onDeserializing; + List onDeserialized; + List onError; - GetCallbackMethodsForType(t, out onSerializing, out onSerialized, out onDeserializing, out onDeserialized, out onError); + GetCallbackMethodsForType(t, out onSerializing, out onSerialized, out onDeserializing, out onDeserialized, out onError); - if (onSerializing != null) - { + if (onSerializing != null) + { #if NETFX_CORE if (!t.IsGenericType() || (t.GetGenericTypeDefinition() != typeof(ConcurrentDictionary<,>))) contract.OnSerializingCallbacks.AddRange(onSerializing); #else - contract.OnSerializingCallbacks.AddRange(onSerializing); + contract.OnSerializingCallbacks.AddRange(onSerializing); #endif - } + } - if (onSerialized != null) - contract.OnSerializedCallbacks.AddRange(onSerialized); + if (onSerialized != null) + contract.OnSerializedCallbacks.AddRange(onSerialized); - if (onDeserializing != null) - contract.OnDeserializingCallbacks.AddRange(onDeserializing); + if (onDeserializing != null) + contract.OnDeserializingCallbacks.AddRange(onDeserializing); - if (onDeserialized != null) - { - // ConcurrentDictionary throws an error here so don't use its OnDeserialized - http://json.codeplex.com/discussions/257093 + if (onDeserialized != null) + { + // ConcurrentDictionary throws an error here so don't use its OnDeserialized - http://json.codeplex.com/discussions/257093 #if !(NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE || PORTABLE40) - if (!t.IsGenericType() || (t.GetGenericTypeDefinition() != typeof(ConcurrentDictionary<,>))) - contract.OnDeserializedCallbacks.AddRange(onDeserialized); + if (!t.IsGenericType() || (t.GetGenericTypeDefinition() != typeof(ConcurrentDictionary<,>))) + contract.OnDeserializedCallbacks.AddRange(onDeserialized); #else - contract.OnDeserializedCallbacks.AddRange(onDeserialized); + contract.OnDeserializedCallbacks.AddRange(onDeserialized); #endif - } + } - if (onError != null) - contract.OnErrorCallbacks.AddRange(onError); - } - - private void GetCallbackMethodsForType(Type type, out List onSerializing, out List onSerialized, out List onDeserializing, out List onDeserialized, out List onError) - { - onSerializing = null; - onSerialized = null; - onDeserializing = null; - onDeserialized = null; - onError = null; - - foreach (Type baseType in GetClassHierarchyForType(type)) - { - // while we allow more than one OnSerialized total, only one can be defined per class - MethodInfo currentOnSerializing = null; - MethodInfo currentOnSerialized = null; - MethodInfo currentOnDeserializing = null; - MethodInfo currentOnDeserialized = null; - MethodInfo currentOnError = null; - - foreach (MethodInfo method in baseType.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) - { - // compact framework errors when getting parameters for a generic method - // lame, but generic methods should not be callbacks anyway - if (method.ContainsGenericParameters) - continue; - - Type prevAttributeType = null; - ParameterInfo[] parameters = method.GetParameters(); - - if (IsValidCallback(method, parameters, typeof(OnSerializingAttribute), currentOnSerializing, ref prevAttributeType)) - { - onSerializing = onSerializing ?? new List(); - onSerializing.Add(JsonContract.CreateSerializationCallback(method)); - currentOnSerializing = method; - } - if (IsValidCallback(method, parameters, typeof(OnSerializedAttribute), currentOnSerialized, ref prevAttributeType)) - { - onSerialized = onSerialized ?? new List(); - onSerialized.Add(JsonContract.CreateSerializationCallback(method)); - currentOnSerialized = method; - } - if (IsValidCallback(method, parameters, typeof(OnDeserializingAttribute), currentOnDeserializing, ref prevAttributeType)) - { - onDeserializing = onDeserializing ?? new List(); - onDeserializing.Add(JsonContract.CreateSerializationCallback(method)); - currentOnDeserializing = method; - } - if (IsValidCallback(method, parameters, typeof(OnDeserializedAttribute), currentOnDeserialized, ref prevAttributeType)) - { - onDeserialized = onDeserialized ?? new List(); - onDeserialized.Add(JsonContract.CreateSerializationCallback(method)); - currentOnDeserialized = method; - } - if (IsValidCallback(method, parameters, typeof(OnErrorAttribute), currentOnError, ref prevAttributeType)) - { - onError = onError ?? new List(); - onError.Add(JsonContract.CreateSerializationErrorCallback(method)); - currentOnError = method; - } + if (onError != null) + contract.OnErrorCallbacks.AddRange(onError); } - } - } - private List GetClassHierarchyForType(Type type) - { - List ret = new List(); + private void GetCallbackMethodsForType(Type type, out List onSerializing, out List onSerialized, out List onDeserializing, out List onDeserialized, out List onError) + { + onSerializing = null; + onSerialized = null; + onDeserializing = null; + onDeserialized = null; + onError = null; - Type current = type; - while (current != null && current != typeof(object)) - { - ret.Add(current); - current = current.BaseType(); - } + foreach (Type baseType in GetClassHierarchyForType(type)) + { + // while we allow more than one OnSerialized total, only one can be defined per class + MethodInfo currentOnSerializing = null; + MethodInfo currentOnSerialized = null; + MethodInfo currentOnDeserializing = null; + MethodInfo currentOnDeserialized = null; + MethodInfo currentOnError = null; - // Return the class list in order of simple => complex - ret.Reverse(); - return ret; - } + foreach (MethodInfo method in baseType.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) + { + // compact framework errors when getting parameters for a generic method + // lame, but generic methods should not be callbacks anyway + if (method.ContainsGenericParameters) + continue; - /// - /// Creates a for the given type. - /// - /// Type of the object. - /// A for the given type. - protected virtual JsonDictionaryContract CreateDictionaryContract(Type objectType) - { - JsonDictionaryContract contract = new JsonDictionaryContract(objectType); - InitializeContract(contract); + Type prevAttributeType = null; + ParameterInfo[] parameters = method.GetParameters(); - contract.PropertyNameResolver = ResolvePropertyName; + if (IsValidCallback(method, parameters, typeof(OnSerializingAttribute), currentOnSerializing, ref prevAttributeType)) + { + onSerializing = onSerializing ?? new List(); + onSerializing.Add(JsonContract.CreateSerializationCallback(method)); + currentOnSerializing = method; + } + if (IsValidCallback(method, parameters, typeof(OnSerializedAttribute), currentOnSerialized, ref prevAttributeType)) + { + onSerialized = onSerialized ?? new List(); + onSerialized.Add(JsonContract.CreateSerializationCallback(method)); + currentOnSerialized = method; + } + if (IsValidCallback(method, parameters, typeof(OnDeserializingAttribute), currentOnDeserializing, ref prevAttributeType)) + { + onDeserializing = onDeserializing ?? new List(); + onDeserializing.Add(JsonContract.CreateSerializationCallback(method)); + currentOnDeserializing = method; + } + if (IsValidCallback(method, parameters, typeof(OnDeserializedAttribute), currentOnDeserialized, ref prevAttributeType)) + { + onDeserialized = onDeserialized ?? new List(); + onDeserialized.Add(JsonContract.CreateSerializationCallback(method)); + currentOnDeserialized = method; + } + if (IsValidCallback(method, parameters, typeof(OnErrorAttribute), currentOnError, ref prevAttributeType)) + { + onError = onError ?? new List(); + onError.Add(JsonContract.CreateSerializationErrorCallback(method)); + currentOnError = method; + } + } + } + } - return contract; - } + private List GetClassHierarchyForType(Type type) + { + List ret = new List(); - /// - /// Creates a for the given type. - /// - /// Type of the object. - /// A for the given type. - protected virtual JsonArrayContract CreateArrayContract(Type objectType) - { - JsonArrayContract contract = new JsonArrayContract(objectType); - InitializeContract(contract); + Type current = type; + while (current != null && current != typeof(object)) + { + ret.Add(current); + current = current.BaseType(); + } - return contract; - } + // Return the class list in order of simple => complex + ret.Reverse(); + return ret; + } - /// - /// Creates a for the given type. - /// - /// Type of the object. - /// A for the given type. - protected virtual JsonPrimitiveContract CreatePrimitiveContract(Type objectType) - { - JsonPrimitiveContract contract = new JsonPrimitiveContract(objectType); - InitializeContract(contract); + /// + /// Creates a for the given type. + /// + /// Type of the object. + /// A for the given type. + protected virtual JsonDictionaryContract CreateDictionaryContract(Type objectType) + { + JsonDictionaryContract contract = new JsonDictionaryContract(objectType); + InitializeContract(contract); - return contract; - } + contract.PropertyNameResolver = ResolvePropertyName; - /// - /// Creates a for the given type. - /// - /// Type of the object. - /// A for the given type. - protected virtual JsonLinqContract CreateLinqContract(Type objectType) - { - JsonLinqContract contract = new JsonLinqContract(objectType); - InitializeContract(contract); + return contract; + } - return contract; - } + /// + /// Creates a for the given type. + /// + /// Type of the object. + /// A for the given type. + protected virtual JsonArrayContract CreateArrayContract(Type objectType) + { + JsonArrayContract contract = new JsonArrayContract(objectType); + InitializeContract(contract); + + return contract; + } + + /// + /// Creates a for the given type. + /// + /// Type of the object. + /// A for the given type. + protected virtual JsonPrimitiveContract CreatePrimitiveContract(Type objectType) + { + JsonPrimitiveContract contract = new JsonPrimitiveContract(objectType); + InitializeContract(contract); + + return contract; + } + + /// + /// Creates a for the given type. + /// + /// Type of the object. + /// A for the given type. + protected virtual JsonLinqContract CreateLinqContract(Type objectType) + { + JsonLinqContract contract = new JsonLinqContract(objectType); + InitializeContract(contract); + + return contract; + } #if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) - /// - /// Creates a for the given type. - /// - /// Type of the object. - /// A for the given type. - protected virtual JsonISerializableContract CreateISerializableContract(Type objectType) - { - JsonISerializableContract contract = new JsonISerializableContract(objectType); - InitializeContract(contract); + /// + /// Creates a for the given type. + /// + /// Type of the object. + /// A for the given type. + protected virtual JsonISerializableContract CreateISerializableContract(Type objectType) + { + JsonISerializableContract contract = new JsonISerializableContract(objectType); + InitializeContract(contract); - ConstructorInfo constructorInfo = contract.NonNullableUnderlyingType.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { typeof(SerializationInfo), typeof(StreamingContext) }, null); - if (constructorInfo != null) - { - MethodCall methodCall = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(constructorInfo); + ConstructorInfo constructorInfo = contract.NonNullableUnderlyingType.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { typeof(SerializationInfo), typeof(StreamingContext) }, null); + if (constructorInfo != null) + { + MethodCall methodCall = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(constructorInfo); - contract.ISerializableCreator = (args => methodCall(null, args)); - } + contract.ISerializableCreator = (args => methodCall(null, args)); + } - return contract; - } + return contract; + } #endif #if !(NET35 || NET20 || PORTABLE40) - /// - /// Creates a for the given type. - /// - /// Type of the object. - /// A for the given type. - protected virtual JsonDynamicContract CreateDynamicContract(Type objectType) - { - JsonDynamicContract contract = new JsonDynamicContract(objectType); - InitializeContract(contract); + /// + /// Creates a for the given type. + /// + /// Type of the object. + /// A for the given type. + protected virtual JsonDynamicContract CreateDynamicContract(Type objectType) + { + JsonDynamicContract contract = new JsonDynamicContract(objectType); + InitializeContract(contract); - contract.PropertyNameResolver = ResolvePropertyName; - contract.Properties.AddRange(CreateProperties(objectType, MemberSerialization.OptOut)); + contract.PropertyNameResolver = ResolvePropertyName; + contract.Properties.AddRange(CreateProperties(objectType, MemberSerialization.OptOut)); - return contract; - } + return contract; + } #endif - /// - /// Creates a for the given type. - /// - /// Type of the object. - /// A for the given type. - protected virtual JsonStringContract CreateStringContract(Type objectType) - { - JsonStringContract contract = new JsonStringContract(objectType); - InitializeContract(contract); + /// + /// Creates a for the given type. + /// + /// Type of the object. + /// A for the given type. + protected virtual JsonStringContract CreateStringContract(Type objectType) + { + JsonStringContract contract = new JsonStringContract(objectType); + InitializeContract(contract); - return contract; - } + return contract; + } - /// - /// Determines which contract type is created for the given type. - /// - /// Type of the object. - /// A for the given type. - protected virtual JsonContract CreateContract(Type objectType) - { - Type t = ReflectionUtils.EnsureNotNullableType(objectType); + /// + /// Determines which contract type is created for the given type. + /// + /// Type of the object. + /// A for the given type. + protected virtual JsonContract CreateContract(Type objectType) + { + Type t = ReflectionUtils.EnsureNotNullableType(objectType); - if (IsJsonPrimitiveType(objectType)) - return CreatePrimitiveContract(objectType); + if (IsJsonPrimitiveType(objectType)) + return CreatePrimitiveContract(objectType); - if (JsonTypeReflector.GetJsonObjectAttribute(t) != null) - return CreateObjectContract(objectType); + if (JsonTypeReflector.GetJsonObjectAttribute(t) != null) + return CreateObjectContract(objectType); - if (JsonTypeReflector.GetJsonArrayAttribute(t) != null) - return CreateArrayContract(objectType); + if (JsonTypeReflector.GetJsonArrayAttribute(t) != null) + return CreateArrayContract(objectType); - if (JsonTypeReflector.GetJsonDictionaryAttribute(t) != null) - return CreateDictionaryContract(objectType); + if (JsonTypeReflector.GetJsonDictionaryAttribute(t) != null) + return CreateDictionaryContract(objectType); - if (t == typeof(JToken) || t.IsSubclassOf(typeof(JToken))) - return CreateLinqContract(objectType); + if (t == typeof(JToken) || t.IsSubclassOf(typeof(JToken))) + return CreateLinqContract(objectType); - if (CollectionUtils.IsDictionaryType(t)) - return CreateDictionaryContract(objectType); + if (CollectionUtils.IsDictionaryType(t)) + return CreateDictionaryContract(objectType); - if (typeof(IEnumerable).IsAssignableFrom(t)) - return CreateArrayContract(objectType); + if (typeof(IEnumerable).IsAssignableFrom(t)) + return CreateArrayContract(objectType); - if (CanConvertToString(t)) - return CreateStringContract(objectType); + if (CanConvertToString(t)) + return CreateStringContract(objectType); #if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) - if (!IgnoreSerializableInterface && typeof(ISerializable).IsAssignableFrom(t)) - return CreateISerializableContract(objectType); + if (!IgnoreSerializableInterface && typeof(ISerializable).IsAssignableFrom(t)) + return CreateISerializableContract(objectType); #endif #if !(NET35 || NET20 || PORTABLE40) - if (typeof(IDynamicMetaObjectProvider).IsAssignableFrom(t)) - return CreateDynamicContract(objectType); + if (typeof(IDynamicMetaObjectProvider).IsAssignableFrom(t)) + return CreateDynamicContract(objectType); #endif #if !(PORTABLE || NETFX_CORE) - // tested last because it is not possible to automatically deserialize custom IConvertible types - if (IsIConvertible(t)) - return CreatePrimitiveContract(t); + // tested last because it is not possible to automatically deserialize custom IConvertible types + if (IsIConvertible(t)) + return CreatePrimitiveContract(t); #endif - return CreateObjectContract(objectType); - } + return CreateObjectContract(objectType); + } - internal static bool IsJsonPrimitiveType(Type t) - { - PrimitiveTypeCode typeCode = ConvertUtils.GetTypeCode(t); + internal static bool IsJsonPrimitiveType(Type t) + { + PrimitiveTypeCode typeCode = ConvertUtils.GetTypeCode(t); - return (typeCode != PrimitiveTypeCode.Empty && typeCode != PrimitiveTypeCode.Object); - } + return (typeCode != PrimitiveTypeCode.Empty && typeCode != PrimitiveTypeCode.Object); + } #if !(PORTABLE || NETFX_CORE) - internal static bool IsIConvertible(Type t) - { - if (typeof(IConvertible).IsAssignableFrom(t) - || (ReflectionUtils.IsNullableType(t) && typeof(IConvertible).IsAssignableFrom(Nullable.GetUnderlyingType(t)))) - { - return !typeof(JToken).IsAssignableFrom(t); - } + internal static bool IsIConvertible(Type t) + { + if (typeof(IConvertible).IsAssignableFrom(t) + || (ReflectionUtils.IsNullableType(t) && typeof(IConvertible).IsAssignableFrom(Nullable.GetUnderlyingType(t)))) + { + return !typeof(JToken).IsAssignableFrom(t); + } - return false; - } + return false; + } #endif - internal static bool CanConvertToString(Type type) - { + internal static bool CanConvertToString(Type type) + { #if !(NETFX_CORE || PORTABLE40 || PORTABLE) - TypeConverter converter = ConvertUtils.GetConverter(type); + TypeConverter converter = ConvertUtils.GetConverter(type); - // use the objectType's TypeConverter if it has one and can convert to a string - if (converter != null + // use the objectType's TypeConverter if it has one and can convert to a string + if (converter != null #if !SILVERLIGHT - && !(converter is ComponentConverter) - && !(converter is ReferenceConverter) + && !(converter is ComponentConverter) + && !(converter is ReferenceConverter) #endif - && converter.GetType() != typeof(TypeConverter)) - { - if (converter.CanConvertTo(typeof(string))) - return true; - } + && converter.GetType() != typeof(TypeConverter)) + { + if (converter.CanConvertTo(typeof(string))) + return true; + } #endif - if (type == typeof(Type) || type.IsSubclassOf(typeof(Type))) - return true; + if (type == typeof(Type) || type.IsSubclassOf(typeof(Type))) + return true; #if SILVERLIGHT if (type == typeof(Guid) || type == typeof(Uri) || type == typeof(TimeSpan)) return true; #endif - return false; - } + return false; + } - private static bool IsValidCallback(MethodInfo method, ParameterInfo[] parameters, Type attributeType, MethodInfo currentCallback, ref Type prevAttributeType) - { - if (!method.IsDefined(attributeType, false)) - return false; + private static bool IsValidCallback(MethodInfo method, ParameterInfo[] parameters, Type attributeType, MethodInfo currentCallback, ref Type prevAttributeType) + { + if (!method.IsDefined(attributeType, false)) + return false; - if (currentCallback != null) - throw new JsonException("Invalid attribute. Both '{0}' and '{1}' in type '{2}' have '{3}'.".FormatWith(CultureInfo.InvariantCulture, method, currentCallback, GetClrTypeFullName(method.DeclaringType), attributeType)); + if (currentCallback != null) + throw new JsonException("Invalid attribute. Both '{0}' and '{1}' in type '{2}' have '{3}'.".FormatWith(CultureInfo.InvariantCulture, method, currentCallback, GetClrTypeFullName(method.DeclaringType), attributeType)); - if (prevAttributeType != null) - throw new JsonException("Invalid Callback. Method '{3}' in type '{2}' has both '{0}' and '{1}'.".FormatWith(CultureInfo.InvariantCulture, prevAttributeType, attributeType, GetClrTypeFullName(method.DeclaringType), method)); + if (prevAttributeType != null) + throw new JsonException("Invalid Callback. Method '{3}' in type '{2}' has both '{0}' and '{1}'.".FormatWith(CultureInfo.InvariantCulture, prevAttributeType, attributeType, GetClrTypeFullName(method.DeclaringType), method)); - if (method.IsVirtual) - throw new JsonException("Virtual Method '{0}' of type '{1}' cannot be marked with '{2}' attribute.".FormatWith(CultureInfo.InvariantCulture, method, GetClrTypeFullName(method.DeclaringType), attributeType)); + if (method.IsVirtual) + throw new JsonException("Virtual Method '{0}' of type '{1}' cannot be marked with '{2}' attribute.".FormatWith(CultureInfo.InvariantCulture, method, GetClrTypeFullName(method.DeclaringType), attributeType)); - if (method.ReturnType != typeof(void)) - throw new JsonException("Serialization Callback '{1}' in type '{0}' must return void.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(method.DeclaringType), method)); + if (method.ReturnType != typeof(void)) + throw new JsonException("Serialization Callback '{1}' in type '{0}' must return void.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(method.DeclaringType), method)); - if (attributeType == typeof(OnErrorAttribute)) - { - if (parameters == null || parameters.Length != 2 || parameters[0].ParameterType != typeof(StreamingContext) || parameters[1].ParameterType != typeof(ErrorContext)) - throw new JsonException("Serialization Error Callback '{1}' in type '{0}' must have two parameters of type '{2}' and '{3}'.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(method.DeclaringType), method, typeof(StreamingContext), typeof(ErrorContext))); - } - else - { - if (parameters == null || parameters.Length != 1 || parameters[0].ParameterType != typeof(StreamingContext)) - throw new JsonException("Serialization Callback '{1}' in type '{0}' must have a single parameter of type '{2}'.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(method.DeclaringType), method, typeof(StreamingContext))); - } + if (attributeType == typeof(OnErrorAttribute)) + { + if (parameters == null || parameters.Length != 2 || parameters[0].ParameterType != typeof(StreamingContext) || parameters[1].ParameterType != typeof(ErrorContext)) + throw new JsonException("Serialization Error Callback '{1}' in type '{0}' must have two parameters of type '{2}' and '{3}'.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(method.DeclaringType), method, typeof(StreamingContext), typeof(ErrorContext))); + } + else + { + if (parameters == null || parameters.Length != 1 || parameters[0].ParameterType != typeof(StreamingContext)) + throw new JsonException("Serialization Callback '{1}' in type '{0}' must have a single parameter of type '{2}'.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(method.DeclaringType), method, typeof(StreamingContext))); + } - prevAttributeType = attributeType; + prevAttributeType = attributeType; - return true; - } + return true; + } - internal static string GetClrTypeFullName(Type type) - { - if (type.IsGenericTypeDefinition() || !type.ContainsGenericParameters()) - return type.FullName; + internal static string GetClrTypeFullName(Type type) + { + if (type.IsGenericTypeDefinition() || !type.ContainsGenericParameters()) + return type.FullName; - return string.Format(CultureInfo.InvariantCulture, "{0}.{1}", new object[] { type.Namespace, type.Name }); - } + return string.Format(CultureInfo.InvariantCulture, "{0}.{1}", new object[] { type.Namespace, type.Name }); + } - /// - /// Creates properties for the given . - /// - /// The type to create properties for. - /// /// The member serialization mode for the type. - /// Properties for the given . - protected virtual IList CreateProperties(Type type, MemberSerialization memberSerialization) - { - List members = GetSerializableMembers(type); - if (members == null) - throw new JsonSerializationException("Null collection of seralizable members returned."); + /// + /// Creates properties for the given . + /// + /// The type to create properties for. + /// /// The member serialization mode for the type. + /// Properties for the given . + protected virtual IList CreateProperties(Type type, MemberSerialization memberSerialization) + { + List members = GetSerializableMembers(type); + if (members == null) + throw new JsonSerializationException("Null collection of seralizable members returned."); - JsonPropertyCollection properties = new JsonPropertyCollection(type); + JsonPropertyCollection properties = new JsonPropertyCollection(type); - foreach (MemberInfo member in members) - { - JsonProperty property = CreateProperty(member, memberSerialization); + foreach (MemberInfo member in members) + { + JsonProperty property = CreateProperty(member, memberSerialization); - if (property != null) - properties.AddProperty(property); - } + if (property != null) + properties.AddProperty(property); + } - IList orderedProperties = properties.OrderBy(p => p.Order ?? -1).ToList(); - return orderedProperties; - } + IList orderedProperties = properties.OrderBy(p => p.Order ?? -1).ToList(); + return orderedProperties; + } - /// - /// Creates the used by the serializer to get and set values from a member. - /// - /// The member. - /// The used by the serializer to get and set values from a member. - protected virtual IValueProvider CreateMemberValueProvider(MemberInfo member) - { - // warning - this method use to cause errors with Intellitrace. Retest in VS Ultimate after changes - IValueProvider valueProvider; + /// + /// Creates the used by the serializer to get and set values from a member. + /// + /// The member. + /// The used by the serializer to get and set values from a member. + protected virtual IValueProvider CreateMemberValueProvider(MemberInfo member) + { + // warning - this method use to cause errors with Intellitrace. Retest in VS Ultimate after changes + IValueProvider valueProvider; #if !(SILVERLIGHT || PORTABLE40 || PORTABLE || NETFX_CORE) - if (DynamicCodeGeneration) - valueProvider = new DynamicValueProvider(member); - else - valueProvider = new ReflectionValueProvider(member); + if (DynamicCodeGeneration) + valueProvider = new DynamicValueProvider(member); + else + valueProvider = new ReflectionValueProvider(member); #elif !(PORTABLE40) valueProvider = new ExpressionValueProvider(member); #else - valueProvider = new ReflectionValueProvider(member); + valueProvider = new ReflectionValueProvider(member); #endif - return valueProvider; - } + return valueProvider; + } - /// - /// Creates a for the given . - /// - /// The member's parent . - /// The member to create a for. - /// A created for the given . - protected virtual JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) - { - JsonProperty property = new JsonProperty(); - property.PropertyType = ReflectionUtils.GetMemberUnderlyingType(member); - property.DeclaringType = member.DeclaringType; - property.ValueProvider = CreateMemberValueProvider(member); + /// + /// Creates a for the given . + /// + /// The member's parent . + /// The member to create a for. + /// A created for the given . + protected virtual JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) + { + JsonProperty property = new JsonProperty(); + property.PropertyType = ReflectionUtils.GetMemberUnderlyingType(member); + property.DeclaringType = member.DeclaringType; + property.ValueProvider = CreateMemberValueProvider(member); - bool allowNonPublicAccess; - SetPropertySettingsFromAttributes(property, member, member.Name, member.DeclaringType, memberSerialization, out allowNonPublicAccess); + bool allowNonPublicAccess; + SetPropertySettingsFromAttributes(property, member, member.Name, member.DeclaringType, memberSerialization, out allowNonPublicAccess); - if (memberSerialization != MemberSerialization.Fields) - { - property.Readable = ReflectionUtils.CanReadMemberValue(member, allowNonPublicAccess); - property.Writable = ReflectionUtils.CanSetMemberValue(member, allowNonPublicAccess, property.HasMemberAttribute); - } - else - { - // write to readonly fields - property.Readable = true; - property.Writable = true; - } - property.ShouldSerialize = CreateShouldSerializeTest(member); + if (memberSerialization != MemberSerialization.Fields) + { + property.Readable = ReflectionUtils.CanReadMemberValue(member, allowNonPublicAccess); + property.Writable = ReflectionUtils.CanSetMemberValue(member, allowNonPublicAccess, property.HasMemberAttribute); + } + else + { + // write to readonly fields + property.Readable = true; + property.Writable = true; + } + property.ShouldSerialize = CreateShouldSerializeTest(member); - SetIsSpecifiedActions(property, member, allowNonPublicAccess); + SetIsSpecifiedActions(property, member, allowNonPublicAccess); - return property; - } + return property; + } - private void SetPropertySettingsFromAttributes(JsonProperty property, object attributeProvider, string name, Type declaringType, MemberSerialization memberSerialization, out bool allowNonPublicAccess) - { + private void SetPropertySettingsFromAttributes(JsonProperty property, object attributeProvider, string name, Type declaringType, MemberSerialization memberSerialization, out bool allowNonPublicAccess) + { #if !NET20 - DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(declaringType); + DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(declaringType); - MemberInfo memberInfo = attributeProvider as MemberInfo; + MemberInfo memberInfo = attributeProvider as MemberInfo; - DataMemberAttribute dataMemberAttribute; - if (dataContractAttribute != null && memberInfo != null) - dataMemberAttribute = JsonTypeReflector.GetDataMemberAttribute((MemberInfo) memberInfo); - else - dataMemberAttribute = null; + DataMemberAttribute dataMemberAttribute; + if (dataContractAttribute != null && memberInfo != null) + dataMemberAttribute = JsonTypeReflector.GetDataMemberAttribute((MemberInfo)memberInfo); + else + dataMemberAttribute = null; #endif - JsonPropertyAttribute propertyAttribute = JsonTypeReflector.GetAttribute(attributeProvider); - if (propertyAttribute != null) - property.HasMemberAttribute = true; + JsonPropertyAttribute propertyAttribute = JsonTypeReflector.GetAttribute(attributeProvider); + if (propertyAttribute != null) + property.HasMemberAttribute = true; - string mappedName; - if (propertyAttribute != null && propertyAttribute.PropertyName != null) - mappedName = propertyAttribute.PropertyName; + string mappedName; + if (propertyAttribute != null && propertyAttribute.PropertyName != null) + mappedName = propertyAttribute.PropertyName; #if !NET20 - else if (dataMemberAttribute != null && dataMemberAttribute.Name != null) - mappedName = dataMemberAttribute.Name; + else if (dataMemberAttribute != null && dataMemberAttribute.Name != null) + mappedName = dataMemberAttribute.Name; #endif - else - mappedName = name; + else + mappedName = name; - property.PropertyName = ResolvePropertyName(mappedName); - property.UnderlyingName = name; + property.PropertyName = ResolvePropertyName(mappedName); + property.UnderlyingName = name; - bool hasMemberAttribute = false; - if (propertyAttribute != null) - { - property._required = propertyAttribute._required; - property.Order = propertyAttribute._order; - property.DefaultValueHandling = propertyAttribute._defaultValueHandling; - hasMemberAttribute = true; - } + bool hasMemberAttribute = false; + if (propertyAttribute != null) + { + property._required = propertyAttribute._required; + property.Order = propertyAttribute._order; + property.DefaultValueHandling = propertyAttribute._defaultValueHandling; + hasMemberAttribute = true; + } #if !NET20 - else if (dataMemberAttribute != null) - { - property._required = (dataMemberAttribute.IsRequired) ? Required.AllowNull : Required.Default; - property.Order = (dataMemberAttribute.Order != -1) ? (int?) dataMemberAttribute.Order : null; - property.DefaultValueHandling = (!dataMemberAttribute.EmitDefaultValue) ? (DefaultValueHandling?) DefaultValueHandling.Ignore : null; - hasMemberAttribute = true; - } + else if (dataMemberAttribute != null) + { + property._required = (dataMemberAttribute.IsRequired) ? Required.AllowNull : Required.Default; + property.Order = (dataMemberAttribute.Order != -1) ? (int?)dataMemberAttribute.Order : null; + property.DefaultValueHandling = (!dataMemberAttribute.EmitDefaultValue) ? (DefaultValueHandling?)DefaultValueHandling.Ignore : null; + hasMemberAttribute = true; + } #endif - bool hasJsonIgnoreAttribute = - JsonTypeReflector.GetAttribute(attributeProvider) != null - // automatically ignore extension data dictionary property if it is public - || JsonTypeReflector.GetAttribute(attributeProvider) != null + bool hasJsonIgnoreAttribute = + JsonTypeReflector.GetAttribute(attributeProvider) != null + // automatically ignore extension data dictionary property if it is public + || JsonTypeReflector.GetAttribute(attributeProvider) != null #if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) - || JsonTypeReflector.GetAttribute(attributeProvider) != null + || JsonTypeReflector.GetAttribute(attributeProvider) != null #endif -; + ; - if (memberSerialization != MemberSerialization.OptIn) - { - bool hasIgnoreDataMemberAttribute = false; + if (memberSerialization != MemberSerialization.OptIn) + { + bool hasIgnoreDataMemberAttribute = false; #if !(NET20 || NET35) - hasIgnoreDataMemberAttribute = (JsonTypeReflector.GetAttribute(attributeProvider) != null); + hasIgnoreDataMemberAttribute = (JsonTypeReflector.GetAttribute(attributeProvider) != null); #endif - // ignored if it has JsonIgnore or NonSerialized or IgnoreDataMember attributes - property.Ignored = (hasJsonIgnoreAttribute || hasIgnoreDataMemberAttribute); - } - else - { - // ignored if it has JsonIgnore/NonSerialized or does not have DataMember or JsonProperty attributes - property.Ignored = (hasJsonIgnoreAttribute || !hasMemberAttribute); - } + // ignored if it has JsonIgnore or NonSerialized or IgnoreDataMember attributes + property.Ignored = (hasJsonIgnoreAttribute || hasIgnoreDataMemberAttribute); + } + else + { + // ignored if it has JsonIgnore/NonSerialized or does not have DataMember or JsonProperty attributes + property.Ignored = (hasJsonIgnoreAttribute || !hasMemberAttribute); + } - // resolve converter for property - // the class type might have a converter but the property converter takes presidence - property.Converter = JsonTypeReflector.GetJsonConverter(attributeProvider, property.PropertyType); - property.MemberConverter = JsonTypeReflector.GetJsonConverter(attributeProvider, property.PropertyType); + // resolve converter for property + // the class type might have a converter but the property converter takes presidence + property.Converter = JsonTypeReflector.GetJsonConverter(attributeProvider, property.PropertyType); + property.MemberConverter = JsonTypeReflector.GetJsonConverter(attributeProvider, property.PropertyType); - DefaultValueAttribute defaultValueAttribute = JsonTypeReflector.GetAttribute(attributeProvider); - if (defaultValueAttribute != null) - property.DefaultValue = defaultValueAttribute.Value; + DefaultValueAttribute defaultValueAttribute = JsonTypeReflector.GetAttribute(attributeProvider); + if (defaultValueAttribute != null) + property.DefaultValue = defaultValueAttribute.Value; - property.NullValueHandling = (propertyAttribute != null) ? propertyAttribute._nullValueHandling : null; - property.ReferenceLoopHandling = (propertyAttribute != null) ? propertyAttribute._referenceLoopHandling : null; - property.ObjectCreationHandling = (propertyAttribute != null) ? propertyAttribute._objectCreationHandling : null; - property.TypeNameHandling = (propertyAttribute != null) ? propertyAttribute._typeNameHandling : null; - property.IsReference = (propertyAttribute != null) ? propertyAttribute._isReference : null; + property.NullValueHandling = (propertyAttribute != null) ? propertyAttribute._nullValueHandling : null; + property.ReferenceLoopHandling = (propertyAttribute != null) ? propertyAttribute._referenceLoopHandling : null; + property.ObjectCreationHandling = (propertyAttribute != null) ? propertyAttribute._objectCreationHandling : null; + property.TypeNameHandling = (propertyAttribute != null) ? propertyAttribute._typeNameHandling : null; + property.IsReference = (propertyAttribute != null) ? propertyAttribute._isReference : null; - property.ItemIsReference = (propertyAttribute != null) ? propertyAttribute._itemIsReference : null; - property.ItemConverter = - (propertyAttribute != null && propertyAttribute.ItemConverterType != null) - ? JsonConverterAttribute.CreateJsonConverterInstance(propertyAttribute.ItemConverterType) - : null; - property.ItemReferenceLoopHandling = (propertyAttribute != null) ? propertyAttribute._itemReferenceLoopHandling : null; - property.ItemTypeNameHandling = (propertyAttribute != null) ? propertyAttribute._itemTypeNameHandling : null; + property.ItemIsReference = (propertyAttribute != null) ? propertyAttribute._itemIsReference : null; + property.ItemConverter = + (propertyAttribute != null && propertyAttribute.ItemConverterType != null) + ? JsonConverterAttribute.CreateJsonConverterInstance(propertyAttribute.ItemConverterType) + : null; + property.ItemReferenceLoopHandling = (propertyAttribute != null) ? propertyAttribute._itemReferenceLoopHandling : null; + property.ItemTypeNameHandling = (propertyAttribute != null) ? propertyAttribute._itemTypeNameHandling : null; - allowNonPublicAccess = false; - if ((DefaultMembersSearchFlags & BindingFlags.NonPublic) == BindingFlags.NonPublic) - allowNonPublicAccess = true; - if (propertyAttribute != null) - allowNonPublicAccess = true; - if (memberSerialization == MemberSerialization.Fields) - allowNonPublicAccess = true; + allowNonPublicAccess = false; + if ((DefaultMembersSearchFlags & BindingFlags.NonPublic) == BindingFlags.NonPublic) + allowNonPublicAccess = true; + if (propertyAttribute != null) + allowNonPublicAccess = true; + if (memberSerialization == MemberSerialization.Fields) + allowNonPublicAccess = true; #if !NET20 - if (dataMemberAttribute != null) - { - allowNonPublicAccess = true; - property.HasMemberAttribute = true; - } + if (dataMemberAttribute != null) + { + allowNonPublicAccess = true; + property.HasMemberAttribute = true; + } #endif + } + + private Predicate CreateShouldSerializeTest(MemberInfo member) + { + MethodInfo shouldSerializeMethod = member.DeclaringType.GetMethod(JsonTypeReflector.ShouldSerializePrefix + member.Name, ReflectionUtils.EmptyTypes); + + if (shouldSerializeMethod == null || shouldSerializeMethod.ReturnType != typeof(bool)) + return null; + + MethodCall shouldSerializeCall = + JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(shouldSerializeMethod); + + return o => (bool)shouldSerializeCall(o); + } + + private void SetIsSpecifiedActions(JsonProperty property, MemberInfo member, bool allowNonPublicAccess) + { + MemberInfo specifiedMember = member.DeclaringType.GetProperty(member.Name + JsonTypeReflector.SpecifiedPostfix); + if (specifiedMember == null) + specifiedMember = member.DeclaringType.GetField(member.Name + JsonTypeReflector.SpecifiedPostfix); + + if (specifiedMember == null || ReflectionUtils.GetMemberUnderlyingType(specifiedMember) != typeof(bool)) + { + return; + } + + Func specifiedPropertyGet = JsonTypeReflector.ReflectionDelegateFactory.CreateGet(specifiedMember); + + property.GetIsSpecified = o => (bool)specifiedPropertyGet(o); + + if (ReflectionUtils.CanSetMemberValue(specifiedMember, allowNonPublicAccess, false)) + property.SetIsSpecified = JsonTypeReflector.ReflectionDelegateFactory.CreateSet(specifiedMember); + } + + /// + /// Resolves the name of the property. + /// + /// Name of the property. + /// Name of the property. + protected internal virtual string ResolvePropertyName(string propertyName) + { + return propertyName; + } + + /// + /// Gets the resolved name of the property. + /// + /// Name of the property. + /// Name of the property. + public string GetResolvedPropertyName(string propertyName) + { + // this is a new method rather than changing the visibility of ResolvePropertyName to avoid + // a breaking change for anyone who has overidden the method + return ResolvePropertyName(propertyName); + } } - - private Predicate CreateShouldSerializeTest(MemberInfo member) - { - MethodInfo shouldSerializeMethod = member.DeclaringType.GetMethod(JsonTypeReflector.ShouldSerializePrefix + member.Name, ReflectionUtils.EmptyTypes); - - if (shouldSerializeMethod == null || shouldSerializeMethod.ReturnType != typeof(bool)) - return null; - - MethodCall shouldSerializeCall = - JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(shouldSerializeMethod); - - return o => (bool)shouldSerializeCall(o); - } - - private void SetIsSpecifiedActions(JsonProperty property, MemberInfo member, bool allowNonPublicAccess) - { - MemberInfo specifiedMember = member.DeclaringType.GetProperty(member.Name + JsonTypeReflector.SpecifiedPostfix); - if (specifiedMember == null) - specifiedMember = member.DeclaringType.GetField(member.Name + JsonTypeReflector.SpecifiedPostfix); - - if (specifiedMember == null || ReflectionUtils.GetMemberUnderlyingType(specifiedMember) != typeof(bool)) - { - return; - } - - Func specifiedPropertyGet = JsonTypeReflector.ReflectionDelegateFactory.CreateGet(specifiedMember); - - property.GetIsSpecified = o => (bool)specifiedPropertyGet(o); - - if (ReflectionUtils.CanSetMemberValue(specifiedMember, allowNonPublicAccess, false)) - property.SetIsSpecified = JsonTypeReflector.ReflectionDelegateFactory.CreateSet(specifiedMember); - } - - /// - /// Resolves the name of the property. - /// - /// Name of the property. - /// Name of the property. - protected internal virtual string ResolvePropertyName(string propertyName) - { - return propertyName; - } - - /// - /// Gets the resolved name of the property. - /// - /// Name of the property. - /// Name of the property. - public string GetResolvedPropertyName(string propertyName) - { - // this is a new method rather than changing the visibility of ResolvePropertyName to avoid - // a breaking change for anyone who has overidden the method - return ResolvePropertyName(propertyName); - } - } -} +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/DefaultReferenceResolver.cs b/Src/Newtonsoft.Json/Serialization/DefaultReferenceResolver.cs index ceb86b80..40787992 100644 --- a/Src/Newtonsoft.Json/Serialization/DefaultReferenceResolver.cs +++ b/Src/Newtonsoft.Json/Serialization/DefaultReferenceResolver.cs @@ -29,55 +29,55 @@ using System.Globalization; namespace Newtonsoft.Json.Serialization { - internal class DefaultReferenceResolver : IReferenceResolver - { - private int _referenceCount; - - private BidirectionalDictionary GetMappings(object context) + internal class DefaultReferenceResolver : IReferenceResolver { - JsonSerializerInternalBase internalSerializer; + private int _referenceCount; - if (context is JsonSerializerInternalBase) - internalSerializer = (JsonSerializerInternalBase) context; - else if (context is JsonSerializerProxy) - internalSerializer = ((JsonSerializerProxy) context).GetInternalSerializer(); - else - throw new JsonException("The DefaultReferenceResolver can only be used internally."); + private BidirectionalDictionary GetMappings(object context) + { + JsonSerializerInternalBase internalSerializer; - return internalSerializer.DefaultReferenceMappings; + if (context is JsonSerializerInternalBase) + internalSerializer = (JsonSerializerInternalBase)context; + else if (context is JsonSerializerProxy) + internalSerializer = ((JsonSerializerProxy)context).GetInternalSerializer(); + else + throw new JsonException("The DefaultReferenceResolver can only be used internally."); + + return internalSerializer.DefaultReferenceMappings; + } + + public object ResolveReference(object context, string reference) + { + object value; + GetMappings(context).TryGetByFirst(reference, out value); + return value; + } + + public string GetReference(object context, object value) + { + var mappings = GetMappings(context); + + string reference; + if (!mappings.TryGetBySecond(value, out reference)) + { + _referenceCount++; + reference = _referenceCount.ToString(CultureInfo.InvariantCulture); + mappings.Set(reference, value); + } + + return reference; + } + + public void AddReference(object context, string reference, object value) + { + GetMappings(context).Set(reference, value); + } + + public bool IsReferenced(object context, object value) + { + string reference; + return GetMappings(context).TryGetBySecond(value, out reference); + } } - - public object ResolveReference(object context, string reference) - { - object value; - GetMappings(context).TryGetByFirst(reference, out value); - return value; - } - - public string GetReference(object context, object value) - { - var mappings = GetMappings(context); - - string reference; - if (!mappings.TryGetBySecond(value, out reference)) - { - _referenceCount++; - reference = _referenceCount.ToString(CultureInfo.InvariantCulture); - mappings.Set(reference, value); - } - - return reference; - } - - public void AddReference(object context, string reference, object value) - { - GetMappings(context).Set(reference, value); - } - - public bool IsReferenced(object context, object value) - { - string reference; - return GetMappings(context).TryGetBySecond(value, out reference); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/DefaultSerializationBinder.cs b/Src/Newtonsoft.Json/Serialization/DefaultSerializationBinder.cs index c3ab114b..fe371e86 100644 --- a/Src/Newtonsoft.Json/Serialization/DefaultSerializationBinder.cs +++ b/Src/Newtonsoft.Json/Serialization/DefaultSerializationBinder.cs @@ -31,130 +31,130 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Serialization { - /// - /// The default serialization binder used when resolving and loading classes from type names. - /// - public class DefaultSerializationBinder : SerializationBinder - { - internal static readonly DefaultSerializationBinder Instance = new DefaultSerializationBinder(); - - private readonly ThreadSafeStore _typeCache = new ThreadSafeStore(GetTypeFromTypeNameKey); - - private static Type GetTypeFromTypeNameKey(TypeNameKey typeNameKey) + /// + /// The default serialization binder used when resolving and loading classes from type names. + /// + public class DefaultSerializationBinder : SerializationBinder { - string assemblyName = typeNameKey.AssemblyName; - string typeName = typeNameKey.TypeName; + internal static readonly DefaultSerializationBinder Instance = new DefaultSerializationBinder(); - if (assemblyName != null) - { - Assembly assembly; + private readonly ThreadSafeStore _typeCache = new ThreadSafeStore(GetTypeFromTypeNameKey); + + private static Type GetTypeFromTypeNameKey(TypeNameKey typeNameKey) + { + string assemblyName = typeNameKey.AssemblyName; + string typeName = typeNameKey.TypeName; + + if (assemblyName != null) + { + Assembly assembly; #if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) - // look, I don't like using obsolete methods as much as you do but this is the only way - // Assembly.Load won't check the GAC for a partial name + // look, I don't like using obsolete methods as much as you do but this is the only way + // Assembly.Load won't check the GAC for a partial name #pragma warning disable 618,612 - assembly = Assembly.LoadWithPartialName(assemblyName); + assembly = Assembly.LoadWithPartialName(assemblyName); #pragma warning restore 618,612 #elif NETFX_CORE || PORTABLE assembly = Assembly.Load(new AssemblyName(assemblyName)); #else - assembly = Assembly.Load(assemblyName); + assembly = Assembly.Load(assemblyName); #endif #if !(PORTABLE40 || PORTABLE || NETFX_CORE) - if (assembly == null) - { - // will find assemblies loaded with Assembly.LoadFile outside of the main directory - Assembly[] loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies(); - foreach (Assembly a in loadedAssemblies) - { - if (a.FullName == assemblyName) - { - assembly = a; - break; - } - } - } + if (assembly == null) + { + // will find assemblies loaded with Assembly.LoadFile outside of the main directory + Assembly[] loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies(); + foreach (Assembly a in loadedAssemblies) + { + if (a.FullName == assemblyName) + { + assembly = a; + break; + } + } + } #endif - if (assembly == null) - throw new JsonSerializationException("Could not load assembly '{0}'.".FormatWith(CultureInfo.InvariantCulture, assemblyName)); + if (assembly == null) + throw new JsonSerializationException("Could not load assembly '{0}'.".FormatWith(CultureInfo.InvariantCulture, assemblyName)); - Type type = assembly.GetType(typeName); - if (type == null) - throw new JsonSerializationException("Could not find type '{0}' in assembly '{1}'.".FormatWith(CultureInfo.InvariantCulture, typeName, assembly.FullName)); + Type type = assembly.GetType(typeName); + if (type == null) + throw new JsonSerializationException("Could not find type '{0}' in assembly '{1}'.".FormatWith(CultureInfo.InvariantCulture, typeName, assembly.FullName)); - return type; - } - else - { - return Type.GetType(typeName); - } - } + return type; + } + else + { + return Type.GetType(typeName); + } + } - internal struct TypeNameKey : IEquatable - { - internal readonly string AssemblyName; - internal readonly string TypeName; + internal struct TypeNameKey : IEquatable + { + internal readonly string AssemblyName; + internal readonly string TypeName; - public TypeNameKey(string assemblyName, string typeName) - { - AssemblyName = assemblyName; - TypeName = typeName; - } + public TypeNameKey(string assemblyName, string typeName) + { + AssemblyName = assemblyName; + TypeName = typeName; + } - public override int GetHashCode() - { - return ((AssemblyName != null) ? AssemblyName.GetHashCode() : 0) ^ ((TypeName != null) ? TypeName.GetHashCode() : 0); - } + public override int GetHashCode() + { + return ((AssemblyName != null) ? AssemblyName.GetHashCode() : 0) ^ ((TypeName != null) ? TypeName.GetHashCode() : 0); + } - public override bool Equals(object obj) - { - if (!(obj is TypeNameKey)) - return false; + public override bool Equals(object obj) + { + if (!(obj is TypeNameKey)) + return false; - return Equals((TypeNameKey)obj); - } + return Equals((TypeNameKey)obj); + } - public bool Equals(TypeNameKey other) - { - return (AssemblyName == other.AssemblyName && TypeName == other.TypeName); - } - } + public bool Equals(TypeNameKey other) + { + return (AssemblyName == other.AssemblyName && TypeName == other.TypeName); + } + } - /// - /// When overridden in a derived class, controls the binding of a serialized object to a type. - /// - /// Specifies the name of the serialized object. - /// Specifies the name of the serialized object. - /// - /// The type of the object the formatter creates a new instance of. - /// - public override Type BindToType(string assemblyName, string typeName) - { - return _typeCache.Get(new TypeNameKey(assemblyName, typeName)); - } + /// + /// When overridden in a derived class, controls the binding of a serialized object to a type. + /// + /// Specifies the name of the serialized object. + /// Specifies the name of the serialized object. + /// + /// The type of the object the formatter creates a new instance of. + /// + public override Type BindToType(string assemblyName, string typeName) + { + return _typeCache.Get(new TypeNameKey(assemblyName, typeName)); + } #if !(NET35 || NET20) - /// - /// When overridden in a derived class, controls the binding of a serialized object to a type. - /// - /// The type of the object the formatter creates a new instance of. - /// Specifies the name of the serialized object. - /// Specifies the name of the serialized object. - public override void BindToName(Type serializedType, out string assemblyName, out string typeName) - { + /// + /// When overridden in a derived class, controls the binding of a serialized object to a type. + /// + /// The type of the object the formatter creates a new instance of. + /// Specifies the name of the serialized object. + /// Specifies the name of the serialized object. + public override void BindToName(Type serializedType, out string assemblyName, out string typeName) + { #if NETFX_CORE || PORTABLE assemblyName = serializedType.GetTypeInfo().Assembly.FullName; typeName = serializedType.FullName; #elif !SILVERLIGHT - assemblyName = serializedType.Assembly.FullName; - typeName = serializedType.FullName; + assemblyName = serializedType.Assembly.FullName; + typeName = serializedType.FullName; #else assemblyName = null; typeName = serializedType.AssemblyQualifiedName; #endif - } + } #endif - } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/DiagnosticsTraceWriter.cs b/Src/Newtonsoft.Json/Serialization/DiagnosticsTraceWriter.cs index 96c75a95..9ab1e071 100644 --- a/Src/Newtonsoft.Json/Serialization/DiagnosticsTraceWriter.cs +++ b/Src/Newtonsoft.Json/Serialization/DiagnosticsTraceWriter.cs @@ -5,70 +5,71 @@ using DiagnosticsTrace = System.Diagnostics.Trace; namespace Newtonsoft.Json.Serialization { - /// - /// Represents a trace writer that writes to the application's instances. - /// - public class DiagnosticsTraceWriter : ITraceWriter - { /// - /// Gets the that will be used to filter the trace messages passed to the writer. - /// For example a filter level of Info will exclude Verbose messages and include Info, - /// Warning and Error messages. + /// Represents a trace writer that writes to the application's instances. /// - /// - /// The that will be used to filter the trace messages passed to the writer. - /// - public TraceLevel LevelFilter { get; set; } - - private TraceEventType GetTraceEventType(TraceLevel level) + public class DiagnosticsTraceWriter : ITraceWriter { - switch (level) - { - case TraceLevel.Error: - return TraceEventType.Error; - case TraceLevel.Warning: - return TraceEventType.Warning; - case TraceLevel.Info: - return TraceEventType.Information; - case TraceLevel.Verbose: - return TraceEventType.Verbose; - default: - throw new ArgumentOutOfRangeException("level"); - } - } + /// + /// Gets the that will be used to filter the trace messages passed to the writer. + /// For example a filter level of Info will exclude Verbose messages and include Info, + /// Warning and Error messages. + /// + /// + /// The that will be used to filter the trace messages passed to the writer. + /// + public TraceLevel LevelFilter { get; set; } - /// - /// Writes the specified trace level, message and optional exception. - /// - /// The at which to write this trace. - /// The trace message. - /// The trace exception. This parameter is optional. - public void Trace(TraceLevel level, string message, Exception ex) - { - if (level == TraceLevel.Off) - return; - - TraceEventCache eventCache = new TraceEventCache(); - TraceEventType traceEventType = GetTraceEventType(level); - - foreach (TraceListener listener in DiagnosticsTrace.Listeners) - { - if (!listener.IsThreadSafe) + private TraceEventType GetTraceEventType(TraceLevel level) { - lock (listener) - { - listener.TraceEvent(eventCache, "Newtonsoft.Json", traceEventType, 0, message); - } - } - else - { - listener.TraceEvent(eventCache, "Newtonsoft.Json", traceEventType, 0, message); + switch (level) + { + case TraceLevel.Error: + return TraceEventType.Error; + case TraceLevel.Warning: + return TraceEventType.Warning; + case TraceLevel.Info: + return TraceEventType.Information; + case TraceLevel.Verbose: + return TraceEventType.Verbose; + default: + throw new ArgumentOutOfRangeException("level"); + } } - if (DiagnosticsTrace.AutoFlush) - listener.Flush(); - } + /// + /// Writes the specified trace level, message and optional exception. + /// + /// The at which to write this trace. + /// The trace message. + /// The trace exception. This parameter is optional. + public void Trace(TraceLevel level, string message, Exception ex) + { + if (level == TraceLevel.Off) + return; + + TraceEventCache eventCache = new TraceEventCache(); + TraceEventType traceEventType = GetTraceEventType(level); + + foreach (TraceListener listener in DiagnosticsTrace.Listeners) + { + if (!listener.IsThreadSafe) + { + lock (listener) + { + listener.TraceEvent(eventCache, "Newtonsoft.Json", traceEventType, 0, message); + } + } + else + { + listener.TraceEvent(eventCache, "Newtonsoft.Json", traceEventType, 0, message); + } + + if (DiagnosticsTrace.AutoFlush) + listener.Flush(); + } + } } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/DynamicValueProvider.cs b/Src/Newtonsoft.Json/Serialization/DynamicValueProvider.cs index bb6a93d6..501fdeba 100644 --- a/Src/Newtonsoft.Json/Serialization/DynamicValueProvider.cs +++ b/Src/Newtonsoft.Json/Serialization/DynamicValueProvider.cs @@ -36,78 +36,79 @@ using System.Globalization; namespace Newtonsoft.Json.Serialization { - /// - /// Get and set values for a using dynamic methods. - /// - public class DynamicValueProvider : IValueProvider - { - private readonly MemberInfo _memberInfo; - private Func _getter; - private Action _setter; - /// - /// Initializes a new instance of the class. + /// Get and set values for a using dynamic methods. /// - /// The member info. - public DynamicValueProvider(MemberInfo memberInfo) + public class DynamicValueProvider : IValueProvider { - ValidationUtils.ArgumentNotNull(memberInfo, "memberInfo"); - _memberInfo = memberInfo; - } + private readonly MemberInfo _memberInfo; + private Func _getter; + private Action _setter; - /// - /// Sets the value. - /// - /// The target to set the value on. - /// The value to set on the target. - public void SetValue(object target, object value) - { - try - { - if (_setter == null) - _setter = DynamicReflectionDelegateFactory.Instance.CreateSet(_memberInfo); + /// + /// Initializes a new instance of the class. + /// + /// The member info. + public DynamicValueProvider(MemberInfo memberInfo) + { + ValidationUtils.ArgumentNotNull(memberInfo, "memberInfo"); + _memberInfo = memberInfo; + } + + /// + /// Sets the value. + /// + /// The target to set the value on. + /// The value to set on the target. + public void SetValue(object target, object value) + { + try + { + if (_setter == null) + _setter = DynamicReflectionDelegateFactory.Instance.CreateSet(_memberInfo); #if DEBUG - // dynamic method doesn't check whether the type is 'legal' to set - // add this check for unit tests - if (value == null) - { - if (!ReflectionUtils.IsNullable(ReflectionUtils.GetMemberUnderlyingType(_memberInfo))) - throw new JsonSerializationException("Incompatible value. Cannot set {0} to null.".FormatWith(CultureInfo.InvariantCulture, _memberInfo)); - } - else if (!ReflectionUtils.GetMemberUnderlyingType(_memberInfo).IsAssignableFrom(value.GetType())) - { - throw new JsonSerializationException("Incompatible value. Cannot set {0} to type {1}.".FormatWith(CultureInfo.InvariantCulture, _memberInfo, value.GetType())); - } + // dynamic method doesn't check whether the type is 'legal' to set + // add this check for unit tests + if (value == null) + { + if (!ReflectionUtils.IsNullable(ReflectionUtils.GetMemberUnderlyingType(_memberInfo))) + throw new JsonSerializationException("Incompatible value. Cannot set {0} to null.".FormatWith(CultureInfo.InvariantCulture, _memberInfo)); + } + else if (!ReflectionUtils.GetMemberUnderlyingType(_memberInfo).IsAssignableFrom(value.GetType())) + { + throw new JsonSerializationException("Incompatible value. Cannot set {0} to type {1}.".FormatWith(CultureInfo.InvariantCulture, _memberInfo, value.GetType())); + } #endif - _setter(target, value); - } - catch (Exception ex) - { - throw new JsonSerializationException("Error setting value to '{0}' on '{1}'.".FormatWith(CultureInfo.InvariantCulture, _memberInfo.Name, target.GetType()), ex); - } - } + _setter(target, value); + } + catch (Exception ex) + { + throw new JsonSerializationException("Error setting value to '{0}' on '{1}'.".FormatWith(CultureInfo.InvariantCulture, _memberInfo.Name, target.GetType()), ex); + } + } - /// - /// Gets the value. - /// - /// The target to get the value from. - /// The value. - public object GetValue(object target) - { - try - { - if (_getter == null) - _getter = DynamicReflectionDelegateFactory.Instance.CreateGet(_memberInfo); + /// + /// Gets the value. + /// + /// The target to get the value from. + /// The value. + public object GetValue(object target) + { + try + { + if (_getter == null) + _getter = DynamicReflectionDelegateFactory.Instance.CreateGet(_memberInfo); - return _getter(target); - } - catch (Exception ex) - { - throw new JsonSerializationException("Error getting value from '{0}' on '{1}'.".FormatWith(CultureInfo.InvariantCulture, _memberInfo.Name, target.GetType()), ex); - } + return _getter(target); + } + catch (Exception ex) + { + throw new JsonSerializationException("Error getting value from '{0}' on '{1}'.".FormatWith(CultureInfo.InvariantCulture, _memberInfo.Name, target.GetType()), ex); + } + } } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/ErrorContext.cs b/Src/Newtonsoft.Json/Serialization/ErrorContext.cs index 1c8e54c5..3bdf11ab 100644 --- a/Src/Newtonsoft.Json/Serialization/ErrorContext.cs +++ b/Src/Newtonsoft.Json/Serialization/ErrorContext.cs @@ -27,45 +27,49 @@ using System; namespace Newtonsoft.Json.Serialization { - /// - /// Provides information surrounding an error. - /// - public class ErrorContext - { - internal ErrorContext(object originalObject, object member, string path, Exception error) + /// + /// Provides information surrounding an error. + /// + public class ErrorContext { - OriginalObject = originalObject; - Member = member; - Error = error; - Path = path; + internal ErrorContext(object originalObject, object member, string path, Exception error) + { + OriginalObject = originalObject; + Member = member; + Error = error; + Path = path; + } + + internal bool Traced { get; set; } + + /// + /// Gets or sets the error. + /// + /// The error. + public Exception Error { get; private set; } + + /// + /// Gets the original object that caused the error. + /// + /// The original object that caused the error. + public object OriginalObject { get; private set; } + + /// + /// Gets the member that caused the error. + /// + /// The member that caused the error. + public object Member { get; private set; } + + /// + /// Gets the path of the JSON location where the error occurred. + /// + /// The path of the JSON location where the error occurred. + public string Path { get; private set; } + + /// + /// Gets or sets a value indicating whether this is handled. + /// + /// true if handled; otherwise, false. + public bool Handled { get; set; } } - - internal bool Traced { get; set; } - - /// - /// Gets or sets the error. - /// - /// The error. - public Exception Error { get; private set; } - /// - /// Gets the original object that caused the error. - /// - /// The original object that caused the error. - public object OriginalObject { get; private set; } - /// - /// Gets the member that caused the error. - /// - /// The member that caused the error. - public object Member { get; private set; } - /// - /// Gets the path of the JSON location where the error occurred. - /// - /// The path of the JSON location where the error occurred. - public string Path { get; private set; } - /// - /// Gets or sets a value indicating whether this is handled. - /// - /// true if handled; otherwise, false. - public bool Handled { get; set; } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/ErrorEventArgs.cs b/Src/Newtonsoft.Json/Serialization/ErrorEventArgs.cs index daa6dbee..cae7d035 100644 --- a/Src/Newtonsoft.Json/Serialization/ErrorEventArgs.cs +++ b/Src/Newtonsoft.Json/Serialization/ErrorEventArgs.cs @@ -27,31 +27,32 @@ using System; namespace Newtonsoft.Json.Serialization { - /// - /// Provides data for the Error event. - /// - public class ErrorEventArgs : EventArgs - { /// - /// Gets the current object the error event is being raised against. + /// Provides data for the Error event. /// - /// The current object the error event is being raised against. - public object CurrentObject { get; private set; } - /// - /// Gets the error context. - /// - /// The error context. - public ErrorContext ErrorContext { get; private set; } - - /// - /// Initializes a new instance of the class. - /// - /// The current object. - /// The error context. - public ErrorEventArgs(object currentObject, ErrorContext errorContext) + public class ErrorEventArgs : EventArgs { - CurrentObject = currentObject; - ErrorContext = errorContext; + /// + /// Gets the current object the error event is being raised against. + /// + /// The current object the error event is being raised against. + public object CurrentObject { get; private set; } + + /// + /// Gets the error context. + /// + /// The error context. + public ErrorContext ErrorContext { get; private set; } + + /// + /// Initializes a new instance of the class. + /// + /// The current object. + /// The error context. + public ErrorEventArgs(object currentObject, ErrorContext errorContext) + { + CurrentObject = currentObject; + ErrorContext = errorContext; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/ExpressionValueProvider.cs b/Src/Newtonsoft.Json/Serialization/ExpressionValueProvider.cs index faa3213b..47102d5e 100644 --- a/Src/Newtonsoft.Json/Serialization/ExpressionValueProvider.cs +++ b/Src/Newtonsoft.Json/Serialization/ExpressionValueProvider.cs @@ -36,78 +36,79 @@ using System.Globalization; namespace Newtonsoft.Json.Serialization { - /// - /// Get and set values for a using dynamic methods. - /// - public class ExpressionValueProvider : IValueProvider - { - private readonly MemberInfo _memberInfo; - private Func _getter; - private Action _setter; - /// - /// Initializes a new instance of the class. + /// Get and set values for a using dynamic methods. /// - /// The member info. - public ExpressionValueProvider(MemberInfo memberInfo) + public class ExpressionValueProvider : IValueProvider { - ValidationUtils.ArgumentNotNull(memberInfo, "memberInfo"); - _memberInfo = memberInfo; - } + private readonly MemberInfo _memberInfo; + private Func _getter; + private Action _setter; - /// - /// Sets the value. - /// - /// The target to set the value on. - /// The value to set on the target. - public void SetValue(object target, object value) - { - try - { - if (_setter == null) - _setter = ExpressionReflectionDelegateFactory.Instance.CreateSet(_memberInfo); + /// + /// Initializes a new instance of the class. + /// + /// The member info. + public ExpressionValueProvider(MemberInfo memberInfo) + { + ValidationUtils.ArgumentNotNull(memberInfo, "memberInfo"); + _memberInfo = memberInfo; + } + + /// + /// Sets the value. + /// + /// The target to set the value on. + /// The value to set on the target. + public void SetValue(object target, object value) + { + try + { + if (_setter == null) + _setter = ExpressionReflectionDelegateFactory.Instance.CreateSet(_memberInfo); #if DEBUG - // dynamic method doesn't check whether the type is 'legal' to set - // add this check for unit tests - if (value == null) - { - if (!ReflectionUtils.IsNullable(ReflectionUtils.GetMemberUnderlyingType(_memberInfo))) - throw new JsonSerializationException("Incompatible value. Cannot set {0} to null.".FormatWith(CultureInfo.InvariantCulture, _memberInfo)); - } - else if (!ReflectionUtils.GetMemberUnderlyingType(_memberInfo).IsAssignableFrom(value.GetType())) - { - throw new JsonSerializationException("Incompatible value. Cannot set {0} to type {1}.".FormatWith(CultureInfo.InvariantCulture, _memberInfo, value.GetType())); - } + // dynamic method doesn't check whether the type is 'legal' to set + // add this check for unit tests + if (value == null) + { + if (!ReflectionUtils.IsNullable(ReflectionUtils.GetMemberUnderlyingType(_memberInfo))) + throw new JsonSerializationException("Incompatible value. Cannot set {0} to null.".FormatWith(CultureInfo.InvariantCulture, _memberInfo)); + } + else if (!ReflectionUtils.GetMemberUnderlyingType(_memberInfo).IsAssignableFrom(value.GetType())) + { + throw new JsonSerializationException("Incompatible value. Cannot set {0} to type {1}.".FormatWith(CultureInfo.InvariantCulture, _memberInfo, value.GetType())); + } #endif - _setter(target, value); - } - catch (Exception ex) - { - throw new JsonSerializationException("Error setting value to '{0}' on '{1}'.".FormatWith(CultureInfo.InvariantCulture, _memberInfo.Name, target.GetType()), ex); - } - } + _setter(target, value); + } + catch (Exception ex) + { + throw new JsonSerializationException("Error setting value to '{0}' on '{1}'.".FormatWith(CultureInfo.InvariantCulture, _memberInfo.Name, target.GetType()), ex); + } + } - /// - /// Gets the value. - /// - /// The target to get the value from. - /// The value. - public object GetValue(object target) - { - try - { - if (_getter == null) - _getter = ExpressionReflectionDelegateFactory.Instance.CreateGet(_memberInfo); + /// + /// Gets the value. + /// + /// The target to get the value from. + /// The value. + public object GetValue(object target) + { + try + { + if (_getter == null) + _getter = ExpressionReflectionDelegateFactory.Instance.CreateGet(_memberInfo); - return _getter(target); - } - catch (Exception ex) - { - throw new JsonSerializationException("Error getting value from '{0}' on '{1}'.".FormatWith(CultureInfo.InvariantCulture, _memberInfo.Name, target.GetType()), ex); - } + return _getter(target); + } + catch (Exception ex) + { + throw new JsonSerializationException("Error getting value from '{0}' on '{1}'.".FormatWith(CultureInfo.InvariantCulture, _memberInfo.Name, target.GetType()), ex); + } + } } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/IContractResolver.cs b/Src/Newtonsoft.Json/Serialization/IContractResolver.cs index a5c5c597..10f44bad 100644 --- a/Src/Newtonsoft.Json/Serialization/IContractResolver.cs +++ b/Src/Newtonsoft.Json/Serialization/IContractResolver.cs @@ -27,20 +27,20 @@ using System; namespace Newtonsoft.Json.Serialization { - /// - /// Used by to resolves a for a given . - /// - /// - /// - /// - /// - public interface IContractResolver - { /// - /// Resolves the contract for a given type. + /// Used by to resolves a for a given . /// - /// The type to resolve a contract for. - /// The contract for a given type. - JsonContract ResolveContract(Type type); - } + /// + /// + /// + /// + public interface IContractResolver + { + /// + /// Resolves the contract for a given type. + /// + /// The type to resolve a contract for. + /// The contract for a given type. + JsonContract ResolveContract(Type type); + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/IReferenceResolver.cs b/Src/Newtonsoft.Json/Serialization/IReferenceResolver.cs index bd96b19f..271e3072 100644 --- a/Src/Newtonsoft.Json/Serialization/IReferenceResolver.cs +++ b/Src/Newtonsoft.Json/Serialization/IReferenceResolver.cs @@ -25,40 +25,43 @@ namespace Newtonsoft.Json.Serialization { - /// - /// Used to resolve references when serializing and deserializing JSON by the . - /// - public interface IReferenceResolver - { /// - /// Resolves a reference to its object. + /// Used to resolve references when serializing and deserializing JSON by the . /// - /// The serialization context. - /// The reference to resolve. - /// The object that - object ResolveReference(object context, string reference); - /// - /// Gets the reference for the sepecified object. - /// - /// The serialization context. - /// The object to get a reference for. - /// The reference to the object. - string GetReference(object context, object value); - /// - /// Determines whether the specified object is referenced. - /// - /// The serialization context. - /// The object to test for a reference. - /// - /// true if the specified object is referenced; otherwise, false. - /// - bool IsReferenced(object context, object value); - /// - /// Adds a reference to the specified object. - /// - /// The serialization context. - /// The reference. - /// The object to reference. - void AddReference(object context, string reference, object value); - } + public interface IReferenceResolver + { + /// + /// Resolves a reference to its object. + /// + /// The serialization context. + /// The reference to resolve. + /// The object that + object ResolveReference(object context, string reference); + + /// + /// Gets the reference for the sepecified object. + /// + /// The serialization context. + /// The object to get a reference for. + /// The reference to the object. + string GetReference(object context, object value); + + /// + /// Determines whether the specified object is referenced. + /// + /// The serialization context. + /// The object to test for a reference. + /// + /// true if the specified object is referenced; otherwise, false. + /// + bool IsReferenced(object context, object value); + + /// + /// Adds a reference to the specified object. + /// + /// The serialization context. + /// The reference. + /// The object to reference. + void AddReference(object context, string reference, object value); + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/ITraceWriter.cs b/Src/Newtonsoft.Json/Serialization/ITraceWriter.cs index 3f4f7bf5..46ed7845 100644 --- a/Src/Newtonsoft.Json/Serialization/ITraceWriter.cs +++ b/Src/Newtonsoft.Json/Serialization/ITraceWriter.cs @@ -1,27 +1,28 @@ using System; using System.Collections.Generic; using System.Diagnostics; + namespace Newtonsoft.Json.Serialization { - /// - /// Represents a trace writer. - /// - public interface ITraceWriter - { /// - /// Gets the that will be used to filter the trace messages passed to the writer. - /// For example a filter level of Info will exclude Verbose messages and include Info, - /// Warning and Error messages. + /// Represents a trace writer. /// - /// The that will be used to filter the trace messages passed to the writer. - TraceLevel LevelFilter { get; } + public interface ITraceWriter + { + /// + /// Gets the that will be used to filter the trace messages passed to the writer. + /// For example a filter level of Info will exclude Verbose messages and include Info, + /// Warning and Error messages. + /// + /// The that will be used to filter the trace messages passed to the writer. + TraceLevel LevelFilter { get; } - /// - /// Writes the specified trace level, message and optional exception. - /// - /// The at which to write this trace. - /// The trace message. - /// The trace exception. This parameter is optional. - void Trace(TraceLevel level, string message, Exception ex); - } + /// + /// Writes the specified trace level, message and optional exception. + /// + /// The at which to write this trace. + /// The trace message. + /// The trace exception. This parameter is optional. + void Trace(TraceLevel level, string message, Exception ex); + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/IValueProvider.cs b/Src/Newtonsoft.Json/Serialization/IValueProvider.cs index 9f75f7ff..921724f8 100644 --- a/Src/Newtonsoft.Json/Serialization/IValueProvider.cs +++ b/Src/Newtonsoft.Json/Serialization/IValueProvider.cs @@ -25,23 +25,23 @@ namespace Newtonsoft.Json.Serialization { - /// - /// Provides methods to get and set values. - /// - public interface IValueProvider - { /// - /// Sets the value. + /// Provides methods to get and set values. /// - /// The target to set the value on. - /// The value to set on the target. - void SetValue(object target, object value); + public interface IValueProvider + { + /// + /// Sets the value. + /// + /// The target to set the value on. + /// The value to set on the target. + void SetValue(object target, object value); - /// - /// Gets the value. - /// - /// The target to get the value from. - /// The value. - object GetValue(object target); - } + /// + /// Gets the value. + /// + /// The target to get the value from. + /// The value. + object GetValue(object target); + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs b/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs index 74bb4570..a6ead5b0 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs @@ -35,150 +35,151 @@ using System.Collections; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json.Serialization { - /// - /// Contract details for a used by the . - /// - public class JsonArrayContract : JsonContainerContract - { /// - /// Gets the of the collection items. + /// Contract details for a used by the . /// - /// The of the collection items. - public Type CollectionItemType { get; private set; } - - /// - /// Gets a value indicating whether the collection type is a multidimensional array. - /// - /// true if the collection type is a multidimensional array; otherwise, false. - public bool IsMultidimensionalArray { get; private set; } - - private readonly bool _isCollectionItemTypeNullableType; - private readonly Type _genericCollectionDefinitionType; - - private Type _genericWrapperType; - private MethodCall _genericWrapperCreator; - private Func _genericTemporaryCollectionCreator; - - internal bool IsArray { get; private set; } - internal bool ShouldCreateWrapper { get; private set; } - internal bool CanDeserialize { get; private set; } - internal MethodBase ParametrizedConstructor { get; private set; } - - /// - /// Initializes a new instance of the class. - /// - /// The underlying type for the contract. - public JsonArrayContract(Type underlyingType) - : base(underlyingType) + public class JsonArrayContract : JsonContainerContract { - ContractType = JsonContractType.Array; - IsArray = CreatedType.IsArray; + /// + /// Gets the of the collection items. + /// + /// The of the collection items. + public Type CollectionItemType { get; private set; } - bool canDeserialize; + /// + /// Gets a value indicating whether the collection type is a multidimensional array. + /// + /// true if the collection type is a multidimensional array; otherwise, false. + public bool IsMultidimensionalArray { get; private set; } - Type tempCollectionType; - if (IsArray) - { - CollectionItemType = ReflectionUtils.GetCollectionItemType(UnderlyingType); - IsReadOnlyOrFixedSize = true; - _genericCollectionDefinitionType = typeof(List<>).MakeGenericType(CollectionItemType); + private readonly bool _isCollectionItemTypeNullableType; + private readonly Type _genericCollectionDefinitionType; - canDeserialize = true; - IsMultidimensionalArray = (IsArray && UnderlyingType.GetArrayRank() > 1); - } - else if (typeof(IList).IsAssignableFrom(underlyingType)) - { - if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(ICollection<>), out _genericCollectionDefinitionType)) - CollectionItemType = _genericCollectionDefinitionType.GetGenericArguments()[0]; - else - CollectionItemType = ReflectionUtils.GetCollectionItemType(underlyingType); + private Type _genericWrapperType; + private MethodCall _genericWrapperCreator; + private Func _genericTemporaryCollectionCreator; - if (underlyingType == typeof(IList)) - CreatedType = typeof(List); + internal bool IsArray { get; private set; } + internal bool ShouldCreateWrapper { get; private set; } + internal bool CanDeserialize { get; private set; } + internal MethodBase ParametrizedConstructor { get; private set; } - if (CollectionItemType != null) - ParametrizedConstructor = CollectionUtils.ResolveEnumableCollectionConstructor(underlyingType, CollectionItemType); + /// + /// Initializes a new instance of the class. + /// + /// The underlying type for the contract. + public JsonArrayContract(Type underlyingType) + : base(underlyingType) + { + ContractType = JsonContractType.Array; + IsArray = CreatedType.IsArray; - IsReadOnlyOrFixedSize = ReflectionUtils.InheritsGenericDefinition(underlyingType, typeof(ReadOnlyCollection<>)); - canDeserialize = true; - } - else if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(ICollection<>), out _genericCollectionDefinitionType)) - { - CollectionItemType = _genericCollectionDefinitionType.GetGenericArguments()[0]; + bool canDeserialize; - if (ReflectionUtils.IsGenericDefinition(underlyingType, typeof(ICollection<>)) - || ReflectionUtils.IsGenericDefinition(underlyingType, typeof(IList<>))) - CreatedType = typeof(List<>).MakeGenericType(CollectionItemType); + Type tempCollectionType; + if (IsArray) + { + CollectionItemType = ReflectionUtils.GetCollectionItemType(UnderlyingType); + IsReadOnlyOrFixedSize = true; + _genericCollectionDefinitionType = typeof(List<>).MakeGenericType(CollectionItemType); + + canDeserialize = true; + IsMultidimensionalArray = (IsArray && UnderlyingType.GetArrayRank() > 1); + } + else if (typeof(IList).IsAssignableFrom(underlyingType)) + { + if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(ICollection<>), out _genericCollectionDefinitionType)) + CollectionItemType = _genericCollectionDefinitionType.GetGenericArguments()[0]; + else + CollectionItemType = ReflectionUtils.GetCollectionItemType(underlyingType); + + if (underlyingType == typeof(IList)) + CreatedType = typeof(List); + + if (CollectionItemType != null) + ParametrizedConstructor = CollectionUtils.ResolveEnumableCollectionConstructor(underlyingType, CollectionItemType); + + IsReadOnlyOrFixedSize = ReflectionUtils.InheritsGenericDefinition(underlyingType, typeof(ReadOnlyCollection<>)); + canDeserialize = true; + } + else if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(ICollection<>), out _genericCollectionDefinitionType)) + { + CollectionItemType = _genericCollectionDefinitionType.GetGenericArguments()[0]; + + if (ReflectionUtils.IsGenericDefinition(underlyingType, typeof(ICollection<>)) + || ReflectionUtils.IsGenericDefinition(underlyingType, typeof(IList<>))) + CreatedType = typeof(List<>).MakeGenericType(CollectionItemType); #if !(NET20 || NET35 || PORTABLE40) - if (ReflectionUtils.IsGenericDefinition(underlyingType, typeof(ISet<>))) - CreatedType = typeof(HashSet<>).MakeGenericType(CollectionItemType); + if (ReflectionUtils.IsGenericDefinition(underlyingType, typeof(ISet<>))) + CreatedType = typeof(HashSet<>).MakeGenericType(CollectionItemType); #endif - ParametrizedConstructor = CollectionUtils.ResolveEnumableCollectionConstructor(underlyingType, CollectionItemType); - canDeserialize = true; - ShouldCreateWrapper = true; - } + ParametrizedConstructor = CollectionUtils.ResolveEnumableCollectionConstructor(underlyingType, CollectionItemType); + canDeserialize = true; + ShouldCreateWrapper = true; + } #if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - else if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(IReadOnlyCollection<>), out tempCollectionType)) - { - CollectionItemType = underlyingType.GetGenericArguments()[0]; + else if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(IReadOnlyCollection<>), out tempCollectionType)) + { + CollectionItemType = underlyingType.GetGenericArguments()[0]; - if (ReflectionUtils.IsGenericDefinition(underlyingType, typeof(IReadOnlyCollection<>)) - || ReflectionUtils.IsGenericDefinition(underlyingType, typeof(IReadOnlyList<>))) - CreatedType = typeof(ReadOnlyCollection<>).MakeGenericType(CollectionItemType); + if (ReflectionUtils.IsGenericDefinition(underlyingType, typeof(IReadOnlyCollection<>)) + || ReflectionUtils.IsGenericDefinition(underlyingType, typeof(IReadOnlyList<>))) + CreatedType = typeof(ReadOnlyCollection<>).MakeGenericType(CollectionItemType); - _genericCollectionDefinitionType = typeof(List<>).MakeGenericType(CollectionItemType); - ParametrizedConstructor = CollectionUtils.ResolveEnumableCollectionConstructor(CreatedType, CollectionItemType); - IsReadOnlyOrFixedSize = true; - canDeserialize = (ParametrizedConstructor != null); - } + _genericCollectionDefinitionType = typeof(List<>).MakeGenericType(CollectionItemType); + ParametrizedConstructor = CollectionUtils.ResolveEnumableCollectionConstructor(CreatedType, CollectionItemType); + IsReadOnlyOrFixedSize = true; + canDeserialize = (ParametrizedConstructor != null); + } #endif - else if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(IEnumerable<>), out tempCollectionType)) - { - CollectionItemType = tempCollectionType.GetGenericArguments()[0]; + else if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(IEnumerable<>), out tempCollectionType)) + { + CollectionItemType = tempCollectionType.GetGenericArguments()[0]; - if (ReflectionUtils.IsGenericDefinition(UnderlyingType, typeof(IEnumerable<>))) - CreatedType = typeof(List<>).MakeGenericType(CollectionItemType); + if (ReflectionUtils.IsGenericDefinition(UnderlyingType, typeof(IEnumerable<>))) + CreatedType = typeof(List<>).MakeGenericType(CollectionItemType); - ParametrizedConstructor = CollectionUtils.ResolveEnumableCollectionConstructor(underlyingType, CollectionItemType); + ParametrizedConstructor = CollectionUtils.ResolveEnumableCollectionConstructor(underlyingType, CollectionItemType); - if (underlyingType.IsGenericType() && underlyingType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) - { - _genericCollectionDefinitionType = tempCollectionType; + if (underlyingType.IsGenericType() && underlyingType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) + { + _genericCollectionDefinitionType = tempCollectionType; - IsReadOnlyOrFixedSize = false; - ShouldCreateWrapper = false; - canDeserialize = true; - } - else - { - _genericCollectionDefinitionType = typeof(List<>).MakeGenericType(CollectionItemType); + IsReadOnlyOrFixedSize = false; + ShouldCreateWrapper = false; + canDeserialize = true; + } + else + { + _genericCollectionDefinitionType = typeof(List<>).MakeGenericType(CollectionItemType); - IsReadOnlyOrFixedSize = true; - ShouldCreateWrapper = true; - canDeserialize = (ParametrizedConstructor != null); - } - } - else - { - // types that implement IEnumerable and nothing else - canDeserialize = false; - ShouldCreateWrapper = true; - } + IsReadOnlyOrFixedSize = true; + ShouldCreateWrapper = true; + canDeserialize = (ParametrizedConstructor != null); + } + } + else + { + // types that implement IEnumerable and nothing else + canDeserialize = false; + ShouldCreateWrapper = true; + } - CanDeserialize = canDeserialize; + CanDeserialize = canDeserialize; - if (CollectionItemType != null) - _isCollectionItemTypeNullableType = ReflectionUtils.IsNullableType(CollectionItemType); + if (CollectionItemType != null) + _isCollectionItemTypeNullableType = ReflectionUtils.IsNullableType(CollectionItemType); #if (NET20 || NET35) - // bug in .NET 2.0 & 3.5 that List> throws an error when adding null via IList.Add(object) - // wrapper will handle calling Add(T) instead + // bug in .NET 2.0 & 3.5 that List> throws an error when adding null via IList.Add(object) + // wrapper will handle calling Add(T) instead if (_isCollectionItemTypeNullableType && (ReflectionUtils.InheritsGenericDefinition(CreatedType, typeof(List<>), out tempCollectionType) || (IsArray && !IsMultidimensionalArray))) @@ -188,50 +189,50 @@ namespace Newtonsoft.Json.Serialization #endif #if !(NET20 || NET35 || NET40 || PORTABLE40) - Type immutableCreatedType; - MethodBase immutableParameterizedCreator; - if (ImmutableCollectionsUtils.TryBuildImmutableForArrayContract(underlyingType, CollectionItemType, out immutableCreatedType, out immutableParameterizedCreator)) - { - CreatedType = immutableCreatedType; - ParametrizedConstructor = immutableParameterizedCreator; - IsReadOnlyOrFixedSize = true; - CanDeserialize = true; - } + Type immutableCreatedType; + MethodBase immutableParameterizedCreator; + if (ImmutableCollectionsUtils.TryBuildImmutableForArrayContract(underlyingType, CollectionItemType, out immutableCreatedType, out immutableParameterizedCreator)) + { + CreatedType = immutableCreatedType; + ParametrizedConstructor = immutableParameterizedCreator; + IsReadOnlyOrFixedSize = true; + CanDeserialize = true; + } #endif + } + + internal IWrappedCollection CreateWrapper(object list) + { + if (_genericWrapperCreator == null) + { + _genericWrapperType = typeof(CollectionWrapper<>).MakeGenericType(CollectionItemType); + + Type constructorArgument; + + if (ReflectionUtils.InheritsGenericDefinition(_genericCollectionDefinitionType, typeof(List<>)) + || _genericCollectionDefinitionType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) + constructorArgument = typeof(ICollection<>).MakeGenericType(CollectionItemType); + else + constructorArgument = _genericCollectionDefinitionType; + + ConstructorInfo genericWrapperConstructor = _genericWrapperType.GetConstructor(new[] { constructorArgument }); + _genericWrapperCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(genericWrapperConstructor); + } + + return (IWrappedCollection)_genericWrapperCreator(null, list); + } + + internal IList CreateTemporaryCollection() + { + if (_genericTemporaryCollectionCreator == null) + { + // multidimensional array will also have array instances in it + Type collectionItemType = (IsMultidimensionalArray) ? typeof(object) : CollectionItemType; + Type temporaryListType = typeof(List<>).MakeGenericType(collectionItemType); + _genericTemporaryCollectionCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateDefaultConstructor(temporaryListType); + } + + return (IList)_genericTemporaryCollectionCreator(); + } } - - internal IWrappedCollection CreateWrapper(object list) - { - if (_genericWrapperCreator == null) - { - _genericWrapperType = typeof(CollectionWrapper<>).MakeGenericType(CollectionItemType); - - Type constructorArgument; - - if (ReflectionUtils.InheritsGenericDefinition(_genericCollectionDefinitionType, typeof(List<>)) - || _genericCollectionDefinitionType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) - constructorArgument = typeof(ICollection<>).MakeGenericType(CollectionItemType); - else - constructorArgument = _genericCollectionDefinitionType; - - ConstructorInfo genericWrapperConstructor = _genericWrapperType.GetConstructor(new[] { constructorArgument }); - _genericWrapperCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(genericWrapperConstructor); - } - - return (IWrappedCollection)_genericWrapperCreator(null, list); - } - - internal IList CreateTemporaryCollection() - { - if (_genericTemporaryCollectionCreator == null) - { - // multidimensional array will also have array instances in it - Type collectionItemType = (IsMultidimensionalArray) ? typeof(object) : CollectionItemType; - Type temporaryListType = typeof(List<>).MakeGenericType(collectionItemType); - _genericTemporaryCollectionCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateDefaultConstructor(temporaryListType); - } - - return (IList)_genericTemporaryCollectionCreator(); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/JsonContainerContract.cs b/Src/Newtonsoft.Json/Serialization/JsonContainerContract.cs index 98783b0b..6e47807d 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonContainerContract.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonContainerContract.cs @@ -32,84 +32,85 @@ using System.Collections; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json.Serialization { - /// - /// Contract details for a used by the . - /// - public class JsonContainerContract : JsonContract - { - private JsonContract _itemContract; - private JsonContract _finalItemContract; - - // will be null for containers that don't have an item type (e.g. IList) or for complex objects - internal JsonContract ItemContract + /// + /// Contract details for a used by the . + /// + public class JsonContainerContract : JsonContract { - get { return _itemContract; } - set - { - _itemContract = value; - if (_itemContract != null) + private JsonContract _itemContract; + private JsonContract _finalItemContract; + + // will be null for containers that don't have an item type (e.g. IList) or for complex objects + internal JsonContract ItemContract { - _finalItemContract = (_itemContract.UnderlyingType.IsSealed()) ? _itemContract : null; + get { return _itemContract; } + set + { + _itemContract = value; + if (_itemContract != null) + { + _finalItemContract = (_itemContract.UnderlyingType.IsSealed()) ? _itemContract : null; + } + else + { + _finalItemContract = null; + } + } } - else + + // the final (i.e. can't be inherited from like a sealed class or valuetype) item contract + internal JsonContract FinalItemContract { - _finalItemContract = null; + get { return _finalItemContract; } + } + + /// + /// Gets or sets the default collection items . + /// + /// The converter. + public JsonConverter ItemConverter { get; set; } + + /// + /// Gets or sets a value indicating whether the collection items preserve object references. + /// + /// true if collection items preserve object references; otherwise, false. + public bool? ItemIsReference { get; set; } + + /// + /// Gets or sets the collection item reference loop handling. + /// + /// The reference loop handling. + public ReferenceLoopHandling? ItemReferenceLoopHandling { get; set; } + + /// + /// Gets or sets the collection item type name handling. + /// + /// The type name handling. + public TypeNameHandling? ItemTypeNameHandling { get; set; } + + /// + /// Initializes a new instance of the class. + /// + /// The underlying type for the contract. + internal JsonContainerContract(Type underlyingType) + : base(underlyingType) + { + JsonContainerAttribute jsonContainerAttribute = JsonTypeReflector.GetJsonContainerAttribute(underlyingType); + + if (jsonContainerAttribute != null) + { + if (jsonContainerAttribute.ItemConverterType != null) + ItemConverter = JsonConverterAttribute.CreateJsonConverterInstance(jsonContainerAttribute.ItemConverterType); + + ItemIsReference = jsonContainerAttribute._itemIsReference; + ItemReferenceLoopHandling = jsonContainerAttribute._itemReferenceLoopHandling; + ItemTypeNameHandling = jsonContainerAttribute._itemTypeNameHandling; + } } - } } - - // the final (i.e. can't be inherited from like a sealed class or valuetype) item contract - internal JsonContract FinalItemContract - { - get { return _finalItemContract; } - } - - /// - /// Gets or sets the default collection items . - /// - /// The converter. - public JsonConverter ItemConverter { get; set; } - - /// - /// Gets or sets a value indicating whether the collection items preserve object references. - /// - /// true if collection items preserve object references; otherwise, false. - public bool? ItemIsReference { get; set; } - - /// - /// Gets or sets the collection item reference loop handling. - /// - /// The reference loop handling. - public ReferenceLoopHandling? ItemReferenceLoopHandling { get; set; } - - /// - /// Gets or sets the collection item type name handling. - /// - /// The type name handling. - public TypeNameHandling? ItemTypeNameHandling { get; set; } - - /// - /// Initializes a new instance of the class. - /// - /// The underlying type for the contract. - internal JsonContainerContract(Type underlyingType) - : base(underlyingType) - { - JsonContainerAttribute jsonContainerAttribute = JsonTypeReflector.GetJsonContainerAttribute(underlyingType); - - if (jsonContainerAttribute != null) - { - if (jsonContainerAttribute.ItemConverterType != null) - ItemConverter = JsonConverterAttribute.CreateJsonConverterInstance(jsonContainerAttribute.ItemConverterType); - - ItemIsReference = jsonContainerAttribute._itemIsReference; - ItemReferenceLoopHandling = jsonContainerAttribute._itemReferenceLoopHandling; - ItemTypeNameHandling = jsonContainerAttribute._itemTypeNameHandling; - } - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/JsonContract.cs b/Src/Newtonsoft.Json/Serialization/JsonContract.cs index c90149a7..24b3191e 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonContract.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonContract.cs @@ -33,375 +33,375 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Serialization { - internal enum JsonContractType - { - None, - Object, - Array, - Primitive, - String, - Dictionary, + internal enum JsonContractType + { + None, + Object, + Array, + Primitive, + String, + Dictionary, #if !(NET35 || NET20 || PORTABLE40) - Dynamic, + Dynamic, #endif #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - Serializable, + Serializable, #endif - Linq - } - - /// - /// Handles serialization callback events. - /// - /// The object that raised the callback event. - /// The streaming context. - public delegate void SerializationCallback(object o, StreamingContext context); - - /// - /// Handles serialization error callback events. - /// - /// The object that raised the callback event. - /// The streaming context. - /// The error context. - public delegate void SerializationErrorCallback(object o, StreamingContext context, ErrorContext errorContext); - - /// - /// Sets extension data for an object during deserialization. - /// - /// The object to set extension data on. - /// The extension data key. - /// The extension data value. - public delegate void ExtensionDataSetter(object o, string key, object value); - - /// - /// Gets extension data for an object during serialization. - /// - /// The object to set extension data on. - public delegate IEnumerable> ExtensionDataGetter(object o); - - /// - /// Contract details for a used by the . - /// - public abstract class JsonContract - { - internal bool IsNullable; - internal bool IsConvertable; - internal bool IsSealed; - internal bool IsEnum; - internal Type NonNullableUnderlyingType; - internal ReadType InternalReadType; - internal JsonContractType ContractType; - internal bool IsReadOnlyOrFixedSize; - internal bool IsInstantiable; - - private List _onDeserializedCallbacks; - private IList _onDeserializingCallbacks; - private IList _onSerializedCallbacks; - private IList _onSerializingCallbacks; - private IList _onErrorCallbacks; - - /// - /// Gets the underlying type for the contract. - /// - /// The underlying type for the contract. - public Type UnderlyingType { get; private set; } - - /// - /// Gets or sets the type created during deserialization. - /// - /// The type created during deserialization. - public Type CreatedType { get; set; } - - /// - /// Gets or sets whether this type contract is serialized as a reference. - /// - /// Whether this type contract is serialized as a reference. - public bool? IsReference { get; set; } - - /// - /// Gets or sets the default for this contract. - /// - /// The converter. - public JsonConverter Converter { get; set; } - - // internally specified JsonConverter's to override default behavour - // checked for after passed in converters and attribute specified converters - internal JsonConverter InternalConverter { get; set; } - - /// - /// Gets or sets all methods called immediately after deserialization of the object. - /// - /// The methods called immediately after deserialization of the object. - public IList OnDeserializedCallbacks - { - get - { - if (_onDeserializedCallbacks == null) - _onDeserializedCallbacks = new List(); - - return _onDeserializedCallbacks; - } + Linq } /// - /// Gets or sets all methods called during deserialization of the object. + /// Handles serialization callback events. /// - /// The methods called during deserialization of the object. - public IList OnDeserializingCallbacks - { - get - { - if (_onDeserializingCallbacks == null) - _onDeserializingCallbacks = new List(); - - return _onDeserializingCallbacks; - } - } + /// The object that raised the callback event. + /// The streaming context. + public delegate void SerializationCallback(object o, StreamingContext context); /// - /// Gets or sets all methods called after serialization of the object graph. + /// Handles serialization error callback events. /// - /// The methods called after serialization of the object graph. - public IList OnSerializedCallbacks - { - get - { - if (_onSerializedCallbacks == null) - _onSerializedCallbacks = new List(); - - return _onSerializedCallbacks; - } - } + /// The object that raised the callback event. + /// The streaming context. + /// The error context. + public delegate void SerializationErrorCallback(object o, StreamingContext context, ErrorContext errorContext); /// - /// Gets or sets all methods called before serialization of the object. + /// Sets extension data for an object during deserialization. /// - /// The methods called before serialization of the object. - public IList OnSerializingCallbacks - { - get - { - if (_onSerializingCallbacks == null) - _onSerializingCallbacks = new List(); - - return _onSerializingCallbacks; - } - } + /// The object to set extension data on. + /// The extension data key. + /// The extension data value. + public delegate void ExtensionDataSetter(object o, string key, object value); /// - /// Gets or sets all method called when an error is thrown during the serialization of the object. + /// Gets extension data for an object during serialization. /// - /// The methods called when an error is thrown during the serialization of the object. - public IList OnErrorCallbacks - { - get - { - if (_onErrorCallbacks == null) - _onErrorCallbacks = new List(); - - return _onErrorCallbacks; - } - } + /// The object to set extension data on. + public delegate IEnumerable> ExtensionDataGetter(object o); /// - /// Gets or sets the method called immediately after deserialization of the object. + /// Contract details for a used by the . /// - /// The method called immediately after deserialization of the object. - [Obsolete("This property is obsolete and has been replaced by the OnDeserializedCallbacks collection.")] - public MethodInfo OnDeserialized + public abstract class JsonContract { - get { return (OnDeserializedCallbacks.Count > 0) ? OnDeserializedCallbacks[0].Method() : null; } - set - { - OnDeserializedCallbacks.Clear(); - OnDeserializedCallbacks.Add(CreateSerializationCallback(value)); - } - } + internal bool IsNullable; + internal bool IsConvertable; + internal bool IsSealed; + internal bool IsEnum; + internal Type NonNullableUnderlyingType; + internal ReadType InternalReadType; + internal JsonContractType ContractType; + internal bool IsReadOnlyOrFixedSize; + internal bool IsInstantiable; - /// - /// Gets or sets the method called during deserialization of the object. - /// - /// The method called during deserialization of the object. - [Obsolete("This property is obsolete and has been replaced by the OnDeserializingCallbacks collection.")] - public MethodInfo OnDeserializing - { - get { return (OnDeserializingCallbacks.Count > 0) ? OnDeserializingCallbacks[0].Method() : null; } - set - { - OnDeserializingCallbacks.Clear(); - OnDeserializingCallbacks.Add(CreateSerializationCallback(value)); - } - } + private List _onDeserializedCallbacks; + private IList _onDeserializingCallbacks; + private IList _onSerializedCallbacks; + private IList _onSerializingCallbacks; + private IList _onErrorCallbacks; - /// - /// Gets or sets the method called after serialization of the object graph. - /// - /// The method called after serialization of the object graph. - [Obsolete("This property is obsolete and has been replaced by the OnSerializedCallbacks collection.")] - public MethodInfo OnSerialized - { - get { return (OnSerializedCallbacks.Count > 0) ? OnSerializedCallbacks[0].Method() : null; } - set - { - OnSerializedCallbacks.Clear(); - OnSerializedCallbacks.Add(CreateSerializationCallback(value)); - } - } + /// + /// Gets the underlying type for the contract. + /// + /// The underlying type for the contract. + public Type UnderlyingType { get; private set; } - /// - /// Gets or sets the method called before serialization of the object. - /// - /// The method called before serialization of the object. - [Obsolete("This property is obsolete and has been replaced by the OnSerializingCallbacks collection.")] - public MethodInfo OnSerializing - { - get { return (OnSerializingCallbacks.Count > 0) ? OnSerializingCallbacks[0].Method() : null; } - set - { - OnSerializingCallbacks.Clear(); - OnSerializingCallbacks.Add(CreateSerializationCallback(value)); - } - } + /// + /// Gets or sets the type created during deserialization. + /// + /// The type created during deserialization. + public Type CreatedType { get; set; } - /// - /// Gets or sets the method called when an error is thrown during the serialization of the object. - /// - /// The method called when an error is thrown during the serialization of the object. - [Obsolete("This property is obsolete and has been replaced by the OnErrorCallbacks collection.")] - public MethodInfo OnError - { - get { return (OnErrorCallbacks.Count > 0) ? OnErrorCallbacks[0].Method() : null; } - set - { - OnErrorCallbacks.Clear(); - OnErrorCallbacks.Add(CreateSerializationErrorCallback(value)); - } - } + /// + /// Gets or sets whether this type contract is serialized as a reference. + /// + /// Whether this type contract is serialized as a reference. + public bool? IsReference { get; set; } - /// - /// Gets or sets the default creator method used to create the object. - /// - /// The default creator method used to create the object. - public Func DefaultCreator { get; set; } + /// + /// Gets or sets the default for this contract. + /// + /// The converter. + public JsonConverter Converter { get; set; } - /// - /// Gets or sets a value indicating whether the default creator is non public. - /// - /// true if the default object creator is non-public; otherwise, false. - public bool DefaultCreatorNonPublic { get; set; } + // internally specified JsonConverter's to override default behavour + // checked for after passed in converters and attribute specified converters + internal JsonConverter InternalConverter { get; set; } - internal JsonContract(Type underlyingType) - { - ValidationUtils.ArgumentNotNull(underlyingType, "underlyingType"); + /// + /// Gets or sets all methods called immediately after deserialization of the object. + /// + /// The methods called immediately after deserialization of the object. + public IList OnDeserializedCallbacks + { + get + { + if (_onDeserializedCallbacks == null) + _onDeserializedCallbacks = new List(); - UnderlyingType = underlyingType; + return _onDeserializedCallbacks; + } + } - IsSealed = underlyingType.IsSealed(); - IsInstantiable = !(underlyingType.IsInterface() || underlyingType.IsAbstract()); + /// + /// Gets or sets all methods called during deserialization of the object. + /// + /// The methods called during deserialization of the object. + public IList OnDeserializingCallbacks + { + get + { + if (_onDeserializingCallbacks == null) + _onDeserializingCallbacks = new List(); - IsNullable = ReflectionUtils.IsNullable(underlyingType); - NonNullableUnderlyingType = (IsNullable && ReflectionUtils.IsNullableType(underlyingType)) ? Nullable.GetUnderlyingType(underlyingType) : underlyingType; + return _onDeserializingCallbacks; + } + } - CreatedType = NonNullableUnderlyingType; + /// + /// Gets or sets all methods called after serialization of the object graph. + /// + /// The methods called after serialization of the object graph. + public IList OnSerializedCallbacks + { + get + { + if (_onSerializedCallbacks == null) + _onSerializedCallbacks = new List(); - IsConvertable = ConvertUtils.IsConvertible(NonNullableUnderlyingType); - IsEnum = NonNullableUnderlyingType.IsEnum(); + return _onSerializedCallbacks; + } + } - if (NonNullableUnderlyingType == typeof(byte[])) - { - InternalReadType = ReadType.ReadAsBytes; - } - else if (NonNullableUnderlyingType == typeof(int)) - { - InternalReadType = ReadType.ReadAsInt32; - } - else if (NonNullableUnderlyingType == typeof(decimal)) - { - InternalReadType = ReadType.ReadAsDecimal; - } - else if (NonNullableUnderlyingType == typeof(string)) - { - InternalReadType = ReadType.ReadAsString; - } - else if (NonNullableUnderlyingType == typeof(DateTime)) - { - InternalReadType = ReadType.ReadAsDateTime; - } + /// + /// Gets or sets all methods called before serialization of the object. + /// + /// The methods called before serialization of the object. + public IList OnSerializingCallbacks + { + get + { + if (_onSerializingCallbacks == null) + _onSerializingCallbacks = new List(); + + return _onSerializingCallbacks; + } + } + + /// + /// Gets or sets all method called when an error is thrown during the serialization of the object. + /// + /// The methods called when an error is thrown during the serialization of the object. + public IList OnErrorCallbacks + { + get + { + if (_onErrorCallbacks == null) + _onErrorCallbacks = new List(); + + return _onErrorCallbacks; + } + } + + /// + /// Gets or sets the method called immediately after deserialization of the object. + /// + /// The method called immediately after deserialization of the object. + [Obsolete("This property is obsolete and has been replaced by the OnDeserializedCallbacks collection.")] + public MethodInfo OnDeserialized + { + get { return (OnDeserializedCallbacks.Count > 0) ? OnDeserializedCallbacks[0].Method() : null; } + set + { + OnDeserializedCallbacks.Clear(); + OnDeserializedCallbacks.Add(CreateSerializationCallback(value)); + } + } + + /// + /// Gets or sets the method called during deserialization of the object. + /// + /// The method called during deserialization of the object. + [Obsolete("This property is obsolete and has been replaced by the OnDeserializingCallbacks collection.")] + public MethodInfo OnDeserializing + { + get { return (OnDeserializingCallbacks.Count > 0) ? OnDeserializingCallbacks[0].Method() : null; } + set + { + OnDeserializingCallbacks.Clear(); + OnDeserializingCallbacks.Add(CreateSerializationCallback(value)); + } + } + + /// + /// Gets or sets the method called after serialization of the object graph. + /// + /// The method called after serialization of the object graph. + [Obsolete("This property is obsolete and has been replaced by the OnSerializedCallbacks collection.")] + public MethodInfo OnSerialized + { + get { return (OnSerializedCallbacks.Count > 0) ? OnSerializedCallbacks[0].Method() : null; } + set + { + OnSerializedCallbacks.Clear(); + OnSerializedCallbacks.Add(CreateSerializationCallback(value)); + } + } + + /// + /// Gets or sets the method called before serialization of the object. + /// + /// The method called before serialization of the object. + [Obsolete("This property is obsolete and has been replaced by the OnSerializingCallbacks collection.")] + public MethodInfo OnSerializing + { + get { return (OnSerializingCallbacks.Count > 0) ? OnSerializingCallbacks[0].Method() : null; } + set + { + OnSerializingCallbacks.Clear(); + OnSerializingCallbacks.Add(CreateSerializationCallback(value)); + } + } + + /// + /// Gets or sets the method called when an error is thrown during the serialization of the object. + /// + /// The method called when an error is thrown during the serialization of the object. + [Obsolete("This property is obsolete and has been replaced by the OnErrorCallbacks collection.")] + public MethodInfo OnError + { + get { return (OnErrorCallbacks.Count > 0) ? OnErrorCallbacks[0].Method() : null; } + set + { + OnErrorCallbacks.Clear(); + OnErrorCallbacks.Add(CreateSerializationErrorCallback(value)); + } + } + + /// + /// Gets or sets the default creator method used to create the object. + /// + /// The default creator method used to create the object. + public Func DefaultCreator { get; set; } + + /// + /// Gets or sets a value indicating whether the default creator is non public. + /// + /// true if the default object creator is non-public; otherwise, false. + public bool DefaultCreatorNonPublic { get; set; } + + internal JsonContract(Type underlyingType) + { + ValidationUtils.ArgumentNotNull(underlyingType, "underlyingType"); + + UnderlyingType = underlyingType; + + IsSealed = underlyingType.IsSealed(); + IsInstantiable = !(underlyingType.IsInterface() || underlyingType.IsAbstract()); + + IsNullable = ReflectionUtils.IsNullable(underlyingType); + NonNullableUnderlyingType = (IsNullable && ReflectionUtils.IsNullableType(underlyingType)) ? Nullable.GetUnderlyingType(underlyingType) : underlyingType; + + CreatedType = NonNullableUnderlyingType; + + IsConvertable = ConvertUtils.IsConvertible(NonNullableUnderlyingType); + IsEnum = NonNullableUnderlyingType.IsEnum(); + + if (NonNullableUnderlyingType == typeof(byte[])) + { + InternalReadType = ReadType.ReadAsBytes; + } + else if (NonNullableUnderlyingType == typeof(int)) + { + InternalReadType = ReadType.ReadAsInt32; + } + else if (NonNullableUnderlyingType == typeof(decimal)) + { + InternalReadType = ReadType.ReadAsDecimal; + } + else if (NonNullableUnderlyingType == typeof(string)) + { + InternalReadType = ReadType.ReadAsString; + } + else if (NonNullableUnderlyingType == typeof(DateTime)) + { + InternalReadType = ReadType.ReadAsDateTime; + } #if !NET20 - else if (NonNullableUnderlyingType == typeof(DateTimeOffset)) - { - InternalReadType = ReadType.ReadAsDateTimeOffset; - } + else if (NonNullableUnderlyingType == typeof(DateTimeOffset)) + { + InternalReadType = ReadType.ReadAsDateTimeOffset; + } #endif - else - { - InternalReadType = ReadType.Read; - } - } - - internal void InvokeOnSerializing(object o, StreamingContext context) - { - if (_onSerializingCallbacks != null) - { - foreach (SerializationCallback callback in _onSerializingCallbacks) - { - callback(o, context); + else + { + InternalReadType = ReadType.Read; + } } - } - } - internal void InvokeOnSerialized(object o, StreamingContext context) - { - if (_onSerializedCallbacks != null) - { - foreach (SerializationCallback callback in _onSerializedCallbacks) + internal void InvokeOnSerializing(object o, StreamingContext context) { - callback(o, context); + if (_onSerializingCallbacks != null) + { + foreach (SerializationCallback callback in _onSerializingCallbacks) + { + callback(o, context); + } + } } - } - } - internal void InvokeOnDeserializing(object o, StreamingContext context) - { - if (_onDeserializingCallbacks != null) - { - foreach (SerializationCallback callback in _onDeserializingCallbacks) + internal void InvokeOnSerialized(object o, StreamingContext context) { - callback(o, context); + if (_onSerializedCallbacks != null) + { + foreach (SerializationCallback callback in _onSerializedCallbacks) + { + callback(o, context); + } + } } - } - } - internal void InvokeOnDeserialized(object o, StreamingContext context) - { - if (_onDeserializedCallbacks != null) - { - foreach (SerializationCallback callback in _onDeserializedCallbacks) + internal void InvokeOnDeserializing(object o, StreamingContext context) { - callback(o, context); + if (_onDeserializingCallbacks != null) + { + foreach (SerializationCallback callback in _onDeserializingCallbacks) + { + callback(o, context); + } + } } - } - } - internal void InvokeOnError(object o, StreamingContext context, ErrorContext errorContext) - { - if (_onErrorCallbacks != null) - { - foreach (SerializationErrorCallback callback in _onErrorCallbacks) + internal void InvokeOnDeserialized(object o, StreamingContext context) { - callback(o, context, errorContext); + if (_onDeserializedCallbacks != null) + { + foreach (SerializationCallback callback in _onDeserializedCallbacks) + { + callback(o, context); + } + } } - } - } - internal static SerializationCallback CreateSerializationCallback(MethodInfo callbackMethodInfo) - { - return (o, context) => callbackMethodInfo.Invoke(o, new object[] { context }); - } + internal void InvokeOnError(object o, StreamingContext context, ErrorContext errorContext) + { + if (_onErrorCallbacks != null) + { + foreach (SerializationErrorCallback callback in _onErrorCallbacks) + { + callback(o, context, errorContext); + } + } + } - internal static SerializationErrorCallback CreateSerializationErrorCallback(MethodInfo callbackMethodInfo) - { - return (o, context, econtext) => callbackMethodInfo.Invoke(o, new object[] { context, econtext }); + internal static SerializationCallback CreateSerializationCallback(MethodInfo callbackMethodInfo) + { + return (o, context) => callbackMethodInfo.Invoke(o, new object[] { context }); + } + + internal static SerializationErrorCallback CreateSerializationErrorCallback(MethodInfo callbackMethodInfo) + { + return (o, context, econtext) => callbackMethodInfo.Invoke(o, new object[] { context, econtext }); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs b/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs index 1622ff9e..c84121bf 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs @@ -29,101 +29,103 @@ using System.Collections.ObjectModel; using System.Reflection; using Newtonsoft.Json.Utilities; using System.Collections; + #if NET20 using Newtonsoft.Json.Utilities.LinqBridge; #endif namespace Newtonsoft.Json.Serialization { - /// - /// Contract details for a used by the . - /// - public class JsonDictionaryContract : JsonContainerContract - { /// - /// Gets or sets the property name resolver. + /// Contract details for a used by the . /// - /// The property name resolver. - public Func PropertyNameResolver { get; set; } - - /// - /// Gets the of the dictionary keys. - /// - /// The of the dictionary keys. - public Type DictionaryKeyType { get; private set; } - /// - /// Gets the of the dictionary values. - /// - /// The of the dictionary values. - public Type DictionaryValueType { get; private set; } - - internal JsonContract KeyContract { get; set; } - - private readonly bool _isDictionaryValueTypeNullableType; - private readonly Type _genericCollectionDefinitionType; - - private Type _genericWrapperType; - private MethodCall _genericWrapperCreator; - - private Func _genericTemporaryDictionaryCreator; - - internal bool ShouldCreateWrapper { get; private set; } - internal MethodBase ParametrizedConstructor { get; private set; } - - /// - /// Initializes a new instance of the class. - /// - /// The underlying type for the contract. - public JsonDictionaryContract(Type underlyingType) - : base(underlyingType) + public class JsonDictionaryContract : JsonContainerContract { - ContractType = JsonContractType.Dictionary; + /// + /// Gets or sets the property name resolver. + /// + /// The property name resolver. + public Func PropertyNameResolver { get; set; } - Type keyType; - Type valueType; + /// + /// Gets the of the dictionary keys. + /// + /// The of the dictionary keys. + public Type DictionaryKeyType { get; private set; } - if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(IDictionary<,>), out _genericCollectionDefinitionType)) - { - keyType = _genericCollectionDefinitionType.GetGenericArguments()[0]; - valueType = _genericCollectionDefinitionType.GetGenericArguments()[1]; + /// + /// Gets the of the dictionary values. + /// + /// The of the dictionary values. + public Type DictionaryValueType { get; private set; } - if (ReflectionUtils.IsGenericDefinition(UnderlyingType, typeof(IDictionary<,>))) - CreatedType = typeof(Dictionary<,>).MakeGenericType(keyType, valueType); + internal JsonContract KeyContract { get; set; } + + private readonly bool _isDictionaryValueTypeNullableType; + private readonly Type _genericCollectionDefinitionType; + + private Type _genericWrapperType; + private MethodCall _genericWrapperCreator; + + private Func _genericTemporaryDictionaryCreator; + + internal bool ShouldCreateWrapper { get; private set; } + internal MethodBase ParametrizedConstructor { get; private set; } + + /// + /// Initializes a new instance of the class. + /// + /// The underlying type for the contract. + public JsonDictionaryContract(Type underlyingType) + : base(underlyingType) + { + ContractType = JsonContractType.Dictionary; + + Type keyType; + Type valueType; + + if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(IDictionary<,>), out _genericCollectionDefinitionType)) + { + keyType = _genericCollectionDefinitionType.GetGenericArguments()[0]; + valueType = _genericCollectionDefinitionType.GetGenericArguments()[1]; + + if (ReflectionUtils.IsGenericDefinition(UnderlyingType, typeof(IDictionary<,>))) + CreatedType = typeof(Dictionary<,>).MakeGenericType(keyType, valueType); #if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - IsReadOnlyOrFixedSize = ReflectionUtils.InheritsGenericDefinition(underlyingType, typeof(ReadOnlyDictionary<,>)); + IsReadOnlyOrFixedSize = ReflectionUtils.InheritsGenericDefinition(underlyingType, typeof(ReadOnlyDictionary<,>)); #endif - } + } #if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - else if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(IReadOnlyDictionary<,>), out _genericCollectionDefinitionType)) - { - keyType = _genericCollectionDefinitionType.GetGenericArguments()[0]; - valueType = _genericCollectionDefinitionType.GetGenericArguments()[1]; + else if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(IReadOnlyDictionary<,>), out _genericCollectionDefinitionType)) + { + keyType = _genericCollectionDefinitionType.GetGenericArguments()[0]; + valueType = _genericCollectionDefinitionType.GetGenericArguments()[1]; - if (ReflectionUtils.IsGenericDefinition(UnderlyingType, typeof(IReadOnlyDictionary<,>))) - CreatedType = typeof(ReadOnlyDictionary<,>).MakeGenericType(keyType, valueType); + if (ReflectionUtils.IsGenericDefinition(UnderlyingType, typeof(IReadOnlyDictionary<,>))) + CreatedType = typeof(ReadOnlyDictionary<,>).MakeGenericType(keyType, valueType); - IsReadOnlyOrFixedSize = true; - } + IsReadOnlyOrFixedSize = true; + } #endif - else - { - ReflectionUtils.GetDictionaryKeyValueTypes(UnderlyingType, out keyType, out valueType); + else + { + ReflectionUtils.GetDictionaryKeyValueTypes(UnderlyingType, out keyType, out valueType); - if (UnderlyingType == typeof(IDictionary)) - CreatedType = typeof(Dictionary); - } + if (UnderlyingType == typeof(IDictionary)) + CreatedType = typeof(Dictionary); + } - if (keyType != null && valueType != null) - ParametrizedConstructor = CollectionUtils.ResolveEnumableCollectionConstructor(CreatedType, typeof(KeyValuePair<,>).MakeGenericType(keyType, valueType)); + if (keyType != null && valueType != null) + ParametrizedConstructor = CollectionUtils.ResolveEnumableCollectionConstructor(CreatedType, typeof(KeyValuePair<,>).MakeGenericType(keyType, valueType)); - ShouldCreateWrapper = !typeof(IDictionary).IsAssignableFrom(CreatedType); + ShouldCreateWrapper = !typeof(IDictionary).IsAssignableFrom(CreatedType); - DictionaryKeyType = keyType; - DictionaryValueType = valueType; + DictionaryKeyType = keyType; + DictionaryValueType = valueType; - if (DictionaryValueType != null) - _isDictionaryValueTypeNullableType = ReflectionUtils.IsNullableType(DictionaryValueType); + if (DictionaryValueType != null) + _isDictionaryValueTypeNullableType = ReflectionUtils.IsNullableType(DictionaryValueType); #if (NET20 || NET35) Type tempDictioanryType; @@ -138,40 +140,40 @@ namespace Newtonsoft.Json.Serialization #endif #if !(NET20 || NET35 || NET40 || PORTABLE40) - Type immutableCreatedType; - MethodBase immutableParameterizedCreator; - if (ImmutableCollectionsUtils.TryBuildImmutableForDictionaryContract(underlyingType, DictionaryKeyType, DictionaryValueType, out immutableCreatedType, out immutableParameterizedCreator)) - { - CreatedType = immutableCreatedType; - ParametrizedConstructor = immutableParameterizedCreator; - IsReadOnlyOrFixedSize = true; - } + Type immutableCreatedType; + MethodBase immutableParameterizedCreator; + if (ImmutableCollectionsUtils.TryBuildImmutableForDictionaryContract(underlyingType, DictionaryKeyType, DictionaryValueType, out immutableCreatedType, out immutableParameterizedCreator)) + { + CreatedType = immutableCreatedType; + ParametrizedConstructor = immutableParameterizedCreator; + IsReadOnlyOrFixedSize = true; + } #endif + } + + internal IWrappedDictionary CreateWrapper(object dictionary) + { + if (_genericWrapperCreator == null) + { + _genericWrapperType = typeof(DictionaryWrapper<,>).MakeGenericType(DictionaryKeyType, DictionaryValueType); + + ConstructorInfo genericWrapperConstructor = _genericWrapperType.GetConstructor(new[] { _genericCollectionDefinitionType }); + _genericWrapperCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(genericWrapperConstructor); + } + + return (IWrappedDictionary)_genericWrapperCreator(null, dictionary); + } + + internal IDictionary CreateTemporaryDictionary() + { + if (_genericTemporaryDictionaryCreator == null) + { + Type temporaryDictionaryType = typeof(Dictionary<,>).MakeGenericType(DictionaryKeyType, DictionaryValueType); + + _genericTemporaryDictionaryCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateDefaultConstructor(temporaryDictionaryType); + } + + return (IDictionary)_genericTemporaryDictionaryCreator(); + } } - - internal IWrappedDictionary CreateWrapper(object dictionary) - { - if (_genericWrapperCreator == null) - { - _genericWrapperType = typeof(DictionaryWrapper<,>).MakeGenericType(DictionaryKeyType, DictionaryValueType); - - ConstructorInfo genericWrapperConstructor = _genericWrapperType.GetConstructor(new[] { _genericCollectionDefinitionType }); - _genericWrapperCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(genericWrapperConstructor); - } - - return (IWrappedDictionary)_genericWrapperCreator(null, dictionary); - } - - internal IDictionary CreateTemporaryDictionary() - { - if (_genericTemporaryDictionaryCreator == null) - { - Type temporaryDictionaryType = typeof(Dictionary<,>).MakeGenericType(DictionaryKeyType, DictionaryValueType); - - _genericTemporaryDictionaryCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateDefaultConstructor(temporaryDictionaryType); - } - - return (IDictionary)_genericTemporaryDictionaryCreator(); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/JsonDynamicContract.cs b/Src/Newtonsoft.Json/Serialization/JsonDynamicContract.cs index 6092dbf3..549ff675 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonDynamicContract.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonDynamicContract.cs @@ -34,85 +34,86 @@ using System.Collections; namespace Newtonsoft.Json.Serialization { - /// - /// Contract details for a used by the . - /// - public class JsonDynamicContract : JsonContainerContract - { /// - /// Gets the object's properties. + /// Contract details for a used by the . /// - /// The object's properties. - public JsonPropertyCollection Properties { get; private set; } - - /// - /// Gets or sets the property name resolver. - /// - /// The property name resolver. - public Func PropertyNameResolver { get; set; } - - private readonly ThreadSafeStore>> _callSiteGetters = - new ThreadSafeStore>>(CreateCallSiteGetter); - - private readonly ThreadSafeStore>> _callSiteSetters = - new ThreadSafeStore>>(CreateCallSiteSetter); - - private static CallSite> CreateCallSiteGetter(string name) + public class JsonDynamicContract : JsonContainerContract { - GetMemberBinder getMemberBinder = (GetMemberBinder)DynamicUtils.BinderWrapper.GetMember(name, typeof(DynamicUtils)); + /// + /// Gets the object's properties. + /// + /// The object's properties. + public JsonPropertyCollection Properties { get; private set; } - return CallSite>.Create(new NoThrowGetBinderMember(getMemberBinder)); + /// + /// Gets or sets the property name resolver. + /// + /// The property name resolver. + public Func PropertyNameResolver { get; set; } + + private readonly ThreadSafeStore>> _callSiteGetters = + new ThreadSafeStore>>(CreateCallSiteGetter); + + private readonly ThreadSafeStore>> _callSiteSetters = + new ThreadSafeStore>>(CreateCallSiteSetter); + + private static CallSite> CreateCallSiteGetter(string name) + { + GetMemberBinder getMemberBinder = (GetMemberBinder)DynamicUtils.BinderWrapper.GetMember(name, typeof(DynamicUtils)); + + return CallSite>.Create(new NoThrowGetBinderMember(getMemberBinder)); + } + + private static CallSite> CreateCallSiteSetter(string name) + { + SetMemberBinder binder = (SetMemberBinder)DynamicUtils.BinderWrapper.SetMember(name, typeof(DynamicUtils)); + + return CallSite>.Create(new NoThrowSetBinderMember(binder)); + } + + /// + /// Initializes a new instance of the class. + /// + /// The underlying type for the contract. + public JsonDynamicContract(Type underlyingType) + : base(underlyingType) + { + ContractType = JsonContractType.Dynamic; + + Properties = new JsonPropertyCollection(UnderlyingType); + } + + internal bool TryGetMember(IDynamicMetaObjectProvider dynamicProvider, string name, out object value) + { + ValidationUtils.ArgumentNotNull(dynamicProvider, "dynamicProvider"); + + CallSite> callSite = _callSiteGetters.Get(name); + + object result = callSite.Target(callSite, dynamicProvider); + + if (!ReferenceEquals(result, NoThrowExpressionVisitor.ErrorResult)) + { + value = result; + return true; + } + else + { + value = null; + return false; + } + } + + internal bool TrySetMember(IDynamicMetaObjectProvider dynamicProvider, string name, object value) + { + ValidationUtils.ArgumentNotNull(dynamicProvider, "dynamicProvider"); + + CallSite> callSite = _callSiteSetters.Get(name); + + object result = callSite.Target(callSite, dynamicProvider, value); + + return !ReferenceEquals(result, NoThrowExpressionVisitor.ErrorResult); + } } - - private static CallSite> CreateCallSiteSetter(string name) - { - SetMemberBinder binder = (SetMemberBinder)DynamicUtils.BinderWrapper.SetMember(name, typeof(DynamicUtils)); - - return CallSite>.Create(new NoThrowSetBinderMember(binder)); - } - - /// - /// Initializes a new instance of the class. - /// - /// The underlying type for the contract. - public JsonDynamicContract(Type underlyingType) - : base(underlyingType) - { - ContractType = JsonContractType.Dynamic; - - Properties = new JsonPropertyCollection(UnderlyingType); - } - - internal bool TryGetMember(IDynamicMetaObjectProvider dynamicProvider, string name, out object value) - { - ValidationUtils.ArgumentNotNull(dynamicProvider, "dynamicProvider"); - - CallSite> callSite = _callSiteGetters.Get(name); - - object result = callSite.Target(callSite, dynamicProvider); - - if (!ReferenceEquals(result, NoThrowExpressionVisitor.ErrorResult)) - { - value = result; - return true; - } - else - { - value = null; - return false; - } - } - - internal bool TrySetMember(IDynamicMetaObjectProvider dynamicProvider, string name, object value) - { - ValidationUtils.ArgumentNotNull(dynamicProvider, "dynamicProvider"); - - CallSite> callSite = _callSiteSetters.Get(name); - - object result = callSite.Target(callSite, dynamicProvider, value); - - return !ReferenceEquals(result, NoThrowExpressionVisitor.ErrorResult); - } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/JsonFormatterConverter.cs b/Src/Newtonsoft.Json/Serialization/JsonFormatterConverter.cs index e6a5533c..31d37d9a 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonFormatterConverter.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonFormatterConverter.cs @@ -32,120 +32,121 @@ using Newtonsoft.Json.Linq; namespace Newtonsoft.Json.Serialization { - internal class JsonFormatterConverter : IFormatterConverter - { - private readonly JsonSerializer _serializer; - - public JsonFormatterConverter(JsonSerializer serializer) + internal class JsonFormatterConverter : IFormatterConverter { - ValidationUtils.ArgumentNotNull(serializer, "serializer"); + private readonly JsonSerializer _serializer; - _serializer = serializer; + public JsonFormatterConverter(JsonSerializer serializer) + { + ValidationUtils.ArgumentNotNull(serializer, "serializer"); + + _serializer = serializer; + } + + private T GetTokenValue(object value) + { + ValidationUtils.ArgumentNotNull(value, "value"); + + JValue v = (JValue)value; + return (T)System.Convert.ChangeType(v.Value, typeof(T), CultureInfo.InvariantCulture); + } + + public object Convert(object value, Type type) + { + ValidationUtils.ArgumentNotNull(value, "value"); + + JToken token = value as JToken; + if (token == null) + throw new ArgumentException("Value is not a JToken.", "value"); + + return _serializer.Deserialize(token.CreateReader(), type); + } + + public object Convert(object value, TypeCode typeCode) + { + ValidationUtils.ArgumentNotNull(value, "value"); + + if (value is JValue) + value = ((JValue)value).Value; + + return System.Convert.ChangeType(value, typeCode, CultureInfo.InvariantCulture); + } + + public bool ToBoolean(object value) + { + return GetTokenValue(value); + } + + public byte ToByte(object value) + { + return GetTokenValue(value); + } + + public char ToChar(object value) + { + return GetTokenValue(value); + } + + public DateTime ToDateTime(object value) + { + return GetTokenValue(value); + } + + public decimal ToDecimal(object value) + { + return GetTokenValue(value); + } + + public double ToDouble(object value) + { + return GetTokenValue(value); + } + + public short ToInt16(object value) + { + return GetTokenValue(value); + } + + public int ToInt32(object value) + { + return GetTokenValue(value); + } + + public long ToInt64(object value) + { + return GetTokenValue(value); + } + + public sbyte ToSByte(object value) + { + return GetTokenValue(value); + } + + public float ToSingle(object value) + { + return GetTokenValue(value); + } + + public string ToString(object value) + { + return GetTokenValue(value); + } + + public ushort ToUInt16(object value) + { + return GetTokenValue(value); + } + + public uint ToUInt32(object value) + { + return GetTokenValue(value); + } + + public ulong ToUInt64(object value) + { + return GetTokenValue(value); + } } - - private T GetTokenValue(object value) - { - ValidationUtils.ArgumentNotNull(value, "value"); - - JValue v = (JValue)value; - return (T)System.Convert.ChangeType(v.Value, typeof(T), CultureInfo.InvariantCulture); - } - - public object Convert(object value, Type type) - { - ValidationUtils.ArgumentNotNull(value, "value"); - - JToken token = value as JToken; - if (token == null) - throw new ArgumentException("Value is not a JToken.", "value"); - - return _serializer.Deserialize(token.CreateReader(), type); - } - - public object Convert(object value, TypeCode typeCode) - { - ValidationUtils.ArgumentNotNull(value, "value"); - - if (value is JValue) - value = ((JValue) value).Value; - - return System.Convert.ChangeType(value, typeCode, CultureInfo.InvariantCulture); - } - - public bool ToBoolean(object value) - { - return GetTokenValue(value); - } - - public byte ToByte(object value) - { - return GetTokenValue(value); - } - - public char ToChar(object value) - { - return GetTokenValue(value); - } - - public DateTime ToDateTime(object value) - { - return GetTokenValue(value); - } - - public decimal ToDecimal(object value) - { - return GetTokenValue(value); - } - - public double ToDouble(object value) - { - return GetTokenValue(value); - } - - public short ToInt16(object value) - { - return GetTokenValue(value); - } - - public int ToInt32(object value) - { - return GetTokenValue(value); - } - - public long ToInt64(object value) - { - return GetTokenValue(value); - } - - public sbyte ToSByte(object value) - { - return GetTokenValue(value); - } - - public float ToSingle(object value) - { - return GetTokenValue(value); - } - - public string ToString(object value) - { - return GetTokenValue(value); - } - - public ushort ToUInt16(object value) - { - return GetTokenValue(value); - } - - public uint ToUInt32(object value) - { - return GetTokenValue(value); - } - - public ulong ToUInt64(object value) - { - return GetTokenValue(value); - } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/JsonISerializableContract.cs b/Src/Newtonsoft.Json/Serialization/JsonISerializableContract.cs index 980d2dc0..4cf5396e 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonISerializableContract.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonISerializableContract.cs @@ -28,26 +28,27 @@ using System; namespace Newtonsoft.Json.Serialization { - /// - /// Contract details for a used by the . - /// - public class JsonISerializableContract : JsonContainerContract - { /// - /// Gets or sets the ISerializable object constructor. + /// Contract details for a used by the . /// - /// The ISerializable object constructor. - public ObjectConstructor ISerializableCreator { get; set; } - - /// - /// Initializes a new instance of the class. - /// - /// The underlying type for the contract. - public JsonISerializableContract(Type underlyingType) - : base(underlyingType) + public class JsonISerializableContract : JsonContainerContract { - ContractType = JsonContractType.Serializable; + /// + /// Gets or sets the ISerializable object constructor. + /// + /// The ISerializable object constructor. + public ObjectConstructor ISerializableCreator { get; set; } + + /// + /// Initializes a new instance of the class. + /// + /// The underlying type for the contract. + public JsonISerializableContract(Type underlyingType) + : base(underlyingType) + { + ContractType = JsonContractType.Serializable; + } } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/JsonLinqContract.cs b/Src/Newtonsoft.Json/Serialization/JsonLinqContract.cs index c107014c..c91b3f00 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonLinqContract.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonLinqContract.cs @@ -27,19 +27,19 @@ using System; namespace Newtonsoft.Json.Serialization { - /// - /// Contract details for a used by the . - /// - public class JsonLinqContract : JsonContract - { /// - /// Initializes a new instance of the class. + /// Contract details for a used by the . /// - /// The underlying type for the contract. - public JsonLinqContract(Type underlyingType) - : base(underlyingType) + public class JsonLinqContract : JsonContract { - ContractType = JsonContractType.Linq; + /// + /// Initializes a new instance of the class. + /// + /// The underlying type for the contract. + public JsonLinqContract(Type underlyingType) + : base(underlyingType) + { + ContractType = JsonContractType.Linq; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs b/Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs index 8ad93da0..a7972648 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs @@ -32,115 +32,116 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Serialization { - /// - /// Contract details for a used by the . - /// - public class JsonObjectContract : JsonContainerContract - { /// - /// Gets or sets the object member serialization. + /// Contract details for a used by the . /// - /// The member object serialization. - public MemberSerialization MemberSerialization { get; set; } - - /// - /// Gets or sets a value that indicates whether the object's properties are required. - /// - /// - /// A value indicating whether the object's properties are required. - /// - public Required? ItemRequired { get; set; } - - /// - /// Gets the object's properties. - /// - /// The object's properties. - public JsonPropertyCollection Properties { get; private set; } - - /// - /// Gets the constructor parameters required for any non-default constructor - /// - public JsonPropertyCollection ConstructorParameters { get; private set; } - - /// - /// Gets or sets the override constructor used to create the object. - /// This is set when a constructor is marked up using the - /// JsonConstructor attribute. - /// - /// The override constructor. - public ConstructorInfo OverrideConstructor { get; set; } - - /// - /// Gets or sets the parametrized constructor used to create the object. - /// - /// The parametrized constructor. - public ConstructorInfo ParametrizedConstructor { get; set; } - - /// - /// Gets or sets the extension data setter. - /// - public ExtensionDataSetter ExtensionDataSetter { get; set; } - - /// - /// Gets or sets the extension data getter. - /// - public ExtensionDataGetter ExtensionDataGetter { get; set; } - - private bool? _hasRequiredOrDefaultValueProperties; - internal bool HasRequiredOrDefaultValueProperties + public class JsonObjectContract : JsonContainerContract { - get - { - if (_hasRequiredOrDefaultValueProperties == null) - { - _hasRequiredOrDefaultValueProperties = false; + /// + /// Gets or sets the object member serialization. + /// + /// The member object serialization. + public MemberSerialization MemberSerialization { get; set; } - if (ItemRequired.GetValueOrDefault(Required.Default) != Required.Default) - { - _hasRequiredOrDefaultValueProperties = true; - } - else - { - foreach (JsonProperty property in Properties) + /// + /// Gets or sets a value that indicates whether the object's properties are required. + /// + /// + /// A value indicating whether the object's properties are required. + /// + public Required? ItemRequired { get; set; } + + /// + /// Gets the object's properties. + /// + /// The object's properties. + public JsonPropertyCollection Properties { get; private set; } + + /// + /// Gets the constructor parameters required for any non-default constructor + /// + public JsonPropertyCollection ConstructorParameters { get; private set; } + + /// + /// Gets or sets the override constructor used to create the object. + /// This is set when a constructor is marked up using the + /// JsonConstructor attribute. + /// + /// The override constructor. + public ConstructorInfo OverrideConstructor { get; set; } + + /// + /// Gets or sets the parametrized constructor used to create the object. + /// + /// The parametrized constructor. + public ConstructorInfo ParametrizedConstructor { get; set; } + + /// + /// Gets or sets the extension data setter. + /// + public ExtensionDataSetter ExtensionDataSetter { get; set; } + + /// + /// Gets or sets the extension data getter. + /// + public ExtensionDataGetter ExtensionDataGetter { get; set; } + + private bool? _hasRequiredOrDefaultValueProperties; + + internal bool HasRequiredOrDefaultValueProperties + { + get { - if (property.Required != Required.Default || ((property.DefaultValueHandling & DefaultValueHandling.Populate) == DefaultValueHandling.Populate) && property.Writable) - { - _hasRequiredOrDefaultValueProperties = true; - break; - } + if (_hasRequiredOrDefaultValueProperties == null) + { + _hasRequiredOrDefaultValueProperties = false; + + if (ItemRequired.GetValueOrDefault(Required.Default) != Required.Default) + { + _hasRequiredOrDefaultValueProperties = true; + } + else + { + foreach (JsonProperty property in Properties) + { + if (property.Required != Required.Default || ((property.DefaultValueHandling & DefaultValueHandling.Populate) == DefaultValueHandling.Populate) && property.Writable) + { + _hasRequiredOrDefaultValueProperties = true; + break; + } + } + } + } + + return _hasRequiredOrDefaultValueProperties.Value; } - } } - return _hasRequiredOrDefaultValueProperties.Value; - } - } + /// + /// Initializes a new instance of the class. + /// + /// The underlying type for the contract. + public JsonObjectContract(Type underlyingType) + : base(underlyingType) + { + ContractType = JsonContractType.Object; - /// - /// Initializes a new instance of the class. - /// - /// The underlying type for the contract. - public JsonObjectContract(Type underlyingType) - : base(underlyingType) - { - ContractType = JsonContractType.Object; - - Properties = new JsonPropertyCollection(UnderlyingType); - ConstructorParameters = new JsonPropertyCollection(UnderlyingType); - } + Properties = new JsonPropertyCollection(UnderlyingType); + ConstructorParameters = new JsonPropertyCollection(UnderlyingType); + } #if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) #if !(NET20 || NET35) - [SecuritySafeCritical] + [SecuritySafeCritical] #endif - internal object GetUninitializedObject() - { - // we should never get here if the environment is not fully trusted, check just in case - if (!JsonTypeReflector.FullyTrusted) - throw new JsonException("Insufficient permissions. Creating an uninitialized '{0}' type requires full trust.".FormatWith(CultureInfo.InvariantCulture, NonNullableUnderlyingType)); + internal object GetUninitializedObject() + { + // we should never get here if the environment is not fully trusted, check just in case + if (!JsonTypeReflector.FullyTrusted) + throw new JsonException("Insufficient permissions. Creating an uninitialized '{0}' type requires full trust.".FormatWith(CultureInfo.InvariantCulture, NonNullableUnderlyingType)); - return FormatterServices.GetUninitializedObject(NonNullableUnderlyingType); - } + return FormatterServices.GetUninitializedObject(NonNullableUnderlyingType); + } #endif - } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/JsonPrimitiveContract.cs b/Src/Newtonsoft.Json/Serialization/JsonPrimitiveContract.cs index c197b5f3..6631dd7c 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonPrimitiveContract.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonPrimitiveContract.cs @@ -28,24 +28,24 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Serialization { - /// - /// Contract details for a used by the . - /// - public class JsonPrimitiveContract : JsonContract - { - internal PrimitiveTypeCode TypeCode { get; set; } - /// - /// Initializes a new instance of the class. + /// Contract details for a used by the . /// - /// The underlying type for the contract. - public JsonPrimitiveContract(Type underlyingType) - : base(underlyingType) + public class JsonPrimitiveContract : JsonContract { - ContractType = JsonContractType.Primitive; + internal PrimitiveTypeCode TypeCode { get; set; } - TypeCode = ConvertUtils.GetTypeCode(underlyingType); - IsReadOnlyOrFixedSize = true; + /// + /// Initializes a new instance of the class. + /// + /// The underlying type for the contract. + public JsonPrimitiveContract(Type underlyingType) + : base(underlyingType) + { + ContractType = JsonContractType.Primitive; + + TypeCode = ConvertUtils.GetTypeCode(underlyingType); + IsReadOnlyOrFixedSize = true; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/JsonProperty.cs b/Src/Newtonsoft.Json/Serialization/JsonProperty.cs index e91d5dd9..634e431b 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonProperty.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonProperty.cs @@ -32,254 +32,251 @@ using Newtonsoft.Json.Utilities.LinqBridge; namespace Newtonsoft.Json.Serialization { - /// - /// Maps a JSON property to a .NET member or constructor parameter. - /// - public class JsonProperty - { - internal Required? _required; - internal bool _hasExplicitDefaultValue; - internal object _defaultValue; - - private string _propertyName; - private bool _skipPropertyNameEscape; - - // use to cache contract during deserialization - internal JsonContract PropertyContract { get; set; } - /// - /// Gets or sets the name of the property. + /// Maps a JSON property to a .NET member or constructor parameter. /// - /// The name of the property. - public string PropertyName + public class JsonProperty { - get { return _propertyName; } - set - { - _propertyName = value; - CalculateSkipPropertyNameEscape(); - } - } + internal Required? _required; + internal bool _hasExplicitDefaultValue; + internal object _defaultValue; - private void CalculateSkipPropertyNameEscape() - { - if (_propertyName == null) - { - _skipPropertyNameEscape = false; - } - else - { - _skipPropertyNameEscape = true; - foreach (char c in _propertyName) + private string _propertyName; + private bool _skipPropertyNameEscape; + + // use to cache contract during deserialization + internal JsonContract PropertyContract { get; set; } + + /// + /// Gets or sets the name of the property. + /// + /// The name of the property. + public string PropertyName { - if (!char.IsLetterOrDigit(c) && c != '_' && c != '@') - { - _skipPropertyNameEscape = false; - break; - } + get { return _propertyName; } + set + { + _propertyName = value; + CalculateSkipPropertyNameEscape(); + } + } + + private void CalculateSkipPropertyNameEscape() + { + if (_propertyName == null) + { + _skipPropertyNameEscape = false; + } + else + { + _skipPropertyNameEscape = true; + foreach (char c in _propertyName) + { + if (!char.IsLetterOrDigit(c) && c != '_' && c != '@') + { + _skipPropertyNameEscape = false; + break; + } + } + } + } + + /// + /// Gets or sets the type that declared this property. + /// + /// The type that declared this property. + public Type DeclaringType { get; set; } + + /// + /// Gets or sets the order of serialization and deserialization of a member. + /// + /// The numeric order of serialization or deserialization. + public int? Order { get; set; } + + /// + /// Gets or sets the name of the underlying member or parameter. + /// + /// The name of the underlying member or parameter. + public string UnderlyingName { get; set; } + + /// + /// Gets the that will get and set the during serialization. + /// + /// The that will get and set the during serialization. + public IValueProvider ValueProvider { get; set; } + + /// + /// Gets or sets the type of the property. + /// + /// The type of the property. + public Type PropertyType { get; set; } + + /// + /// Gets or sets the for the property. + /// If set this converter takes presidence over the contract converter for the property type. + /// + /// The converter. + public JsonConverter Converter { get; set; } + + /// + /// Gets the member converter. + /// + /// The member converter. + public JsonConverter MemberConverter { get; set; } + + /// + /// Gets a value indicating whether this is ignored. + /// + /// true if ignored; otherwise, false. + public bool Ignored { get; set; } + + /// + /// Gets a value indicating whether this is readable. + /// + /// true if readable; otherwise, false. + public bool Readable { get; set; } + + /// + /// Gets a value indicating whether this is writable. + /// + /// true if writable; otherwise, false. + public bool Writable { get; set; } + + /// + /// Gets a value indicating whether this has a member attribute. + /// + /// true if has a member attribute; otherwise, false. + public bool HasMemberAttribute { get; set; } + + /// + /// Gets the default value. + /// + /// The default value. + public object DefaultValue + { + get { return _defaultValue; } + set + { + _hasExplicitDefaultValue = true; + _defaultValue = value; + } + } + + internal object GetResolvedDefaultValue() + { + if (!_hasExplicitDefaultValue && PropertyType != null) + return ReflectionUtils.GetDefaultValue(PropertyType); + + return _defaultValue; + } + + /// + /// Gets a value indicating whether this is required. + /// + /// A value indicating whether this is required. + public Required Required + { + get { return _required ?? Required.Default; } + set { _required = value; } + } + + /// + /// Gets a value indicating whether this property preserves object references. + /// + /// + /// true if this instance is reference; otherwise, false. + /// + public bool? IsReference { get; set; } + + /// + /// Gets the property null value handling. + /// + /// The null value handling. + public NullValueHandling? NullValueHandling { get; set; } + + /// + /// Gets the property default value handling. + /// + /// The default value handling. + public DefaultValueHandling? DefaultValueHandling { get; set; } + + /// + /// Gets the property reference loop handling. + /// + /// The reference loop handling. + public ReferenceLoopHandling? ReferenceLoopHandling { get; set; } + + /// + /// Gets the property object creation handling. + /// + /// The object creation handling. + public ObjectCreationHandling? ObjectCreationHandling { get; set; } + + /// + /// Gets or sets the type name handling. + /// + /// The type name handling. + public TypeNameHandling? TypeNameHandling { get; set; } + + /// + /// Gets or sets a predicate used to determine whether the property should be serialize. + /// + /// A predicate used to determine whether the property should be serialize. + public Predicate ShouldSerialize { get; set; } + + /// + /// Gets or sets a predicate used to determine whether the property should be serialized. + /// + /// A predicate used to determine whether the property should be serialized. + public Predicate GetIsSpecified { get; set; } + + /// + /// Gets or sets an action used to set whether the property has been deserialized. + /// + /// An action used to set whether the property has been deserialized. + public Action SetIsSpecified { get; set; } + + /// + /// Returns a that represents this instance. + /// + /// + /// A that represents this instance. + /// + public override string ToString() + { + return PropertyName; + } + + /// + /// Gets or sets the converter used when serializing the property's collection items. + /// + /// The collection's items converter. + public JsonConverter ItemConverter { get; set; } + + /// + /// Gets or sets whether this property's collection items are serialized as a reference. + /// + /// Whether this property's collection items are serialized as a reference. + public bool? ItemIsReference { get; set; } + + /// + /// Gets or sets the the type name handling used when serializing the property's collection items. + /// + /// The collection's items type name handling. + public TypeNameHandling? ItemTypeNameHandling { get; set; } + + /// + /// Gets or sets the the reference loop handling used when serializing the property's collection items. + /// + /// The collection's items reference loop handling. + public ReferenceLoopHandling? ItemReferenceLoopHandling { get; set; } + + internal void WritePropertyName(JsonWriter writer) + { + if (_skipPropertyNameEscape) + writer.WritePropertyName(PropertyName, false); + else + writer.WritePropertyName(PropertyName); } - } } - - /// - /// Gets or sets the type that declared this property. - /// - /// The type that declared this property. - public Type DeclaringType { get; set; } - - /// - /// Gets or sets the order of serialization and deserialization of a member. - /// - /// The numeric order of serialization or deserialization. - public int? Order { get; set; } - - /// - /// Gets or sets the name of the underlying member or parameter. - /// - /// The name of the underlying member or parameter. - public string UnderlyingName { get; set; } - - /// - /// Gets the that will get and set the during serialization. - /// - /// The that will get and set the during serialization. - public IValueProvider ValueProvider { get; set; } - - /// - /// Gets or sets the type of the property. - /// - /// The type of the property. - public Type PropertyType { get; set; } - - /// - /// Gets or sets the for the property. - /// If set this converter takes presidence over the contract converter for the property type. - /// - /// The converter. - public JsonConverter Converter { get; set; } - - /// - /// Gets the member converter. - /// - /// The member converter. - public JsonConverter MemberConverter { get; set; } - - /// - /// Gets a value indicating whether this is ignored. - /// - /// true if ignored; otherwise, false. - public bool Ignored { get; set; } - - /// - /// Gets a value indicating whether this is readable. - /// - /// true if readable; otherwise, false. - public bool Readable { get; set; } - - /// - /// Gets a value indicating whether this is writable. - /// - /// true if writable; otherwise, false. - public bool Writable { get; set; } - - /// - /// Gets a value indicating whether this has a member attribute. - /// - /// true if has a member attribute; otherwise, false. - public bool HasMemberAttribute { get; set; } - - /// - /// Gets the default value. - /// - /// The default value. - public object DefaultValue - { - get - { - return _defaultValue; - } - set - { - _hasExplicitDefaultValue = true; - _defaultValue = value; - } - } - - internal object GetResolvedDefaultValue() - { - if (!_hasExplicitDefaultValue && PropertyType != null) - return ReflectionUtils.GetDefaultValue(PropertyType); - - return _defaultValue; - } - - /// - /// Gets a value indicating whether this is required. - /// - /// A value indicating whether this is required. - public Required Required - { - get { return _required ?? Required.Default; } - set { _required = value; } - } - - /// - /// Gets a value indicating whether this property preserves object references. - /// - /// - /// true if this instance is reference; otherwise, false. - /// - public bool? IsReference { get; set; } - - /// - /// Gets the property null value handling. - /// - /// The null value handling. - public NullValueHandling? NullValueHandling { get; set; } - - /// - /// Gets the property default value handling. - /// - /// The default value handling. - public DefaultValueHandling? DefaultValueHandling { get; set; } - - /// - /// Gets the property reference loop handling. - /// - /// The reference loop handling. - public ReferenceLoopHandling? ReferenceLoopHandling { get; set; } - - /// - /// Gets the property object creation handling. - /// - /// The object creation handling. - public ObjectCreationHandling? ObjectCreationHandling { get; set; } - - /// - /// Gets or sets the type name handling. - /// - /// The type name handling. - public TypeNameHandling? TypeNameHandling { get; set; } - - /// - /// Gets or sets a predicate used to determine whether the property should be serialize. - /// - /// A predicate used to determine whether the property should be serialize. - public Predicate ShouldSerialize { get; set; } - - /// - /// Gets or sets a predicate used to determine whether the property should be serialized. - /// - /// A predicate used to determine whether the property should be serialized. - public Predicate GetIsSpecified { get; set; } - - /// - /// Gets or sets an action used to set whether the property has been deserialized. - /// - /// An action used to set whether the property has been deserialized. - public Action SetIsSpecified { get; set; } - - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override string ToString() - { - return PropertyName; - } - - /// - /// Gets or sets the converter used when serializing the property's collection items. - /// - /// The collection's items converter. - public JsonConverter ItemConverter { get; set; } - - /// - /// Gets or sets whether this property's collection items are serialized as a reference. - /// - /// Whether this property's collection items are serialized as a reference. - public bool? ItemIsReference { get; set; } - - /// - /// Gets or sets the the type name handling used when serializing the property's collection items. - /// - /// The collection's items type name handling. - public TypeNameHandling? ItemTypeNameHandling { get; set; } - - /// - /// Gets or sets the the reference loop handling used when serializing the property's collection items. - /// - /// The collection's items reference loop handling. - public ReferenceLoopHandling? ItemReferenceLoopHandling { get; set; } - - internal void WritePropertyName(JsonWriter writer) - { - if (_skipPropertyNameEscape) - writer.WritePropertyName(PropertyName, false); - else - writer.WritePropertyName(PropertyName); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/JsonPropertyCollection.cs b/Src/Newtonsoft.Json/Serialization/JsonPropertyCollection.cs index ed0129ee..406f4b8d 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonPropertyCollection.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonPropertyCollection.cs @@ -32,134 +32,134 @@ using System.Globalization; namespace Newtonsoft.Json.Serialization { - /// - /// A collection of objects. - /// - public class JsonPropertyCollection : KeyedCollection - { - private readonly Type _type; - /// - /// Initializes a new instance of the class. + /// A collection of objects. /// - /// The type. - public JsonPropertyCollection(Type type) - : base(StringComparer.Ordinal) + public class JsonPropertyCollection : KeyedCollection { - ValidationUtils.ArgumentNotNull(type, "type"); - _type = type; - } + private readonly Type _type; - /// - /// When implemented in a derived class, extracts the key from the specified element. - /// - /// The element from which to extract the key. - /// The key for the specified element. - protected override string GetKeyForItem(JsonProperty item) - { - return item.PropertyName; - } - - /// - /// Adds a object. - /// - /// The property to add to the collection. - public void AddProperty(JsonProperty property) - { - if (Contains(property.PropertyName)) - { - // don't overwrite existing property with ignored property - if (property.Ignored) - return; - - JsonProperty existingProperty = this[property.PropertyName]; - bool duplicateProperty = true; - - if (existingProperty.Ignored) + /// + /// Initializes a new instance of the class. + /// + /// The type. + public JsonPropertyCollection(Type type) + : base(StringComparer.Ordinal) { - // remove ignored property so it can be replaced in collection - Remove(existingProperty); - duplicateProperty = false; + ValidationUtils.ArgumentNotNull(type, "type"); + _type = type; } - else + + /// + /// When implemented in a derived class, extracts the key from the specified element. + /// + /// The element from which to extract the key. + /// The key for the specified element. + protected override string GetKeyForItem(JsonProperty item) { - if (property.DeclaringType != null && existingProperty.DeclaringType != null) - { - if (property.DeclaringType.IsSubclassOf(existingProperty.DeclaringType)) + return item.PropertyName; + } + + /// + /// Adds a object. + /// + /// The property to add to the collection. + public void AddProperty(JsonProperty property) + { + if (Contains(property.PropertyName)) { - // current property is on a derived class and hides the existing - Remove(existingProperty); - duplicateProperty = false; + // don't overwrite existing property with ignored property + if (property.Ignored) + return; + + JsonProperty existingProperty = this[property.PropertyName]; + bool duplicateProperty = true; + + if (existingProperty.Ignored) + { + // remove ignored property so it can be replaced in collection + Remove(existingProperty); + duplicateProperty = false; + } + else + { + if (property.DeclaringType != null && existingProperty.DeclaringType != null) + { + if (property.DeclaringType.IsSubclassOf(existingProperty.DeclaringType)) + { + // current property is on a derived class and hides the existing + Remove(existingProperty); + duplicateProperty = false; + } + if (existingProperty.DeclaringType.IsSubclassOf(property.DeclaringType)) + { + // current property is hidden by the existing so don't add it + return; + } + } + } + + if (duplicateProperty) + throw new JsonSerializationException("A member with the name '{0}' already exists on '{1}'. Use the JsonPropertyAttribute to specify another name.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName, _type)); } - if (existingProperty.DeclaringType.IsSubclassOf(property.DeclaringType)) - { - // current property is hidden by the existing so don't add it - return; - } - } + + Add(property); } - if (duplicateProperty) - throw new JsonSerializationException("A member with the name '{0}' already exists on '{1}'. Use the JsonPropertyAttribute to specify another name.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName, _type)); - } - - Add(property); - } - - /// - /// Gets the closest matching object. - /// First attempts to get an exact case match of propertyName and then - /// a case insensitive match. - /// - /// Name of the property. - /// A matching property if found. - public JsonProperty GetClosestMatchProperty(string propertyName) - { - JsonProperty property = GetProperty(propertyName, StringComparison.Ordinal); - if (property == null) - property = GetProperty(propertyName, StringComparison.OrdinalIgnoreCase); - - return property; - } - - private bool TryGetValue(string key, out JsonProperty item) - { - if (Dictionary == null) - { - item = default(JsonProperty); - return false; - } - - return Dictionary.TryGetValue(key, out item); - } - - /// - /// Gets a property by property name. - /// - /// The name of the property to get. - /// Type property name string comparison. - /// A matching property if found. - public JsonProperty GetProperty(string propertyName, StringComparison comparisonType) - { - // KeyedCollection has an ordinal comparer - if (comparisonType == StringComparison.Ordinal) - { - JsonProperty property; - if (TryGetValue(propertyName, out property)) - return property; - - return null; - } - - foreach (JsonProperty property in this) - { - if (string.Equals(propertyName, property.PropertyName, comparisonType)) + /// + /// Gets the closest matching object. + /// First attempts to get an exact case match of propertyName and then + /// a case insensitive match. + /// + /// Name of the property. + /// A matching property if found. + public JsonProperty GetClosestMatchProperty(string propertyName) { - return property; - } - } + JsonProperty property = GetProperty(propertyName, StringComparison.Ordinal); + if (property == null) + property = GetProperty(propertyName, StringComparison.OrdinalIgnoreCase); - return null; + return property; + } + + private bool TryGetValue(string key, out JsonProperty item) + { + if (Dictionary == null) + { + item = default(JsonProperty); + return false; + } + + return Dictionary.TryGetValue(key, out item); + } + + /// + /// Gets a property by property name. + /// + /// The name of the property to get. + /// Type property name string comparison. + /// A matching property if found. + public JsonProperty GetProperty(string propertyName, StringComparison comparisonType) + { + // KeyedCollection has an ordinal comparer + if (comparisonType == StringComparison.Ordinal) + { + JsonProperty property; + if (TryGetValue(propertyName, out property)) + return property; + + return null; + } + + foreach (JsonProperty property in this) + { + if (string.Equals(propertyName, property.PropertyName, comparisonType)) + { + return property; + } + } + + return null; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalBase.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalBase.cs index c81b9903..b49b662d 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalBase.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalBase.cs @@ -32,110 +32,110 @@ using Newtonsoft.Json.Utilities; namespace Newtonsoft.Json.Serialization { - internal abstract class JsonSerializerInternalBase - { - private class ReferenceEqualsEqualityComparer : IEqualityComparer + internal abstract class JsonSerializerInternalBase { - bool IEqualityComparer.Equals(object x, object y) - { - return ReferenceEquals(x, y); - } + private class ReferenceEqualsEqualityComparer : IEqualityComparer + { + bool IEqualityComparer.Equals(object x, object y) + { + return ReferenceEquals(x, y); + } - int IEqualityComparer.GetHashCode(object obj) - { + int IEqualityComparer.GetHashCode(object obj) + { #if !(NETFX_CORE) - // put objects in a bucket based on their reference - return RuntimeHelpers.GetHashCode(obj); + // put objects in a bucket based on their reference + return RuntimeHelpers.GetHashCode(obj); #else - // put all objects in the same bucket so ReferenceEquals is called on all + // put all objects in the same bucket so ReferenceEquals is called on all return -1; #endif - } + } + } + + private ErrorContext _currentErrorContext; + private BidirectionalDictionary _mappings; + private bool _serializing; + + internal readonly JsonSerializer Serializer; + internal readonly ITraceWriter TraceWriter; + + protected JsonSerializerInternalBase(JsonSerializer serializer) + { + ValidationUtils.ArgumentNotNull(serializer, "serializer"); + + Serializer = serializer; + TraceWriter = serializer.TraceWriter; + + // kind of a hack but meh. might clean this up later + _serializing = (GetType() == typeof(JsonSerializerInternalWriter)); + } + + internal BidirectionalDictionary DefaultReferenceMappings + { + get + { + // override equality comparer for object key dictionary + // object will be modified as it deserializes and might have mutable hashcode + if (_mappings == null) + _mappings = new BidirectionalDictionary( + EqualityComparer.Default, + new ReferenceEqualsEqualityComparer(), + "A different value already has the Id '{0}'.", + "A different Id has already been assigned for value '{0}'."); + + return _mappings; + } + } + + private ErrorContext GetErrorContext(object currentObject, object member, string path, Exception error) + { + if (_currentErrorContext == null) + _currentErrorContext = new ErrorContext(currentObject, member, path, error); + + if (_currentErrorContext.Error != error) + throw new InvalidOperationException("Current error context error is different to requested error."); + + return _currentErrorContext; + } + + protected void ClearErrorContext() + { + if (_currentErrorContext == null) + throw new InvalidOperationException("Could not clear error context. Error context is already null."); + + _currentErrorContext = null; + } + + protected bool IsErrorHandled(object currentObject, JsonContract contract, object keyValue, IJsonLineInfo lineInfo, string path, Exception ex) + { + ErrorContext errorContext = GetErrorContext(currentObject, keyValue, path, ex); + + if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Error && !errorContext.Traced) + { + // only write error once + errorContext.Traced = true; + + string message = (_serializing) ? "Error serializing" : "Error deserializing"; + if (contract != null) + message += " " + contract.UnderlyingType; + message += ". " + ex.Message; + + // add line information to non-json.net exception message + if (!(ex is JsonException)) + message = JsonPosition.FormatMessage(lineInfo, path, message); + + TraceWriter.Trace(TraceLevel.Error, message, ex); + } + + // attribute method is non-static so don't invoke if no object + if (contract != null && currentObject != null) + contract.InvokeOnError(currentObject, Serializer.Context, errorContext); + + if (!errorContext.Handled) + Serializer.OnError(new ErrorEventArgs(currentObject, errorContext)); + + return errorContext.Handled; + } } - - private ErrorContext _currentErrorContext; - private BidirectionalDictionary _mappings; - private bool _serializing; - - internal readonly JsonSerializer Serializer; - internal readonly ITraceWriter TraceWriter; - - protected JsonSerializerInternalBase(JsonSerializer serializer) - { - ValidationUtils.ArgumentNotNull(serializer, "serializer"); - - Serializer = serializer; - TraceWriter = serializer.TraceWriter; - - // kind of a hack but meh. might clean this up later - _serializing = (GetType() == typeof (JsonSerializerInternalWriter)); - } - - internal BidirectionalDictionary DefaultReferenceMappings - { - get - { - // override equality comparer for object key dictionary - // object will be modified as it deserializes and might have mutable hashcode - if (_mappings == null) - _mappings = new BidirectionalDictionary( - EqualityComparer.Default, - new ReferenceEqualsEqualityComparer(), - "A different value already has the Id '{0}'.", - "A different Id has already been assigned for value '{0}'."); - - return _mappings; - } - } - - private ErrorContext GetErrorContext(object currentObject, object member, string path, Exception error) - { - if (_currentErrorContext == null) - _currentErrorContext = new ErrorContext(currentObject, member, path, error); - - if (_currentErrorContext.Error != error) - throw new InvalidOperationException("Current error context error is different to requested error."); - - return _currentErrorContext; - } - - protected void ClearErrorContext() - { - if (_currentErrorContext == null) - throw new InvalidOperationException("Could not clear error context. Error context is already null."); - - _currentErrorContext = null; - } - - protected bool IsErrorHandled(object currentObject, JsonContract contract, object keyValue, IJsonLineInfo lineInfo, string path, Exception ex) - { - ErrorContext errorContext = GetErrorContext(currentObject, keyValue, path, ex); - - if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Error && !errorContext.Traced) - { - // only write error once - errorContext.Traced = true; - - string message = (_serializing) ? "Error serializing" : "Error deserializing"; - if (contract != null) - message += " " + contract.UnderlyingType; - message += ". " + ex.Message; - - // add line information to non-json.net exception message - if (!(ex is JsonException)) - message = JsonPosition.FormatMessage(lineInfo, path, message); - - TraceWriter.Trace(TraceLevel.Error, message, ex); - } - - // attribute method is non-static so don't invoke if no object - if (contract != null && currentObject != null) - contract.InvokeOnError(currentObject, Serializer.Context, errorContext); - - if (!errorContext.Handled) - Serializer.OnError(new ErrorEventArgs(currentObject, errorContext)); - - return errorContext.Handled; - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs index 0a3ff215..9b4932ab 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs @@ -44,1847 +44,1848 @@ using Newtonsoft.Json.Utilities; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json.Serialization { - internal class JsonSerializerInternalReader : JsonSerializerInternalBase - { - internal enum PropertyPresence + internal class JsonSerializerInternalReader : JsonSerializerInternalBase { - None, - Null, - Value - } + internal enum PropertyPresence + { + None, + Null, + Value + } - private JsonSerializerProxy _internalSerializer; + private JsonSerializerProxy _internalSerializer; #if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) - private JsonFormatterConverter _formatterConverter; + private JsonFormatterConverter _formatterConverter; #endif - public JsonSerializerInternalReader(JsonSerializer serializer) - : base(serializer) - { - } - - public void Populate(JsonReader reader, object target) - { - ValidationUtils.ArgumentNotNull(target, "target"); - - Type objectType = target.GetType(); - - JsonContract contract = Serializer._contractResolver.ResolveContract(objectType); - - if (reader.TokenType == JsonToken.None) - reader.Read(); - - if (reader.TokenType == JsonToken.StartArray) - { - if (contract.ContractType == JsonContractType.Array) + public JsonSerializerInternalReader(JsonSerializer serializer) + : base(serializer) { - JsonArrayContract arrayContract = (JsonArrayContract) contract; - - PopulateList((arrayContract.ShouldCreateWrapper) ? arrayContract.CreateWrapper(target) : (IList)target, reader, arrayContract, null, null); - } - else - { - throw JsonSerializationException.Create(reader, "Cannot populate JSON array onto type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType)); - } - } - else if (reader.TokenType == JsonToken.StartObject) - { - CheckedRead(reader); - - string id = null; - if (reader.TokenType == JsonToken.PropertyName && string.Equals(reader.Value.ToString(), JsonTypeReflector.IdPropertyName, StringComparison.Ordinal)) - { - CheckedRead(reader); - id = (reader.Value != null) ? reader.Value.ToString() : null; - CheckedRead(reader); } - if (contract.ContractType == JsonContractType.Dictionary) + public void Populate(JsonReader reader, object target) { - JsonDictionaryContract dictionaryContract = (JsonDictionaryContract)contract; - PopulateDictionary((dictionaryContract.ShouldCreateWrapper) ? dictionaryContract.CreateWrapper(target) : (IDictionary)target, reader, dictionaryContract, null, id); - } - else if (contract.ContractType == JsonContractType.Object) - { - PopulateObject(target, reader, (JsonObjectContract) contract, null, id); - } - else - { - throw JsonSerializationException.Create(reader, "Cannot populate JSON object onto type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType)); - } - } - else - { - throw JsonSerializationException.Create(reader, "Unexpected initial token '{0}' when populating object. Expected JSON object or array.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); - } - } + ValidationUtils.ArgumentNotNull(target, "target"); - private JsonContract GetContractSafe(Type type) - { - if (type == null) - return null; + Type objectType = target.GetType(); - return Serializer._contractResolver.ResolveContract(type); - } + JsonContract contract = Serializer._contractResolver.ResolveContract(objectType); - public object Deserialize(JsonReader reader, Type objectType, bool checkAdditionalContent) - { - if (reader == null) - throw new ArgumentNullException("reader"); + if (reader.TokenType == JsonToken.None) + reader.Read(); - JsonContract contract = GetContractSafe(objectType); + if (reader.TokenType == JsonToken.StartArray) + { + if (contract.ContractType == JsonContractType.Array) + { + JsonArrayContract arrayContract = (JsonArrayContract)contract; - try - { - JsonConverter converter = GetConverter(contract, null, null, null); + PopulateList((arrayContract.ShouldCreateWrapper) ? arrayContract.CreateWrapper(target) : (IList)target, reader, arrayContract, null, null); + } + else + { + throw JsonSerializationException.Create(reader, "Cannot populate JSON array onto type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType)); + } + } + else if (reader.TokenType == JsonToken.StartObject) + { + CheckedRead(reader); - if (reader.TokenType == JsonToken.None && !ReadForType(reader, contract, converter != null)) - { - if (contract != null && !contract.IsNullable) - throw JsonSerializationException.Create(reader, "No JSON content found and type '{0}' is not nullable.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); + string id = null; + if (reader.TokenType == JsonToken.PropertyName && string.Equals(reader.Value.ToString(), JsonTypeReflector.IdPropertyName, StringComparison.Ordinal)) + { + CheckedRead(reader); + id = (reader.Value != null) ? reader.Value.ToString() : null; + CheckedRead(reader); + } - return null; + if (contract.ContractType == JsonContractType.Dictionary) + { + JsonDictionaryContract dictionaryContract = (JsonDictionaryContract)contract; + PopulateDictionary((dictionaryContract.ShouldCreateWrapper) ? dictionaryContract.CreateWrapper(target) : (IDictionary)target, reader, dictionaryContract, null, id); + } + else if (contract.ContractType == JsonContractType.Object) + { + PopulateObject(target, reader, (JsonObjectContract)contract, null, id); + } + else + { + throw JsonSerializationException.Create(reader, "Cannot populate JSON object onto type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType)); + } + } + else + { + throw JsonSerializationException.Create(reader, "Unexpected initial token '{0}' when populating object. Expected JSON object or array.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); + } } - object deserializedValue; - - if (converter != null && converter.CanRead) - deserializedValue = DeserializeConvertable(converter, reader, objectType, null); - else - deserializedValue = CreateValueInternal(reader, objectType, contract, null, null, null, null); - - if (checkAdditionalContent) + private JsonContract GetContractSafe(Type type) { - if (reader.Read() && reader.TokenType != JsonToken.Comment) - throw new JsonSerializationException("Additional text found in JSON string after finishing deserializing object."); + if (type == null) + return null; + + return Serializer._contractResolver.ResolveContract(type); } - return deserializedValue; - } - catch (Exception ex) - { - if (IsErrorHandled(null, contract, null, reader as IJsonLineInfo, reader.Path, ex)) + public object Deserialize(JsonReader reader, Type objectType, bool checkAdditionalContent) { - HandleError(reader, false, 0); - return null; + if (reader == null) + throw new ArgumentNullException("reader"); + + JsonContract contract = GetContractSafe(objectType); + + try + { + JsonConverter converter = GetConverter(contract, null, null, null); + + if (reader.TokenType == JsonToken.None && !ReadForType(reader, contract, converter != null)) + { + if (contract != null && !contract.IsNullable) + throw JsonSerializationException.Create(reader, "No JSON content found and type '{0}' is not nullable.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); + + return null; + } + + object deserializedValue; + + if (converter != null && converter.CanRead) + deserializedValue = DeserializeConvertable(converter, reader, objectType, null); + else + deserializedValue = CreateValueInternal(reader, objectType, contract, null, null, null, null); + + if (checkAdditionalContent) + { + if (reader.Read() && reader.TokenType != JsonToken.Comment) + throw new JsonSerializationException("Additional text found in JSON string after finishing deserializing object."); + } + + return deserializedValue; + } + catch (Exception ex) + { + if (IsErrorHandled(null, contract, null, reader as IJsonLineInfo, reader.Path, ex)) + { + HandleError(reader, false, 0); + return null; + } + else + { + throw; + } + } } - else + + private JsonSerializerProxy GetInternalSerializer() { - throw; + if (_internalSerializer == null) + _internalSerializer = new JsonSerializerProxy(this); + + return _internalSerializer; } - } - } - - private JsonSerializerProxy GetInternalSerializer() - { - if (_internalSerializer == null) - _internalSerializer = new JsonSerializerProxy(this); - - return _internalSerializer; - } #if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) - private JsonFormatterConverter GetFormatterConverter() - { - if (_formatterConverter == null) - _formatterConverter = new JsonFormatterConverter(GetInternalSerializer()); + private JsonFormatterConverter GetFormatterConverter() + { + if (_formatterConverter == null) + _formatterConverter = new JsonFormatterConverter(GetInternalSerializer()); - return _formatterConverter; - } + return _formatterConverter; + } #endif - private JToken CreateJToken(JsonReader reader, JsonContract contract) - { - ValidationUtils.ArgumentNotNull(reader, "reader"); - - if (contract != null && contract.UnderlyingType == typeof (JRaw)) - { - return JRaw.Create(reader); - } - else - { - JToken token; - using (JTokenWriter writer = new JTokenWriter()) + private JToken CreateJToken(JsonReader reader, JsonContract contract) { - writer.WriteToken(reader); - token = writer.Token; + ValidationUtils.ArgumentNotNull(reader, "reader"); + + if (contract != null && contract.UnderlyingType == typeof(JRaw)) + { + return JRaw.Create(reader); + } + else + { + JToken token; + using (JTokenWriter writer = new JTokenWriter()) + { + writer.WriteToken(reader); + token = writer.Token; + } + + return token; + } } - return token; - } - } - - private JToken CreateJObject(JsonReader reader) - { - ValidationUtils.ArgumentNotNull(reader, "reader"); - - // this is needed because we've already read inside the object, looking for special properties - JToken token; - using (JTokenWriter writer = new JTokenWriter()) - { - writer.WriteStartObject(); - - if (reader.TokenType == JsonToken.PropertyName) - writer.WriteToken(reader, reader.Depth - 1, true, true); - else - writer.WriteEndObject(); - - token = writer.Token; - } - - return token; - } - - private object CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, object existingValue) - { - if (contract != null && contract.ContractType == JsonContractType.Linq) - return CreateJToken(reader, contract); - - do - { - switch (reader.TokenType) + private JToken CreateJObject(JsonReader reader) { - // populate a typed object or generic dictionary/array - // depending upon whether an objectType was supplied - case JsonToken.StartObject: - return CreateObject(reader, objectType, contract, member, containerContract, containerMember, existingValue); - case JsonToken.StartArray: - return CreateList(reader, objectType, contract, member, existingValue, null); - case JsonToken.Integer: - case JsonToken.Float: - case JsonToken.Boolean: - case JsonToken.Date: - case JsonToken.Bytes: - return EnsureType(reader, reader.Value, CultureInfo.InvariantCulture, contract, objectType); - case JsonToken.String: - string s = (string)reader.Value; + ValidationUtils.ArgumentNotNull(reader, "reader"); - // convert empty string to null automatically for nullable types - if (string.IsNullOrEmpty(s) && objectType != typeof(string) && objectType != typeof(object) && contract != null && contract.IsNullable) - return null; + // this is needed because we've already read inside the object, looking for special properties + JToken token; + using (JTokenWriter writer = new JTokenWriter()) + { + writer.WriteStartObject(); - // string that needs to be returned as a byte array should be base 64 decoded - if (objectType == typeof (byte[])) - return Convert.FromBase64String(s); + if (reader.TokenType == JsonToken.PropertyName) + writer.WriteToken(reader, reader.Depth - 1, true, true); + else + writer.WriteEndObject(); - return EnsureType(reader, s, CultureInfo.InvariantCulture, contract, objectType); - case JsonToken.StartConstructor: - string constructorName = reader.Value.ToString(); + token = writer.Token; + } - return EnsureType(reader, constructorName, CultureInfo.InvariantCulture, contract, objectType); - case JsonToken.Null: - case JsonToken.Undefined: + return token; + } + + private object CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, object existingValue) + { + if (contract != null && contract.ContractType == JsonContractType.Linq) + return CreateJToken(reader, contract); + + do + { + switch (reader.TokenType) + { + // populate a typed object or generic dictionary/array + // depending upon whether an objectType was supplied + case JsonToken.StartObject: + return CreateObject(reader, objectType, contract, member, containerContract, containerMember, existingValue); + case JsonToken.StartArray: + return CreateList(reader, objectType, contract, member, existingValue, null); + case JsonToken.Integer: + case JsonToken.Float: + case JsonToken.Boolean: + case JsonToken.Date: + case JsonToken.Bytes: + return EnsureType(reader, reader.Value, CultureInfo.InvariantCulture, contract, objectType); + case JsonToken.String: + string s = (string)reader.Value; + + // convert empty string to null automatically for nullable types + if (string.IsNullOrEmpty(s) && objectType != typeof(string) && objectType != typeof(object) && contract != null && contract.IsNullable) + return null; + + // string that needs to be returned as a byte array should be base 64 decoded + if (objectType == typeof(byte[])) + return Convert.FromBase64String(s); + + return EnsureType(reader, s, CultureInfo.InvariantCulture, contract, objectType); + case JsonToken.StartConstructor: + string constructorName = reader.Value.ToString(); + + return EnsureType(reader, constructorName, CultureInfo.InvariantCulture, contract, objectType); + case JsonToken.Null: + case JsonToken.Undefined: #if !(NETFX_CORE || PORTABLE40 || PORTABLE) - if (objectType == typeof (DBNull)) - return DBNull.Value; + if (objectType == typeof(DBNull)) + return DBNull.Value; #endif - return EnsureType(reader, reader.Value, CultureInfo.InvariantCulture, contract, objectType); - case JsonToken.Raw: - return new JRaw((string) reader.Value); - case JsonToken.Comment: - // ignore - break; - default: - throw JsonSerializationException.Create(reader, "Unexpected token while deserializing object: " + reader.TokenType); + return EnsureType(reader, reader.Value, CultureInfo.InvariantCulture, contract, objectType); + case JsonToken.Raw: + return new JRaw((string)reader.Value); + case JsonToken.Comment: + // ignore + break; + default: + throw JsonSerializationException.Create(reader, "Unexpected token while deserializing object: " + reader.TokenType); + } + } while (reader.Read()); + + throw JsonSerializationException.Create(reader, "Unexpected end when deserializing object."); } - } while (reader.Read()); - throw JsonSerializationException.Create(reader, "Unexpected end when deserializing object."); - } - - internal string GetExpectedDescription(JsonContract contract) - { - switch (contract.ContractType) - { - case JsonContractType.Object: - case JsonContractType.Dictionary: + internal string GetExpectedDescription(JsonContract contract) + { + switch (contract.ContractType) + { + case JsonContractType.Object: + case JsonContractType.Dictionary: #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - case JsonContractType.Serializable: + case JsonContractType.Serializable: #endif #if !(NET35 || NET20 || PORTABLE40) - case JsonContractType.Dynamic: + case JsonContractType.Dynamic: #endif - return @"JSON object (e.g. {""name"":""value""})"; - case JsonContractType.Array: - return @"JSON array (e.g. [1,2,3])"; - case JsonContractType.Primitive: - return @"JSON primitive value (e.g. string, number, boolean, null)"; - case JsonContractType.String: - return @"JSON string value"; - default: - throw new ArgumentOutOfRangeException(); - } - } - - private JsonConverter GetConverter(JsonContract contract, JsonConverter memberConverter, JsonContainerContract containerContract, JsonProperty containerProperty) - { - JsonConverter converter = null; - if (memberConverter != null) - { - // member attribute converter - converter = memberConverter; - } - else if (containerProperty != null && containerProperty.ItemConverter != null) - { - converter = containerProperty.ItemConverter; - } - else if (containerContract != null && containerContract.ItemConverter != null) - { - converter = containerContract.ItemConverter; - } - else if (contract != null) - { - JsonConverter matchingConverter; - if (contract.Converter != null) - // class attribute converter - converter = contract.Converter; - else if ((matchingConverter = Serializer.GetMatchingConverter(contract.UnderlyingType)) != null) - // passed in converters - converter = matchingConverter; - else if (contract.InternalConverter != null) - // internally specified converter - converter = contract.InternalConverter; - } - return converter; - } - - private object CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, object existingValue) - { - CheckedRead(reader); - - string id; - object newValue; - if (ReadSpecialProperties(reader, ref objectType, ref contract, member, containerContract, containerMember, existingValue, out newValue, out id)) - return newValue; - - if (HasNoDefinedType(contract)) - return CreateJObject(reader); - - switch (contract.ContractType) - { - case JsonContractType.Object: - { - bool createdFromNonDefaultConstructor = false; - JsonObjectContract objectContract = (JsonObjectContract) contract; - object targetObject; - if (existingValue != null) - targetObject = existingValue; - else - targetObject = CreateNewObject(reader, objectContract, member, containerMember, id, out createdFromNonDefaultConstructor); - - // don't populate if read from non-default constructor because the object has already been read - if (createdFromNonDefaultConstructor) - return targetObject; - - return PopulateObject(targetObject, reader, objectContract, member, id); - } - case JsonContractType.Primitive: - { - JsonPrimitiveContract primitiveContract = (JsonPrimitiveContract) contract; - // if the content is inside $value then read past it - if (reader.TokenType == JsonToken.PropertyName && string.Equals(reader.Value.ToString(), JsonTypeReflector.ValuePropertyName, StringComparison.Ordinal)) - { - CheckedRead(reader); - - // the token should not be an object because the $type value could have been included in the object - // without needing the $value property - if (reader.TokenType == JsonToken.StartObject) - throw JsonSerializationException.Create(reader, "Unexpected token when deserializing primitive value: " + reader.TokenType); - - object value = CreateValueInternal(reader, objectType, primitiveContract, member, null, null, existingValue); - - CheckedRead(reader); - return value; + return @"JSON object (e.g. {""name"":""value""})"; + case JsonContractType.Array: + return @"JSON array (e.g. [1,2,3])"; + case JsonContractType.Primitive: + return @"JSON primitive value (e.g. string, number, boolean, null)"; + case JsonContractType.String: + return @"JSON string value"; + default: + throw new ArgumentOutOfRangeException(); } - break; - } - case JsonContractType.Dictionary: - { - JsonDictionaryContract dictionaryContract = (JsonDictionaryContract) contract; - object targetDictionary; + } - if (existingValue == null) + private JsonConverter GetConverter(JsonContract contract, JsonConverter memberConverter, JsonContainerContract containerContract, JsonProperty containerProperty) + { + JsonConverter converter = null; + if (memberConverter != null) { - bool createdFromNonDefaultConstructor; - IDictionary dictionary = CreateNewDictionary(reader, dictionaryContract, out createdFromNonDefaultConstructor); - - if (createdFromNonDefaultConstructor) - { - if (id != null) - throw JsonSerializationException.Create(reader, "Cannot preserve reference to readonly dictionary, or dictionary created from a non-default constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); - - if (contract.OnSerializingCallbacks.Count > 0) - throw JsonSerializationException.Create(reader, "Cannot call OnSerializing on readonly dictionary, or dictionary created from a non-default constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); - - if (contract.OnErrorCallbacks.Count > 0) - throw JsonSerializationException.Create(reader, "Cannot call OnError on readonly list, or dictionary created from a non-default constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); - - if (dictionaryContract.ParametrizedConstructor == null) - throw JsonSerializationException.Create(reader, "Cannot deserialize readonly or fixed size dictionary: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); - } - - PopulateDictionary(dictionary, reader, dictionaryContract, member, id); - - if (createdFromNonDefaultConstructor) - { - ConstructorInfo constructor = dictionaryContract.ParametrizedConstructor as ConstructorInfo; - if (constructor != null) - return constructor.Invoke(new object[] { dictionary }); - - return dictionaryContract.ParametrizedConstructor.Invoke(null, new object[] { dictionary }); - } - else if (dictionary is IWrappedDictionary) - { - return ((IWrappedDictionary)dictionary).UnderlyingDictionary; - } - - targetDictionary = dictionary; + // member attribute converter + converter = memberConverter; } - else + else if (containerProperty != null && containerProperty.ItemConverter != null) { - targetDictionary = PopulateDictionary(dictionaryContract.ShouldCreateWrapper ? dictionaryContract.CreateWrapper(existingValue) : (IDictionary) existingValue, reader, dictionaryContract, member, id); + converter = containerProperty.ItemConverter; } + else if (containerContract != null && containerContract.ItemConverter != null) + { + converter = containerContract.ItemConverter; + } + else if (contract != null) + { + JsonConverter matchingConverter; + if (contract.Converter != null) + // class attribute converter + converter = contract.Converter; + else if ((matchingConverter = Serializer.GetMatchingConverter(contract.UnderlyingType)) != null) + // passed in converters + converter = matchingConverter; + else if (contract.InternalConverter != null) + // internally specified converter + converter = contract.InternalConverter; + } + return converter; + } - return targetDictionary; - } + private object CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, object existingValue) + { + CheckedRead(reader); + + string id; + object newValue; + if (ReadSpecialProperties(reader, ref objectType, ref contract, member, containerContract, containerMember, existingValue, out newValue, out id)) + return newValue; + + if (HasNoDefinedType(contract)) + return CreateJObject(reader); + + switch (contract.ContractType) + { + case JsonContractType.Object: + { + bool createdFromNonDefaultConstructor = false; + JsonObjectContract objectContract = (JsonObjectContract)contract; + object targetObject; + if (existingValue != null) + targetObject = existingValue; + else + targetObject = CreateNewObject(reader, objectContract, member, containerMember, id, out createdFromNonDefaultConstructor); + + // don't populate if read from non-default constructor because the object has already been read + if (createdFromNonDefaultConstructor) + return targetObject; + + return PopulateObject(targetObject, reader, objectContract, member, id); + } + case JsonContractType.Primitive: + { + JsonPrimitiveContract primitiveContract = (JsonPrimitiveContract)contract; + // if the content is inside $value then read past it + if (reader.TokenType == JsonToken.PropertyName && string.Equals(reader.Value.ToString(), JsonTypeReflector.ValuePropertyName, StringComparison.Ordinal)) + { + CheckedRead(reader); + + // the token should not be an object because the $type value could have been included in the object + // without needing the $value property + if (reader.TokenType == JsonToken.StartObject) + throw JsonSerializationException.Create(reader, "Unexpected token when deserializing primitive value: " + reader.TokenType); + + object value = CreateValueInternal(reader, objectType, primitiveContract, member, null, null, existingValue); + + CheckedRead(reader); + return value; + } + break; + } + case JsonContractType.Dictionary: + { + JsonDictionaryContract dictionaryContract = (JsonDictionaryContract)contract; + object targetDictionary; + + if (existingValue == null) + { + bool createdFromNonDefaultConstructor; + IDictionary dictionary = CreateNewDictionary(reader, dictionaryContract, out createdFromNonDefaultConstructor); + + if (createdFromNonDefaultConstructor) + { + if (id != null) + throw JsonSerializationException.Create(reader, "Cannot preserve reference to readonly dictionary, or dictionary created from a non-default constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); + + if (contract.OnSerializingCallbacks.Count > 0) + throw JsonSerializationException.Create(reader, "Cannot call OnSerializing on readonly dictionary, or dictionary created from a non-default constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); + + if (contract.OnErrorCallbacks.Count > 0) + throw JsonSerializationException.Create(reader, "Cannot call OnError on readonly list, or dictionary created from a non-default constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); + + if (dictionaryContract.ParametrizedConstructor == null) + throw JsonSerializationException.Create(reader, "Cannot deserialize readonly or fixed size dictionary: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); + } + + PopulateDictionary(dictionary, reader, dictionaryContract, member, id); + + if (createdFromNonDefaultConstructor) + { + ConstructorInfo constructor = dictionaryContract.ParametrizedConstructor as ConstructorInfo; + if (constructor != null) + return constructor.Invoke(new object[] { dictionary }); + + return dictionaryContract.ParametrizedConstructor.Invoke(null, new object[] { dictionary }); + } + else if (dictionary is IWrappedDictionary) + { + return ((IWrappedDictionary)dictionary).UnderlyingDictionary; + } + + targetDictionary = dictionary; + } + else + { + targetDictionary = PopulateDictionary(dictionaryContract.ShouldCreateWrapper ? dictionaryContract.CreateWrapper(existingValue) : (IDictionary)existingValue, reader, dictionaryContract, member, id); + } + + return targetDictionary; + } #if !(NET35 || NET20 || PORTABLE40) - case JsonContractType.Dynamic: - JsonDynamicContract dynamicContract = (JsonDynamicContract) contract; - return CreateDynamic(reader, dynamicContract, member, id); + case JsonContractType.Dynamic: + JsonDynamicContract dynamicContract = (JsonDynamicContract)contract; + return CreateDynamic(reader, dynamicContract, member, id); #endif #if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) - case JsonContractType.Serializable: - JsonISerializableContract serializableContract = (JsonISerializableContract) contract; - return CreateISerializable(reader, serializableContract, member, id); + case JsonContractType.Serializable: + JsonISerializableContract serializableContract = (JsonISerializableContract)contract; + return CreateISerializable(reader, serializableContract, member, id); #endif - } + } - throw JsonSerializationException.Create(reader, @"Cannot deserialize the current JSON object (e.g. {{""name"":""value""}}) into type '{0}' because the type requires a {1} to deserialize correctly. + throw JsonSerializationException.Create(reader, @"Cannot deserialize the current JSON object (e.g. {{""name"":""value""}}) into type '{0}' because the type requires a {1} to deserialize correctly. To fix this error either change the JSON to a {1} or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object. ".FormatWith(CultureInfo.InvariantCulture, objectType, GetExpectedDescription(contract))); - } - - private bool ReadSpecialProperties(JsonReader reader, ref Type objectType, ref JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, object existingValue, out object newValue, out string id) - { - id = null; - newValue = null; - - if (reader.TokenType == JsonToken.PropertyName) - { - string propertyName = reader.Value.ToString(); - - if (propertyName.Length > 0 && propertyName[0] == '$') - { - // read 'special' properties - // $type, $id, $ref, etc - bool specialProperty; - - do - { - propertyName = reader.Value.ToString(); - - if (string.Equals(propertyName, JsonTypeReflector.RefPropertyName, StringComparison.Ordinal)) - { - CheckedRead(reader); - if (reader.TokenType != JsonToken.String && reader.TokenType != JsonToken.Null) - throw JsonSerializationException.Create(reader, "JSON reference {0} property must have a string or null value.".FormatWith(CultureInfo.InvariantCulture, JsonTypeReflector.RefPropertyName)); - - string reference = (reader.Value != null) ? reader.Value.ToString() : null; - - CheckedRead(reader); - - if (reference != null) - { - if (reader.TokenType == JsonToken.PropertyName) - throw JsonSerializationException.Create(reader, "Additional content found in JSON reference object. A JSON reference object should only have a {0} property.".FormatWith(CultureInfo.InvariantCulture, JsonTypeReflector.RefPropertyName)); - - newValue = Serializer.GetReferenceResolver().ResolveReference(this, reference); - - if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) - TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Resolved object reference '{0}' to {1}.".FormatWith(CultureInfo.InvariantCulture, reference, newValue.GetType())), null); - - return true; - } - else - { - specialProperty = true; - } - } - else if (string.Equals(propertyName, JsonTypeReflector.TypePropertyName, StringComparison.Ordinal)) - { - CheckedRead(reader); - string qualifiedTypeName = reader.Value.ToString(); - - TypeNameHandling resolvedTypeNameHandling = - ((member != null) ? member.TypeNameHandling : null) - ?? ((containerContract != null) ? containerContract.ItemTypeNameHandling : null) - ?? ((containerMember != null) ? containerMember.ItemTypeNameHandling : null) - ?? Serializer._typeNameHandling; - - if (resolvedTypeNameHandling != TypeNameHandling.None) - { - string typeName; - string assemblyName; - ReflectionUtils.SplitFullyQualifiedTypeName(qualifiedTypeName, out typeName, out assemblyName); - - Type specifiedType; - try - { - specifiedType = Serializer._binder.BindToType(assemblyName, typeName); - } - catch (Exception ex) - { - throw JsonSerializationException.Create(reader, "Error resolving type specified in JSON '{0}'.".FormatWith(CultureInfo.InvariantCulture, qualifiedTypeName), ex); - } - - if (specifiedType == null) - throw JsonSerializationException.Create(reader, "Type specified in JSON '{0}' was not resolved.".FormatWith(CultureInfo.InvariantCulture, qualifiedTypeName)); - - if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) - TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Resolved type '{0}' to {1}.".FormatWith(CultureInfo.InvariantCulture, qualifiedTypeName, specifiedType)), null); - - if (objectType != null -#if !(NET35 || NET20 || PORTABLE40) - && objectType != typeof (IDynamicMetaObjectProvider) -#endif - && !objectType.IsAssignableFrom(specifiedType)) - throw JsonSerializationException.Create(reader, "Type specified in JSON '{0}' is not compatible with '{1}'.".FormatWith(CultureInfo.InvariantCulture, specifiedType.AssemblyQualifiedName, objectType.AssemblyQualifiedName)); - - objectType = specifiedType; - contract = GetContractSafe(specifiedType); - } - - CheckedRead(reader); - - specialProperty = true; - } - else if (string.Equals(propertyName, JsonTypeReflector.IdPropertyName, StringComparison.Ordinal)) - { - CheckedRead(reader); - - id = (reader.Value != null) ? reader.Value.ToString() : null; - - CheckedRead(reader); - specialProperty = true; - } - else if (string.Equals(propertyName, JsonTypeReflector.ArrayValuesPropertyName, StringComparison.Ordinal)) - { - CheckedRead(reader); - object list = CreateList(reader, objectType, contract, member, existingValue, id); - CheckedRead(reader); - newValue = list; - return true; - } - else - { - specialProperty = false; - } - } while (specialProperty - && reader.TokenType == JsonToken.PropertyName); } - } - return false; - } - private JsonArrayContract EnsureArrayContract(JsonReader reader, Type objectType, JsonContract contract) - { - if (contract == null) - throw JsonSerializationException.Create(reader, "Could not resolve type '{0}' to a JsonContract.".FormatWith(CultureInfo.InvariantCulture, objectType)); + private bool ReadSpecialProperties(JsonReader reader, ref Type objectType, ref JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, object existingValue, out object newValue, out string id) + { + id = null; + newValue = null; - JsonArrayContract arrayContract = contract as JsonArrayContract; - if (arrayContract == null) - throw JsonSerializationException.Create(reader, @"Cannot deserialize the current JSON array (e.g. [1,2,3]) into type '{0}' because the type requires a {1} to deserialize correctly. + if (reader.TokenType == JsonToken.PropertyName) + { + string propertyName = reader.Value.ToString(); + + if (propertyName.Length > 0 && propertyName[0] == '$') + { + // read 'special' properties + // $type, $id, $ref, etc + bool specialProperty; + + do + { + propertyName = reader.Value.ToString(); + + if (string.Equals(propertyName, JsonTypeReflector.RefPropertyName, StringComparison.Ordinal)) + { + CheckedRead(reader); + if (reader.TokenType != JsonToken.String && reader.TokenType != JsonToken.Null) + throw JsonSerializationException.Create(reader, "JSON reference {0} property must have a string or null value.".FormatWith(CultureInfo.InvariantCulture, JsonTypeReflector.RefPropertyName)); + + string reference = (reader.Value != null) ? reader.Value.ToString() : null; + + CheckedRead(reader); + + if (reference != null) + { + if (reader.TokenType == JsonToken.PropertyName) + throw JsonSerializationException.Create(reader, "Additional content found in JSON reference object. A JSON reference object should only have a {0} property.".FormatWith(CultureInfo.InvariantCulture, JsonTypeReflector.RefPropertyName)); + + newValue = Serializer.GetReferenceResolver().ResolveReference(this, reference); + + if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) + TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Resolved object reference '{0}' to {1}.".FormatWith(CultureInfo.InvariantCulture, reference, newValue.GetType())), null); + + return true; + } + else + { + specialProperty = true; + } + } + else if (string.Equals(propertyName, JsonTypeReflector.TypePropertyName, StringComparison.Ordinal)) + { + CheckedRead(reader); + string qualifiedTypeName = reader.Value.ToString(); + + TypeNameHandling resolvedTypeNameHandling = + ((member != null) ? member.TypeNameHandling : null) + ?? ((containerContract != null) ? containerContract.ItemTypeNameHandling : null) + ?? ((containerMember != null) ? containerMember.ItemTypeNameHandling : null) + ?? Serializer._typeNameHandling; + + if (resolvedTypeNameHandling != TypeNameHandling.None) + { + string typeName; + string assemblyName; + ReflectionUtils.SplitFullyQualifiedTypeName(qualifiedTypeName, out typeName, out assemblyName); + + Type specifiedType; + try + { + specifiedType = Serializer._binder.BindToType(assemblyName, typeName); + } + catch (Exception ex) + { + throw JsonSerializationException.Create(reader, "Error resolving type specified in JSON '{0}'.".FormatWith(CultureInfo.InvariantCulture, qualifiedTypeName), ex); + } + + if (specifiedType == null) + throw JsonSerializationException.Create(reader, "Type specified in JSON '{0}' was not resolved.".FormatWith(CultureInfo.InvariantCulture, qualifiedTypeName)); + + if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) + TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Resolved type '{0}' to {1}.".FormatWith(CultureInfo.InvariantCulture, qualifiedTypeName, specifiedType)), null); + + if (objectType != null +#if !(NET35 || NET20 || PORTABLE40) + && objectType != typeof(IDynamicMetaObjectProvider) +#endif + && !objectType.IsAssignableFrom(specifiedType)) + throw JsonSerializationException.Create(reader, "Type specified in JSON '{0}' is not compatible with '{1}'.".FormatWith(CultureInfo.InvariantCulture, specifiedType.AssemblyQualifiedName, objectType.AssemblyQualifiedName)); + + objectType = specifiedType; + contract = GetContractSafe(specifiedType); + } + + CheckedRead(reader); + + specialProperty = true; + } + else if (string.Equals(propertyName, JsonTypeReflector.IdPropertyName, StringComparison.Ordinal)) + { + CheckedRead(reader); + + id = (reader.Value != null) ? reader.Value.ToString() : null; + + CheckedRead(reader); + specialProperty = true; + } + else if (string.Equals(propertyName, JsonTypeReflector.ArrayValuesPropertyName, StringComparison.Ordinal)) + { + CheckedRead(reader); + object list = CreateList(reader, objectType, contract, member, existingValue, id); + CheckedRead(reader); + newValue = list; + return true; + } + else + { + specialProperty = false; + } + } while (specialProperty + && reader.TokenType == JsonToken.PropertyName); + } + } + return false; + } + + private JsonArrayContract EnsureArrayContract(JsonReader reader, Type objectType, JsonContract contract) + { + if (contract == null) + throw JsonSerializationException.Create(reader, "Could not resolve type '{0}' to a JsonContract.".FormatWith(CultureInfo.InvariantCulture, objectType)); + + JsonArrayContract arrayContract = contract as JsonArrayContract; + if (arrayContract == null) + throw JsonSerializationException.Create(reader, @"Cannot deserialize the current JSON array (e.g. [1,2,3]) into type '{0}' because the type requires a {1} to deserialize correctly. To fix this error either change the JSON to a {1} or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array. ".FormatWith(CultureInfo.InvariantCulture, objectType, GetExpectedDescription(contract))); - return arrayContract; - } - - private void CheckedRead(JsonReader reader) - { - if (!reader.Read()) - throw JsonSerializationException.Create(reader, "Unexpected end when deserializing object."); - } - - private object CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, object existingValue, string id) - { - object value; - - if (HasNoDefinedType(contract)) - return CreateJToken(reader, contract); - - JsonArrayContract arrayContract = EnsureArrayContract(reader, objectType, contract); - - if (existingValue == null) - { - bool createdFromNonDefaultConstructor; - IList list = CreateNewList(reader, arrayContract, out createdFromNonDefaultConstructor); - - if (createdFromNonDefaultConstructor) - { - if (id != null) - throw JsonSerializationException.Create(reader, "Cannot preserve reference to array or readonly list, or list created from a non-default constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); - - if (contract.OnSerializingCallbacks.Count > 0) - throw JsonSerializationException.Create(reader, "Cannot call OnSerializing on an array or readonly list, or list created from a non-default constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); - - if (contract.OnErrorCallbacks.Count > 0) - throw JsonSerializationException.Create(reader, "Cannot call OnError on an array or readonly list, or list created from a non-default constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); - - if (arrayContract.ParametrizedConstructor == null && !arrayContract.IsArray) - throw JsonSerializationException.Create(reader, "Cannot deserialize readonly or fixed size list: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); + return arrayContract; } - if (!arrayContract.IsMultidimensionalArray) - PopulateList(list, reader, arrayContract, member, id); - else - PopulateMultidimensionalArray(list, reader, arrayContract, member, id); - - if (createdFromNonDefaultConstructor) + private void CheckedRead(JsonReader reader) { - if (arrayContract.IsMultidimensionalArray) - { - list = CollectionUtils.ToMultidimensionalArray(list, arrayContract.CollectionItemType, contract.CreatedType.GetArrayRank()); - } - else if (arrayContract.IsArray) - { - Array a = Array.CreateInstance(arrayContract.CollectionItemType, list.Count); - list.CopyTo(a, 0); - list = a; - } - else - { - // call constructor that takes IEnumerable - ConstructorInfo constructor = arrayContract.ParametrizedConstructor as ConstructorInfo; - if (constructor != null) - return constructor.Invoke(new object[] { list }); - - return arrayContract.ParametrizedConstructor.Invoke(null, new object[] { list }); - } - } - else if (list is IWrappedCollection) - { - return ((IWrappedCollection)list).UnderlyingCollection; + if (!reader.Read()) + throw JsonSerializationException.Create(reader, "Unexpected end when deserializing object."); } - value = list; - } - else - { - value = PopulateList((arrayContract.ShouldCreateWrapper) ? arrayContract.CreateWrapper(existingValue) : (IList) existingValue, reader, arrayContract, member, id); - } - - return value; - } - - private bool HasNoDefinedType(JsonContract contract) - { - return (contract == null || contract.UnderlyingType == typeof (object) || contract.ContractType == JsonContractType.Linq -#if !(NET35 || NET20 || PORTABLE40) - || contract.UnderlyingType == typeof(IDynamicMetaObjectProvider) -#endif - ); - } - - private object EnsureType(JsonReader reader, object value, CultureInfo culture, JsonContract contract, Type targetType) - { - if (targetType == null) - return value; - - Type valueType = ReflectionUtils.GetObjectType(value); - - // type of value and type of target don't match - // attempt to convert value's type to target's type - if (valueType != targetType) - { - if (value == null && contract.IsNullable) - return null; - - try + private object CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, object existingValue, string id) { - if (contract.IsConvertable) - { - JsonPrimitiveContract primitiveContract = (JsonPrimitiveContract)contract; + object value; - if (contract.IsEnum) + if (HasNoDefinedType(contract)) + return CreateJToken(reader, contract); + + JsonArrayContract arrayContract = EnsureArrayContract(reader, objectType, contract); + + if (existingValue == null) { - if (value is string) - return Enum.Parse(contract.NonNullableUnderlyingType, value.ToString(), true); - else if (ConvertUtils.IsInteger(primitiveContract.TypeCode)) - return Enum.ToObject(contract.NonNullableUnderlyingType, value); + bool createdFromNonDefaultConstructor; + IList list = CreateNewList(reader, arrayContract, out createdFromNonDefaultConstructor); + + if (createdFromNonDefaultConstructor) + { + if (id != null) + throw JsonSerializationException.Create(reader, "Cannot preserve reference to array or readonly list, or list created from a non-default constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); + + if (contract.OnSerializingCallbacks.Count > 0) + throw JsonSerializationException.Create(reader, "Cannot call OnSerializing on an array or readonly list, or list created from a non-default constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); + + if (contract.OnErrorCallbacks.Count > 0) + throw JsonSerializationException.Create(reader, "Cannot call OnError on an array or readonly list, or list created from a non-default constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); + + if (arrayContract.ParametrizedConstructor == null && !arrayContract.IsArray) + throw JsonSerializationException.Create(reader, "Cannot deserialize readonly or fixed size list: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); + } + + if (!arrayContract.IsMultidimensionalArray) + PopulateList(list, reader, arrayContract, member, id); + else + PopulateMultidimensionalArray(list, reader, arrayContract, member, id); + + if (createdFromNonDefaultConstructor) + { + if (arrayContract.IsMultidimensionalArray) + { + list = CollectionUtils.ToMultidimensionalArray(list, arrayContract.CollectionItemType, contract.CreatedType.GetArrayRank()); + } + else if (arrayContract.IsArray) + { + Array a = Array.CreateInstance(arrayContract.CollectionItemType, list.Count); + list.CopyTo(a, 0); + list = a; + } + else + { + // call constructor that takes IEnumerable + ConstructorInfo constructor = arrayContract.ParametrizedConstructor as ConstructorInfo; + if (constructor != null) + return constructor.Invoke(new object[] { list }); + + return arrayContract.ParametrizedConstructor.Invoke(null, new object[] { list }); + } + } + else if (list is IWrappedCollection) + { + return ((IWrappedCollection)list).UnderlyingCollection; + } + + value = list; } + else + { + value = PopulateList((arrayContract.ShouldCreateWrapper) ? arrayContract.CreateWrapper(existingValue) : (IList)existingValue, reader, arrayContract, member, id); + } + + return value; + } + + private bool HasNoDefinedType(JsonContract contract) + { + return (contract == null || contract.UnderlyingType == typeof(object) || contract.ContractType == JsonContractType.Linq +#if !(NET35 || NET20 || PORTABLE40) + || contract.UnderlyingType == typeof(IDynamicMetaObjectProvider) +#endif + ); + } + + private object EnsureType(JsonReader reader, object value, CultureInfo culture, JsonContract contract, Type targetType) + { + if (targetType == null) + return value; + + Type valueType = ReflectionUtils.GetObjectType(value); + + // type of value and type of target don't match + // attempt to convert value's type to target's type + if (valueType != targetType) + { + if (value == null && contract.IsNullable) + return null; + + try + { + if (contract.IsConvertable) + { + JsonPrimitiveContract primitiveContract = (JsonPrimitiveContract)contract; + + if (contract.IsEnum) + { + if (value is string) + return Enum.Parse(contract.NonNullableUnderlyingType, value.ToString(), true); + else if (ConvertUtils.IsInteger(primitiveContract.TypeCode)) + return Enum.ToObject(contract.NonNullableUnderlyingType, value); + } #if !(PORTABLE || PORTABLE40 || NET35 || NET20 || SILVERLIGHT) - if (value is BigInteger) - return ConvertUtils.FromBigInteger((BigInteger)value, targetType); + if (value is BigInteger) + return ConvertUtils.FromBigInteger((BigInteger)value, targetType); #endif - // this won't work when converting to a custom IConvertible - return Convert.ChangeType(value, contract.NonNullableUnderlyingType, culture); - } + // this won't work when converting to a custom IConvertible + return Convert.ChangeType(value, contract.NonNullableUnderlyingType, culture); + } - return ConvertUtils.ConvertOrCast(value, culture, contract.NonNullableUnderlyingType); - } - catch (Exception ex) - { - throw JsonSerializationException.Create(reader, "Error converting value {0} to type '{1}'.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.FormatValueForPrint(value), targetType), ex); - } - } + return ConvertUtils.ConvertOrCast(value, culture, contract.NonNullableUnderlyingType); + } + catch (Exception ex) + { + throw JsonSerializationException.Create(reader, "Error converting value {0} to type '{1}'.".FormatWith(CultureInfo.InvariantCulture, MiscellaneousUtils.FormatValueForPrint(value), targetType), ex); + } + } - return value; - } - - private bool SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, object target) - { - object currentValue; - bool useExistingValue; - JsonContract propertyContract; - bool gottenCurrentValue; - - if (CalculatePropertyDetails(property, ref propertyConverter, containerContract, containerProperty, reader, target, out useExistingValue, out currentValue, out propertyContract, out gottenCurrentValue)) - return false; - - object value; - - if (propertyConverter != null && propertyConverter.CanRead) - { - if (!gottenCurrentValue && target != null && property.Readable) - currentValue = property.ValueProvider.GetValue(target); - - value = DeserializeConvertable(propertyConverter, reader, property.PropertyType, currentValue); - } - else - { - value = CreateValueInternal(reader, property.PropertyType, propertyContract, property, containerContract, containerProperty, (useExistingValue) ? currentValue : null); - } - - // always set the value if useExistingValue is false, - // otherwise also set it if CreateValue returns a new value compared to the currentValue - // this could happen because of a JsonConverter against the type - if ((!useExistingValue || value != currentValue) - && ShouldSetPropertyValue(property, value)) - { - 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); + return value; } - return true; - } - - // the value wasn't set be JSON was populated onto the existing value - return useExistingValue; - } - - private bool CalculatePropertyDetails(JsonProperty property, ref JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, object target, out bool useExistingValue, out object currentValue, out JsonContract propertyContract, out bool gottenCurrentValue) - { - currentValue = null; - useExistingValue = false; - propertyContract = null; - gottenCurrentValue = false; - - if (property.Ignored) - return true; - - JsonToken tokenType = reader.TokenType; - - if (property.PropertyContract == null) - property.PropertyContract = GetContractSafe(property.PropertyType); - - ObjectCreationHandling objectCreationHandling = - property.ObjectCreationHandling.GetValueOrDefault(Serializer._objectCreationHandling); - - if ((objectCreationHandling != ObjectCreationHandling.Replace) - && (tokenType == JsonToken.StartArray || tokenType == JsonToken.StartObject) - && property.Readable) - { - currentValue = property.ValueProvider.GetValue(target); - gottenCurrentValue = true; - - if (currentValue != null) + private bool SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, object target) { - propertyContract = GetContractSafe(currentValue.GetType()); + object currentValue; + bool useExistingValue; + JsonContract propertyContract; + bool gottenCurrentValue; - useExistingValue = (!propertyContract.IsReadOnlyOrFixedSize && !propertyContract.UnderlyingType.IsValueType()); + if (CalculatePropertyDetails(property, ref propertyConverter, containerContract, containerProperty, reader, target, out useExistingValue, out currentValue, out propertyContract, out gottenCurrentValue)) + return false; + + object value; + + if (propertyConverter != null && propertyConverter.CanRead) + { + if (!gottenCurrentValue && target != null && property.Readable) + currentValue = property.ValueProvider.GetValue(target); + + value = DeserializeConvertable(propertyConverter, reader, property.PropertyType, currentValue); + } + else + { + value = CreateValueInternal(reader, property.PropertyType, propertyContract, property, containerContract, containerProperty, (useExistingValue) ? currentValue : null); + } + + // always set the value if useExistingValue is false, + // otherwise also set it if CreateValue returns a new value compared to the currentValue + // this could happen because of a JsonConverter against the type + if ((!useExistingValue || value != currentValue) + && ShouldSetPropertyValue(property, value)) + { + 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); + } + + return true; + } + + // the value wasn't set be JSON was populated onto the existing value + return useExistingValue; } - } - if (!property.Writable && !useExistingValue) - return true; - - // test tokentype here because null might not be convertable to some types, e.g. ignoring null when applied to DateTime - if (property.NullValueHandling.GetValueOrDefault(Serializer._nullValueHandling) == NullValueHandling.Ignore && tokenType == JsonToken.Null) - return true; - - // test tokentype here because default value might not be convertable to actual type, e.g. default of "" for DateTime - if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer._defaultValueHandling), DefaultValueHandling.Ignore) - && !HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer._defaultValueHandling), DefaultValueHandling.Populate) - && JsonReader.IsPrimitiveToken(tokenType) - && MiscellaneousUtils.ValueEquals(reader.Value, property.GetResolvedDefaultValue())) - return true; - - if (currentValue == null) - { - propertyContract = property.PropertyContract; - } - else - { - propertyContract = GetContractSafe(currentValue.GetType()); - - if (propertyContract != property.PropertyContract) - propertyConverter = GetConverter(propertyContract, property.MemberConverter, containerContract, containerProperty); - } - - return false; - } - - private void AddReference(JsonReader reader, string id, object value) - { - try - { - if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) - TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Read object reference Id '{0}' for {1}.".FormatWith(CultureInfo.InvariantCulture, id, value.GetType())), null); - - Serializer.GetReferenceResolver().AddReference(this, id, value); - } - catch (Exception ex) - { - throw JsonSerializationException.Create(reader, "Error reading object reference '{0}'.".FormatWith(CultureInfo.InvariantCulture, id), ex); - } - } - - private bool HasFlag(DefaultValueHandling value, DefaultValueHandling flag) - { - return ((value & flag) == flag); - } - - private bool ShouldSetPropertyValue(JsonProperty property, object value) - { - if (property.NullValueHandling.GetValueOrDefault(Serializer._nullValueHandling) == NullValueHandling.Ignore && value == null) - return false; - - if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer._defaultValueHandling), DefaultValueHandling.Ignore) - && !HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer._defaultValueHandling), DefaultValueHandling.Populate) - && MiscellaneousUtils.ValueEquals(value, property.GetResolvedDefaultValue())) - return false; - - if (!property.Writable) - return false; - - return true; - } - - private IList CreateNewList(JsonReader reader, JsonArrayContract contract, out bool createdFromNonDefaultConstructor) - { - // some types like non-generic IEnumerable can be serialized but not deserialized - if (!contract.CanDeserialize) - throw JsonSerializationException.Create(reader, "Cannot create and populate list type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.CreatedType)); - - if (contract.IsReadOnlyOrFixedSize) - { - createdFromNonDefaultConstructor = true; - IList list = contract.CreateTemporaryCollection(); - - if (contract.ShouldCreateWrapper) - list = contract.CreateWrapper(list); - - return list; - } - else if (contract.DefaultCreator != null && (!contract.DefaultCreatorNonPublic || Serializer._constructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor)) - { - object list = contract.DefaultCreator(); - - if (contract.ShouldCreateWrapper) - list = contract.CreateWrapper(list); - - createdFromNonDefaultConstructor = false; - return (IList)list; - } - else if (contract.ParametrizedConstructor != null) - { - createdFromNonDefaultConstructor = true; - return contract.CreateTemporaryCollection(); - } - else - { - throw JsonSerializationException.Create(reader, "Unable to find a constructor to use for type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); - } - } - - private IDictionary CreateNewDictionary(JsonReader reader, JsonDictionaryContract contract, out bool createdFromNonDefaultConstructor) - { - if (contract.IsReadOnlyOrFixedSize) - { - createdFromNonDefaultConstructor = true; - return contract.CreateTemporaryDictionary(); - } - else if (contract.DefaultCreator != null && (!contract.DefaultCreatorNonPublic || Serializer._constructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor)) - { - object dictionary = contract.DefaultCreator(); - - if (contract.ShouldCreateWrapper) - dictionary = contract.CreateWrapper(dictionary); - - createdFromNonDefaultConstructor = false; - return (IDictionary) dictionary; - } - else if (contract.ParametrizedConstructor != null) - { - createdFromNonDefaultConstructor = true; - return contract.CreateTemporaryDictionary(); - } - else - { - throw JsonSerializationException.Create(reader, "Unable to find a default constructor to use for type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); - } - } - - private void OnDeserializing(JsonReader reader, JsonContract contract, object value) - { - if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) - TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Started deserializing {0}".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)), null); - - contract.InvokeOnDeserializing(value, Serializer._context); - } - - private void OnDeserialized(JsonReader reader, JsonContract contract, object value) - { - if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) - TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Finished deserializing {0}".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)), null); - - contract.InvokeOnDeserialized(value, Serializer._context); - } - - private object PopulateDictionary(IDictionary dictionary, JsonReader reader, JsonDictionaryContract contract, JsonProperty containerProperty, string id) - { - IWrappedDictionary wrappedDictionary = dictionary as IWrappedDictionary; - object underlyingDictionary = wrappedDictionary != null ? wrappedDictionary.UnderlyingDictionary : dictionary; - - if (id != null) - AddReference(reader, id, underlyingDictionary); - - OnDeserializing(reader, contract, underlyingDictionary); - - int initialDepth = reader.Depth; - - if (contract.KeyContract == null) - contract.KeyContract = GetContractSafe(contract.DictionaryKeyType); - - if (contract.ItemContract == null) - contract.ItemContract = GetContractSafe(contract.DictionaryValueType); - - JsonConverter dictionaryValueConverter = contract.ItemConverter ?? GetConverter(contract.ItemContract, null, contract, containerProperty); - PrimitiveTypeCode keyTypeCode = (contract.KeyContract is JsonPrimitiveContract) ? ((JsonPrimitiveContract)contract.KeyContract).TypeCode : PrimitiveTypeCode.Empty; - - bool finished = false; - do - { - switch (reader.TokenType) + private bool CalculatePropertyDetails(JsonProperty property, ref JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, object target, out bool useExistingValue, out object currentValue, out JsonContract propertyContract, out bool gottenCurrentValue) + { + currentValue = null; + useExistingValue = false; + propertyContract = null; + gottenCurrentValue = false; + + if (property.Ignored) + return true; + + JsonToken tokenType = reader.TokenType; + + if (property.PropertyContract == null) + property.PropertyContract = GetContractSafe(property.PropertyType); + + ObjectCreationHandling objectCreationHandling = + property.ObjectCreationHandling.GetValueOrDefault(Serializer._objectCreationHandling); + + if ((objectCreationHandling != ObjectCreationHandling.Replace) + && (tokenType == JsonToken.StartArray || tokenType == JsonToken.StartObject) + && property.Readable) + { + currentValue = property.ValueProvider.GetValue(target); + gottenCurrentValue = true; + + if (currentValue != null) + { + propertyContract = GetContractSafe(currentValue.GetType()); + + useExistingValue = (!propertyContract.IsReadOnlyOrFixedSize && !propertyContract.UnderlyingType.IsValueType()); + } + } + + if (!property.Writable && !useExistingValue) + return true; + + // test tokentype here because null might not be convertable to some types, e.g. ignoring null when applied to DateTime + if (property.NullValueHandling.GetValueOrDefault(Serializer._nullValueHandling) == NullValueHandling.Ignore && tokenType == JsonToken.Null) + return true; + + // test tokentype here because default value might not be convertable to actual type, e.g. default of "" for DateTime + if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer._defaultValueHandling), DefaultValueHandling.Ignore) + && !HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer._defaultValueHandling), DefaultValueHandling.Populate) + && JsonReader.IsPrimitiveToken(tokenType) + && MiscellaneousUtils.ValueEquals(reader.Value, property.GetResolvedDefaultValue())) + return true; + + if (currentValue == null) + { + propertyContract = property.PropertyContract; + } + else + { + propertyContract = GetContractSafe(currentValue.GetType()); + + if (propertyContract != property.PropertyContract) + propertyConverter = GetConverter(propertyContract, property.MemberConverter, containerContract, containerProperty); + } + + return false; + } + + private void AddReference(JsonReader reader, string id, object value) { - case JsonToken.PropertyName: - object keyValue = reader.Value; try { - try - { - object dt; - // this is for correctly reading ISO and MS formatted dictionary keys - if ((keyTypeCode == PrimitiveTypeCode.DateTime || keyTypeCode == PrimitiveTypeCode.DateTimeNullable) - && DateTimeUtils.TryParseDateTime(keyValue.ToString(), DateParseHandling.DateTime, reader.DateTimeZoneHandling, out dt)) - { - keyValue = dt; - } -#if !NET20 - else if ((keyTypeCode == PrimitiveTypeCode.DateTimeOffset || keyTypeCode == PrimitiveTypeCode.DateTimeOffsetNullable) - && DateTimeUtils.TryParseDateTime(keyValue.ToString(), DateParseHandling.DateTimeOffset, reader.DateTimeZoneHandling, out dt)) - { - keyValue = dt; - } -#endif - else - { - keyValue = EnsureType(reader, keyValue, CultureInfo.InvariantCulture, contract.KeyContract, contract.DictionaryKeyType); - } - } - catch (Exception ex) - { - throw JsonSerializationException.Create(reader, "Could not convert string '{0}' to dictionary key type '{1}'. Create a TypeConverter to convert from the string to the key type object.".FormatWith(CultureInfo.InvariantCulture, reader.Value, contract.DictionaryKeyType), ex); - } + if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) + TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Read object reference Id '{0}' for {1}.".FormatWith(CultureInfo.InvariantCulture, id, value.GetType())), null); - if (!ReadForType(reader, contract.ItemContract, dictionaryValueConverter != null)) - throw JsonSerializationException.Create(reader, "Unexpected end when deserializing object."); - - object itemValue; - if (dictionaryValueConverter != null && dictionaryValueConverter.CanRead) - itemValue = DeserializeConvertable(dictionaryValueConverter, reader, contract.DictionaryValueType, null); - else - itemValue = CreateValueInternal(reader, contract.DictionaryValueType, contract.ItemContract, null, contract, containerProperty, null); - - dictionary[keyValue] = itemValue; + Serializer.GetReferenceResolver().AddReference(this, id, value); } catch (Exception ex) { - if (IsErrorHandled(underlyingDictionary, contract, keyValue, reader as IJsonLineInfo, reader.Path, ex)) - HandleError(reader, true, initialDepth); - else - throw; + throw JsonSerializationException.Create(reader, "Error reading object reference '{0}'.".FormatWith(CultureInfo.InvariantCulture, id), ex); } - break; - case JsonToken.Comment: - break; - case JsonToken.EndObject: - finished = true; - break; - default: - throw JsonSerializationException.Create(reader, "Unexpected token when deserializing object: " + reader.TokenType); } - } while (!finished && reader.Read()); - if (!finished) - ThrowUnexpectedEndException(reader, contract, underlyingDictionary, "Unexpected end when deserializing object."); - - OnDeserialized(reader, contract, underlyingDictionary); - return underlyingDictionary; - } - - private object PopulateMultidimensionalArray(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, string id) - { - int rank = contract.UnderlyingType.GetArrayRank(); - - if (id != null) - AddReference(reader, id, list); - - OnDeserializing(reader, contract, list); - - JsonContract collectionItemContract = GetContractSafe(contract.CollectionItemType); - JsonConverter collectionItemConverter = GetConverter(collectionItemContract, null, contract, containerProperty); - - int? previousErrorIndex = null; - Stack listStack = new Stack(); - listStack.Push(list); - IList currentList = list; - - bool finished = false; - do - { - int initialDepth = reader.Depth; - - if (listStack.Count == rank) + private bool HasFlag(DefaultValueHandling value, DefaultValueHandling flag) { - try - { - if (ReadForType(reader, collectionItemContract, collectionItemConverter != null)) + return ((value & flag) == flag); + } + + private bool ShouldSetPropertyValue(JsonProperty property, object value) + { + if (property.NullValueHandling.GetValueOrDefault(Serializer._nullValueHandling) == NullValueHandling.Ignore && value == null) + return false; + + if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer._defaultValueHandling), DefaultValueHandling.Ignore) + && !HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer._defaultValueHandling), DefaultValueHandling.Populate) + && MiscellaneousUtils.ValueEquals(value, property.GetResolvedDefaultValue())) + return false; + + if (!property.Writable) + return false; + + return true; + } + + private IList CreateNewList(JsonReader reader, JsonArrayContract contract, out bool createdFromNonDefaultConstructor) + { + // some types like non-generic IEnumerable can be serialized but not deserialized + if (!contract.CanDeserialize) + throw JsonSerializationException.Create(reader, "Cannot create and populate list type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.CreatedType)); + + if (contract.IsReadOnlyOrFixedSize) { - switch (reader.TokenType) - { - case JsonToken.EndArray: - listStack.Pop(); - currentList = listStack.Peek(); - previousErrorIndex = null; - break; - case JsonToken.Comment: - break; - default: - object value; + createdFromNonDefaultConstructor = true; + IList list = contract.CreateTemporaryCollection(); - if (collectionItemConverter != null && collectionItemConverter.CanRead) - value = DeserializeConvertable(collectionItemConverter, reader, contract.CollectionItemType, null); - else - value = CreateValueInternal(reader, contract.CollectionItemType, collectionItemContract, null, contract, containerProperty, null); + if (contract.ShouldCreateWrapper) + list = contract.CreateWrapper(list); - currentList.Add(value); - break; - } + return list; + } + else if (contract.DefaultCreator != null && (!contract.DefaultCreatorNonPublic || Serializer._constructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor)) + { + object list = contract.DefaultCreator(); + + if (contract.ShouldCreateWrapper) + list = contract.CreateWrapper(list); + + createdFromNonDefaultConstructor = false; + return (IList)list; + } + else if (contract.ParametrizedConstructor != null) + { + createdFromNonDefaultConstructor = true; + return contract.CreateTemporaryCollection(); } else { - break; + throw JsonSerializationException.Create(reader, "Unable to find a constructor to use for type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); } - } - catch (Exception ex) - { - JsonPosition errorPosition = reader.GetPosition(initialDepth); + } - if (IsErrorHandled(list, contract, errorPosition.Position, reader as IJsonLineInfo, reader.Path, ex)) + private IDictionary CreateNewDictionary(JsonReader reader, JsonDictionaryContract contract, out bool createdFromNonDefaultConstructor) + { + if (contract.IsReadOnlyOrFixedSize) { - HandleError(reader, true, initialDepth); + createdFromNonDefaultConstructor = true; + return contract.CreateTemporaryDictionary(); + } + else if (contract.DefaultCreator != null && (!contract.DefaultCreatorNonPublic || Serializer._constructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor)) + { + object dictionary = contract.DefaultCreator(); - if (previousErrorIndex != null && previousErrorIndex == errorPosition.Position) - { - // reader index has not moved since previous error handling - // break out of reading array to prevent infinite loop - throw JsonSerializationException.Create(reader, "Infinite loop detected from error handling.", ex); - } - else - { - previousErrorIndex = errorPosition.Position; - } + if (contract.ShouldCreateWrapper) + dictionary = contract.CreateWrapper(dictionary); + + createdFromNonDefaultConstructor = false; + return (IDictionary)dictionary; + } + else if (contract.ParametrizedConstructor != null) + { + createdFromNonDefaultConstructor = true; + return contract.CreateTemporaryDictionary(); } else { - throw; + throw JsonSerializationException.Create(reader, "Unable to find a default constructor to use for type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); } - } } - else - { - if (reader.Read()) - { - switch (reader.TokenType) - { - case JsonToken.StartArray: - IList newList = new List(); - currentList.Add(newList); - listStack.Push(newList); - currentList = newList; - break; - case JsonToken.EndArray: - listStack.Pop(); - if (listStack.Count > 0) + private void OnDeserializing(JsonReader reader, JsonContract contract, object value) + { + if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) + TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Started deserializing {0}".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)), null); + + contract.InvokeOnDeserializing(value, Serializer._context); + } + + private void OnDeserialized(JsonReader reader, JsonContract contract, object value) + { + if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) + TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Finished deserializing {0}".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)), null); + + contract.InvokeOnDeserialized(value, Serializer._context); + } + + private object PopulateDictionary(IDictionary dictionary, JsonReader reader, JsonDictionaryContract contract, JsonProperty containerProperty, string id) + { + IWrappedDictionary wrappedDictionary = dictionary as IWrappedDictionary; + object underlyingDictionary = wrappedDictionary != null ? wrappedDictionary.UnderlyingDictionary : dictionary; + + if (id != null) + AddReference(reader, id, underlyingDictionary); + + OnDeserializing(reader, contract, underlyingDictionary); + + int initialDepth = reader.Depth; + + if (contract.KeyContract == null) + contract.KeyContract = GetContractSafe(contract.DictionaryKeyType); + + if (contract.ItemContract == null) + contract.ItemContract = GetContractSafe(contract.DictionaryValueType); + + JsonConverter dictionaryValueConverter = contract.ItemConverter ?? GetConverter(contract.ItemContract, null, contract, containerProperty); + PrimitiveTypeCode keyTypeCode = (contract.KeyContract is JsonPrimitiveContract) ? ((JsonPrimitiveContract)contract.KeyContract).TypeCode : PrimitiveTypeCode.Empty; + + bool finished = false; + do + { + switch (reader.TokenType) { - currentList = listStack.Peek(); + case JsonToken.PropertyName: + object keyValue = reader.Value; + try + { + try + { + object dt; + // this is for correctly reading ISO and MS formatted dictionary keys + if ((keyTypeCode == PrimitiveTypeCode.DateTime || keyTypeCode == PrimitiveTypeCode.DateTimeNullable) + && DateTimeUtils.TryParseDateTime(keyValue.ToString(), DateParseHandling.DateTime, reader.DateTimeZoneHandling, out dt)) + { + keyValue = dt; + } +#if !NET20 + else if ((keyTypeCode == PrimitiveTypeCode.DateTimeOffset || keyTypeCode == PrimitiveTypeCode.DateTimeOffsetNullable) + && DateTimeUtils.TryParseDateTime(keyValue.ToString(), DateParseHandling.DateTimeOffset, reader.DateTimeZoneHandling, out dt)) + { + keyValue = dt; + } +#endif + else + { + keyValue = EnsureType(reader, keyValue, CultureInfo.InvariantCulture, contract.KeyContract, contract.DictionaryKeyType); + } + } + catch (Exception ex) + { + throw JsonSerializationException.Create(reader, "Could not convert string '{0}' to dictionary key type '{1}'. Create a TypeConverter to convert from the string to the key type object.".FormatWith(CultureInfo.InvariantCulture, reader.Value, contract.DictionaryKeyType), ex); + } + + if (!ReadForType(reader, contract.ItemContract, dictionaryValueConverter != null)) + throw JsonSerializationException.Create(reader, "Unexpected end when deserializing object."); + + object itemValue; + if (dictionaryValueConverter != null && dictionaryValueConverter.CanRead) + itemValue = DeserializeConvertable(dictionaryValueConverter, reader, contract.DictionaryValueType, null); + else + itemValue = CreateValueInternal(reader, contract.DictionaryValueType, contract.ItemContract, null, contract, containerProperty, null); + + dictionary[keyValue] = itemValue; + } + catch (Exception ex) + { + if (IsErrorHandled(underlyingDictionary, contract, keyValue, reader as IJsonLineInfo, reader.Path, ex)) + HandleError(reader, true, initialDepth); + else + throw; + } + break; + case JsonToken.Comment: + break; + case JsonToken.EndObject: + finished = true; + break; + default: + throw JsonSerializationException.Create(reader, "Unexpected token when deserializing object: " + reader.TokenType); + } + } while (!finished && reader.Read()); + + if (!finished) + ThrowUnexpectedEndException(reader, contract, underlyingDictionary, "Unexpected end when deserializing object."); + + OnDeserialized(reader, contract, underlyingDictionary); + return underlyingDictionary; + } + + private object PopulateMultidimensionalArray(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, string id) + { + int rank = contract.UnderlyingType.GetArrayRank(); + + if (id != null) + AddReference(reader, id, list); + + OnDeserializing(reader, contract, list); + + JsonContract collectionItemContract = GetContractSafe(contract.CollectionItemType); + JsonConverter collectionItemConverter = GetConverter(collectionItemContract, null, contract, containerProperty); + + int? previousErrorIndex = null; + Stack listStack = new Stack(); + listStack.Push(list); + IList currentList = list; + + bool finished = false; + do + { + int initialDepth = reader.Depth; + + if (listStack.Count == rank) + { + try + { + if (ReadForType(reader, collectionItemContract, collectionItemConverter != null)) + { + switch (reader.TokenType) + { + case JsonToken.EndArray: + listStack.Pop(); + currentList = listStack.Peek(); + previousErrorIndex = null; + break; + case JsonToken.Comment: + break; + default: + object value; + + if (collectionItemConverter != null && collectionItemConverter.CanRead) + value = DeserializeConvertable(collectionItemConverter, reader, contract.CollectionItemType, null); + else + value = CreateValueInternal(reader, contract.CollectionItemType, collectionItemContract, null, contract, containerProperty, null); + + currentList.Add(value); + break; + } + } + else + { + break; + } + } + catch (Exception ex) + { + JsonPosition errorPosition = reader.GetPosition(initialDepth); + + if (IsErrorHandled(list, contract, errorPosition.Position, reader as IJsonLineInfo, reader.Path, ex)) + { + HandleError(reader, true, initialDepth); + + if (previousErrorIndex != null && previousErrorIndex == errorPosition.Position) + { + // reader index has not moved since previous error handling + // break out of reading array to prevent infinite loop + throw JsonSerializationException.Create(reader, "Infinite loop detected from error handling.", ex); + } + else + { + previousErrorIndex = errorPosition.Position; + } + } + else + { + throw; + } + } } else { - finished = true; + if (reader.Read()) + { + switch (reader.TokenType) + { + case JsonToken.StartArray: + IList newList = new List(); + currentList.Add(newList); + listStack.Push(newList); + currentList = newList; + break; + case JsonToken.EndArray: + listStack.Pop(); + + if (listStack.Count > 0) + { + currentList = listStack.Peek(); + } + else + { + finished = true; + } + break; + case JsonToken.Comment: + break; + default: + throw JsonSerializationException.Create(reader, "Unexpected token when deserializing multidimensional array: " + reader.TokenType); + } + } + else + { + break; + } } - break; - case JsonToken.Comment: - break; - default: - throw JsonSerializationException.Create(reader, "Unexpected token when deserializing multidimensional array: " + reader.TokenType); - } - } - else - { - break; - } + } while (!finished); + + if (!finished) + ThrowUnexpectedEndException(reader, contract, list, "Unexpected end when deserializing array."); + + OnDeserialized(reader, contract, list); + return list; } - } while (!finished); - if (!finished) - ThrowUnexpectedEndException(reader, contract, list, "Unexpected end when deserializing array."); - - OnDeserialized(reader, contract, list); - return list; - } - - private void ThrowUnexpectedEndException(JsonReader reader, JsonContract contract, object currentObject, string message) - { - try - { - throw JsonSerializationException.Create(reader, message); - } - catch (Exception ex) - { - if (IsErrorHandled(currentObject, contract, null, reader as IJsonLineInfo, reader.Path, ex)) - HandleError(reader, false, 0); - else - throw; - } - } - - private object PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, string id) - { - IWrappedCollection wrappedCollection = list as IWrappedCollection; - object underlyingList = wrappedCollection != null ? wrappedCollection.UnderlyingCollection : list; - - if (id != null) - AddReference(reader, id, underlyingList); - - // can't populate an existing array - if (list.IsFixedSize) - { - reader.Skip(); - return underlyingList; - } - - OnDeserializing(reader, contract, underlyingList); - - int initialDepth = reader.Depth; - - if (contract.ItemContract == null) - contract.ItemContract = GetContractSafe(contract.CollectionItemType); - - JsonConverter collectionItemConverter = GetConverter(contract.ItemContract, null, contract, containerProperty); - - int? previousErrorIndex = null; - - bool finished = false; - do - { - try + private void ThrowUnexpectedEndException(JsonReader reader, JsonContract contract, object currentObject, string message) { - if (ReadForType(reader, contract.ItemContract, collectionItemConverter != null)) - { - switch (reader.TokenType) + try { - case JsonToken.EndArray: - finished = true; - break; - case JsonToken.Comment: - break; - default: - object value; - - if (collectionItemConverter != null && collectionItemConverter.CanRead) - value = DeserializeConvertable(collectionItemConverter, reader, contract.CollectionItemType, null); + throw JsonSerializationException.Create(reader, message); + } + catch (Exception ex) + { + if (IsErrorHandled(currentObject, contract, null, reader as IJsonLineInfo, reader.Path, ex)) + HandleError(reader, false, 0); else - value = CreateValueInternal(reader, contract.CollectionItemType, contract.ItemContract, null, contract, containerProperty, null); - - list.Add(value); - break; + throw; } - } - else - { - break; - } } - catch (Exception ex) + + private object PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, string id) { - JsonPosition errorPosition = reader.GetPosition(initialDepth); + IWrappedCollection wrappedCollection = list as IWrappedCollection; + object underlyingList = wrappedCollection != null ? wrappedCollection.UnderlyingCollection : list; - if (IsErrorHandled(underlyingList, contract, errorPosition.Position, reader as IJsonLineInfo, reader.Path, ex)) - { - HandleError(reader, true, initialDepth); + if (id != null) + AddReference(reader, id, underlyingList); - if (previousErrorIndex != null && previousErrorIndex == errorPosition.Position) + // can't populate an existing array + if (list.IsFixedSize) { - // reader index has not moved since previous error handling - // break out of reading array to prevent infinite loop - throw JsonSerializationException.Create(reader, "Infinite loop detected from error handling.", ex); + reader.Skip(); + return underlyingList; } - else + + OnDeserializing(reader, contract, underlyingList); + + int initialDepth = reader.Depth; + + if (contract.ItemContract == null) + contract.ItemContract = GetContractSafe(contract.CollectionItemType); + + JsonConverter collectionItemConverter = GetConverter(contract.ItemContract, null, contract, containerProperty); + + int? previousErrorIndex = null; + + bool finished = false; + do { - previousErrorIndex = errorPosition.Position; - } - } - else - { - throw; - } + try + { + if (ReadForType(reader, contract.ItemContract, collectionItemConverter != null)) + { + switch (reader.TokenType) + { + case JsonToken.EndArray: + finished = true; + break; + case JsonToken.Comment: + break; + default: + object value; + + if (collectionItemConverter != null && collectionItemConverter.CanRead) + value = DeserializeConvertable(collectionItemConverter, reader, contract.CollectionItemType, null); + else + value = CreateValueInternal(reader, contract.CollectionItemType, contract.ItemContract, null, contract, containerProperty, null); + + list.Add(value); + break; + } + } + else + { + break; + } + } + catch (Exception ex) + { + JsonPosition errorPosition = reader.GetPosition(initialDepth); + + if (IsErrorHandled(underlyingList, contract, errorPosition.Position, reader as IJsonLineInfo, reader.Path, ex)) + { + HandleError(reader, true, initialDepth); + + if (previousErrorIndex != null && previousErrorIndex == errorPosition.Position) + { + // reader index has not moved since previous error handling + // break out of reading array to prevent infinite loop + throw JsonSerializationException.Create(reader, "Infinite loop detected from error handling.", ex); + } + else + { + previousErrorIndex = errorPosition.Position; + } + } + else + { + throw; + } + } + } while (!finished); + + if (!finished) + ThrowUnexpectedEndException(reader, contract, underlyingList, "Unexpected end when deserializing array."); + + OnDeserialized(reader, contract, underlyingList); + return underlyingList; } - } while (!finished); - - if (!finished) - ThrowUnexpectedEndException(reader, contract, underlyingList, "Unexpected end when deserializing array."); - - OnDeserialized(reader, contract, underlyingList); - return underlyingList; - } #if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) - private object CreateISerializable(JsonReader reader, JsonISerializableContract contract, JsonProperty member, string id) - { - Type objectType = contract.UnderlyingType; + private object CreateISerializable(JsonReader reader, JsonISerializableContract contract, JsonProperty member, string id) + { + Type objectType = contract.UnderlyingType; - if (!JsonTypeReflector.FullyTrusted) - { - throw JsonSerializationException.Create(reader, @"Type '{0}' implements ISerializable but cannot be deserialized using the ISerializable interface because the current application is not fully trusted and ISerializable can expose secure data. + if (!JsonTypeReflector.FullyTrusted) + { + throw JsonSerializationException.Create(reader, @"Type '{0}' implements ISerializable but cannot be deserialized using the ISerializable interface because the current application is not fully trusted and ISerializable can expose secure data. To fix this error either change the environment to be fully trusted, change the application to not deserialize the type, add JsonObjectAttribute to the type or change the JsonSerializer setting ContractResolver to use a new DefaultContractResolver with IgnoreSerializableInterface set to true. ".FormatWith(CultureInfo.InvariantCulture, objectType)); - } - - if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) - TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Deserializing {0} using ISerializable constructor.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)), null); - - SerializationInfo serializationInfo = new SerializationInfo(contract.UnderlyingType, GetFormatterConverter()); - - bool finished = false; - do - { - switch (reader.TokenType) - { - case JsonToken.PropertyName: - string memberName = reader.Value.ToString(); - if (!reader.Read()) - throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName)); - - if (reader.TokenType == JsonToken.StartObject) - { - // this will read any potential type names embedded in json - object o = CreateObject(reader, null, null, null, contract, member, null); - serializationInfo.AddValue(memberName, o); } - else + + if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) + TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Deserializing {0} using ISerializable constructor.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)), null); + + SerializationInfo serializationInfo = new SerializationInfo(contract.UnderlyingType, GetFormatterConverter()); + + bool finished = false; + do { - serializationInfo.AddValue(memberName, JToken.ReadFrom(reader)); - } - break; - case JsonToken.Comment: - break; - case JsonToken.EndObject: - finished = true; - break; - default: - throw JsonSerializationException.Create(reader, "Unexpected token when deserializing object: " + reader.TokenType); + switch (reader.TokenType) + { + case JsonToken.PropertyName: + string memberName = reader.Value.ToString(); + if (!reader.Read()) + throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName)); + + if (reader.TokenType == JsonToken.StartObject) + { + // this will read any potential type names embedded in json + object o = CreateObject(reader, null, null, null, contract, member, null); + serializationInfo.AddValue(memberName, o); + } + else + { + serializationInfo.AddValue(memberName, JToken.ReadFrom(reader)); + } + break; + case JsonToken.Comment: + break; + case JsonToken.EndObject: + finished = true; + break; + default: + throw JsonSerializationException.Create(reader, "Unexpected token when deserializing object: " + reader.TokenType); + } + } while (!finished && reader.Read()); + + if (!finished) + ThrowUnexpectedEndException(reader, contract, serializationInfo, "Unexpected end when deserializing object."); + + if (contract.ISerializableCreator == null) + throw JsonSerializationException.Create(reader, "ISerializable type '{0}' does not have a valid constructor. To correctly implement ISerializable a constructor that takes SerializationInfo and StreamingContext parameters should be present.".FormatWith(CultureInfo.InvariantCulture, objectType)); + + object createdObject = contract.ISerializableCreator(serializationInfo, Serializer._context); + + if (id != null) + AddReference(reader, id, createdObject); + + // these are together because OnDeserializing takes an object but for an ISerializable the object is fully created in the constructor + OnDeserializing(reader, contract, createdObject); + OnDeserialized(reader, contract, createdObject); + + return createdObject; } - } while (!finished && reader.Read()); - - if (!finished) - ThrowUnexpectedEndException(reader, contract, serializationInfo, "Unexpected end when deserializing object."); - - if (contract.ISerializableCreator == null) - throw JsonSerializationException.Create(reader, "ISerializable type '{0}' does not have a valid constructor. To correctly implement ISerializable a constructor that takes SerializationInfo and StreamingContext parameters should be present.".FormatWith(CultureInfo.InvariantCulture, objectType)); - - object createdObject = contract.ISerializableCreator(serializationInfo, Serializer._context); - - if (id != null) - AddReference(reader, id, createdObject); - - // these are together because OnDeserializing takes an object but for an ISerializable the object is fully created in the constructor - OnDeserializing(reader, contract, createdObject); - OnDeserialized(reader, contract, createdObject); - - return createdObject; - } #endif #if !(NET35 || NET20 || PORTABLE40) - private object CreateDynamic(JsonReader reader, JsonDynamicContract contract, JsonProperty member, string id) - { - IDynamicMetaObjectProvider newObject; - - if (!contract.IsInstantiable) - throw JsonSerializationException.Create(reader, "Could not create an instance of type {0}. Type is an interface or abstract class and cannot be instantiated.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); - - if (contract.DefaultCreator != null && - (!contract.DefaultCreatorNonPublic || Serializer._constructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor)) - newObject = (IDynamicMetaObjectProvider) contract.DefaultCreator(); - else - throw JsonSerializationException.Create(reader, "Unable to find a default constructor to use for type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); - - if (id != null) - AddReference(reader, id, newObject); - - OnDeserializing(reader, contract, newObject); - - int initialDepth = reader.Depth; - - bool finished = false; - do - { - switch (reader.TokenType) + private object CreateDynamic(JsonReader reader, JsonDynamicContract contract, JsonProperty member, string id) { - case JsonToken.PropertyName: - string memberName = reader.Value.ToString(); + IDynamicMetaObjectProvider newObject; - try + if (!contract.IsInstantiable) + throw JsonSerializationException.Create(reader, "Could not create an instance of type {0}. Type is an interface or abstract class and cannot be instantiated.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); + + if (contract.DefaultCreator != null && + (!contract.DefaultCreatorNonPublic || Serializer._constructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor)) + newObject = (IDynamicMetaObjectProvider)contract.DefaultCreator(); + else + throw JsonSerializationException.Create(reader, "Unable to find a default constructor to use for type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); + + if (id != null) + AddReference(reader, id, newObject); + + OnDeserializing(reader, contract, newObject); + + int initialDepth = reader.Depth; + + bool finished = false; + do { - if (!reader.Read()) - throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName)); + switch (reader.TokenType) + { + case JsonToken.PropertyName: + string memberName = reader.Value.ToString(); - // first attempt to find a settable property, otherwise fall back to a dynamic set without type - JsonProperty property = contract.Properties.GetClosestMatchProperty(memberName); + try + { + if (!reader.Read()) + throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName)); - if (property != null && property.Writable && !property.Ignored) - { - if (property.PropertyContract == null) - property.PropertyContract = GetContractSafe(property.PropertyType); + // first attempt to find a settable property, otherwise fall back to a dynamic set without type + JsonProperty property = contract.Properties.GetClosestMatchProperty(memberName); - JsonConverter propertyConverter = GetConverter(property.PropertyContract, property.MemberConverter, null, null); + if (property != null && property.Writable && !property.Ignored) + { + if (property.PropertyContract == null) + property.PropertyContract = GetContractSafe(property.PropertyType); - if (!SetPropertyValue(property, propertyConverter, null, member, reader, newObject)) - reader.Skip(); - } - else - { - Type t = (JsonReader.IsPrimitiveToken(reader.TokenType)) ? reader.ValueType : typeof (IDynamicMetaObjectProvider); + JsonConverter propertyConverter = GetConverter(property.PropertyContract, property.MemberConverter, null, null); - JsonContract dynamicMemberContract = GetContractSafe(t); - JsonConverter dynamicMemberConverter = GetConverter(dynamicMemberContract, null, null, member); + if (!SetPropertyValue(property, propertyConverter, null, member, reader, newObject)) + reader.Skip(); + } + else + { + Type t = (JsonReader.IsPrimitiveToken(reader.TokenType)) ? reader.ValueType : typeof(IDynamicMetaObjectProvider); - object value; - if (dynamicMemberConverter != null && dynamicMemberConverter.CanRead) - value = DeserializeConvertable(dynamicMemberConverter, reader, t, null); - else - value = CreateValueInternal(reader, t, dynamicMemberContract, null, null, member, null); + JsonContract dynamicMemberContract = GetContractSafe(t); + JsonConverter dynamicMemberConverter = GetConverter(dynamicMemberContract, null, null, member); - contract.TrySetMember(newObject, memberName, value); - } - } - catch (Exception ex) - { - if (IsErrorHandled(newObject, contract, memberName, reader as IJsonLineInfo, reader.Path, ex)) - HandleError(reader, true, initialDepth); - else - throw; - } - break; - case JsonToken.EndObject: - finished = true; - break; - default: - throw JsonSerializationException.Create(reader, "Unexpected token when deserializing object: " + reader.TokenType); + object value; + if (dynamicMemberConverter != null && dynamicMemberConverter.CanRead) + value = DeserializeConvertable(dynamicMemberConverter, reader, t, null); + else + value = CreateValueInternal(reader, t, dynamicMemberContract, null, null, member, null); + + contract.TrySetMember(newObject, memberName, value); + } + } + catch (Exception ex) + { + if (IsErrorHandled(newObject, contract, memberName, reader as IJsonLineInfo, reader.Path, ex)) + HandleError(reader, true, initialDepth); + else + throw; + } + break; + case JsonToken.EndObject: + finished = true; + break; + default: + throw JsonSerializationException.Create(reader, "Unexpected token when deserializing object: " + reader.TokenType); + } + } while (!finished && reader.Read()); + + if (!finished) + ThrowUnexpectedEndException(reader, contract, newObject, "Unexpected end when deserializing object."); + + OnDeserialized(reader, contract, newObject); + + return newObject; } - } while (!finished && reader.Read()); - - if (!finished) - ThrowUnexpectedEndException(reader, contract, newObject, "Unexpected end when deserializing object."); - - OnDeserialized(reader, contract, newObject); - - return newObject; - } #endif - private object CreateObjectFromNonDefaultConstructor(JsonReader reader, JsonObjectContract contract, JsonProperty containerProperty, ConstructorInfo constructorInfo, string id) - { - ValidationUtils.ArgumentNotNull(constructorInfo, "constructorInfo"); - - // only need to keep a track of properies presence if they are required or a value should be defaulted if missing - Dictionary propertiesPresence = (contract.HasRequiredOrDefaultValueProperties || HasFlag(Serializer._defaultValueHandling, DefaultValueHandling.Populate)) - ? contract.Properties.ToDictionary(m => m, m => PropertyPresence.None) - : null; - - Type objectType = contract.UnderlyingType; - - if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) - TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Deserializing {0} using a non-default constructor '{1}'.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType, constructorInfo)), null); - - IDictionary propertyValues = ResolvePropertyAndConstructorValues(contract, containerProperty, reader, objectType); - - IDictionary constructorParameters = constructorInfo.GetParameters().ToDictionary(p => p, p => (object) null); - IDictionary remainingPropertyValues = new Dictionary(); - - foreach (KeyValuePair propertyValue in propertyValues) - { - ParameterInfo matchingConstructorParameter = constructorParameters.ForgivingCaseSensitiveFind(kv => kv.Key.Name, propertyValue.Key.UnderlyingName).Key; - if (matchingConstructorParameter != null) - constructorParameters[matchingConstructorParameter] = propertyValue.Value; - else - remainingPropertyValues.Add(propertyValue); - - if (propertiesPresence != null) + private object CreateObjectFromNonDefaultConstructor(JsonReader reader, JsonObjectContract contract, JsonProperty containerProperty, ConstructorInfo constructorInfo, string id) { - // map from constructor property to normal property - var property = propertiesPresence.Keys.FirstOrDefault(p => p.PropertyName == propertyValue.Key.PropertyName); - if (property != null) - propertiesPresence[property] = (propertyValue.Value == null) ? PropertyPresence.Null : PropertyPresence.Value; - } - } + ValidationUtils.ArgumentNotNull(constructorInfo, "constructorInfo"); - object createdObject = constructorInfo.Invoke(constructorParameters.Values.ToArray()); + // only need to keep a track of properies presence if they are required or a value should be defaulted if missing + Dictionary propertiesPresence = (contract.HasRequiredOrDefaultValueProperties || HasFlag(Serializer._defaultValueHandling, DefaultValueHandling.Populate)) + ? contract.Properties.ToDictionary(m => m, m => PropertyPresence.None) + : null; - if (id != null) - AddReference(reader, id, createdObject); + Type objectType = contract.UnderlyingType; - OnDeserializing(reader, contract, createdObject); + if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) + TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Deserializing {0} using a non-default constructor '{1}'.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType, constructorInfo)), null); - // go through unused values and set the newly created object's properties - foreach (KeyValuePair remainingPropertyValue in remainingPropertyValues) - { - JsonProperty property = remainingPropertyValue.Key; - object value = remainingPropertyValue.Value; + IDictionary propertyValues = ResolvePropertyAndConstructorValues(contract, containerProperty, reader, objectType); - if (ShouldSetPropertyValue(remainingPropertyValue.Key, remainingPropertyValue.Value)) - { - property.ValueProvider.SetValue(createdObject, value); - } - else if (!property.Writable && value != null) - { - // handle readonly collection/dictionary properties - JsonContract propertyContract = Serializer._contractResolver.ResolveContract(property.PropertyType); + IDictionary constructorParameters = constructorInfo.GetParameters().ToDictionary(p => p, p => (object)null); + IDictionary remainingPropertyValues = new Dictionary(); - if (propertyContract.ContractType == JsonContractType.Array) - { - JsonArrayContract propertyArrayContract = (JsonArrayContract)propertyContract; - - object createdObjectCollection = property.ValueProvider.GetValue(createdObject); - if (createdObjectCollection != null) + foreach (KeyValuePair propertyValue in propertyValues) { - IWrappedCollection createdObjectCollectionWrapper = propertyArrayContract.CreateWrapper(createdObjectCollection); - IWrappedCollection newValues = propertyArrayContract.CreateWrapper(value); - - foreach (object newValue in newValues) - { - createdObjectCollectionWrapper.Add(newValue); - } - } - } - else if (propertyContract.ContractType == JsonContractType.Dictionary) - { - JsonDictionaryContract dictionaryContract = (JsonDictionaryContract)propertyContract; - - object createdObjectDictionary = property.ValueProvider.GetValue(createdObject); - if (createdObjectDictionary != null) - { - IDictionary targetDictionary = (dictionaryContract.ShouldCreateWrapper) ? dictionaryContract.CreateWrapper(createdObjectDictionary) : (IDictionary) createdObjectDictionary; - IDictionary newValues = (dictionaryContract.ShouldCreateWrapper) ? dictionaryContract.CreateWrapper(value) : (IDictionary) value; - - foreach (DictionaryEntry newValue in newValues) - { - targetDictionary.Add(newValue.Key, newValue.Value); - } - } - } - } - } - - EndObject(createdObject, reader, contract, reader.Depth, propertiesPresence); - - OnDeserialized(reader, contract, createdObject); - return createdObject; - } - - private object DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, object existingValue) - { - if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) - TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Started deserializing {0} with converter {1}.".FormatWith(CultureInfo.InvariantCulture, objectType, converter.GetType())), null); - - object value = converter.ReadJson(reader, objectType, existingValue, GetInternalSerializer()); - - if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) - TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Finished deserializing {0} with converter {1}.".FormatWith(CultureInfo.InvariantCulture, objectType, converter.GetType())), null); - - return value; - } - - private IDictionary ResolvePropertyAndConstructorValues(JsonObjectContract contract, JsonProperty containerProperty, JsonReader reader, Type objectType) - { - IDictionary propertyValues = new Dictionary(); - bool exit = false; - do - { - switch (reader.TokenType) - { - case JsonToken.PropertyName: - string memberName = reader.Value.ToString(); - - // attempt exact case match first - // then try match ignoring case - JsonProperty property = contract.ConstructorParameters.GetClosestMatchProperty(memberName) ?? - contract.Properties.GetClosestMatchProperty(memberName); - - if (property != null) - { - if (property.PropertyContract == null) - property.PropertyContract = GetContractSafe(property.PropertyType); - - JsonConverter propertyConverter = GetConverter(property.PropertyContract, property.MemberConverter, contract, containerProperty); - - if (!ReadForType(reader, property.PropertyContract, propertyConverter != null)) - throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName)); - - if (!property.Ignored) - { - if (property.PropertyContract == null) - property.PropertyContract = GetContractSafe(property.PropertyType); - - object propertyValue; - if (propertyConverter != null && propertyConverter.CanRead) - propertyValue = DeserializeConvertable(propertyConverter, reader, property.PropertyType, null); + ParameterInfo matchingConstructorParameter = constructorParameters.ForgivingCaseSensitiveFind(kv => kv.Key.Name, propertyValue.Key.UnderlyingName).Key; + if (matchingConstructorParameter != null) + constructorParameters[matchingConstructorParameter] = propertyValue.Value; else - propertyValue = CreateValueInternal(reader, property.PropertyType, property.PropertyContract, property, contract, containerProperty, null); + remainingPropertyValues.Add(propertyValue); - propertyValues[property] = propertyValue; - } - else - { - reader.Skip(); - } + if (propertiesPresence != null) + { + // map from constructor property to normal property + var property = propertiesPresence.Keys.FirstOrDefault(p => p.PropertyName == propertyValue.Key.PropertyName); + if (property != null) + propertiesPresence[property] = (propertyValue.Value == null) ? PropertyPresence.Null : PropertyPresence.Value; + } + } + + object createdObject = constructorInfo.Invoke(constructorParameters.Values.ToArray()); + + if (id != null) + AddReference(reader, id, createdObject); + + OnDeserializing(reader, contract, createdObject); + + // go through unused values and set the newly created object's properties + foreach (KeyValuePair remainingPropertyValue in remainingPropertyValues) + { + JsonProperty property = remainingPropertyValue.Key; + object value = remainingPropertyValue.Value; + + if (ShouldSetPropertyValue(remainingPropertyValue.Key, remainingPropertyValue.Value)) + { + property.ValueProvider.SetValue(createdObject, value); + } + else if (!property.Writable && value != null) + { + // handle readonly collection/dictionary properties + JsonContract propertyContract = Serializer._contractResolver.ResolveContract(property.PropertyType); + + if (propertyContract.ContractType == JsonContractType.Array) + { + JsonArrayContract propertyArrayContract = (JsonArrayContract)propertyContract; + + object createdObjectCollection = property.ValueProvider.GetValue(createdObject); + if (createdObjectCollection != null) + { + IWrappedCollection createdObjectCollectionWrapper = propertyArrayContract.CreateWrapper(createdObjectCollection); + IWrappedCollection newValues = propertyArrayContract.CreateWrapper(value); + + foreach (object newValue in newValues) + { + createdObjectCollectionWrapper.Add(newValue); + } + } + } + else if (propertyContract.ContractType == JsonContractType.Dictionary) + { + JsonDictionaryContract dictionaryContract = (JsonDictionaryContract)propertyContract; + + object createdObjectDictionary = property.ValueProvider.GetValue(createdObject); + if (createdObjectDictionary != null) + { + IDictionary targetDictionary = (dictionaryContract.ShouldCreateWrapper) ? dictionaryContract.CreateWrapper(createdObjectDictionary) : (IDictionary)createdObjectDictionary; + IDictionary newValues = (dictionaryContract.ShouldCreateWrapper) ? dictionaryContract.CreateWrapper(value) : (IDictionary)value; + + foreach (DictionaryEntry newValue in newValues) + { + targetDictionary.Add(newValue.Key, newValue.Value); + } + } + } + } + } + + EndObject(createdObject, reader, contract, reader.Depth, propertiesPresence); + + OnDeserialized(reader, contract, createdObject); + return createdObject; + } + + private object DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, object existingValue) + { + if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) + TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Started deserializing {0} with converter {1}.".FormatWith(CultureInfo.InvariantCulture, objectType, converter.GetType())), null); + + object value = converter.ReadJson(reader, objectType, existingValue, GetInternalSerializer()); + + if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) + TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Finished deserializing {0} with converter {1}.".FormatWith(CultureInfo.InvariantCulture, objectType, converter.GetType())), null); + + return value; + } + + private IDictionary ResolvePropertyAndConstructorValues(JsonObjectContract contract, JsonProperty containerProperty, JsonReader reader, Type objectType) + { + IDictionary propertyValues = new Dictionary(); + bool exit = false; + do + { + switch (reader.TokenType) + { + case JsonToken.PropertyName: + string memberName = reader.Value.ToString(); + + // attempt exact case match first + // then try match ignoring case + JsonProperty property = contract.ConstructorParameters.GetClosestMatchProperty(memberName) ?? + contract.Properties.GetClosestMatchProperty(memberName); + + if (property != null) + { + if (property.PropertyContract == null) + property.PropertyContract = GetContractSafe(property.PropertyType); + + JsonConverter propertyConverter = GetConverter(property.PropertyContract, property.MemberConverter, contract, containerProperty); + + if (!ReadForType(reader, property.PropertyContract, propertyConverter != null)) + throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName)); + + if (!property.Ignored) + { + if (property.PropertyContract == null) + property.PropertyContract = GetContractSafe(property.PropertyType); + + object propertyValue; + if (propertyConverter != null && propertyConverter.CanRead) + propertyValue = DeserializeConvertable(propertyConverter, reader, property.PropertyType, null); + else + propertyValue = CreateValueInternal(reader, property.PropertyType, property.PropertyContract, property, contract, containerProperty, null); + + propertyValues[property] = propertyValue; + } + else + { + reader.Skip(); + } + } + else + { + if (!reader.Read()) + throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName)); + + if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) + TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Could not find member '{0}' on {1}.".FormatWith(CultureInfo.InvariantCulture, memberName, contract.UnderlyingType)), null); + + if (Serializer._missingMemberHandling == MissingMemberHandling.Error) + throw JsonSerializationException.Create(reader, "Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, objectType.Name)); + + reader.Skip(); + } + break; + case JsonToken.Comment: + break; + case JsonToken.EndObject: + exit = true; + break; + default: + throw JsonSerializationException.Create(reader, "Unexpected token when deserializing object: " + reader.TokenType); + } + } while (!exit && reader.Read()); + + return propertyValues; + } + + private bool ReadForType(JsonReader reader, JsonContract contract, bool hasConverter) + { + // don't read properties with converters as a specific value + // the value might be a string which will then get converted which will error if read as date for example + if (hasConverter) + return reader.Read(); + + ReadType t = (contract != null) ? contract.InternalReadType : ReadType.Read; + + switch (t) + { + case ReadType.Read: + do + { + if (!reader.Read()) + return false; + } while (reader.TokenType == JsonToken.Comment); + + return true; + case ReadType.ReadAsInt32: + reader.ReadAsInt32(); + break; + case ReadType.ReadAsDecimal: + reader.ReadAsDecimal(); + break; + case ReadType.ReadAsBytes: + reader.ReadAsBytes(); + break; + case ReadType.ReadAsString: + reader.ReadAsString(); + break; + case ReadType.ReadAsDateTime: + reader.ReadAsDateTime(); + break; +#if !NET20 + case ReadType.ReadAsDateTimeOffset: + reader.ReadAsDateTimeOffset(); + break; +#endif + default: + throw new ArgumentOutOfRangeException(); + } + + return (reader.TokenType != JsonToken.None); + } + + public object CreateNewObject(JsonReader reader, JsonObjectContract objectContract, JsonProperty containerMember, JsonProperty containerProperty, string id, out bool createdFromNonDefaultConstructor) + { + object newObject = null; + + if (!objectContract.IsInstantiable) + throw JsonSerializationException.Create(reader, "Could not create an instance of type {0}. Type is an interface or abstract class and cannot be instantiated.".FormatWith(CultureInfo.InvariantCulture, objectContract.UnderlyingType)); + + if (objectContract.OverrideConstructor != null) + { + if (objectContract.OverrideConstructor.GetParameters().Length > 0) + { + createdFromNonDefaultConstructor = true; + return CreateObjectFromNonDefaultConstructor(reader, objectContract, containerMember, objectContract.OverrideConstructor, id); + } + + newObject = objectContract.OverrideConstructor.Invoke(null); + } + else if (objectContract.DefaultCreator != null && + (!objectContract.DefaultCreatorNonPublic || Serializer._constructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor || objectContract.ParametrizedConstructor == null)) + { + // use the default constructor if it is... + // public + // non-public and the user has change constructor handling settings + // non-public and there is no other constructor + newObject = objectContract.DefaultCreator(); + } + else if (objectContract.ParametrizedConstructor != null) + { + createdFromNonDefaultConstructor = true; + return CreateObjectFromNonDefaultConstructor(reader, objectContract, containerMember, objectContract.ParametrizedConstructor, id); + } + + if (newObject == null) + throw JsonSerializationException.Create(reader, "Unable to find a constructor to use for type {0}. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute.".FormatWith(CultureInfo.InvariantCulture, objectContract.UnderlyingType)); + + createdFromNonDefaultConstructor = false; + return newObject; + } + + private object PopulateObject(object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, string id) + { + OnDeserializing(reader, contract, newObject); + + // only need to keep a track of properies presence if they are required or a value should be defaulted if missing + Dictionary propertiesPresence = (contract.HasRequiredOrDefaultValueProperties || HasFlag(Serializer._defaultValueHandling, DefaultValueHandling.Populate)) + ? contract.Properties.ToDictionary(m => m, m => PropertyPresence.None) + : null; + + if (id != null) + AddReference(reader, id, newObject); + + int initialDepth = reader.Depth; + + bool finished = false; + do + { + switch (reader.TokenType) + { + case JsonToken.PropertyName: + { + string memberName = reader.Value.ToString(); + + try + { + // attempt exact case match first + // then try match ignoring case + JsonProperty property = contract.Properties.GetClosestMatchProperty(memberName); + + if (property == null) + { + if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) + TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Could not find member '{0}' on {1}".FormatWith(CultureInfo.InvariantCulture, memberName, contract.UnderlyingType)), null); + + if (Serializer._missingMemberHandling == MissingMemberHandling.Error) + throw JsonSerializationException.Create(reader, "Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, contract.UnderlyingType.Name)); + + if (!reader.Read()) + break; + + SetExtensionData(contract, member, reader, memberName, newObject); + continue; + } + + if (property.PropertyContract == null) + property.PropertyContract = GetContractSafe(property.PropertyType); + + JsonConverter propertyConverter = GetConverter(property.PropertyContract, property.MemberConverter, contract, member); + + if (!ReadForType(reader, property.PropertyContract, propertyConverter != null)) + throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName)); + + SetPropertyPresence(reader, property, propertiesPresence); + + // set extension data if property is ignored or readonly + if (!SetPropertyValue(property, propertyConverter, contract, member, reader, newObject)) + SetExtensionData(contract, member, reader, memberName, newObject); + } + catch (Exception ex) + { + if (IsErrorHandled(newObject, contract, memberName, reader as IJsonLineInfo, reader.Path, ex)) + HandleError(reader, true, initialDepth); + else + throw; + } + } + break; + case JsonToken.EndObject: + finished = true; + break; + case JsonToken.Comment: + // ignore + break; + default: + throw JsonSerializationException.Create(reader, "Unexpected token when deserializing object: " + reader.TokenType); + } + } while (!finished && reader.Read()); + + if (!finished) + ThrowUnexpectedEndException(reader, contract, newObject, "Unexpected end when deserializing object."); + + EndObject(newObject, reader, contract, initialDepth, propertiesPresence); + + OnDeserialized(reader, contract, newObject); + return newObject; + } + + private void SetExtensionData(JsonObjectContract contract, JsonProperty member, JsonReader reader, string memberName, object o) + { + if (contract.ExtensionDataSetter != null) + { + try + { + object value = CreateValueInternal(reader, null, null, null, contract, member, null); + + contract.ExtensionDataSetter(o, memberName, value); + } + catch (Exception ex) + { + throw JsonSerializationException.Create(reader, "Error setting value in extension data for type '{0}'.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType), ex); + } } else { - if (!reader.Read()) - throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName)); - - if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) - TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Could not find member '{0}' on {1}.".FormatWith(CultureInfo.InvariantCulture, memberName, contract.UnderlyingType)), null); - - if (Serializer._missingMemberHandling == MissingMemberHandling.Error) - throw JsonSerializationException.Create(reader, "Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, objectType.Name)); - - reader.Skip(); + reader.Skip(); } - break; - case JsonToken.Comment: - break; - case JsonToken.EndObject: - exit = true; - break; - default: - throw JsonSerializationException.Create(reader, "Unexpected token when deserializing object: " + reader.TokenType); - } - } while (!exit && reader.Read()); - - return propertyValues; - } - - private bool ReadForType(JsonReader reader, JsonContract contract, bool hasConverter) - { - // don't read properties with converters as a specific value - // the value might be a string which will then get converted which will error if read as date for example - if (hasConverter) - return reader.Read(); - - ReadType t = (contract != null) ? contract.InternalReadType : ReadType.Read; - - switch (t) - { - case ReadType.Read: - do - { - if (!reader.Read()) - return false; - } while (reader.TokenType == JsonToken.Comment); - - return true; - case ReadType.ReadAsInt32: - reader.ReadAsInt32(); - break; - case ReadType.ReadAsDecimal: - reader.ReadAsDecimal(); - break; - case ReadType.ReadAsBytes: - reader.ReadAsBytes(); - break; - case ReadType.ReadAsString: - reader.ReadAsString(); - break; - case ReadType.ReadAsDateTime: - reader.ReadAsDateTime(); - break; -#if !NET20 - case ReadType.ReadAsDateTimeOffset: - reader.ReadAsDateTimeOffset(); - break; -#endif - default: - throw new ArgumentOutOfRangeException(); - } - - return (reader.TokenType != JsonToken.None); - } - - public object CreateNewObject(JsonReader reader, JsonObjectContract objectContract, JsonProperty containerMember, JsonProperty containerProperty, string id, out bool createdFromNonDefaultConstructor) - { - object newObject = null; - - if (!objectContract.IsInstantiable) - throw JsonSerializationException.Create(reader, "Could not create an instance of type {0}. Type is an interface or abstract class and cannot be instantiated.".FormatWith(CultureInfo.InvariantCulture, objectContract.UnderlyingType)); - - if (objectContract.OverrideConstructor != null) - { - if (objectContract.OverrideConstructor.GetParameters().Length > 0) - { - createdFromNonDefaultConstructor = true; - return CreateObjectFromNonDefaultConstructor(reader, objectContract, containerMember, objectContract.OverrideConstructor, id); } - newObject = objectContract.OverrideConstructor.Invoke(null); - } - else if (objectContract.DefaultCreator != null && - (!objectContract.DefaultCreatorNonPublic || Serializer._constructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor || objectContract.ParametrizedConstructor == null)) - { - // use the default constructor if it is... - // public - // non-public and the user has change constructor handling settings - // non-public and there is no other constructor - newObject = objectContract.DefaultCreator(); - } - else if (objectContract.ParametrizedConstructor != null) - { - createdFromNonDefaultConstructor = true; - return CreateObjectFromNonDefaultConstructor(reader, objectContract, containerMember, objectContract.ParametrizedConstructor, id); - } - - if (newObject == null) - throw JsonSerializationException.Create(reader, "Unable to find a constructor to use for type {0}. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute.".FormatWith(CultureInfo.InvariantCulture, objectContract.UnderlyingType)); - - createdFromNonDefaultConstructor = false; - return newObject; - } - - private object PopulateObject(object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, string id) - { - OnDeserializing(reader, contract, newObject); - - // only need to keep a track of properies presence if they are required or a value should be defaulted if missing - Dictionary propertiesPresence = (contract.HasRequiredOrDefaultValueProperties || HasFlag(Serializer._defaultValueHandling, DefaultValueHandling.Populate)) - ? contract.Properties.ToDictionary(m => m, m => PropertyPresence.None) - : null; - - if (id != null) - AddReference(reader, id, newObject); - - int initialDepth = reader.Depth; - - bool finished = false; - do - { - switch (reader.TokenType) + private void EndObject(object newObject, JsonReader reader, JsonObjectContract contract, int initialDepth, Dictionary propertiesPresence) { - case JsonToken.PropertyName: + if (propertiesPresence != null) { - string memberName = reader.Value.ToString(); - - try - { - // attempt exact case match first - // then try match ignoring case - JsonProperty property = contract.Properties.GetClosestMatchProperty(memberName); - - if (property == null) + foreach (KeyValuePair propertyPresence in propertiesPresence) { - if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) - TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Could not find member '{0}' on {1}".FormatWith(CultureInfo.InvariantCulture, memberName, contract.UnderlyingType)), null); + JsonProperty property = propertyPresence.Key; + PropertyPresence presence = propertyPresence.Value; - if (Serializer._missingMemberHandling == MissingMemberHandling.Error) - throw JsonSerializationException.Create(reader, "Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, contract.UnderlyingType.Name)); + if (presence == PropertyPresence.None || presence == PropertyPresence.Null) + { + try + { + Required resolvedRequired = property._required ?? contract.ItemRequired ?? Required.Default; - if (!reader.Read()) - break; + switch (presence) + { + case PropertyPresence.None: + if (resolvedRequired == Required.AllowNull || resolvedRequired == Required.Always) + throw JsonSerializationException.Create(reader, "Required property '{0}' not found in JSON.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName)); - SetExtensionData(contract, member, reader, memberName, newObject); - continue; + if (property.PropertyContract == null) + property.PropertyContract = GetContractSafe(property.PropertyType); + + if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer._defaultValueHandling), DefaultValueHandling.Populate) && property.Writable) + property.ValueProvider.SetValue(newObject, EnsureType(reader, property.GetResolvedDefaultValue(), CultureInfo.InvariantCulture, property.PropertyContract, property.PropertyType)); + break; + case PropertyPresence.Null: + if (resolvedRequired == Required.Always) + throw JsonSerializationException.Create(reader, "Required property '{0}' expects a value but got null.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName)); + break; + } + } + catch (Exception ex) + { + if (IsErrorHandled(newObject, contract, property.PropertyName, reader as IJsonLineInfo, reader.Path, ex)) + HandleError(reader, true, initialDepth); + else + throw; + } + } } - - if (property.PropertyContract == null) - property.PropertyContract = GetContractSafe(property.PropertyType); - - JsonConverter propertyConverter = GetConverter(property.PropertyContract, property.MemberConverter, contract, member); - - if (!ReadForType(reader, property.PropertyContract, propertyConverter != null)) - throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName)); - - SetPropertyPresence(reader, property, propertiesPresence); - - // set extension data if property is ignored or readonly - if (!SetPropertyValue(property, propertyConverter, contract, member, reader, newObject)) - SetExtensionData(contract, member, reader, memberName, newObject); - } - catch (Exception ex) - { - if (IsErrorHandled(newObject, contract, memberName, reader as IJsonLineInfo, reader.Path, ex)) - HandleError(reader, true, initialDepth); - else - throw; - } } - break; - case JsonToken.EndObject: - finished = true; - break; - case JsonToken.Comment: - // ignore - break; - default: - throw JsonSerializationException.Create(reader, "Unexpected token when deserializing object: " + reader.TokenType); } - } while (!finished && reader.Read()); - if (!finished) - ThrowUnexpectedEndException(reader, contract, newObject, "Unexpected end when deserializing object."); - - EndObject(newObject, reader, contract, initialDepth, propertiesPresence); - - OnDeserialized(reader, contract, newObject); - return newObject; - } - - private void SetExtensionData(JsonObjectContract contract, JsonProperty member, JsonReader reader, string memberName, object o) - { - if (contract.ExtensionDataSetter != null) - { - try + private void SetPropertyPresence(JsonReader reader, JsonProperty property, Dictionary requiredProperties) { - object value = CreateValueInternal(reader, null, null, null, contract, member, null); - - contract.ExtensionDataSetter(o, memberName, value); - } - catch (Exception ex) - { - throw JsonSerializationException.Create(reader, "Error setting value in extension data for type '{0}'.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType), ex); - } - } - else - { - reader.Skip(); - } - } - - private void EndObject(object newObject, JsonReader reader, JsonObjectContract contract, int initialDepth, Dictionary propertiesPresence) - { - if (propertiesPresence != null) - { - foreach (KeyValuePair propertyPresence in propertiesPresence) - { - JsonProperty property = propertyPresence.Key; - PropertyPresence presence = propertyPresence.Value; - - if (presence == PropertyPresence.None || presence == PropertyPresence.Null) - { - try + if (property != null && requiredProperties != null) { - Required resolvedRequired = property._required ?? contract.ItemRequired ?? Required.Default; - - switch (presence) - { - case PropertyPresence.None: - if (resolvedRequired == Required.AllowNull || resolvedRequired == Required.Always) - throw JsonSerializationException.Create(reader, "Required property '{0}' not found in JSON.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName)); - - if (property.PropertyContract == null) - property.PropertyContract = GetContractSafe(property.PropertyType); - - if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer._defaultValueHandling), DefaultValueHandling.Populate) && property.Writable) - property.ValueProvider.SetValue(newObject, EnsureType(reader, property.GetResolvedDefaultValue(), CultureInfo.InvariantCulture, property.PropertyContract, property.PropertyType)); - break; - case PropertyPresence.Null: - if (resolvedRequired == Required.Always) - throw JsonSerializationException.Create(reader, "Required property '{0}' expects a value but got null.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName)); - break; - } + requiredProperties[property] = (reader.TokenType == JsonToken.Null || reader.TokenType == JsonToken.Undefined) + ? PropertyPresence.Null + : PropertyPresence.Value; } - catch (Exception ex) - { - if (IsErrorHandled(newObject, contract, property.PropertyName, reader as IJsonLineInfo, reader.Path, ex)) - HandleError(reader, true, initialDepth); - else - throw; - } - } } - } - } - private void SetPropertyPresence(JsonReader reader, JsonProperty property, Dictionary requiredProperties) - { - if (property != null && requiredProperties != null) - { - requiredProperties[property] = (reader.TokenType == JsonToken.Null || reader.TokenType == JsonToken.Undefined) - ? PropertyPresence.Null - : PropertyPresence.Value; - } - } - - private void HandleError(JsonReader reader, bool readPastError, int initialDepth) - { - ClearErrorContext(); - - if (readPastError) - { - reader.Skip(); - - while (reader.Depth > (initialDepth + 1)) + private void HandleError(JsonReader reader, bool readPastError, int initialDepth) { - if (!reader.Read()) - break; + ClearErrorContext(); + + if (readPastError) + { + reader.Skip(); + + while (reader.Depth > (initialDepth + 1)) + { + if (!reader.Read()) + break; + } + } } - } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs index 77be1f9b..0061544a 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs @@ -41,278 +41,279 @@ using System.Runtime.Serialization; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json.Serialization { - internal class JsonSerializerInternalWriter : JsonSerializerInternalBase - { - private JsonContract _rootContract; - private readonly List _serializeStack = new List(); - private JsonSerializerProxy _internalSerializer; - - public JsonSerializerInternalWriter(JsonSerializer serializer) - : base(serializer) + internal class JsonSerializerInternalWriter : JsonSerializerInternalBase { - } + private JsonContract _rootContract; + private readonly List _serializeStack = new List(); + private JsonSerializerProxy _internalSerializer; - public void Serialize(JsonWriter jsonWriter, object value, Type objectType) - { - if (jsonWriter == null) - throw new ArgumentNullException("jsonWriter"); - - if (objectType != null) - _rootContract = Serializer._contractResolver.ResolveContract(objectType); - - SerializeValue(jsonWriter, value, GetContractSafe(value), null, null, null); - } - - private JsonSerializerProxy GetInternalSerializer() - { - if (_internalSerializer == null) - _internalSerializer = new JsonSerializerProxy(this); - - return _internalSerializer; - } - - private JsonContract GetContractSafe(object value) - { - if (value == null) - return null; - - return Serializer._contractResolver.ResolveContract(value.GetType()); - } - - private void SerializePrimitive(JsonWriter writer, object value, JsonPrimitiveContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty) - { - if (contract.TypeCode == PrimitiveTypeCode.Bytes) - { - // if type name handling is enabled then wrap the base64 byte string in an object with the type name - bool includeTypeDetails = ShouldWriteType(TypeNameHandling.Objects, contract, member, containerContract, containerProperty); - if (includeTypeDetails) + public JsonSerializerInternalWriter(JsonSerializer serializer) + : base(serializer) { - writer.WriteStartObject(); - WriteTypeProperty(writer, contract.CreatedType); - writer.WritePropertyName(JsonTypeReflector.ValuePropertyName, false); - - JsonWriter.WriteValue(writer, contract.TypeCode, value); - - writer.WriteEndObject(); - return; } - } - JsonWriter.WriteValue(writer, contract.TypeCode, value); - } + public void Serialize(JsonWriter jsonWriter, object value, Type objectType) + { + if (jsonWriter == null) + throw new ArgumentNullException("jsonWriter"); - private void SerializeValue(JsonWriter writer, object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty) - { - if (value == null) - { - writer.WriteNull(); - return; - } + if (objectType != null) + _rootContract = Serializer._contractResolver.ResolveContract(objectType); - JsonConverter converter; - if ((((converter = (member != null) ? member.Converter : null) != null) - || ((converter = (containerProperty != null) ? containerProperty.ItemConverter : null) != null) - || ((converter = (containerContract != null) ? containerContract.ItemConverter : null) != null) - || ((converter = valueContract.Converter) != null) - || ((converter = Serializer.GetMatchingConverter(valueContract.UnderlyingType)) != null) - || ((converter = valueContract.InternalConverter) != null)) - && converter.CanWrite) - { - SerializeConvertable(writer, converter, value, valueContract, containerContract, containerProperty); - return; - } + SerializeValue(jsonWriter, value, GetContractSafe(value), null, null, null); + } - switch (valueContract.ContractType) - { - case JsonContractType.Object: - SerializeObject(writer, value, (JsonObjectContract)valueContract, member, containerContract, containerProperty); - break; - case JsonContractType.Array: - JsonArrayContract arrayContract = (JsonArrayContract) valueContract; - if (!arrayContract.IsMultidimensionalArray) - SerializeList(writer, (IEnumerable)value, arrayContract, member, containerContract, containerProperty); - else - SerializeMultidimensionalArray(writer, (Array)value, arrayContract, member, containerContract, containerProperty); - break; - case JsonContractType.Primitive: - SerializePrimitive(writer, value, (JsonPrimitiveContract)valueContract, member, containerContract, containerProperty); - break; - case JsonContractType.String: - SerializeString(writer, value, (JsonStringContract)valueContract); - break; - case JsonContractType.Dictionary: - JsonDictionaryContract dictionaryContract = (JsonDictionaryContract) valueContract; - SerializeDictionary(writer, (value is IDictionary) ? (IDictionary) value : dictionaryContract.CreateWrapper(value), dictionaryContract, member, containerContract, containerProperty); - break; + private JsonSerializerProxy GetInternalSerializer() + { + if (_internalSerializer == null) + _internalSerializer = new JsonSerializerProxy(this); + + return _internalSerializer; + } + + private JsonContract GetContractSafe(object value) + { + if (value == null) + return null; + + return Serializer._contractResolver.ResolveContract(value.GetType()); + } + + private void SerializePrimitive(JsonWriter writer, object value, JsonPrimitiveContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty) + { + if (contract.TypeCode == PrimitiveTypeCode.Bytes) + { + // if type name handling is enabled then wrap the base64 byte string in an object with the type name + bool includeTypeDetails = ShouldWriteType(TypeNameHandling.Objects, contract, member, containerContract, containerProperty); + if (includeTypeDetails) + { + writer.WriteStartObject(); + WriteTypeProperty(writer, contract.CreatedType); + writer.WritePropertyName(JsonTypeReflector.ValuePropertyName, false); + + JsonWriter.WriteValue(writer, contract.TypeCode, value); + + writer.WriteEndObject(); + return; + } + } + + JsonWriter.WriteValue(writer, contract.TypeCode, value); + } + + private void SerializeValue(JsonWriter writer, object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty) + { + if (value == null) + { + writer.WriteNull(); + return; + } + + JsonConverter converter; + if ((((converter = (member != null) ? member.Converter : null) != null) + || ((converter = (containerProperty != null) ? containerProperty.ItemConverter : null) != null) + || ((converter = (containerContract != null) ? containerContract.ItemConverter : null) != null) + || ((converter = valueContract.Converter) != null) + || ((converter = Serializer.GetMatchingConverter(valueContract.UnderlyingType)) != null) + || ((converter = valueContract.InternalConverter) != null)) + && converter.CanWrite) + { + SerializeConvertable(writer, converter, value, valueContract, containerContract, containerProperty); + return; + } + + switch (valueContract.ContractType) + { + case JsonContractType.Object: + SerializeObject(writer, value, (JsonObjectContract)valueContract, member, containerContract, containerProperty); + break; + case JsonContractType.Array: + JsonArrayContract arrayContract = (JsonArrayContract)valueContract; + if (!arrayContract.IsMultidimensionalArray) + SerializeList(writer, (IEnumerable)value, arrayContract, member, containerContract, containerProperty); + else + SerializeMultidimensionalArray(writer, (Array)value, arrayContract, member, containerContract, containerProperty); + break; + case JsonContractType.Primitive: + SerializePrimitive(writer, value, (JsonPrimitiveContract)valueContract, member, containerContract, containerProperty); + break; + case JsonContractType.String: + SerializeString(writer, value, (JsonStringContract)valueContract); + break; + case JsonContractType.Dictionary: + JsonDictionaryContract dictionaryContract = (JsonDictionaryContract)valueContract; + SerializeDictionary(writer, (value is IDictionary) ? (IDictionary)value : dictionaryContract.CreateWrapper(value), dictionaryContract, member, containerContract, containerProperty); + break; #if !(NET35 || NET20 || PORTABLE40) - case JsonContractType.Dynamic: - SerializeDynamic(writer, (IDynamicMetaObjectProvider)value, (JsonDynamicContract)valueContract, member, containerContract, containerProperty); - break; + case JsonContractType.Dynamic: + SerializeDynamic(writer, (IDynamicMetaObjectProvider)value, (JsonDynamicContract)valueContract, member, containerContract, containerProperty); + break; #endif #if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) - case JsonContractType.Serializable: - SerializeISerializable(writer, (ISerializable)value, (JsonISerializableContract)valueContract, member, containerContract, containerProperty); - break; + case JsonContractType.Serializable: + SerializeISerializable(writer, (ISerializable)value, (JsonISerializableContract)valueContract, member, containerContract, containerProperty); + break; #endif - case JsonContractType.Linq: - ((JToken) value).WriteTo(writer, Serializer.Converters.ToArray()); - break; - } - } + case JsonContractType.Linq: + ((JToken)value).WriteTo(writer, Serializer.Converters.ToArray()); + break; + } + } - private bool? ResolveIsReference(JsonContract contract, JsonProperty property, JsonContainerContract collectionContract, JsonProperty containerProperty) - { - bool? isReference = null; - - // value could be coming from a dictionary or array and not have a property - if (property != null) - isReference = property.IsReference; - - if (isReference == null && containerProperty != null) - isReference = containerProperty.ItemIsReference; - - if (isReference == null && collectionContract != null) - isReference = collectionContract.ItemIsReference; - - if (isReference == null) - isReference = contract.IsReference; - - return isReference; - } - - private bool ShouldWriteReference(object value, JsonProperty property, JsonContract valueContract, JsonContainerContract collectionContract, JsonProperty containerProperty) - { - if (value == null) - return false; - if (valueContract.ContractType == JsonContractType.Primitive || valueContract.ContractType == JsonContractType.String) - return false; - - bool? isReference = ResolveIsReference(valueContract, property, collectionContract, containerProperty); - - if (isReference == null) - { - if (valueContract.ContractType == JsonContractType.Array) - isReference = HasFlag(Serializer._preserveReferencesHandling, PreserveReferencesHandling.Arrays); - else - isReference = HasFlag(Serializer._preserveReferencesHandling, PreserveReferencesHandling.Objects); - } - - if (!isReference.Value) - return false; - - return Serializer.GetReferenceResolver().IsReferenced(this, value); - } - - private bool ShouldWriteProperty(object memberValue, JsonProperty property) - { - if (property.NullValueHandling.GetValueOrDefault(Serializer._nullValueHandling) == NullValueHandling.Ignore && - memberValue == null) - return false; - - if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer._defaultValueHandling), DefaultValueHandling.Ignore) - && MiscellaneousUtils.ValueEquals(memberValue, property.GetResolvedDefaultValue())) - return false; - - return true; - } - - private bool CheckForCircularReference(JsonWriter writer, object value, JsonProperty property, JsonContract contract, JsonContainerContract containerContract, JsonProperty containerProperty) - { - if (value == null || contract.ContractType == JsonContractType.Primitive || contract.ContractType == JsonContractType.String) - return true; - - ReferenceLoopHandling? referenceLoopHandling = null; - - if (property != null) - referenceLoopHandling = property.ReferenceLoopHandling; - - if (referenceLoopHandling == null && containerProperty != null) - referenceLoopHandling = containerProperty.ItemReferenceLoopHandling; - - if (referenceLoopHandling == null && containerContract != null) - referenceLoopHandling = containerContract.ItemReferenceLoopHandling; - - if (_serializeStack.IndexOf(value) != -1) - { - string message = "Self referencing loop detected"; - if (property != null) - message += " for property '{0}'".FormatWith(CultureInfo.InvariantCulture, property.PropertyName); - message += " with type '{0}'.".FormatWith(CultureInfo.InvariantCulture, value.GetType()); - - switch (referenceLoopHandling.GetValueOrDefault(Serializer._referenceLoopHandling)) + private bool? ResolveIsReference(JsonContract contract, JsonProperty property, JsonContainerContract collectionContract, JsonProperty containerProperty) { - case ReferenceLoopHandling.Error: - throw JsonSerializationException.Create(null, writer.ContainerPath, message, null); - case ReferenceLoopHandling.Ignore: - if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) - TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, writer.Path, message + ". Skipping serializing self referenced value."), null); + bool? isReference = null; - return false; - case ReferenceLoopHandling.Serialize: - if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) - TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, writer.Path, message + ". Serializing self referenced value."), null); + // value could be coming from a dictionary or array and not have a property + if (property != null) + isReference = property.IsReference; + + if (isReference == null && containerProperty != null) + isReference = containerProperty.ItemIsReference; + + if (isReference == null && collectionContract != null) + isReference = collectionContract.ItemIsReference; + + if (isReference == null) + isReference = contract.IsReference; + + return isReference; + } + + private bool ShouldWriteReference(object value, JsonProperty property, JsonContract valueContract, JsonContainerContract collectionContract, JsonProperty containerProperty) + { + if (value == null) + return false; + if (valueContract.ContractType == JsonContractType.Primitive || valueContract.ContractType == JsonContractType.String) + return false; + + bool? isReference = ResolveIsReference(valueContract, property, collectionContract, containerProperty); + + if (isReference == null) + { + if (valueContract.ContractType == JsonContractType.Array) + isReference = HasFlag(Serializer._preserveReferencesHandling, PreserveReferencesHandling.Arrays); + else + isReference = HasFlag(Serializer._preserveReferencesHandling, PreserveReferencesHandling.Objects); + } + + if (!isReference.Value) + return false; + + return Serializer.GetReferenceResolver().IsReferenced(this, value); + } + + private bool ShouldWriteProperty(object memberValue, JsonProperty property) + { + if (property.NullValueHandling.GetValueOrDefault(Serializer._nullValueHandling) == NullValueHandling.Ignore && + memberValue == null) + return false; + + if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer._defaultValueHandling), DefaultValueHandling.Ignore) + && MiscellaneousUtils.ValueEquals(memberValue, property.GetResolvedDefaultValue())) + return false; return true; } - } - return true; - } - - private void WriteReference(JsonWriter writer, object value) - { - string reference = GetReference(writer, value); - - if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) - TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(null, writer.Path, "Writing object reference to Id '{0}' for {1}.".FormatWith(CultureInfo.InvariantCulture, reference, value.GetType())), null); - - writer.WriteStartObject(); - writer.WritePropertyName(JsonTypeReflector.RefPropertyName, false); - writer.WriteValue(reference); - writer.WriteEndObject(); - } - - private string GetReference(JsonWriter writer, object value) - { - try - { - string reference = Serializer.GetReferenceResolver().GetReference(this, value); - - return reference; - } - catch (Exception ex) - { - throw JsonSerializationException.Create(null, writer.ContainerPath, "Error writing object reference for '{0}'.".FormatWith(CultureInfo.InvariantCulture, value.GetType()), ex); - } - } - - internal static bool TryConvertToString(object value, Type type, out string s) - { -#if !(NETFX_CORE || PORTABLE40 || PORTABLE) - TypeConverter converter = ConvertUtils.GetConverter(type); - - // use the objectType's TypeConverter if it has one and can convert to a string - if (converter != null -#if !SILVERLIGHT - && !(converter is ComponentConverter) -#endif - && converter.GetType() != typeof(TypeConverter)) - { - if (converter.CanConvertTo(typeof(string))) + private bool CheckForCircularReference(JsonWriter writer, object value, JsonProperty property, JsonContract contract, JsonContainerContract containerContract, JsonProperty containerProperty) { + if (value == null || contract.ContractType == JsonContractType.Primitive || contract.ContractType == JsonContractType.String) + return true; + + ReferenceLoopHandling? referenceLoopHandling = null; + + if (property != null) + referenceLoopHandling = property.ReferenceLoopHandling; + + if (referenceLoopHandling == null && containerProperty != null) + referenceLoopHandling = containerProperty.ItemReferenceLoopHandling; + + if (referenceLoopHandling == null && containerContract != null) + referenceLoopHandling = containerContract.ItemReferenceLoopHandling; + + if (_serializeStack.IndexOf(value) != -1) + { + string message = "Self referencing loop detected"; + if (property != null) + message += " for property '{0}'".FormatWith(CultureInfo.InvariantCulture, property.PropertyName); + message += " with type '{0}'.".FormatWith(CultureInfo.InvariantCulture, value.GetType()); + + switch (referenceLoopHandling.GetValueOrDefault(Serializer._referenceLoopHandling)) + { + case ReferenceLoopHandling.Error: + throw JsonSerializationException.Create(null, writer.ContainerPath, message, null); + case ReferenceLoopHandling.Ignore: + if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) + TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, writer.Path, message + ". Skipping serializing self referenced value."), null); + + return false; + case ReferenceLoopHandling.Serialize: + if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) + TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, writer.Path, message + ". Serializing self referenced value."), null); + + return true; + } + } + + return true; + } + + private void WriteReference(JsonWriter writer, object value) + { + string reference = GetReference(writer, value); + + if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) + TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(null, writer.Path, "Writing object reference to Id '{0}' for {1}.".FormatWith(CultureInfo.InvariantCulture, reference, value.GetType())), null); + + writer.WriteStartObject(); + writer.WritePropertyName(JsonTypeReflector.RefPropertyName, false); + writer.WriteValue(reference); + writer.WriteEndObject(); + } + + private string GetReference(JsonWriter writer, object value) + { + try + { + string reference = Serializer.GetReferenceResolver().GetReference(this, value); + + return reference; + } + catch (Exception ex) + { + throw JsonSerializationException.Create(null, writer.ContainerPath, "Error writing object reference for '{0}'.".FormatWith(CultureInfo.InvariantCulture, value.GetType()), ex); + } + } + + internal static bool TryConvertToString(object value, Type type, out string s) + { +#if !(NETFX_CORE || PORTABLE40 || PORTABLE) + TypeConverter converter = ConvertUtils.GetConverter(type); + + // use the objectType's TypeConverter if it has one and can convert to a string + if (converter != null #if !SILVERLIGHT - s = converter.ConvertToInvariantString(value); + && !(converter is ComponentConverter) +#endif + && converter.GetType() != typeof(TypeConverter)) + { + if (converter.CanConvertTo(typeof(string))) + { +#if !SILVERLIGHT + s = converter.ConvertToInvariantString(value); #else s = converter.ConvertToString(value); #endif - - return true; - } - } + + return true; + } + } #endif #if SILVERLIGHT || NETFX_CORE || PORTABLE @@ -323,688 +324,688 @@ namespace Newtonsoft.Json.Serialization } #endif - if (value is Type) - { - s = ((Type)value).AssemblyQualifiedName; - return true; - } - - s = null; - return false; - } - - private void SerializeString(JsonWriter writer, object value, JsonStringContract contract) - { - OnSerializing(writer, contract, value); - - string s; - TryConvertToString(value, contract.UnderlyingType, out s); - writer.WriteValue(s); - - OnSerialized(writer, contract, value); - } - - private void OnSerializing(JsonWriter writer, JsonContract contract, object value) - { - if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) - TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(null, writer.Path, "Started serializing {0}".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)), null); - - contract.InvokeOnSerializing(value, Serializer._context); - } - - private void OnSerialized(JsonWriter writer, JsonContract contract, object value) - { - if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) - TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(null, writer.Path, "Finished serializing {0}".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)), null); - - contract.InvokeOnSerialized(value, Serializer._context); - } - - private void SerializeObject(JsonWriter writer, object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) - { - OnSerializing(writer, contract, value); - - _serializeStack.Add(value); - - WriteObjectStart(writer, value, contract, member, collectionContract, containerProperty); - - int initialDepth = writer.Top; - - for (int index = 0; index < contract.Properties.Count; index++) - { - JsonProperty property = contract.Properties[index]; - try - { - object memberValue; - JsonContract memberContract; - - if (!CalculatePropertyValues(writer, value, contract, member, property, out memberContract, out memberValue)) - continue; - - property.WritePropertyName(writer); - SerializeValue(writer, memberValue, memberContract, property, contract, member); - } - catch (Exception ex) - { - if (IsErrorHandled(value, contract, property.PropertyName, null, writer.ContainerPath, ex)) - HandleError(writer, initialDepth); - else - throw; - } - } - - if (contract.ExtensionDataGetter != null) - { - IEnumerable> extensionData = contract.ExtensionDataGetter(value); - if (extensionData != null) - { - foreach (KeyValuePair e in extensionData) - { - JsonContract keyContract = GetContractSafe(e.Key); - JsonContract valueContract = GetContractSafe(e.Value); - - bool escape; - string propertyName = GetPropertyName(writer, e.Key, keyContract, out escape); - - if (ShouldWriteReference(e.Value, null, valueContract, contract, member)) + if (value is Type) { - writer.WritePropertyName(propertyName); - WriteReference(writer, e.Value); + s = ((Type)value).AssemblyQualifiedName; + return true; } - else - { - if (!CheckForCircularReference(writer, e.Value, null, valueContract, contract, member)) - continue; - writer.WritePropertyName(propertyName); - - SerializeValue(writer, e.Value, valueContract, null, contract, member); - } - } - } - } - - writer.WriteEndObject(); - - _serializeStack.RemoveAt(_serializeStack.Count - 1); - - OnSerialized(writer, contract, value); - } - - 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(writer, property, value) && IsSpecified(writer, property, value)) - { - if (property.PropertyContract == null) - property.PropertyContract = Serializer._contractResolver.ResolveContract(property.PropertyType); - - memberValue = property.ValueProvider.GetValue(value); - memberContract = (property.PropertyContract.IsSealed) ? property.PropertyContract : GetContractSafe(memberValue); - - if (ShouldWriteProperty(memberValue, property)) - { - if (ShouldWriteReference(memberValue, property, memberContract, contract, member)) - { - property.WritePropertyName(writer); - WriteReference(writer, memberValue); + s = null; return false; - } + } - if (!CheckForCircularReference(writer, memberValue, property, memberContract, contract, member)) + private void SerializeString(JsonWriter writer, object value, JsonStringContract contract) + { + OnSerializing(writer, contract, value); + + string s; + TryConvertToString(value, contract.UnderlyingType, out s); + writer.WriteValue(s); + + OnSerialized(writer, contract, value); + } + + private void OnSerializing(JsonWriter writer, JsonContract contract, object value) + { + if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) + TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(null, writer.Path, "Started serializing {0}".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)), null); + + contract.InvokeOnSerializing(value, Serializer._context); + } + + private void OnSerialized(JsonWriter writer, JsonContract contract, object value) + { + if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) + TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(null, writer.Path, "Finished serializing {0}".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)), null); + + contract.InvokeOnSerialized(value, Serializer._context); + } + + private void SerializeObject(JsonWriter writer, object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) + { + OnSerializing(writer, contract, value); + + _serializeStack.Add(value); + + WriteObjectStart(writer, value, contract, member, collectionContract, containerProperty); + + int initialDepth = writer.Top; + + for (int index = 0; index < contract.Properties.Count; index++) + { + JsonProperty property = contract.Properties[index]; + try + { + object memberValue; + JsonContract memberContract; + + if (!CalculatePropertyValues(writer, value, contract, member, property, out memberContract, out memberValue)) + continue; + + property.WritePropertyName(writer); + SerializeValue(writer, memberValue, memberContract, property, contract, member); + } + catch (Exception ex) + { + if (IsErrorHandled(value, contract, property.PropertyName, null, writer.ContainerPath, ex)) + HandleError(writer, initialDepth); + else + throw; + } + } + + if (contract.ExtensionDataGetter != null) + { + IEnumerable> extensionData = contract.ExtensionDataGetter(value); + if (extensionData != null) + { + foreach (KeyValuePair e in extensionData) + { + JsonContract keyContract = GetContractSafe(e.Key); + JsonContract valueContract = GetContractSafe(e.Value); + + bool escape; + string propertyName = GetPropertyName(writer, e.Key, keyContract, out escape); + + if (ShouldWriteReference(e.Value, null, valueContract, contract, member)) + { + writer.WritePropertyName(propertyName); + WriteReference(writer, e.Value); + } + else + { + if (!CheckForCircularReference(writer, e.Value, null, valueContract, contract, member)) + continue; + + writer.WritePropertyName(propertyName); + + SerializeValue(writer, e.Value, valueContract, null, contract, member); + } + } + } + } + + writer.WriteEndObject(); + + _serializeStack.RemoveAt(_serializeStack.Count - 1); + + OnSerialized(writer, contract, value); + } + + 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(writer, property, value) && IsSpecified(writer, property, value)) + { + if (property.PropertyContract == null) + property.PropertyContract = Serializer._contractResolver.ResolveContract(property.PropertyType); + + memberValue = property.ValueProvider.GetValue(value); + memberContract = (property.PropertyContract.IsSealed) ? property.PropertyContract : GetContractSafe(memberValue); + + if (ShouldWriteProperty(memberValue, property)) + { + if (ShouldWriteReference(memberValue, property, memberContract, contract, member)) + { + property.WritePropertyName(writer); + WriteReference(writer, memberValue); + return false; + } + + if (!CheckForCircularReference(writer, memberValue, property, memberContract, contract, member)) + return false; + + if (memberValue == null) + { + JsonObjectContract objectContract = contract as JsonObjectContract; + Required resolvedRequired = property._required ?? ((objectContract != null) ? objectContract.ItemRequired : null) ?? Required.Default; + if (resolvedRequired == Required.Always) + throw JsonSerializationException.Create(null, writer.ContainerPath, "Cannot write a null value for property '{0}'. Property requires a value.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName), null); + } + + return true; + } + } + + memberContract = null; + memberValue = null; return false; - - if (memberValue == null) - { - JsonObjectContract objectContract = contract as JsonObjectContract; - Required resolvedRequired = property._required ?? ((objectContract != null) ? objectContract.ItemRequired : null) ?? Required.Default; - if (resolvedRequired == Required.Always) - throw JsonSerializationException.Create(null, writer.ContainerPath, "Cannot write a null value for property '{0}'. Property requires a value.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName), null); - } - - return true; } - } - memberContract = null; - memberValue = null; - return false; - } - - private void WriteObjectStart(JsonWriter writer, object value, JsonContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) - { - writer.WriteStartObject(); - - bool isReference = ResolveIsReference(contract, member, collectionContract, containerProperty) ?? HasFlag(Serializer._preserveReferencesHandling, PreserveReferencesHandling.Objects); - if (isReference) - { - WriteReferenceIdProperty(writer, contract.UnderlyingType, value); - } - if (ShouldWriteType(TypeNameHandling.Objects, contract, member, collectionContract, containerProperty)) - { - WriteTypeProperty(writer, contract.UnderlyingType); - } - } - - private void WriteReferenceIdProperty(JsonWriter writer, Type type, object value) - { - string reference = GetReference(writer, value); - - if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) - TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, writer.Path, "Writing object reference Id '{0}' for {1}.".FormatWith(CultureInfo.InvariantCulture, reference, type)), null); - - writer.WritePropertyName(JsonTypeReflector.IdPropertyName, false); - writer.WriteValue(reference); - } - - private void WriteTypeProperty(JsonWriter writer, Type type) - { - string typeName = ReflectionUtils.GetTypeName(type, Serializer._typeNameAssemblyFormat, Serializer._binder); - - if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) - TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, writer.Path, "Writing type name '{0}' for {1}.".FormatWith(CultureInfo.InvariantCulture, typeName, type)), null); - - writer.WritePropertyName(JsonTypeReflector.TypePropertyName, false); - writer.WriteValue(typeName); - } - - private bool HasFlag(DefaultValueHandling value, DefaultValueHandling flag) - { - return ((value & flag) == flag); - } - - private bool HasFlag(PreserveReferencesHandling value, PreserveReferencesHandling flag) - { - return ((value & flag) == flag); - } - - private bool HasFlag(TypeNameHandling value, TypeNameHandling flag) - { - return ((value & flag) == flag); - } - - private void SerializeConvertable(JsonWriter writer, JsonConverter converter, object value, JsonContract contract, JsonContainerContract collectionContract, JsonProperty containerProperty) - { - if (ShouldWriteReference(value, null, contract, collectionContract, containerProperty)) - { - WriteReference(writer, value); - } - else - { - if (!CheckForCircularReference(writer, value, null, contract, collectionContract, containerProperty)) - return; - - _serializeStack.Add(value); - - if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) - TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(null, writer.Path, "Started serializing {0} with converter {1}.".FormatWith(CultureInfo.InvariantCulture, value.GetType(), converter.GetType())), null); - - converter.WriteJson(writer, value, GetInternalSerializer()); - - if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) - TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(null, writer.Path, "Finished serializing {0} with converter {1}.".FormatWith(CultureInfo.InvariantCulture, value.GetType(), converter.GetType())), null); - - _serializeStack.RemoveAt(_serializeStack.Count - 1); - } - } - - private void SerializeList(JsonWriter writer, IEnumerable values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) - { - IWrappedCollection wrappedCollection = values as IWrappedCollection; - object underlyingList = wrappedCollection != null ? wrappedCollection.UnderlyingCollection : values; - - OnSerializing(writer, contract, underlyingList); - - _serializeStack.Add(underlyingList); - - bool hasWrittenMetadataObject = WriteStartArray(writer, underlyingList, contract, member, collectionContract, containerProperty); - - writer.WriteStartArray(); - - int initialDepth = writer.Top; - - int index = 0; - // note that an error in the IEnumerable won't be caught - foreach (object value in values) - { - try + private void WriteObjectStart(JsonWriter writer, object value, JsonContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) { - JsonContract valueContract = contract.FinalItemContract ?? GetContractSafe(value); + writer.WriteStartObject(); - if (ShouldWriteReference(value, null, valueContract, contract, member)) - { - WriteReference(writer, value); - } - else - { - if (CheckForCircularReference(writer, value, null, valueContract, contract, member)) + bool isReference = ResolveIsReference(contract, member, collectionContract, containerProperty) ?? HasFlag(Serializer._preserveReferencesHandling, PreserveReferencesHandling.Objects); + if (isReference) { - SerializeValue(writer, value, valueContract, null, contract, member); + WriteReferenceIdProperty(writer, contract.UnderlyingType, value); } - } - } - catch (Exception ex) - { - if (IsErrorHandled(underlyingList, contract, index, null, writer.ContainerPath, ex)) - HandleError(writer, initialDepth); - else - throw; - } - finally - { - index++; - } - } - - writer.WriteEndArray(); - - if (hasWrittenMetadataObject) - writer.WriteEndObject(); - - _serializeStack.RemoveAt(_serializeStack.Count - 1); - - OnSerialized(writer, contract, underlyingList); - } - - private void SerializeMultidimensionalArray(JsonWriter writer, Array values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) - { - OnSerializing(writer, contract, values); - - _serializeStack.Add(values); - - bool hasWrittenMetadataObject = WriteStartArray(writer, values, contract, member, collectionContract, containerProperty); - - SerializeMultidimensionalArray(writer, values, contract, member, writer.Top, new int[0]); - - if (hasWrittenMetadataObject) - writer.WriteEndObject(); - - _serializeStack.RemoveAt(_serializeStack.Count - 1); - - OnSerialized(writer, contract, values); - } - - private void SerializeMultidimensionalArray(JsonWriter writer, Array values, JsonArrayContract contract, JsonProperty member, int initialDepth, int[] indices) - { - int dimension = indices.Length; - int[] newIndices = new int[dimension + 1]; - for (int i = 0; i < dimension; i++) - { - newIndices[i] = indices[i]; - } - - writer.WriteStartArray(); - - for (int i = 0; i < values.GetLength(dimension); i++) - { - newIndices[dimension] = i; - bool isTopLevel = (newIndices.Length == values.Rank); - - if (isTopLevel) - { - object value = values.GetValue(newIndices); - - try - { - JsonContract valueContract = contract.FinalItemContract ?? GetContractSafe(value); - - if (ShouldWriteReference(value, null, valueContract, contract, member)) + if (ShouldWriteType(TypeNameHandling.Objects, contract, member, collectionContract, containerProperty)) { - WriteReference(writer, value); + WriteTypeProperty(writer, contract.UnderlyingType); + } + } + + private void WriteReferenceIdProperty(JsonWriter writer, Type type, object value) + { + string reference = GetReference(writer, value); + + if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) + TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, writer.Path, "Writing object reference Id '{0}' for {1}.".FormatWith(CultureInfo.InvariantCulture, reference, type)), null); + + writer.WritePropertyName(JsonTypeReflector.IdPropertyName, false); + writer.WriteValue(reference); + } + + private void WriteTypeProperty(JsonWriter writer, Type type) + { + string typeName = ReflectionUtils.GetTypeName(type, Serializer._typeNameAssemblyFormat, Serializer._binder); + + if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) + TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, writer.Path, "Writing type name '{0}' for {1}.".FormatWith(CultureInfo.InvariantCulture, typeName, type)), null); + + writer.WritePropertyName(JsonTypeReflector.TypePropertyName, false); + writer.WriteValue(typeName); + } + + private bool HasFlag(DefaultValueHandling value, DefaultValueHandling flag) + { + return ((value & flag) == flag); + } + + private bool HasFlag(PreserveReferencesHandling value, PreserveReferencesHandling flag) + { + return ((value & flag) == flag); + } + + private bool HasFlag(TypeNameHandling value, TypeNameHandling flag) + { + return ((value & flag) == flag); + } + + private void SerializeConvertable(JsonWriter writer, JsonConverter converter, object value, JsonContract contract, JsonContainerContract collectionContract, JsonProperty containerProperty) + { + if (ShouldWriteReference(value, null, contract, collectionContract, containerProperty)) + { + WriteReference(writer, value); } else { - if (CheckForCircularReference(writer, value, null, valueContract, contract, member)) - { - SerializeValue(writer, value, valueContract, null, contract, member); - } + if (!CheckForCircularReference(writer, value, null, contract, collectionContract, containerProperty)) + return; + + _serializeStack.Add(value); + + if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) + TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(null, writer.Path, "Started serializing {0} with converter {1}.".FormatWith(CultureInfo.InvariantCulture, value.GetType(), converter.GetType())), null); + + converter.WriteJson(writer, value, GetInternalSerializer()); + + if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info) + TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(null, writer.Path, "Finished serializing {0} with converter {1}.".FormatWith(CultureInfo.InvariantCulture, value.GetType(), converter.GetType())), null); + + _serializeStack.RemoveAt(_serializeStack.Count - 1); } - } - catch (Exception ex) - { - if (IsErrorHandled(values, contract, i, null, writer.ContainerPath, ex)) - HandleError(writer, initialDepth + 1); - else - throw; - } } - else + + private void SerializeList(JsonWriter writer, IEnumerable values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) { - SerializeMultidimensionalArray(writer, values, contract, member, initialDepth + 1, newIndices); + IWrappedCollection wrappedCollection = values as IWrappedCollection; + object underlyingList = wrappedCollection != null ? wrappedCollection.UnderlyingCollection : values; + + OnSerializing(writer, contract, underlyingList); + + _serializeStack.Add(underlyingList); + + bool hasWrittenMetadataObject = WriteStartArray(writer, underlyingList, contract, member, collectionContract, containerProperty); + + writer.WriteStartArray(); + + int initialDepth = writer.Top; + + int index = 0; + // note that an error in the IEnumerable won't be caught + foreach (object value in values) + { + try + { + JsonContract valueContract = contract.FinalItemContract ?? GetContractSafe(value); + + if (ShouldWriteReference(value, null, valueContract, contract, member)) + { + WriteReference(writer, value); + } + else + { + if (CheckForCircularReference(writer, value, null, valueContract, contract, member)) + { + SerializeValue(writer, value, valueContract, null, contract, member); + } + } + } + catch (Exception ex) + { + if (IsErrorHandled(underlyingList, contract, index, null, writer.ContainerPath, ex)) + HandleError(writer, initialDepth); + else + throw; + } + finally + { + index++; + } + } + + writer.WriteEndArray(); + + if (hasWrittenMetadataObject) + writer.WriteEndObject(); + + _serializeStack.RemoveAt(_serializeStack.Count - 1); + + OnSerialized(writer, contract, underlyingList); } - } - writer.WriteEndArray(); - } - - private bool WriteStartArray(JsonWriter writer, object values, JsonArrayContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty) - { - bool isReference = ResolveIsReference(contract, member, containerContract, containerProperty) ?? HasFlag(Serializer._preserveReferencesHandling, PreserveReferencesHandling.Arrays); - bool includeTypeDetails = ShouldWriteType(TypeNameHandling.Arrays, contract, member, containerContract, containerProperty); - bool writeMetadataObject = isReference || includeTypeDetails; - - if (writeMetadataObject) - { - writer.WriteStartObject(); - - if (isReference) + private void SerializeMultidimensionalArray(JsonWriter writer, Array values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) { - WriteReferenceIdProperty(writer, contract.UnderlyingType, values); + OnSerializing(writer, contract, values); + + _serializeStack.Add(values); + + bool hasWrittenMetadataObject = WriteStartArray(writer, values, contract, member, collectionContract, containerProperty); + + SerializeMultidimensionalArray(writer, values, contract, member, writer.Top, new int[0]); + + if (hasWrittenMetadataObject) + writer.WriteEndObject(); + + _serializeStack.RemoveAt(_serializeStack.Count - 1); + + OnSerialized(writer, contract, values); } - if (includeTypeDetails) + + private void SerializeMultidimensionalArray(JsonWriter writer, Array values, JsonArrayContract contract, JsonProperty member, int initialDepth, int[] indices) { - WriteTypeProperty(writer, values.GetType()); + int dimension = indices.Length; + int[] newIndices = new int[dimension + 1]; + for (int i = 0; i < dimension; i++) + { + newIndices[i] = indices[i]; + } + + writer.WriteStartArray(); + + for (int i = 0; i < values.GetLength(dimension); i++) + { + newIndices[dimension] = i; + bool isTopLevel = (newIndices.Length == values.Rank); + + if (isTopLevel) + { + object value = values.GetValue(newIndices); + + try + { + JsonContract valueContract = contract.FinalItemContract ?? GetContractSafe(value); + + if (ShouldWriteReference(value, null, valueContract, contract, member)) + { + WriteReference(writer, value); + } + else + { + if (CheckForCircularReference(writer, value, null, valueContract, contract, member)) + { + SerializeValue(writer, value, valueContract, null, contract, member); + } + } + } + catch (Exception ex) + { + if (IsErrorHandled(values, contract, i, null, writer.ContainerPath, ex)) + HandleError(writer, initialDepth + 1); + else + throw; + } + } + else + { + SerializeMultidimensionalArray(writer, values, contract, member, initialDepth + 1, newIndices); + } + } + + writer.WriteEndArray(); } - writer.WritePropertyName(JsonTypeReflector.ArrayValuesPropertyName, false); - } - if (contract.ItemContract == null) - contract.ItemContract = Serializer._contractResolver.ResolveContract(contract.CollectionItemType ?? typeof (object)); + private bool WriteStartArray(JsonWriter writer, object values, JsonArrayContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty) + { + bool isReference = ResolveIsReference(contract, member, containerContract, containerProperty) ?? HasFlag(Serializer._preserveReferencesHandling, PreserveReferencesHandling.Arrays); + bool includeTypeDetails = ShouldWriteType(TypeNameHandling.Arrays, contract, member, containerContract, containerProperty); + bool writeMetadataObject = isReference || includeTypeDetails; - return writeMetadataObject; - } + if (writeMetadataObject) + { + writer.WriteStartObject(); + + if (isReference) + { + WriteReferenceIdProperty(writer, contract.UnderlyingType, values); + } + if (includeTypeDetails) + { + WriteTypeProperty(writer, values.GetType()); + } + writer.WritePropertyName(JsonTypeReflector.ArrayValuesPropertyName, false); + } + + if (contract.ItemContract == null) + contract.ItemContract = Serializer._contractResolver.ResolveContract(contract.CollectionItemType ?? typeof(object)); + + return writeMetadataObject; + } #if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) #if !(NET20 || NET35) - [SecuritySafeCritical] + [SecuritySafeCritical] #endif - private void SerializeISerializable(JsonWriter writer, ISerializable value, JsonISerializableContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) - { - if (!JsonTypeReflector.FullyTrusted) - { - throw JsonSerializationException.Create(null, writer.ContainerPath, @"Type '{0}' implements ISerializable but cannot be serialized using the ISerializable interface because the current application is not fully trusted and ISerializable can expose secure data. -To fix this error either change the environment to be fully trusted, change the application to not deserialize the type, add JsonObjectAttribute to the type or change the JsonSerializer setting ContractResolver to use a new DefaultContractResolver with IgnoreSerializableInterface set to true.".FormatWith(CultureInfo.InvariantCulture, value.GetType()), null); - } - - OnSerializing(writer, contract, value); - _serializeStack.Add(value); - - WriteObjectStart(writer, value, contract, member, collectionContract, containerProperty); - - SerializationInfo serializationInfo = new SerializationInfo(contract.UnderlyingType, new FormatterConverter()); - value.GetObjectData(serializationInfo, Serializer._context); - - foreach (SerializationEntry serializationEntry in serializationInfo) - { - JsonContract valueContract = GetContractSafe(serializationEntry.Value); - - if (CheckForCircularReference(writer, serializationEntry.Value, null, valueContract, contract, member)) + private void SerializeISerializable(JsonWriter writer, ISerializable value, JsonISerializableContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) { - writer.WritePropertyName(serializationEntry.Name); - SerializeValue(writer, serializationEntry.Value, valueContract, null, contract, member); + if (!JsonTypeReflector.FullyTrusted) + { + throw JsonSerializationException.Create(null, writer.ContainerPath, @"Type '{0}' implements ISerializable but cannot be serialized using the ISerializable interface because the current application is not fully trusted and ISerializable can expose secure data. +To fix this error either change the environment to be fully trusted, change the application to not deserialize the type, add JsonObjectAttribute to the type or change the JsonSerializer setting ContractResolver to use a new DefaultContractResolver with IgnoreSerializableInterface set to true.".FormatWith(CultureInfo.InvariantCulture, value.GetType()), null); + } + + OnSerializing(writer, contract, value); + _serializeStack.Add(value); + + WriteObjectStart(writer, value, contract, member, collectionContract, containerProperty); + + SerializationInfo serializationInfo = new SerializationInfo(contract.UnderlyingType, new FormatterConverter()); + value.GetObjectData(serializationInfo, Serializer._context); + + foreach (SerializationEntry serializationEntry in serializationInfo) + { + JsonContract valueContract = GetContractSafe(serializationEntry.Value); + + if (CheckForCircularReference(writer, serializationEntry.Value, null, valueContract, contract, member)) + { + writer.WritePropertyName(serializationEntry.Name); + SerializeValue(writer, serializationEntry.Value, valueContract, null, contract, member); + } + } + + writer.WriteEndObject(); + + _serializeStack.RemoveAt(_serializeStack.Count - 1); + OnSerialized(writer, contract, value); } - } - - writer.WriteEndObject(); - - _serializeStack.RemoveAt(_serializeStack.Count - 1); - OnSerialized(writer, contract, value); - } #endif #if !(NET35 || NET20 || PORTABLE40) - private void SerializeDynamic(JsonWriter writer, IDynamicMetaObjectProvider value, JsonDynamicContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) - { - OnSerializing(writer, contract, value); - _serializeStack.Add(value); - - WriteObjectStart(writer, value, contract, member, collectionContract, containerProperty); - - int initialDepth = writer.Top; - - for (int index = 0; index < contract.Properties.Count; index++) - { - JsonProperty property = contract.Properties[index]; - - // only write non-dynamic properties that have an explicit attribute - if (property.HasMemberAttribute) + private void SerializeDynamic(JsonWriter writer, IDynamicMetaObjectProvider value, JsonDynamicContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) { - try - { - object memberValue; - JsonContract memberContract; + OnSerializing(writer, contract, value); + _serializeStack.Add(value); - if (!CalculatePropertyValues(writer, value, contract, member, property, out memberContract, out memberValue)) - continue; + WriteObjectStart(writer, value, contract, member, collectionContract, containerProperty); - property.WritePropertyName(writer); - SerializeValue(writer, memberValue, memberContract, property, contract, member); - } - catch (Exception ex) - { - if (IsErrorHandled(value, contract, property.PropertyName, null, writer.ContainerPath, ex)) - HandleError(writer, initialDepth); - else - throw; - } - } - } + int initialDepth = writer.Top; - foreach (string memberName in value.GetDynamicMemberNames()) - { - object memberValue; - if (contract.TryGetMember(value, memberName, out memberValue)) - { - try - { - JsonContract valueContract = GetContractSafe(memberValue); - - if (!ShouldWriteDynamicProperty(memberValue)) - continue; - - if (CheckForCircularReference(writer, memberValue, null, valueContract, contract, member)) + for (int index = 0; index < contract.Properties.Count; index++) { - string resolvedPropertyName = (contract.PropertyNameResolver != null) - ? contract.PropertyNameResolver(memberName) - : memberName; + JsonProperty property = contract.Properties[index]; - writer.WritePropertyName(resolvedPropertyName); - SerializeValue(writer, memberValue, valueContract, null, contract, member); + // only write non-dynamic properties that have an explicit attribute + if (property.HasMemberAttribute) + { + try + { + object memberValue; + JsonContract memberContract; + + if (!CalculatePropertyValues(writer, value, contract, member, property, out memberContract, out memberValue)) + continue; + + property.WritePropertyName(writer); + SerializeValue(writer, memberValue, memberContract, property, contract, member); + } + catch (Exception ex) + { + if (IsErrorHandled(value, contract, property.PropertyName, null, writer.ContainerPath, ex)) + HandleError(writer, initialDepth); + else + throw; + } + } } - } - catch (Exception ex) - { - if (IsErrorHandled(value, contract, memberName, null, writer.ContainerPath, ex)) - HandleError(writer, initialDepth); - else - throw; - } + + foreach (string memberName in value.GetDynamicMemberNames()) + { + object memberValue; + if (contract.TryGetMember(value, memberName, out memberValue)) + { + try + { + JsonContract valueContract = GetContractSafe(memberValue); + + if (!ShouldWriteDynamicProperty(memberValue)) + continue; + + if (CheckForCircularReference(writer, memberValue, null, valueContract, contract, member)) + { + string resolvedPropertyName = (contract.PropertyNameResolver != null) + ? contract.PropertyNameResolver(memberName) + : memberName; + + writer.WritePropertyName(resolvedPropertyName); + SerializeValue(writer, memberValue, valueContract, null, contract, member); + } + } + catch (Exception ex) + { + if (IsErrorHandled(value, contract, memberName, null, writer.ContainerPath, ex)) + HandleError(writer, initialDepth); + else + throw; + } + } + } + + writer.WriteEndObject(); + + _serializeStack.RemoveAt(_serializeStack.Count - 1); + OnSerialized(writer, contract, value); } - } - - writer.WriteEndObject(); - - _serializeStack.RemoveAt(_serializeStack.Count - 1); - OnSerialized(writer, contract, value); - } #endif - private bool ShouldWriteDynamicProperty(object memberValue) - { - if (Serializer._nullValueHandling == NullValueHandling.Ignore && memberValue == null) - return false; - - if (HasFlag(Serializer._defaultValueHandling, DefaultValueHandling.Ignore) && - (memberValue == null || MiscellaneousUtils.ValueEquals(memberValue, ReflectionUtils.GetDefaultValue(memberValue.GetType())))) - return false; - - return true; - } - - private bool ShouldWriteType(TypeNameHandling typeNameHandlingFlag, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty) - { - TypeNameHandling resolvedTypeNameHandling = - ((member != null) ? member.TypeNameHandling : null) - ?? ((containerProperty != null) ? containerProperty.ItemTypeNameHandling : null) - ?? ((containerContract != null) ? containerContract.ItemTypeNameHandling : null) - ?? Serializer._typeNameHandling; - - if (HasFlag(resolvedTypeNameHandling, typeNameHandlingFlag)) - return true; - - // instance type and the property's type's contract default type are different (no need to put the type in JSON because the type will be created by default) - if (HasFlag(resolvedTypeNameHandling, TypeNameHandling.Auto)) - { - if (member != null) + private bool ShouldWriteDynamicProperty(object memberValue) { - if (contract.UnderlyingType != member.PropertyContract.CreatedType) + if (Serializer._nullValueHandling == NullValueHandling.Ignore && memberValue == null) + return false; + + if (HasFlag(Serializer._defaultValueHandling, DefaultValueHandling.Ignore) && + (memberValue == null || MiscellaneousUtils.ValueEquals(memberValue, ReflectionUtils.GetDefaultValue(memberValue.GetType())))) + return false; + return true; } - else if (containerContract != null) + + private bool ShouldWriteType(TypeNameHandling typeNameHandlingFlag, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty) { - if (containerContract.ItemContract == null || contract.UnderlyingType != containerContract.ItemContract.CreatedType) - return true; + TypeNameHandling resolvedTypeNameHandling = + ((member != null) ? member.TypeNameHandling : null) + ?? ((containerProperty != null) ? containerProperty.ItemTypeNameHandling : null) + ?? ((containerContract != null) ? containerContract.ItemTypeNameHandling : null) + ?? Serializer._typeNameHandling; + + if (HasFlag(resolvedTypeNameHandling, typeNameHandlingFlag)) + return true; + + // instance type and the property's type's contract default type are different (no need to put the type in JSON because the type will be created by default) + if (HasFlag(resolvedTypeNameHandling, TypeNameHandling.Auto)) + { + if (member != null) + { + if (contract.UnderlyingType != member.PropertyContract.CreatedType) + return true; + } + else if (containerContract != null) + { + if (containerContract.ItemContract == null || contract.UnderlyingType != containerContract.ItemContract.CreatedType) + return true; + } + else if (_rootContract != null && _serializeStack.Count == 1) + { + if (contract.UnderlyingType != _rootContract.CreatedType) + return true; + } + } + + return false; } - else if (_rootContract != null && _serializeStack.Count == 1) + + private void SerializeDictionary(JsonWriter writer, IDictionary values, JsonDictionaryContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) { - if (contract.UnderlyingType != _rootContract.CreatedType) - return true; + IWrappedDictionary wrappedDictionary = values as IWrappedDictionary; + object underlyingDictionary = wrappedDictionary != null ? wrappedDictionary.UnderlyingDictionary : values; + + OnSerializing(writer, contract, underlyingDictionary); + _serializeStack.Add(underlyingDictionary); + + WriteObjectStart(writer, underlyingDictionary, contract, member, collectionContract, containerProperty); + + if (contract.ItemContract == null) + contract.ItemContract = Serializer._contractResolver.ResolveContract(contract.DictionaryValueType ?? typeof(object)); + + if (contract.KeyContract == null) + contract.KeyContract = Serializer._contractResolver.ResolveContract(contract.DictionaryKeyType ?? typeof(object)); + + int initialDepth = writer.Top; + + foreach (DictionaryEntry entry in values) + { + bool escape; + string propertyName = GetPropertyName(writer, entry.Key, contract.KeyContract, out escape); + + propertyName = (contract.PropertyNameResolver != null) + ? contract.PropertyNameResolver(propertyName) + : propertyName; + + try + { + object value = entry.Value; + JsonContract valueContract = contract.FinalItemContract ?? GetContractSafe(value); + + if (ShouldWriteReference(value, null, valueContract, contract, member)) + { + writer.WritePropertyName(propertyName, escape); + WriteReference(writer, value); + } + else + { + if (!CheckForCircularReference(writer, value, null, valueContract, contract, member)) + continue; + + writer.WritePropertyName(propertyName, escape); + + SerializeValue(writer, value, valueContract, null, contract, member); + } + } + catch (Exception ex) + { + if (IsErrorHandled(underlyingDictionary, contract, propertyName, null, writer.ContainerPath, ex)) + HandleError(writer, initialDepth); + else + throw; + } + } + + writer.WriteEndObject(); + + _serializeStack.RemoveAt(_serializeStack.Count - 1); + + OnSerialized(writer, contract, underlyingDictionary); } - } - return false; - } - - private void SerializeDictionary(JsonWriter writer, IDictionary values, JsonDictionaryContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) - { - IWrappedDictionary wrappedDictionary = values as IWrappedDictionary; - object underlyingDictionary = wrappedDictionary != null ? wrappedDictionary.UnderlyingDictionary : values; - - OnSerializing(writer, contract, underlyingDictionary); - _serializeStack.Add(underlyingDictionary); - - WriteObjectStart(writer, underlyingDictionary, contract, member, collectionContract, containerProperty); - - if (contract.ItemContract == null) - contract.ItemContract = Serializer._contractResolver.ResolveContract(contract.DictionaryValueType ?? typeof(object)); - - if (contract.KeyContract == null) - contract.KeyContract = Serializer._contractResolver.ResolveContract(contract.DictionaryKeyType ?? typeof(object)); - - int initialDepth = writer.Top; - - foreach (DictionaryEntry entry in values) - { - bool escape; - string propertyName = GetPropertyName(writer, entry.Key, contract.KeyContract, out escape); - - propertyName = (contract.PropertyNameResolver != null) - ? contract.PropertyNameResolver(propertyName) - : propertyName; - - try + private string GetPropertyName(JsonWriter writer, object name, JsonContract contract, out bool escape) { - object value = entry.Value; - JsonContract valueContract = contract.FinalItemContract ?? GetContractSafe(value); + string propertyName; - if (ShouldWriteReference(value, null, valueContract, contract, member)) - { - writer.WritePropertyName(propertyName, escape); - WriteReference(writer, value); - } - else - { - if (!CheckForCircularReference(writer, value, null, valueContract, contract, member)) - continue; - - writer.WritePropertyName(propertyName, escape); - - SerializeValue(writer, value, valueContract, null, contract, member); - } - } - catch (Exception ex) - { - if (IsErrorHandled(underlyingDictionary, contract, propertyName, null, writer.ContainerPath, ex)) - HandleError(writer, initialDepth); - else - throw; - } - } - - writer.WriteEndObject(); - - _serializeStack.RemoveAt(_serializeStack.Count - 1); - - OnSerialized(writer, contract, underlyingDictionary); - } - - private string GetPropertyName(JsonWriter writer, object name, JsonContract contract, out bool escape) - { - string propertyName; - - if (contract.ContractType == JsonContractType.Primitive) - { - JsonPrimitiveContract primitiveContract = (JsonPrimitiveContract)contract; - if (primitiveContract.TypeCode == PrimitiveTypeCode.DateTime || primitiveContract.TypeCode == PrimitiveTypeCode.DateTimeNullable) - { - escape = false; - StringWriter sw = new StringWriter(CultureInfo.InvariantCulture); - DateTimeUtils.WriteDateTimeString(sw, (DateTime)name, writer.DateFormatHandling, writer.DateFormatString, writer.Culture); - return sw.ToString(); - } + if (contract.ContractType == JsonContractType.Primitive) + { + JsonPrimitiveContract primitiveContract = (JsonPrimitiveContract)contract; + if (primitiveContract.TypeCode == PrimitiveTypeCode.DateTime || primitiveContract.TypeCode == PrimitiveTypeCode.DateTimeNullable) + { + escape = false; + StringWriter sw = new StringWriter(CultureInfo.InvariantCulture); + DateTimeUtils.WriteDateTimeString(sw, (DateTime)name, writer.DateFormatHandling, writer.DateFormatString, writer.Culture); + return sw.ToString(); + } #if !NET20 - else if (primitiveContract.TypeCode == PrimitiveTypeCode.DateTimeOffset || primitiveContract.TypeCode == PrimitiveTypeCode.DateTimeOffsetNullable) - { - escape = false; - StringWriter sw = new StringWriter(CultureInfo.InvariantCulture); - DateTimeUtils.WriteDateTimeOffsetString(sw, (DateTimeOffset)name, writer.DateFormatHandling, writer.DateFormatString, writer.Culture); - return sw.ToString(); - } + else if (primitiveContract.TypeCode == PrimitiveTypeCode.DateTimeOffset || primitiveContract.TypeCode == PrimitiveTypeCode.DateTimeOffsetNullable) + { + escape = false; + StringWriter sw = new StringWriter(CultureInfo.InvariantCulture); + DateTimeUtils.WriteDateTimeOffsetString(sw, (DateTimeOffset)name, writer.DateFormatHandling, writer.DateFormatString, writer.Culture); + return sw.ToString(); + } #endif - else + else + { + escape = true; + return Convert.ToString(name, CultureInfo.InvariantCulture); + } + } + else if (TryConvertToString(name, name.GetType(), out propertyName)) + { + escape = true; + return propertyName; + } + else + { + escape = true; + return name.ToString(); + } + } + + private void HandleError(JsonWriter writer, int initialDepth) { - escape = true; - return Convert.ToString(name, CultureInfo.InvariantCulture); + ClearErrorContext(); + + if (writer.WriteState == WriteState.Property) + writer.WriteNull(); + + while (writer.Top > initialDepth) + { + writer.WriteEnd(); + } + } + + private bool ShouldSerialize(JsonWriter writer, JsonProperty property, object target) + { + if (property.ShouldSerialize == null) + return true; + + 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(JsonWriter writer, JsonProperty property, object target) + { + if (property.GetIsSpecified == null) + return true; + + 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; } - } - else if (TryConvertToString(name, name.GetType(), out propertyName)) - { - escape = true; - return propertyName; - } - else - { - escape = true; - return name.ToString(); - } } - - private void HandleError(JsonWriter writer, int initialDepth) - { - ClearErrorContext(); - - if (writer.WriteState == WriteState.Property) - writer.WriteNull(); - - while (writer.Top > initialDepth) - { - writer.WriteEnd(); - } - } - - private bool ShouldSerialize(JsonWriter writer, JsonProperty property, object target) - { - if (property.ShouldSerialize == null) - return true; - - 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(JsonWriter writer, JsonProperty property, object target) - { - if (property.GetIsSpecified == null) - return true; - - 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 diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerProxy.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerProxy.cs index 6d1e1566..f42600af 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonSerializerProxy.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerProxy.cs @@ -31,219 +31,219 @@ using System.Runtime.Serialization; namespace Newtonsoft.Json.Serialization { - internal class JsonSerializerProxy : JsonSerializer - { - private readonly JsonSerializerInternalReader _serializerReader; - private readonly JsonSerializerInternalWriter _serializerWriter; - private readonly JsonSerializer _serializer; - - public override event EventHandler Error + internal class JsonSerializerProxy : JsonSerializer { - add { _serializer.Error += value; } - remove { _serializer.Error -= value; } + private readonly JsonSerializerInternalReader _serializerReader; + private readonly JsonSerializerInternalWriter _serializerWriter; + private readonly JsonSerializer _serializer; + + public override event EventHandler Error + { + add { _serializer.Error += value; } + remove { _serializer.Error -= value; } + } + + public override IReferenceResolver ReferenceResolver + { + get { return _serializer.ReferenceResolver; } + set { _serializer.ReferenceResolver = value; } + } + + public override ITraceWriter TraceWriter + { + get { return _serializer.TraceWriter; } + set { _serializer.TraceWriter = value; } + } + + public override JsonConverterCollection Converters + { + get { return _serializer.Converters; } + } + + public override DefaultValueHandling DefaultValueHandling + { + get { return _serializer.DefaultValueHandling; } + set { _serializer.DefaultValueHandling = value; } + } + + public override IContractResolver ContractResolver + { + get { return _serializer.ContractResolver; } + set { _serializer.ContractResolver = value; } + } + + public override MissingMemberHandling MissingMemberHandling + { + get { return _serializer.MissingMemberHandling; } + set { _serializer.MissingMemberHandling = value; } + } + + public override NullValueHandling NullValueHandling + { + get { return _serializer.NullValueHandling; } + set { _serializer.NullValueHandling = value; } + } + + public override ObjectCreationHandling ObjectCreationHandling + { + get { return _serializer.ObjectCreationHandling; } + set { _serializer.ObjectCreationHandling = value; } + } + + public override ReferenceLoopHandling ReferenceLoopHandling + { + get { return _serializer.ReferenceLoopHandling; } + set { _serializer.ReferenceLoopHandling = value; } + } + + public override PreserveReferencesHandling PreserveReferencesHandling + { + get { return _serializer.PreserveReferencesHandling; } + set { _serializer.PreserveReferencesHandling = value; } + } + + public override TypeNameHandling TypeNameHandling + { + get { return _serializer.TypeNameHandling; } + set { _serializer.TypeNameHandling = value; } + } + + public override FormatterAssemblyStyle TypeNameAssemblyFormat + { + get { return _serializer.TypeNameAssemblyFormat; } + set { _serializer.TypeNameAssemblyFormat = value; } + } + + public override ConstructorHandling ConstructorHandling + { + get { return _serializer.ConstructorHandling; } + set { _serializer.ConstructorHandling = value; } + } + + public override SerializationBinder Binder + { + get { return _serializer.Binder; } + set { _serializer.Binder = value; } + } + + public override StreamingContext Context + { + get { return _serializer.Context; } + set { _serializer.Context = value; } + } + + public override Formatting Formatting + { + get { return _serializer.Formatting; } + set { _serializer.Formatting = value; } + } + + public override DateFormatHandling DateFormatHandling + { + get { return _serializer.DateFormatHandling; } + set { _serializer.DateFormatHandling = value; } + } + + public override DateTimeZoneHandling DateTimeZoneHandling + { + get { return _serializer.DateTimeZoneHandling; } + set { _serializer.DateTimeZoneHandling = value; } + } + + public override DateParseHandling DateParseHandling + { + get { return _serializer.DateParseHandling; } + set { _serializer.DateParseHandling = value; } + } + + public override FloatFormatHandling FloatFormatHandling + { + get { return _serializer.FloatFormatHandling; } + set { _serializer.FloatFormatHandling = value; } + } + + public override FloatParseHandling FloatParseHandling + { + get { return _serializer.FloatParseHandling; } + set { _serializer.FloatParseHandling = value; } + } + + public override StringEscapeHandling StringEscapeHandling + { + get { return _serializer.StringEscapeHandling; } + set { _serializer.StringEscapeHandling = value; } + } + + public override string DateFormatString + { + get { return _serializer.DateFormatString; } + set { _serializer.DateFormatString = value; } + } + + public override CultureInfo Culture + { + get { return _serializer.Culture; } + set { _serializer.Culture = value; } + } + + public override int? MaxDepth + { + get { return _serializer.MaxDepth; } + set { _serializer.MaxDepth = value; } + } + + public override bool CheckAdditionalContent + { + get { return _serializer.CheckAdditionalContent; } + set { _serializer.CheckAdditionalContent = value; } + } + + internal JsonSerializerInternalBase GetInternalSerializer() + { + if (_serializerReader != null) + return _serializerReader; + else + return _serializerWriter; + } + + public JsonSerializerProxy(JsonSerializerInternalReader serializerReader) + { + ValidationUtils.ArgumentNotNull(serializerReader, "serializerReader"); + + _serializerReader = serializerReader; + _serializer = serializerReader.Serializer; + } + + public JsonSerializerProxy(JsonSerializerInternalWriter serializerWriter) + { + ValidationUtils.ArgumentNotNull(serializerWriter, "serializerWriter"); + + _serializerWriter = serializerWriter; + _serializer = serializerWriter.Serializer; + } + + internal override object DeserializeInternal(JsonReader reader, Type objectType) + { + if (_serializerReader != null) + return _serializerReader.Deserialize(reader, objectType, false); + else + return _serializer.Deserialize(reader, objectType); + } + + internal override void PopulateInternal(JsonReader reader, object target) + { + if (_serializerReader != null) + _serializerReader.Populate(reader, target); + else + _serializer.Populate(reader, target); + } + + internal override void SerializeInternal(JsonWriter jsonWriter, object value, Type rootType) + { + if (_serializerWriter != null) + _serializerWriter.Serialize(jsonWriter, value, rootType); + else + _serializer.Serialize(jsonWriter, value); + } } - - public override IReferenceResolver ReferenceResolver - { - get { return _serializer.ReferenceResolver; } - set { _serializer.ReferenceResolver = value; } - } - - public override ITraceWriter TraceWriter - { - get { return _serializer.TraceWriter; } - set { _serializer.TraceWriter = value; } - } - - public override JsonConverterCollection Converters - { - get { return _serializer.Converters; } - } - - public override DefaultValueHandling DefaultValueHandling - { - get { return _serializer.DefaultValueHandling; } - set { _serializer.DefaultValueHandling = value; } - } - - public override IContractResolver ContractResolver - { - get { return _serializer.ContractResolver; } - set { _serializer.ContractResolver = value; } - } - - public override MissingMemberHandling MissingMemberHandling - { - get { return _serializer.MissingMemberHandling; } - set { _serializer.MissingMemberHandling = value; } - } - - public override NullValueHandling NullValueHandling - { - get { return _serializer.NullValueHandling; } - set { _serializer.NullValueHandling = value; } - } - - public override ObjectCreationHandling ObjectCreationHandling - { - get { return _serializer.ObjectCreationHandling; } - set { _serializer.ObjectCreationHandling = value; } - } - - public override ReferenceLoopHandling ReferenceLoopHandling - { - get { return _serializer.ReferenceLoopHandling; } - set { _serializer.ReferenceLoopHandling = value; } - } - - public override PreserveReferencesHandling PreserveReferencesHandling - { - get { return _serializer.PreserveReferencesHandling; } - set { _serializer.PreserveReferencesHandling = value; } - } - - public override TypeNameHandling TypeNameHandling - { - get { return _serializer.TypeNameHandling; } - set { _serializer.TypeNameHandling = value; } - } - - public override FormatterAssemblyStyle TypeNameAssemblyFormat - { - get { return _serializer.TypeNameAssemblyFormat; } - set { _serializer.TypeNameAssemblyFormat = value; } - } - - public override ConstructorHandling ConstructorHandling - { - get { return _serializer.ConstructorHandling; } - set { _serializer.ConstructorHandling = value; } - } - - public override SerializationBinder Binder - { - get { return _serializer.Binder; } - set { _serializer.Binder = value; } - } - - public override StreamingContext Context - { - get { return _serializer.Context; } - set { _serializer.Context = value; } - } - - public override Formatting Formatting - { - get { return _serializer.Formatting; } - set { _serializer.Formatting = value; } - } - - public override DateFormatHandling DateFormatHandling - { - get { return _serializer.DateFormatHandling; } - set { _serializer.DateFormatHandling = value; } - } - - public override DateTimeZoneHandling DateTimeZoneHandling - { - get { return _serializer.DateTimeZoneHandling; } - set { _serializer.DateTimeZoneHandling = value; } - } - - public override DateParseHandling DateParseHandling - { - get { return _serializer.DateParseHandling; } - set { _serializer.DateParseHandling = value; } - } - - public override FloatFormatHandling FloatFormatHandling - { - get { return _serializer.FloatFormatHandling; } - set { _serializer.FloatFormatHandling = value; } - } - - public override FloatParseHandling FloatParseHandling - { - get { return _serializer.FloatParseHandling; } - set { _serializer.FloatParseHandling = value; } - } - - public override StringEscapeHandling StringEscapeHandling - { - get { return _serializer.StringEscapeHandling; } - set { _serializer.StringEscapeHandling = value; } - } - - public override string DateFormatString - { - get { return _serializer.DateFormatString; } - set { _serializer.DateFormatString = value; } - } - - public override CultureInfo Culture - { - get { return _serializer.Culture; } - set { _serializer.Culture = value; } - } - - public override int? MaxDepth - { - get { return _serializer.MaxDepth; } - set { _serializer.MaxDepth = value; } - } - - public override bool CheckAdditionalContent - { - get { return _serializer.CheckAdditionalContent; } - set { _serializer.CheckAdditionalContent = value; } - } - - internal JsonSerializerInternalBase GetInternalSerializer() - { - if (_serializerReader != null) - return _serializerReader; - else - return _serializerWriter; - } - - public JsonSerializerProxy(JsonSerializerInternalReader serializerReader) - { - ValidationUtils.ArgumentNotNull(serializerReader, "serializerReader"); - - _serializerReader = serializerReader; - _serializer = serializerReader.Serializer; - } - - public JsonSerializerProxy(JsonSerializerInternalWriter serializerWriter) - { - ValidationUtils.ArgumentNotNull(serializerWriter, "serializerWriter"); - - _serializerWriter = serializerWriter; - _serializer = serializerWriter.Serializer; - } - - internal override object DeserializeInternal(JsonReader reader, Type objectType) - { - if (_serializerReader != null) - return _serializerReader.Deserialize(reader, objectType, false); - else - return _serializer.Deserialize(reader, objectType); - } - - internal override void PopulateInternal(JsonReader reader, object target) - { - if (_serializerReader != null) - _serializerReader.Populate(reader, target); - else - _serializer.Populate(reader, target); - } - - internal override void SerializeInternal(JsonWriter jsonWriter, object value, Type rootType) - { - if (_serializerWriter != null) - _serializerWriter.Serialize(jsonWriter, value, rootType); - else - _serializer.Serialize(jsonWriter, value); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/JsonStringContract.cs b/Src/Newtonsoft.Json/Serialization/JsonStringContract.cs index 3668ab4b..be096bc5 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonStringContract.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonStringContract.cs @@ -27,19 +27,19 @@ using System; namespace Newtonsoft.Json.Serialization { - /// - /// Contract details for a used by the . - /// - public class JsonStringContract : JsonPrimitiveContract - { /// - /// Initializes a new instance of the class. + /// Contract details for a used by the . /// - /// The underlying type for the contract. - public JsonStringContract(Type underlyingType) - : base(underlyingType) + public class JsonStringContract : JsonPrimitiveContract { - ContractType = JsonContractType.String; + /// + /// Initializes a new instance of the class. + /// + /// The underlying type for the contract. + public JsonStringContract(Type underlyingType) + : base(underlyingType) + { + ContractType = JsonContractType.String; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs b/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs index ec55e700..bbea6cc4 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs @@ -42,33 +42,34 @@ using System.Runtime.Serialization; namespace Newtonsoft.Json.Serialization { #if !SILVERLIGHT && !NET20 && !NETFX_CORE - internal interface IMetadataTypeAttribute - { - Type MetadataClassType { get; } - } + internal interface IMetadataTypeAttribute + { + Type MetadataClassType { get; } + } #endif - internal static class JsonTypeReflector - { - private static bool? _dynamicCodeGeneration; - private static bool? _fullyTrusted; + internal static class JsonTypeReflector + { + private static bool? _dynamicCodeGeneration; + private static bool? _fullyTrusted; - public const string IdPropertyName = "$id"; - public const string RefPropertyName = "$ref"; - public const string TypePropertyName = "$type"; - public const string ValuePropertyName = "$value"; - public const string ArrayValuesPropertyName = "$values"; + public const string IdPropertyName = "$id"; + public const string RefPropertyName = "$ref"; + public const string TypePropertyName = "$type"; + public const string ValuePropertyName = "$value"; + public const string ArrayValuesPropertyName = "$values"; - public const string ShouldSerializePrefix = "ShouldSerialize"; - public const string SpecifiedPostfix = "Specified"; + public const string ShouldSerializePrefix = "ShouldSerialize"; + public const string SpecifiedPostfix = "Specified"; - private static readonly ThreadSafeStore JsonConverterTypeCache = new ThreadSafeStore(GetJsonConverterTypeFromAttribute); + private static readonly ThreadSafeStore JsonConverterTypeCache = new ThreadSafeStore(GetJsonConverterTypeFromAttribute); #if !(SILVERLIGHT || NET20 || NETFX_CORE || PORTABLE40 || PORTABLE) - private static readonly ThreadSafeStore AssociatedMetadataTypesCache = new ThreadSafeStore(GetAssociateMetadataTypeFromAttribute); + private static readonly ThreadSafeStore AssociatedMetadataTypesCache = new ThreadSafeStore(GetAssociateMetadataTypeFromAttribute); - private const string MetadataTypeAttributeTypeName = - "System.ComponentModel.DataAnnotations.MetadataTypeAttribute, System.ComponentModel.DataAnnotations, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; - private static Type _cachedMetadataTypeAttributeType; + private const string MetadataTypeAttributeTypeName = + "System.ComponentModel.DataAnnotations.MetadataTypeAttribute, System.ComponentModel.DataAnnotations, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; + + private static Type _cachedMetadataTypeAttributeType; #endif #if SILVERLIGHT private static readonly ThreadSafeStore TypeConverterTypeCache = new ThreadSafeStore(GetTypeConverterTypeFromAttribute); @@ -88,140 +89,140 @@ namespace Newtonsoft.Json.Serialization } #endif - public static JsonContainerAttribute GetJsonContainerAttribute(Type type) - { - return CachedAttributeGetter.GetAttribute(type); - } + public static JsonContainerAttribute GetJsonContainerAttribute(Type type) + { + return CachedAttributeGetter.GetAttribute(type); + } - public static JsonObjectAttribute GetJsonObjectAttribute(Type type) - { - return GetJsonContainerAttribute(type) as JsonObjectAttribute; - } + public static JsonObjectAttribute GetJsonObjectAttribute(Type type) + { + return GetJsonContainerAttribute(type) as JsonObjectAttribute; + } - public static JsonArrayAttribute GetJsonArrayAttribute(Type type) - { - return GetJsonContainerAttribute(type) as JsonArrayAttribute; - } + public static JsonArrayAttribute GetJsonArrayAttribute(Type type) + { + return GetJsonContainerAttribute(type) as JsonArrayAttribute; + } - public static JsonDictionaryAttribute GetJsonDictionaryAttribute(Type type) - { - return GetJsonContainerAttribute(type) as JsonDictionaryAttribute; - } + public static JsonDictionaryAttribute GetJsonDictionaryAttribute(Type type) + { + return GetJsonContainerAttribute(type) as JsonDictionaryAttribute; + } #if !(SILVERLIGHT || NETFX_CORE || PORTABLE || PORTABLE40) - public static SerializableAttribute GetSerializableAttribute(Type type) - { - return CachedAttributeGetter.GetAttribute(type); - } -#endif - -#if !NET20 - public static DataContractAttribute GetDataContractAttribute(Type type) - { - // DataContractAttribute does not have inheritance - Type currentType = type; - - while (currentType != null) - { - DataContractAttribute result = CachedAttributeGetter.GetAttribute(currentType); - if (result != null) - return result; - - currentType = currentType.BaseType(); - } - - return null; - } - - public static DataMemberAttribute GetDataMemberAttribute(MemberInfo memberInfo) - { - // DataMemberAttribute does not have inheritance - - // can't override a field - if (memberInfo.MemberType() == MemberTypes.Field) - return CachedAttributeGetter.GetAttribute(memberInfo); - - // search property and then search base properties if nothing is returned and the property is virtual - PropertyInfo propertyInfo = (PropertyInfo)memberInfo; - DataMemberAttribute result = CachedAttributeGetter.GetAttribute(propertyInfo); - if (result == null) - { - if (propertyInfo.IsVirtual()) + public static SerializableAttribute GetSerializableAttribute(Type type) { - Type currentType = propertyInfo.DeclaringType; - - while (result == null && currentType != null) - { - PropertyInfo baseProperty = (PropertyInfo)ReflectionUtils.GetMemberInfoFromType(currentType, propertyInfo); - if (baseProperty != null && baseProperty.IsVirtual()) - result = CachedAttributeGetter.GetAttribute(baseProperty); - - currentType = currentType.BaseType(); - } + return CachedAttributeGetter.GetAttribute(type); } - } - - return result; - } #endif - public static MemberSerialization GetObjectMemberSerialization(Type objectType, bool ignoreSerializableAttribute) - { - JsonObjectAttribute objectAttribute = GetJsonObjectAttribute(objectType); - if (objectAttribute != null) - return objectAttribute.MemberSerialization; +#if !NET20 + public static DataContractAttribute GetDataContractAttribute(Type type) + { + // DataContractAttribute does not have inheritance + Type currentType = type; + + while (currentType != null) + { + DataContractAttribute result = CachedAttributeGetter.GetAttribute(currentType); + if (result != null) + return result; + + currentType = currentType.BaseType(); + } + + return null; + } + + public static DataMemberAttribute GetDataMemberAttribute(MemberInfo memberInfo) + { + // DataMemberAttribute does not have inheritance + + // can't override a field + if (memberInfo.MemberType() == MemberTypes.Field) + return CachedAttributeGetter.GetAttribute(memberInfo); + + // search property and then search base properties if nothing is returned and the property is virtual + PropertyInfo propertyInfo = (PropertyInfo)memberInfo; + DataMemberAttribute result = CachedAttributeGetter.GetAttribute(propertyInfo); + if (result == null) + { + if (propertyInfo.IsVirtual()) + { + Type currentType = propertyInfo.DeclaringType; + + while (result == null && currentType != null) + { + PropertyInfo baseProperty = (PropertyInfo)ReflectionUtils.GetMemberInfoFromType(currentType, propertyInfo); + if (baseProperty != null && baseProperty.IsVirtual()) + result = CachedAttributeGetter.GetAttribute(baseProperty); + + currentType = currentType.BaseType(); + } + } + } + + return result; + } +#endif + + public static MemberSerialization GetObjectMemberSerialization(Type objectType, bool ignoreSerializableAttribute) + { + JsonObjectAttribute objectAttribute = GetJsonObjectAttribute(objectType); + if (objectAttribute != null) + return objectAttribute.MemberSerialization; #if !NET20 - DataContractAttribute dataContractAttribute = GetDataContractAttribute(objectType); - if (dataContractAttribute != null) - return MemberSerialization.OptIn; + DataContractAttribute dataContractAttribute = GetDataContractAttribute(objectType); + if (dataContractAttribute != null) + return MemberSerialization.OptIn; #endif #if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) - if (!ignoreSerializableAttribute) - { - SerializableAttribute serializableAttribute = GetSerializableAttribute(objectType); - if (serializableAttribute != null) - return MemberSerialization.Fields; - } + if (!ignoreSerializableAttribute) + { + SerializableAttribute serializableAttribute = GetSerializableAttribute(objectType); + if (serializableAttribute != null) + return MemberSerialization.Fields; + } #endif - // the default - return MemberSerialization.OptOut; - } + // the default + return MemberSerialization.OptOut; + } - private static Type GetJsonConverterType(object attributeProvider) - { - return JsonConverterTypeCache.Get(attributeProvider); - } + private static Type GetJsonConverterType(object attributeProvider) + { + return JsonConverterTypeCache.Get(attributeProvider); + } - private static Type GetJsonConverterTypeFromAttribute(object attributeProvider) - { - JsonConverterAttribute converterAttribute = GetAttribute(attributeProvider); - return (converterAttribute != null) - ? converterAttribute.ConverterType - : null; - } + private static Type GetJsonConverterTypeFromAttribute(object attributeProvider) + { + JsonConverterAttribute converterAttribute = GetAttribute(attributeProvider); + return (converterAttribute != null) + ? converterAttribute.ConverterType + : null; + } - public static JsonConverter GetJsonConverter(object attributeProvider, Type targetConvertedType) - { - Type converterType = GetJsonConverterType(attributeProvider); + public static JsonConverter GetJsonConverter(object attributeProvider, Type targetConvertedType) + { + Type converterType = GetJsonConverterType(attributeProvider); - if (converterType != null) - { - JsonConverter memberConverter = JsonConverterAttribute.CreateJsonConverterInstance(converterType); + if (converterType != null) + { + JsonConverter memberConverter = JsonConverterAttribute.CreateJsonConverterInstance(converterType); - return memberConverter; - } + return memberConverter; + } - return null; - } + return null; + } #if !(NETFX_CORE || PORTABLE40 || PORTABLE) - public static TypeConverter GetTypeConverter(Type type) - { + public static TypeConverter GetTypeConverter(Type type) + { #if !SILVERLIGHT - return TypeDescriptor.GetConverter(type); + return TypeDescriptor.GetConverter(type); #else Type converterType = GetTypeConverterType(type); @@ -230,188 +231,188 @@ namespace Newtonsoft.Json.Serialization return null; #endif - } -#endif - -#if !(SILVERLIGHT || NET20 || NETFX_CORE || PORTABLE40 || PORTABLE) - private static Type GetAssociatedMetadataType(Type type) - { - return AssociatedMetadataTypesCache.Get(type); - } - - private static Type GetAssociateMetadataTypeFromAttribute(Type type) - { - Type metadataTypeAttributeType = GetMetadataTypeAttributeType(); - if (metadataTypeAttributeType == null) - return null; - - object attribute = type.GetCustomAttributes(metadataTypeAttributeType, true).SingleOrDefault(); - if (attribute == null) - return null; - - IMetadataTypeAttribute metadataTypeAttribute = (DynamicCodeGeneration) - ? DynamicWrapper.CreateWrapper(attribute) - : new LateBoundMetadataTypeAttribute(attribute); - - return metadataTypeAttribute.MetadataClassType; - } - - private static Type GetMetadataTypeAttributeType() - { - // always attempt to get the metadata type attribute type - // the assembly may have been loaded since last time - if (_cachedMetadataTypeAttributeType == null) - { - Type metadataTypeAttributeType = Type.GetType(MetadataTypeAttributeTypeName); - - if (metadataTypeAttributeType != null) - _cachedMetadataTypeAttributeType = metadataTypeAttributeType; - else - return null; - } - - return _cachedMetadataTypeAttributeType; - } -#endif - - private static T GetAttribute(Type type) where T : Attribute - { - T attribute; - -#if !(SILVERLIGHT || NET20 || NETFX_CORE || PORTABLE40 || PORTABLE) - Type metadataType = GetAssociatedMetadataType(type); - if (metadataType != null) - { - attribute = ReflectionUtils.GetAttribute(metadataType, true); - if (attribute != null) - return attribute; - } -#endif - - attribute = ReflectionUtils.GetAttribute(type, true); - if (attribute != null) - return attribute; - - foreach (Type typeInterface in type.GetInterfaces()) - { - attribute = ReflectionUtils.GetAttribute(typeInterface, true); - if (attribute != null) - return attribute; - } - - return null; - } - - private static T GetAttribute(MemberInfo memberInfo) where T : Attribute - { - T attribute; - -#if !(SILVERLIGHT || NET20 || NETFX_CORE || PORTABLE40 || PORTABLE) - Type metadataType = GetAssociatedMetadataType(memberInfo.DeclaringType); - if (metadataType != null) - { - MemberInfo metadataTypeMemberInfo = ReflectionUtils.GetMemberInfoFromType(metadataType, memberInfo); - - if (metadataTypeMemberInfo != null) - { - attribute = ReflectionUtils.GetAttribute(metadataTypeMemberInfo, true); - if (attribute != null) - return attribute; } - } #endif - attribute = ReflectionUtils.GetAttribute(memberInfo, true); - if (attribute != null) - return attribute; - - if (memberInfo.DeclaringType != null) - { - foreach (Type typeInterface in memberInfo.DeclaringType.GetInterfaces()) +#if !(SILVERLIGHT || NET20 || NETFX_CORE || PORTABLE40 || PORTABLE) + private static Type GetAssociatedMetadataType(Type type) { - MemberInfo interfaceTypeMemberInfo = ReflectionUtils.GetMemberInfoFromType(typeInterface, memberInfo); + return AssociatedMetadataTypesCache.Get(type); + } - if (interfaceTypeMemberInfo != null) - { - attribute = ReflectionUtils.GetAttribute(interfaceTypeMemberInfo, true); + private static Type GetAssociateMetadataTypeFromAttribute(Type type) + { + Type metadataTypeAttributeType = GetMetadataTypeAttributeType(); + if (metadataTypeAttributeType == null) + return null; + + object attribute = type.GetCustomAttributes(metadataTypeAttributeType, true).SingleOrDefault(); + if (attribute == null) + return null; + + IMetadataTypeAttribute metadataTypeAttribute = (DynamicCodeGeneration) + ? DynamicWrapper.CreateWrapper(attribute) + : new LateBoundMetadataTypeAttribute(attribute); + + return metadataTypeAttribute.MetadataClassType; + } + + private static Type GetMetadataTypeAttributeType() + { + // always attempt to get the metadata type attribute type + // the assembly may have been loaded since last time + if (_cachedMetadataTypeAttributeType == null) + { + Type metadataTypeAttributeType = Type.GetType(MetadataTypeAttributeTypeName); + + if (metadataTypeAttributeType != null) + _cachedMetadataTypeAttributeType = metadataTypeAttributeType; + else + return null; + } + + return _cachedMetadataTypeAttributeType; + } +#endif + + private static T GetAttribute(Type type) where T : Attribute + { + T attribute; + +#if !(SILVERLIGHT || NET20 || NETFX_CORE || PORTABLE40 || PORTABLE) + Type metadataType = GetAssociatedMetadataType(type); + if (metadataType != null) + { + attribute = ReflectionUtils.GetAttribute(metadataType, true); + if (attribute != null) + return attribute; + } +#endif + + attribute = ReflectionUtils.GetAttribute(type, true); if (attribute != null) - return attribute; - } + return attribute; + + foreach (Type typeInterface in type.GetInterfaces()) + { + attribute = ReflectionUtils.GetAttribute(typeInterface, true); + if (attribute != null) + return attribute; + } + + return null; } - } - return null; - } + private static T GetAttribute(MemberInfo memberInfo) where T : Attribute + { + T attribute; - public static T GetAttribute(object provider) where T : Attribute - { - Type type = provider as Type; - if (type != null) - return GetAttribute(type); +#if !(SILVERLIGHT || NET20 || NETFX_CORE || PORTABLE40 || PORTABLE) + Type metadataType = GetAssociatedMetadataType(memberInfo.DeclaringType); + if (metadataType != null) + { + MemberInfo metadataTypeMemberInfo = ReflectionUtils.GetMemberInfoFromType(metadataType, memberInfo); - MemberInfo memberInfo = provider as MemberInfo; - if (memberInfo != null) - return GetAttribute(memberInfo); + if (metadataTypeMemberInfo != null) + { + attribute = ReflectionUtils.GetAttribute(metadataTypeMemberInfo, true); + if (attribute != null) + return attribute; + } + } +#endif - return ReflectionUtils.GetAttribute(provider, true); - } + attribute = ReflectionUtils.GetAttribute(memberInfo, true); + if (attribute != null) + return attribute; + + if (memberInfo.DeclaringType != null) + { + foreach (Type typeInterface in memberInfo.DeclaringType.GetInterfaces()) + { + MemberInfo interfaceTypeMemberInfo = ReflectionUtils.GetMemberInfoFromType(typeInterface, memberInfo); + + if (interfaceTypeMemberInfo != null) + { + attribute = ReflectionUtils.GetAttribute(interfaceTypeMemberInfo, true); + if (attribute != null) + return attribute; + } + } + } + + return null; + } + + public static T GetAttribute(object provider) where T : Attribute + { + Type type = provider as Type; + if (type != null) + return GetAttribute(type); + + MemberInfo memberInfo = provider as MemberInfo; + if (memberInfo != null) + return GetAttribute(memberInfo); + + return ReflectionUtils.GetAttribute(provider, true); + } #if DEBUG - internal static void SetFullyTrusted(bool fullyTrusted) - { - _fullyTrusted = fullyTrusted; - } - - internal static void SetDynamicCodeGeneration(bool dynamicCodeGeneration) - { - _dynamicCodeGeneration = dynamicCodeGeneration; - } -#endif - - public static bool DynamicCodeGeneration - { -#if !(NET20 || NET35 || SILVERLIGHT || NETFX_CORE || PORTABLE) - [SecuritySafeCritical] -#endif - get - { - if (_dynamicCodeGeneration == null) + internal static void SetFullyTrusted(bool fullyTrusted) { -#if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) - try - { - new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand(); - new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess).Demand(); - new SecurityPermission(SecurityPermissionFlag.SkipVerification).Demand(); - new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); - new SecurityPermission(PermissionState.Unrestricted).Demand(); - _dynamicCodeGeneration = true; - } - catch (Exception) - { - _dynamicCodeGeneration = false; - } -#else - _dynamicCodeGeneration = false; -#endif + _fullyTrusted = fullyTrusted; } - return _dynamicCodeGeneration.Value; - } - } - - public static bool FullyTrusted - { - get - { - if (_fullyTrusted == null) + internal static void SetDynamicCodeGeneration(bool dynamicCodeGeneration) { -#if (NETFX_CORE || SILVERLIGHT || PORTABLE || PORTABLE40) - _fullyTrusted = false; -#elif !(NET20 || NET35 || PORTABLE40) - AppDomain appDomain = AppDomain.CurrentDomain; + _dynamicCodeGeneration = dynamicCodeGeneration; + } +#endif - _fullyTrusted = appDomain.IsHomogenous && appDomain.IsFullyTrusted; + public static bool DynamicCodeGeneration + { +#if !(NET20 || NET35 || SILVERLIGHT || NETFX_CORE || PORTABLE) + [SecuritySafeCritical] +#endif + get + { + if (_dynamicCodeGeneration == null) + { +#if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) + try + { + new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand(); + new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess).Demand(); + new SecurityPermission(SecurityPermissionFlag.SkipVerification).Demand(); + new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); + new SecurityPermission(PermissionState.Unrestricted).Demand(); + _dynamicCodeGeneration = true; + } + catch (Exception) + { + _dynamicCodeGeneration = false; + } +#else + _dynamicCodeGeneration = false; +#endif + } + + return _dynamicCodeGeneration.Value; + } + } + + public static bool FullyTrusted + { + get + { + if (_fullyTrusted == null) + { +#if (NETFX_CORE || SILVERLIGHT || PORTABLE || PORTABLE40) + _fullyTrusted = false; +#elif !(NET20 || NET35 || PORTABLE40) + AppDomain appDomain = AppDomain.CurrentDomain; + + _fullyTrusted = appDomain.IsHomogenous && appDomain.IsFullyTrusted; #else try { @@ -423,27 +424,27 @@ namespace Newtonsoft.Json.Serialization _fullyTrusted = false; } #endif + } + + return _fullyTrusted.Value; + } } - return _fullyTrusted.Value; - } - } - - public static ReflectionDelegateFactory ReflectionDelegateFactory - { - get - { + public static ReflectionDelegateFactory ReflectionDelegateFactory + { + get + { #if !(SILVERLIGHT || PORTABLE40 || PORTABLE || NETFX_CORE) - if (DynamicCodeGeneration) - return DynamicReflectionDelegateFactory.Instance; + if (DynamicCodeGeneration) + return DynamicReflectionDelegateFactory.Instance; - return LateBoundReflectionDelegateFactory.Instance; + return LateBoundReflectionDelegateFactory.Instance; #elif !(PORTABLE40) return ExpressionReflectionDelegateFactory.Instance; #else - return LateBoundReflectionDelegateFactory.Instance; + return LateBoundReflectionDelegateFactory.Instance; #endif - } + } + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/LateBoundMetadataTypeAttribute.cs b/Src/Newtonsoft.Json/Serialization/LateBoundMetadataTypeAttribute.cs index 07cb72f3..8c31d32c 100644 --- a/Src/Newtonsoft.Json/Serialization/LateBoundMetadataTypeAttribute.cs +++ b/Src/Newtonsoft.Json/Serialization/LateBoundMetadataTypeAttribute.cs @@ -33,27 +33,28 @@ using System.Reflection; namespace Newtonsoft.Json.Serialization { - internal class LateBoundMetadataTypeAttribute : IMetadataTypeAttribute - { - private static PropertyInfo _metadataClassTypeProperty; - - private readonly object _attribute; - - public LateBoundMetadataTypeAttribute(object attribute) + internal class LateBoundMetadataTypeAttribute : IMetadataTypeAttribute { - _attribute = attribute; - } + private static PropertyInfo _metadataClassTypeProperty; - public Type MetadataClassType - { - get - { - if (_metadataClassTypeProperty == null) - _metadataClassTypeProperty = _attribute.GetType().GetProperty("MetadataClassType"); + private readonly object _attribute; - return (Type)ReflectionUtils.GetMemberValue(_metadataClassTypeProperty, _attribute); - } + public LateBoundMetadataTypeAttribute(object attribute) + { + _attribute = attribute; + } + + public Type MetadataClassType + { + get + { + if (_metadataClassTypeProperty == null) + _metadataClassTypeProperty = _attribute.GetType().GetProperty("MetadataClassType"); + + return (Type)ReflectionUtils.GetMemberValue(_metadataClassTypeProperty, _attribute); + } + } } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/MemoryTraceWriter.cs b/Src/Newtonsoft.Json/Serialization/MemoryTraceWriter.cs index 0d40ea5a..f8ed8bac 100644 --- a/Src/Newtonsoft.Json/Serialization/MemoryTraceWriter.cs +++ b/Src/Newtonsoft.Json/Serialization/MemoryTraceWriter.cs @@ -6,76 +6,76 @@ using System.Text; namespace Newtonsoft.Json.Serialization { - /// - /// Represents a trace writer that writes to memory. When the trace message limit is - /// reached then old trace messages will be removed as new messages are added. - /// - public class MemoryTraceWriter : ITraceWriter - { - private readonly Queue _traceMessages; - /// - /// Gets the that will be used to filter the trace messages passed to the writer. - /// For example a filter level of Info will exclude Verbose messages and include Info, - /// Warning and Error messages. + /// Represents a trace writer that writes to memory. When the trace message limit is + /// reached then old trace messages will be removed as new messages are added. /// - /// - /// The that will be used to filter the trace messages passed to the writer. - /// - public TraceLevel LevelFilter { get; set; } - - /// - /// Initializes a new instance of the class. - /// - public MemoryTraceWriter() + public class MemoryTraceWriter : ITraceWriter { - LevelFilter = TraceLevel.Verbose; - _traceMessages = new Queue(); + private readonly Queue _traceMessages; + + /// + /// Gets the that will be used to filter the trace messages passed to the writer. + /// For example a filter level of Info will exclude Verbose messages and include Info, + /// Warning and Error messages. + /// + /// + /// The that will be used to filter the trace messages passed to the writer. + /// + public TraceLevel LevelFilter { get; set; } + + /// + /// Initializes a new instance of the class. + /// + public MemoryTraceWriter() + { + LevelFilter = TraceLevel.Verbose; + _traceMessages = new Queue(); + } + + /// + /// Writes the specified trace level, message and optional exception. + /// + /// The at which to write this trace. + /// The trace message. + /// The trace exception. This parameter is optional. + public void Trace(TraceLevel level, string message, Exception ex) + { + string traceMessage = DateTime.Now.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff", CultureInfo.InvariantCulture) + " " + level.ToString("g") + " " + message; + + if (_traceMessages.Count >= 1000) + _traceMessages.Dequeue(); + + _traceMessages.Enqueue(traceMessage); + } + + /// + /// Returns an enumeration of the most recent trace messages. + /// + /// An enumeration of the most recent trace messages. + public IEnumerable GetTraceMessages() + { + return _traceMessages; + } + + /// + /// Returns a of the most recent trace messages. + /// + /// + /// A of the most recent trace messages. + /// + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + foreach (string traceMessage in _traceMessages) + { + if (sb.Length > 0) + sb.AppendLine(); + + sb.Append(traceMessage); + } + + return sb.ToString(); + } } - - /// - /// Writes the specified trace level, message and optional exception. - /// - /// The at which to write this trace. - /// The trace message. - /// The trace exception. This parameter is optional. - public void Trace(TraceLevel level, string message, Exception ex) - { - string traceMessage = DateTime.Now.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff", CultureInfo.InvariantCulture) + " " + level.ToString("g") + " " + message; - - if (_traceMessages.Count >= 1000) - _traceMessages.Dequeue(); - - _traceMessages.Enqueue(traceMessage); - } - - /// - /// Returns an enumeration of the most recent trace messages. - /// - /// An enumeration of the most recent trace messages. - public IEnumerable GetTraceMessages() - { - return _traceMessages; - } - - /// - /// Returns a of the most recent trace messages. - /// - /// - /// A of the most recent trace messages. - /// - public override string ToString() - { - StringBuilder sb = new StringBuilder(); - foreach (string traceMessage in _traceMessages) - { - if (sb.Length > 0) - sb.AppendLine(); - - sb.Append(traceMessage); - } - - return sb.ToString(); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/ObjectConstructor.cs b/Src/Newtonsoft.Json/Serialization/ObjectConstructor.cs index b731707a..380674fe 100644 --- a/Src/Newtonsoft.Json/Serialization/ObjectConstructor.cs +++ b/Src/Newtonsoft.Json/Serialization/ObjectConstructor.cs @@ -25,9 +25,9 @@ namespace Newtonsoft.Json.Serialization { - /// - /// Represents a method that constructs an object. - /// - /// The object type to create. - public delegate object ObjectConstructor(params object[] args); + /// + /// Represents a method that constructs an object. + /// + /// The object type to create. + public delegate object ObjectConstructor(params object[] args); } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/OnErrorAttribute.cs b/Src/Newtonsoft.Json/Serialization/OnErrorAttribute.cs index 73e2df09..cb33296e 100644 --- a/Src/Newtonsoft.Json/Serialization/OnErrorAttribute.cs +++ b/Src/Newtonsoft.Json/Serialization/OnErrorAttribute.cs @@ -27,11 +27,11 @@ using System; namespace Newtonsoft.Json.Serialization { - /// - /// When applied to a method, specifies that the method is called when an error occurs serializing an object. - /// - [AttributeUsage(AttributeTargets.Method, Inherited = false)] - public sealed class OnErrorAttribute : Attribute - { - } + /// + /// When applied to a method, specifies that the method is called when an error occurs serializing an object. + /// + [AttributeUsage(AttributeTargets.Method, Inherited = false)] + public sealed class OnErrorAttribute : Attribute + { + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/ReflectionValueProvider.cs b/Src/Newtonsoft.Json/Serialization/ReflectionValueProvider.cs index 581c3e12..0fcc11ff 100644 --- a/Src/Newtonsoft.Json/Serialization/ReflectionValueProvider.cs +++ b/Src/Newtonsoft.Json/Serialization/ReflectionValueProvider.cs @@ -30,55 +30,55 @@ using System.Globalization; namespace Newtonsoft.Json.Serialization { - /// - /// Get and set values for a using reflection. - /// - public class ReflectionValueProvider : IValueProvider - { - private readonly MemberInfo _memberInfo; - /// - /// Initializes a new instance of the class. + /// Get and set values for a using reflection. /// - /// The member info. - public ReflectionValueProvider(MemberInfo memberInfo) + public class ReflectionValueProvider : IValueProvider { - ValidationUtils.ArgumentNotNull(memberInfo, "memberInfo"); - _memberInfo = memberInfo; - } + private readonly MemberInfo _memberInfo; - /// - /// Sets the value. - /// - /// The target to set the value on. - /// The value to set on the target. - public void SetValue(object target, object value) - { - try - { - ReflectionUtils.SetMemberValue(_memberInfo, target, value); - } - catch (Exception ex) - { - throw new JsonSerializationException("Error setting value to '{0}' on '{1}'.".FormatWith(CultureInfo.InvariantCulture, _memberInfo.Name, target.GetType()), ex); - } - } + /// + /// Initializes a new instance of the class. + /// + /// The member info. + public ReflectionValueProvider(MemberInfo memberInfo) + { + ValidationUtils.ArgumentNotNull(memberInfo, "memberInfo"); + _memberInfo = memberInfo; + } - /// - /// Gets the value. - /// - /// The target to get the value from. - /// The value. - public object GetValue(object target) - { - try - { - return ReflectionUtils.GetMemberValue(_memberInfo, target); - } - catch (Exception ex) - { - throw new JsonSerializationException("Error getting value from '{0}' on '{1}'.".FormatWith(CultureInfo.InvariantCulture, _memberInfo.Name, target.GetType()), ex); - } + /// + /// Sets the value. + /// + /// The target to set the value on. + /// The value to set on the target. + public void SetValue(object target, object value) + { + try + { + ReflectionUtils.SetMemberValue(_memberInfo, target, value); + } + catch (Exception ex) + { + throw new JsonSerializationException("Error setting value to '{0}' on '{1}'.".FormatWith(CultureInfo.InvariantCulture, _memberInfo.Name, target.GetType()), ex); + } + } + + /// + /// Gets the value. + /// + /// The target to get the value from. + /// The value. + public object GetValue(object target) + { + try + { + return ReflectionUtils.GetMemberValue(_memberInfo, target); + } + catch (Exception ex) + { + throw new JsonSerializationException("Error getting value from '{0}' on '{1}'.".FormatWith(CultureInfo.InvariantCulture, _memberInfo.Name, target.GetType()), ex); + } + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/TraceJsonReader.cs b/Src/Newtonsoft.Json/Serialization/TraceJsonReader.cs index b126dafb..4b12c0d5 100644 --- a/Src/Newtonsoft.Json/Serialization/TraceJsonReader.cs +++ b/Src/Newtonsoft.Json/Serialization/TraceJsonReader.cs @@ -6,135 +6,135 @@ 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) + internal class TraceJsonReader : JsonReader, IJsonLineInfo { - _innerReader = innerReader; + private readonly JsonReader _innerReader; + private readonly JsonTextWriter _textWriter; + private readonly StringWriter _sw; - _sw = new StringWriter(CultureInfo.InvariantCulture); - _textWriter = new JsonTextWriter(_sw); - _textWriter.Formatting = Formatting.Indented; - } + public TraceJsonReader(JsonReader innerReader) + { + _innerReader = innerReader; - public string GetJson() - { - return _sw.ToString(); - } + _sw = new StringWriter(CultureInfo.InvariantCulture); + _textWriter = new JsonTextWriter(_sw); + _textWriter.Formatting = Formatting.Indented; + } - public override bool Read() - { - var value = _innerReader.Read(); - _textWriter.WriteToken(_innerReader, false, false); - return value; - } + public string GetJson() + { + return _sw.ToString(); + } - public override int? ReadAsInt32() - { - var value = _innerReader.ReadAsInt32(); - _textWriter.WriteToken(_innerReader, false, false); - return value; - } + public override bool Read() + { + var value = _innerReader.Read(); + _textWriter.WriteToken(_innerReader, false, false); + return value; + } - public override string ReadAsString() - { - var value = _innerReader.ReadAsString(); - _textWriter.WriteToken(_innerReader, false, false); - return value; - } + public override int? ReadAsInt32() + { + var value = _innerReader.ReadAsInt32(); + _textWriter.WriteToken(_innerReader, false, false); + return value; + } - public override byte[] ReadAsBytes() - { - var value = _innerReader.ReadAsBytes(); - _textWriter.WriteToken(_innerReader, false, false); - return value; - } + public override string ReadAsString() + { + var value = _innerReader.ReadAsString(); + _textWriter.WriteToken(_innerReader, false, false); + return value; + } - public override decimal? ReadAsDecimal() - { - var value = _innerReader.ReadAsDecimal(); - _textWriter.WriteToken(_innerReader, false, false); - return value; - } + public override byte[] ReadAsBytes() + { + var value = _innerReader.ReadAsBytes(); + _textWriter.WriteToken(_innerReader, false, false); + return value; + } - public override DateTime? ReadAsDateTime() - { - var value = _innerReader.ReadAsDateTime(); - _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; - } + 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 int Depth + { + get { return _innerReader.Depth; } + } - public override string Path - { - get { return _innerReader.Path; } - } + public override string Path + { + get { return _innerReader.Path; } + } - public override char QuoteChar - { - get { return _innerReader.QuoteChar; } - protected internal set { _innerReader.QuoteChar = value; } - } + public override char QuoteChar + { + get { return _innerReader.QuoteChar; } + protected internal set { _innerReader.QuoteChar = value; } + } - public override JsonToken TokenType - { - get { return _innerReader.TokenType; } - } + public override JsonToken TokenType + { + get { return _innerReader.TokenType; } + } - public override object Value - { - get { return _innerReader.Value; } - } + public override object Value + { + get { return _innerReader.Value; } + } - public override Type ValueType - { - get { return _innerReader.ValueType; } - } + public override Type ValueType + { + get { return _innerReader.ValueType; } + } - public override void Close() - { - _innerReader.Close(); - } + public override void Close() + { + _innerReader.Close(); + } - bool IJsonLineInfo.HasLineInfo() - { - IJsonLineInfo lineInfo = _innerReader as IJsonLineInfo; - return lineInfo != null && lineInfo.HasLineInfo(); - } + 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.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; - } + 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 index 265103b8..b5e3b582 100644 --- a/Src/Newtonsoft.Json/Serialization/TraceJsonWriter.cs +++ b/Src/Newtonsoft.Json/Serialization/TraceJsonWriter.cs @@ -9,340 +9,340 @@ 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) + internal class TraceJsonWriter : JsonWriter { - _innerWriter = innerWriter; + private readonly JsonWriter _innerWriter; + private readonly JsonTextWriter _textWriter; + private readonly StringWriter _sw; - _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 TraceJsonWriter(JsonWriter innerWriter) + { + _innerWriter = innerWriter; - public string GetJson() - { - return _sw.ToString(); - } + _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 override void WriteValue(decimal value) - { - _textWriter.WriteValue(value); - _innerWriter.WriteValue(value); - base.WriteValue(value); - } + public string GetJson() + { + return _sw.ToString(); + } - public override void WriteValue(bool value) - { - _textWriter.WriteValue(value); - _innerWriter.WriteValue(value); - base.WriteValue(value); - } + public override void WriteValue(decimal 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(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(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(DateTime 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); - } + 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 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 WriteUndefined() + { + _textWriter.WriteUndefined(); + _innerWriter.WriteUndefined(); + base.WriteUndefined(); + } - public override void WriteNull() - { - _textWriter.WriteNull(); - _innerWriter.WriteNull(); - 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(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(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(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(long value) + { + _textWriter.WriteValue(value); + _innerWriter.WriteValue(value); + base.WriteValue(value); + } - public override void WriteValue(object 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 + if (value is BigInteger) + { + _textWriter.WriteValue(value); + _innerWriter.WriteValue(value); + InternalWriteValue(JsonToken.Integer); + } + else #endif - { - _textWriter.WriteValue(value); - _innerWriter.WriteValue(value); - base.WriteValue(value); - } + { + _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(); + } } - - 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 diff --git a/Src/Newtonsoft.Json/SerializationBinder.cs b/Src/Newtonsoft.Json/SerializationBinder.cs index 864951e6..74ad77ce 100644 --- a/Src/Newtonsoft.Json/SerializationBinder.cs +++ b/Src/Newtonsoft.Json/SerializationBinder.cs @@ -1,33 +1,35 @@ -#if SILVERLIGHT || PocketPC || NETFX_CORE || PORTABLE40 || PORTABLE + +#if SILVERLIGHT || PocketPC || NETFX_CORE || PORTABLE40 || PORTABLE using System; using System.Reflection; namespace Newtonsoft.Json { - /// - /// Allows users to control class loading and mandate what class to load. - /// - public abstract class SerializationBinder - { /// - /// When overridden in a derived class, controls the binding of a serialized object to a type. + /// Allows users to control class loading and mandate what class to load. /// - /// Specifies the name of the serialized object. - /// Specifies the name of the serialized object - /// The type of the object the formatter creates a new instance of. - public abstract Type BindToType(string assemblyName, string typeName); - - /// - /// When overridden in a derived class, controls the binding of a serialized object to a type. - /// - /// The type of the object the formatter creates a new instance of. - /// Specifies the name of the serialized object. - /// Specifies the name of the serialized object. - public virtual void BindToName(Type serializedType, out string assemblyName, out string typeName) + public abstract class SerializationBinder { - assemblyName = null; - typeName = null; + /// + /// When overridden in a derived class, controls the binding of a serialized object to a type. + /// + /// Specifies the name of the serialized object. + /// Specifies the name of the serialized object + /// The type of the object the formatter creates a new instance of. + public abstract Type BindToType(string assemblyName, string typeName); + + /// + /// When overridden in a derived class, controls the binding of a serialized object to a type. + /// + /// The type of the object the formatter creates a new instance of. + /// Specifies the name of the serialized object. + /// Specifies the name of the serialized object. + public virtual void BindToName(Type serializedType, out string assemblyName, out string typeName) + { + assemblyName = null; + typeName = null; + } } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json/StringEscapeHandling.cs b/Src/Newtonsoft.Json/StringEscapeHandling.cs index cf530a17..13a332b3 100644 --- a/Src/Newtonsoft.Json/StringEscapeHandling.cs +++ b/Src/Newtonsoft.Json/StringEscapeHandling.cs @@ -25,22 +25,24 @@ namespace Newtonsoft.Json { - /// - /// Specifies how strings are escaped when writing JSON text. - /// - public enum StringEscapeHandling - { /// - /// Only control characters (e.g. newline) are escaped. + /// Specifies how strings are escaped when writing JSON text. /// - Default, - /// - /// All non-ASCII and control characters (e.g. newline) are escaped. - /// - EscapeNonAscii, - /// - /// HTML (<, >, &, ', ") and control characters (e.g. newline) are escaped. - /// - EscapeHtml - } + public enum StringEscapeHandling + { + /// + /// Only control characters (e.g. newline) are escaped. + /// + Default, + + /// + /// All non-ASCII and control characters (e.g. newline) are escaped. + /// + EscapeNonAscii, + + /// + /// HTML (<, >, &, ', ") and control characters (e.g. newline) are escaped. + /// + EscapeHtml + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/TraceLevel.cs b/Src/Newtonsoft.Json/TraceLevel.cs index c6106b7d..bc51d9df 100644 --- a/Src/Newtonsoft.Json/TraceLevel.cs +++ b/Src/Newtonsoft.Json/TraceLevel.cs @@ -1,33 +1,39 @@ -#if (NETFX_CORE || SILVERLIGHT || PORTABLE40 || PORTABLE) + +#if (NETFX_CORE || SILVERLIGHT || PORTABLE40 || PORTABLE) using Newtonsoft.Json.Serialization; namespace Newtonsoft.Json { - /// - /// Specifies what messages to output for the class. - /// - public enum TraceLevel - { /// - /// Output no tracing and debugging messages. + /// Specifies what messages to output for the class. /// - Off, - /// - /// Output error-handling messages. - /// - Error, - /// - /// Output warnings and error-handling messages. - /// - Warning, - /// - /// Output informational messages, warnings, and error-handling messages. - /// - Info, - /// - /// Output all debugging and tracing messages. - /// - Verbose - } + public enum TraceLevel + { + /// + /// Output no tracing and debugging messages. + /// + Off, + + /// + /// Output error-handling messages. + /// + Error, + + /// + /// Output warnings and error-handling messages. + /// + Warning, + + /// + /// Output informational messages, warnings, and error-handling messages. + /// + Info, + + /// + /// Output all debugging and tracing messages. + /// + Verbose + } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json/TypeNameHandling.cs b/Src/Newtonsoft.Json/TypeNameHandling.cs index c9b574a7..deb0c88e 100644 --- a/Src/Newtonsoft.Json/TypeNameHandling.cs +++ b/Src/Newtonsoft.Json/TypeNameHandling.cs @@ -27,31 +27,35 @@ using System; namespace Newtonsoft.Json { - /// - /// Specifies type name handling options for the . - /// - [Flags] - public enum TypeNameHandling - { /// - /// Do not include the .NET type name when serializing types. + /// Specifies type name handling options for the . /// - None = 0, - /// - /// Include the .NET type name when serializing into a JSON object structure. - /// - Objects = 1, - /// - /// Include the .NET type name when serializing into a JSON array structure. - /// - Arrays = 2, - /// - /// Always include the .NET type name when serializing. - /// - All = Objects | Arrays, - /// - /// Include the .NET type name when the type of the object being serialized is not the same as its declared type. - /// - Auto = 4 - } + [Flags] + public enum TypeNameHandling + { + /// + /// Do not include the .NET type name when serializing types. + /// + None = 0, + + /// + /// Include the .NET type name when serializing into a JSON object structure. + /// + Objects = 1, + + /// + /// Include the .NET type name when serializing into a JSON array structure. + /// + Arrays = 2, + + /// + /// Always include the .NET type name when serializing. + /// + All = Objects | Arrays, + + /// + /// Include the .NET type name when the type of the object being serialized is not the same as its declared type. + /// + Auto = 4 + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/Base64Encoder.cs b/Src/Newtonsoft.Json/Utilities/Base64Encoder.cs index 263bc0b9..5867e7ab 100644 --- a/Src/Newtonsoft.Json/Utilities/Base64Encoder.cs +++ b/Src/Newtonsoft.Json/Utilities/Base64Encoder.cs @@ -28,93 +28,93 @@ using System.IO; namespace Newtonsoft.Json.Utilities { - internal class Base64Encoder - { - private const int Base64LineSize = 76; - private const int LineSizeInBytes = 57; - - private readonly char[] _charsLine = new char[Base64LineSize]; - private readonly TextWriter _writer; - - private byte[] _leftOverBytes; - private int _leftOverBytesCount; - - public Base64Encoder(TextWriter writer) + internal class Base64Encoder { - ValidationUtils.ArgumentNotNull(writer, "writer"); - _writer = writer; + private const int Base64LineSize = 76; + private const int LineSizeInBytes = 57; + + private readonly char[] _charsLine = new char[Base64LineSize]; + private readonly TextWriter _writer; + + private byte[] _leftOverBytes; + private int _leftOverBytesCount; + + public Base64Encoder(TextWriter writer) + { + ValidationUtils.ArgumentNotNull(writer, "writer"); + _writer = writer; + } + + public void Encode(byte[] buffer, int index, int count) + { + if (buffer == null) + throw new ArgumentNullException("buffer"); + + if (index < 0) + throw new ArgumentOutOfRangeException("index"); + + if (count < 0) + throw new ArgumentOutOfRangeException("count"); + + if (count > (buffer.Length - index)) + throw new ArgumentOutOfRangeException("count"); + + if (_leftOverBytesCount > 0) + { + int leftOverBytesCount = _leftOverBytesCount; + while (leftOverBytesCount < 3 && count > 0) + { + _leftOverBytes[leftOverBytesCount++] = buffer[index++]; + count--; + } + if (count == 0 && leftOverBytesCount < 3) + { + _leftOverBytesCount = leftOverBytesCount; + return; + } + int num2 = Convert.ToBase64CharArray(_leftOverBytes, 0, 3, _charsLine, 0); + WriteChars(_charsLine, 0, num2); + } + _leftOverBytesCount = count % 3; + if (_leftOverBytesCount > 0) + { + count -= _leftOverBytesCount; + if (_leftOverBytes == null) + { + _leftOverBytes = new byte[3]; + } + for (int i = 0; i < _leftOverBytesCount; i++) + { + _leftOverBytes[i] = buffer[(index + count) + i]; + } + } + int num4 = index + count; + int length = LineSizeInBytes; + while (index < num4) + { + if ((index + length) > num4) + { + length = num4 - index; + } + int num6 = Convert.ToBase64CharArray(buffer, index, length, _charsLine, 0); + WriteChars(_charsLine, 0, num6); + index += length; + } + } + + public void Flush() + { + if (_leftOverBytesCount > 0) + { + int count = Convert.ToBase64CharArray(_leftOverBytes, 0, _leftOverBytesCount, _charsLine, 0); + WriteChars(_charsLine, 0, count); + _leftOverBytesCount = 0; + } + } + + private void WriteChars(char[] chars, int index, int count) + { + _writer.Write(chars, index, count); + } } - - public void Encode(byte[] buffer, int index, int count) - { - if (buffer == null) - throw new ArgumentNullException("buffer"); - - if (index < 0) - throw new ArgumentOutOfRangeException("index"); - - if (count < 0) - throw new ArgumentOutOfRangeException("count"); - - if (count > (buffer.Length - index)) - throw new ArgumentOutOfRangeException("count"); - - if (_leftOverBytesCount > 0) - { - int leftOverBytesCount = _leftOverBytesCount; - while (leftOverBytesCount < 3 && count > 0) - { - _leftOverBytes[leftOverBytesCount++] = buffer[index++]; - count--; - } - if (count == 0 && leftOverBytesCount < 3) - { - _leftOverBytesCount = leftOverBytesCount; - return; - } - int num2 = Convert.ToBase64CharArray(_leftOverBytes, 0, 3, _charsLine, 0); - WriteChars(_charsLine, 0, num2); - } - _leftOverBytesCount = count % 3; - if (_leftOverBytesCount > 0) - { - count -= _leftOverBytesCount; - if (_leftOverBytes == null) - { - _leftOverBytes = new byte[3]; - } - for (int i = 0; i < _leftOverBytesCount; i++) - { - _leftOverBytes[i] = buffer[(index + count) + i]; - } - } - int num4 = index + count; - int length = LineSizeInBytes; - while (index < num4) - { - if ((index + length) > num4) - { - length = num4 - index; - } - int num6 = Convert.ToBase64CharArray(buffer, index, length, _charsLine, 0); - WriteChars(_charsLine, 0, num6); - index += length; - } - } - - public void Flush() - { - if (_leftOverBytesCount > 0) - { - int count = Convert.ToBase64CharArray(_leftOverBytes, 0, _leftOverBytesCount, _charsLine, 0); - WriteChars(_charsLine, 0, count); - _leftOverBytesCount = 0; - } - } - - private void WriteChars(char[] chars, int index, int count) - { - _writer.Write(chars, index, count); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/BidirectionalDictionary.cs b/Src/Newtonsoft.Json/Utilities/BidirectionalDictionary.cs index 37ecaa4b..2711adf7 100644 --- a/Src/Newtonsoft.Json/Utilities/BidirectionalDictionary.cs +++ b/Src/Newtonsoft.Json/Utilities/BidirectionalDictionary.cs @@ -29,65 +29,65 @@ using System.Globalization; namespace Newtonsoft.Json.Utilities { - internal class BidirectionalDictionary - { - private readonly IDictionary _firstToSecond; - private readonly IDictionary _secondToFirst; - private readonly string _duplicateFirstErrorMessage; - private readonly string _duplicateSecondErrorMessage; - - public BidirectionalDictionary() - : this(EqualityComparer.Default, EqualityComparer.Default) + internal class BidirectionalDictionary { + private readonly IDictionary _firstToSecond; + private readonly IDictionary _secondToFirst; + private readonly string _duplicateFirstErrorMessage; + private readonly string _duplicateSecondErrorMessage; + + public BidirectionalDictionary() + : this(EqualityComparer.Default, EqualityComparer.Default) + { + } + + public BidirectionalDictionary(IEqualityComparer firstEqualityComparer, IEqualityComparer secondEqualityComparer) + : this( + firstEqualityComparer, + secondEqualityComparer, + "Duplicate item already exists for '{0}'.", + "Duplicate item already exists for '{0}'.") + { + } + + public BidirectionalDictionary(IEqualityComparer firstEqualityComparer, IEqualityComparer secondEqualityComparer, + string duplicateFirstErrorMessage, string duplicateSecondErrorMessage) + { + _firstToSecond = new Dictionary(firstEqualityComparer); + _secondToFirst = new Dictionary(secondEqualityComparer); + _duplicateFirstErrorMessage = duplicateFirstErrorMessage; + _duplicateSecondErrorMessage = duplicateSecondErrorMessage; + } + + public void Set(TFirst first, TSecond second) + { + TFirst existingFirst; + TSecond existingSecond; + + if (_firstToSecond.TryGetValue(first, out existingSecond)) + { + if (!existingSecond.Equals(second)) + throw new ArgumentException(_duplicateFirstErrorMessage.FormatWith(CultureInfo.InvariantCulture, first)); + } + + if (_secondToFirst.TryGetValue(second, out existingFirst)) + { + if (!existingFirst.Equals(first)) + throw new ArgumentException(_duplicateSecondErrorMessage.FormatWith(CultureInfo.InvariantCulture, second)); + } + + _firstToSecond.Add(first, second); + _secondToFirst.Add(second, first); + } + + public bool TryGetByFirst(TFirst first, out TSecond second) + { + return _firstToSecond.TryGetValue(first, out second); + } + + public bool TryGetBySecond(TSecond second, out TFirst first) + { + return _secondToFirst.TryGetValue(second, out first); + } } - - public BidirectionalDictionary(IEqualityComparer firstEqualityComparer, IEqualityComparer secondEqualityComparer) - : this( - firstEqualityComparer, - secondEqualityComparer, - "Duplicate item already exists for '{0}'.", - "Duplicate item already exists for '{0}'.") - { - } - - public BidirectionalDictionary(IEqualityComparer firstEqualityComparer, IEqualityComparer secondEqualityComparer, - string duplicateFirstErrorMessage, string duplicateSecondErrorMessage) - { - _firstToSecond = new Dictionary(firstEqualityComparer); - _secondToFirst = new Dictionary(secondEqualityComparer); - _duplicateFirstErrorMessage = duplicateFirstErrorMessage; - _duplicateSecondErrorMessage = duplicateSecondErrorMessage; - } - - public void Set(TFirst first, TSecond second) - { - TFirst existingFirst; - TSecond existingSecond; - - if (_firstToSecond.TryGetValue(first, out existingSecond)) - { - if (!existingSecond.Equals(second)) - throw new ArgumentException(_duplicateFirstErrorMessage.FormatWith(CultureInfo.InvariantCulture, first)); - } - - if (_secondToFirst.TryGetValue(second, out existingFirst)) - { - if (!existingFirst.Equals(first)) - throw new ArgumentException(_duplicateSecondErrorMessage.FormatWith(CultureInfo.InvariantCulture, second)); - } - - _firstToSecond.Add(first, second); - _secondToFirst.Add(second, first); - } - - public bool TryGetByFirst(TFirst first, out TSecond second) - { - return _firstToSecond.TryGetValue(first, out second); - } - - public bool TryGetBySecond(TSecond second, out TFirst first) - { - return _secondToFirst.TryGetValue(second, out first); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/CollectionUtils.cs b/Src/Newtonsoft.Json/Utilities/CollectionUtils.cs index ce5dbad6..f47812e1 100644 --- a/Src/Newtonsoft.Json/Utilities/CollectionUtils.cs +++ b/Src/Newtonsoft.Json/Utilities/CollectionUtils.cs @@ -39,243 +39,243 @@ using Newtonsoft.Json.Serialization; namespace Newtonsoft.Json.Utilities { - internal static class CollectionUtils - { - /// - /// Determines whether the collection is null or empty. - /// - /// The collection. - /// - /// true if the collection is null or empty; otherwise, false. - /// - public static bool IsNullOrEmpty(ICollection collection) + internal static class CollectionUtils { - if (collection != null) - { - return (collection.Count == 0); - } - return true; - } + /// + /// Determines whether the collection is null or empty. + /// + /// The collection. + /// + /// true if the collection is null or empty; otherwise, false. + /// + public static bool IsNullOrEmpty(ICollection collection) + { + if (collection != null) + { + return (collection.Count == 0); + } + return true; + } - /// - /// Adds the elements of the specified collection to the specified generic IList. - /// - /// The list to add to. - /// The collection of elements to add. - public static void AddRange(this IList initial, IEnumerable collection) - { - if (initial == null) - throw new ArgumentNullException("initial"); + /// + /// Adds the elements of the specified collection to the specified generic IList. + /// + /// The list to add to. + /// The collection of elements to add. + public static void AddRange(this IList initial, IEnumerable collection) + { + if (initial == null) + throw new ArgumentNullException("initial"); - if (collection == null) - return; + if (collection == null) + return; - foreach (T value in collection) - { - initial.Add(value); - } - } + foreach (T value in collection) + { + initial.Add(value); + } + } #if (NET20 || NET35 || SILVERLIGHT || PORTABLE40) - public static void AddRange(this IList initial, IEnumerable collection) - { - ValidationUtils.ArgumentNotNull(initial, "initial"); + public static void AddRange(this IList initial, IEnumerable collection) + { + ValidationUtils.ArgumentNotNull(initial, "initial"); - // because earlier versions of .NET didn't support covariant generics - initial.AddRange(collection.Cast()); - } + // because earlier versions of .NET didn't support covariant generics + initial.AddRange(collection.Cast()); + } #endif - public static bool IsDictionaryType(Type type) - { - ValidationUtils.ArgumentNotNull(type, "type"); + public static bool IsDictionaryType(Type type) + { + ValidationUtils.ArgumentNotNull(type, "type"); - if (typeof(IDictionary).IsAssignableFrom(type)) - return true; - if (ReflectionUtils.ImplementsGenericDefinition(type, typeof(IDictionary<,>))) - return true; + if (typeof(IDictionary).IsAssignableFrom(type)) + return true; + if (ReflectionUtils.ImplementsGenericDefinition(type, typeof(IDictionary<,>))) + return true; #if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - if (ReflectionUtils.ImplementsGenericDefinition(type, typeof(IReadOnlyDictionary<,>))) - return true; + if (ReflectionUtils.ImplementsGenericDefinition(type, typeof(IReadOnlyDictionary<,>))) + return true; #endif - return false; - } - - public static ConstructorInfo ResolveEnumableCollectionConstructor(Type collectionType, Type collectionItemType) - { - Type genericEnumerable = typeof(IEnumerable<>).MakeGenericType(collectionItemType); - - foreach (ConstructorInfo constructor in collectionType.GetConstructors(BindingFlags.Public | BindingFlags.Instance)) - { - IList parameters = constructor.GetParameters(); - - if (parameters.Count == 1) - { - if (genericEnumerable.IsAssignableFrom(parameters[0].ParameterType)) - return constructor; + return false; } - } - return null; - } - - public static bool AddDistinct(this IList list, T value) - { - return list.AddDistinct(value, EqualityComparer.Default); - } - - public static bool AddDistinct(this IList list, T value, IEqualityComparer comparer) - { - if (list.ContainsValue(value, comparer)) - return false; - - list.Add(value); - return true; - } - - // this is here because LINQ Bridge doesn't support Contains with IEqualityComparer - public static bool ContainsValue(this IEnumerable source, TSource value, IEqualityComparer comparer) - { - if (comparer == null) - comparer = EqualityComparer.Default; - - if (source == null) - throw new ArgumentNullException("source"); - - foreach (TSource local in source) - { - if (comparer.Equals(local, value)) - return true; - } - - return false; - } - - public static bool AddRangeDistinct(this IList list, IEnumerable values, IEqualityComparer comparer) - { - bool allAdded = true; - foreach (T value in values) - { - if (!list.AddDistinct(value, comparer)) - allAdded = false; - } - - return allAdded; - } - - public static int IndexOf(this IEnumerable collection, Func predicate) - { - int index = 0; - foreach (T value in collection) - { - if (predicate(value)) - return index; - - index++; - } - - return -1; - } - - /// - /// Returns the index of the first occurrence in a sequence by using a specified IEqualityComparer. - /// - /// The type of the elements of source. - /// A sequence in which to locate a value. - /// The object to locate in the sequence - /// An equality comparer to compare values. - /// The zero-based index of the first occurrence of value within the entire sequence, if found; otherwise, –1. - public static int IndexOf(this IEnumerable list, TSource value, IEqualityComparer comparer) - { - int index = 0; - foreach (TSource item in list) - { - if (comparer.Equals(item, value)) + public static ConstructorInfo ResolveEnumableCollectionConstructor(Type collectionType, Type collectionItemType) { - return index; + Type genericEnumerable = typeof(IEnumerable<>).MakeGenericType(collectionItemType); + + foreach (ConstructorInfo constructor in collectionType.GetConstructors(BindingFlags.Public | BindingFlags.Instance)) + { + IList parameters = constructor.GetParameters(); + + if (parameters.Count == 1) + { + if (genericEnumerable.IsAssignableFrom(parameters[0].ParameterType)) + return constructor; + } + } + + return null; + } + + public static bool AddDistinct(this IList list, T value) + { + return list.AddDistinct(value, EqualityComparer.Default); + } + + public static bool AddDistinct(this IList list, T value, IEqualityComparer comparer) + { + if (list.ContainsValue(value, comparer)) + return false; + + list.Add(value); + return true; + } + + // this is here because LINQ Bridge doesn't support Contains with IEqualityComparer + public static bool ContainsValue(this IEnumerable source, TSource value, IEqualityComparer comparer) + { + if (comparer == null) + comparer = EqualityComparer.Default; + + if (source == null) + throw new ArgumentNullException("source"); + + foreach (TSource local in source) + { + if (comparer.Equals(local, value)) + return true; + } + + return false; + } + + public static bool AddRangeDistinct(this IList list, IEnumerable values, IEqualityComparer comparer) + { + bool allAdded = true; + foreach (T value in values) + { + if (!list.AddDistinct(value, comparer)) + allAdded = false; + } + + return allAdded; + } + + public static int IndexOf(this IEnumerable collection, Func predicate) + { + int index = 0; + foreach (T value in collection) + { + if (predicate(value)) + return index; + + index++; + } + + return -1; + } + + /// + /// Returns the index of the first occurrence in a sequence by using a specified IEqualityComparer. + /// + /// The type of the elements of source. + /// A sequence in which to locate a value. + /// The object to locate in the sequence + /// An equality comparer to compare values. + /// The zero-based index of the first occurrence of value within the entire sequence, if found; otherwise, –1. + public static int IndexOf(this IEnumerable list, TSource value, IEqualityComparer comparer) + { + int index = 0; + foreach (TSource item in list) + { + if (comparer.Equals(item, value)) + { + return index; + } + index++; + } + return -1; + } + + private static IList GetDimensions(IList values) + { + IList dimensions = new List(); + + IList currentArray = values; + while (true) + { + dimensions.Add(currentArray.Count); + if (currentArray.Count == 0) + break; + + object v = currentArray[0]; + if (v is IList) + currentArray = (IList)v; + else + break; + } + + return dimensions; + } + + private static void CopyFromJaggedToMultidimensionalArray(IList values, Array multidimensionalArray, int[] indices) + { + int dimension = indices.Length; + if (dimension == multidimensionalArray.Rank) + { + multidimensionalArray.SetValue(JaggedArrayGetValue(values, indices), indices); + return; + } + + int dimensionLength = multidimensionalArray.GetLength(dimension); + IList list = (IList)JaggedArrayGetValue(values, indices); + int currentValuesLength = list.Count; + if (currentValuesLength != dimensionLength) + throw new Exception("Cannot deserialize non-cubical array as multidimensional array."); + + int[] newIndices = new int[dimension + 1]; + for (int i = 0; i < dimension; i++) + { + newIndices[i] = indices[i]; + } + + for (int i = 0; i < multidimensionalArray.GetLength(dimension); i++) + { + newIndices[dimension] = i; + CopyFromJaggedToMultidimensionalArray(values, multidimensionalArray, newIndices); + } + } + + private static object JaggedArrayGetValue(IList values, int[] indices) + { + IList currentList = values; + for (int i = 0; i < indices.Length; i++) + { + int index = indices[i]; + if (i == indices.Length - 1) + return currentList[index]; + else + currentList = (IList)currentList[index]; + } + return currentList; + } + + public static Array ToMultidimensionalArray(IList values, Type type, int rank) + { + IList dimensions = GetDimensions(values); + + while (dimensions.Count < rank) + { + dimensions.Add(0); + } + + Array multidimensionalArray = Array.CreateInstance(type, dimensions.ToArray()); + CopyFromJaggedToMultidimensionalArray(values, multidimensionalArray, new int[0]); + + return multidimensionalArray; } - index++; - } - return -1; } - - private static IList GetDimensions(IList values) - { - IList dimensions = new List(); - - IList currentArray = values; - while (true) - { - dimensions.Add(currentArray.Count); - if (currentArray.Count == 0) - break; - - object v = currentArray[0]; - if (v is IList) - currentArray = (IList)v; - else - break; - } - - return dimensions; - } - - private static void CopyFromJaggedToMultidimensionalArray(IList values, Array multidimensionalArray, int[] indices) - { - int dimension = indices.Length; - if (dimension == multidimensionalArray.Rank) - { - multidimensionalArray.SetValue(JaggedArrayGetValue(values, indices), indices); - return; - } - - int dimensionLength = multidimensionalArray.GetLength(dimension); - IList list = (IList)JaggedArrayGetValue(values, indices); - int currentValuesLength = list.Count; - if (currentValuesLength != dimensionLength) - throw new Exception("Cannot deserialize non-cubical array as multidimensional array."); - - int[] newIndices = new int[dimension + 1]; - for (int i = 0; i < dimension; i++) - { - newIndices[i] = indices[i]; - } - - for (int i = 0; i < multidimensionalArray.GetLength(dimension); i++) - { - newIndices[dimension] = i; - CopyFromJaggedToMultidimensionalArray(values, multidimensionalArray, newIndices); - } - } - - private static object JaggedArrayGetValue(IList values, int[] indices) - { - IList currentList = values; - for (int i = 0; i < indices.Length; i++) - { - int index = indices[i]; - if (i == indices.Length - 1) - return currentList[index]; - else - currentList = (IList)currentList[index]; - } - return currentList; - } - - public static Array ToMultidimensionalArray(IList values, Type type, int rank) - { - IList dimensions = GetDimensions(values); - - while (dimensions.Count < rank) - { - dimensions.Add(0); - } - - Array multidimensionalArray = Array.CreateInstance(type, dimensions.ToArray()); - CopyFromJaggedToMultidimensionalArray(values, multidimensionalArray, new int[0]); - - return multidimensionalArray; - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/CollectionWrapper.cs b/Src/Newtonsoft.Json/Utilities/CollectionWrapper.cs index 24f2fa07..2497845f 100644 --- a/Src/Newtonsoft.Json/Utilities/CollectionWrapper.cs +++ b/Src/Newtonsoft.Json/Utilities/CollectionWrapper.cs @@ -32,250 +32,251 @@ using System.Globalization; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json.Utilities { - internal interface IWrappedCollection : IList - { - object UnderlyingCollection { get; } - } - - internal class CollectionWrapper : ICollection, IWrappedCollection - { - private readonly IList _list; - private readonly ICollection _genericCollection; - private object _syncRoot; - - public CollectionWrapper(IList list) + internal interface IWrappedCollection : IList { - ValidationUtils.ArgumentNotNull(list, "list"); - - if (list is ICollection) - _genericCollection = (ICollection)list; - else - _list = list; + object UnderlyingCollection { get; } } - public CollectionWrapper(ICollection list) + internal class CollectionWrapper : ICollection, IWrappedCollection { - ValidationUtils.ArgumentNotNull(list, "list"); + private readonly IList _list; + private readonly ICollection _genericCollection; + private object _syncRoot; - _genericCollection = list; + public CollectionWrapper(IList list) + { + ValidationUtils.ArgumentNotNull(list, "list"); + + if (list is ICollection) + _genericCollection = (ICollection)list; + else + _list = list; + } + + public CollectionWrapper(ICollection list) + { + ValidationUtils.ArgumentNotNull(list, "list"); + + _genericCollection = list; + } + + public virtual void Add(T item) + { + if (_genericCollection != null) + _genericCollection.Add(item); + else + _list.Add(item); + } + + public virtual void Clear() + { + if (_genericCollection != null) + _genericCollection.Clear(); + else + _list.Clear(); + } + + public virtual bool Contains(T item) + { + if (_genericCollection != null) + return _genericCollection.Contains(item); + else + return _list.Contains(item); + } + + public virtual void CopyTo(T[] array, int arrayIndex) + { + if (_genericCollection != null) + _genericCollection.CopyTo(array, arrayIndex); + else + _list.CopyTo(array, arrayIndex); + } + + public virtual int Count + { + get + { + if (_genericCollection != null) + return _genericCollection.Count; + else + return _list.Count; + } + } + + public virtual bool IsReadOnly + { + get + { + if (_genericCollection != null) + return _genericCollection.IsReadOnly; + else + return _list.IsReadOnly; + } + } + + public virtual bool Remove(T item) + { + if (_genericCollection != null) + { + return _genericCollection.Remove(item); + } + else + { + bool contains = _list.Contains(item); + + if (contains) + _list.Remove(item); + + return contains; + } + } + + public virtual IEnumerator GetEnumerator() + { + if (_genericCollection != null) + return _genericCollection.GetEnumerator(); + + return _list.Cast().GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + if (_genericCollection != null) + return _genericCollection.GetEnumerator(); + else + return _list.GetEnumerator(); + } + + int IList.Add(object value) + { + VerifyValueType(value); + Add((T)value); + + return (Count - 1); + } + + bool IList.Contains(object value) + { + if (IsCompatibleObject(value)) + return Contains((T)value); + + return false; + } + + int IList.IndexOf(object value) + { + if (_genericCollection != null) + throw new InvalidOperationException("Wrapped ICollection does not support IndexOf."); + + if (IsCompatibleObject(value)) + return _list.IndexOf((T)value); + + return -1; + } + + void IList.RemoveAt(int index) + { + if (_genericCollection != null) + throw new InvalidOperationException("Wrapped ICollection does not support RemoveAt."); + + _list.RemoveAt(index); + } + + void IList.Insert(int index, object value) + { + if (_genericCollection != null) + throw new InvalidOperationException("Wrapped ICollection does not support Insert."); + + VerifyValueType(value); + _list.Insert(index, (T)value); + } + + bool IList.IsFixedSize + { + get + { + if (_genericCollection != null) + // ICollection only has IsReadOnly + return _genericCollection.IsReadOnly; + else + return _list.IsFixedSize; + } + } + + void IList.Remove(object value) + { + if (IsCompatibleObject(value)) + Remove((T)value); + } + + object IList.this[int index] + { + get + { + if (_genericCollection != null) + throw new InvalidOperationException("Wrapped ICollection does not support indexer."); + + return _list[index]; + } + set + { + if (_genericCollection != null) + throw new InvalidOperationException("Wrapped ICollection does not support indexer."); + + VerifyValueType(value); + _list[index] = (T)value; + } + } + + void ICollection.CopyTo(Array array, int arrayIndex) + { + CopyTo((T[])array, arrayIndex); + } + + bool ICollection.IsSynchronized + { + get { return false; } + } + + object ICollection.SyncRoot + { + get + { + if (_syncRoot == null) + Interlocked.CompareExchange(ref _syncRoot, new object(), null); + + return _syncRoot; + } + } + + private static void VerifyValueType(object value) + { + if (!IsCompatibleObject(value)) + throw new ArgumentException("The value '{0}' is not of type '{1}' and cannot be used in this generic collection.".FormatWith(CultureInfo.InvariantCulture, value, typeof(T)), "value"); + } + + private static bool IsCompatibleObject(object value) + { + if (!(value is T) && (value != null || (typeof(T).IsValueType() && !ReflectionUtils.IsNullableType(typeof(T))))) + return false; + + return true; + } + + public object UnderlyingCollection + { + get + { + if (_genericCollection != null) + return _genericCollection; + else + return _list; + } + } } - - public virtual void Add(T item) - { - if (_genericCollection != null) - _genericCollection.Add(item); - else - _list.Add(item); - } - - public virtual void Clear() - { - if (_genericCollection != null) - _genericCollection.Clear(); - else - _list.Clear(); - } - - public virtual bool Contains(T item) - { - if (_genericCollection != null) - return _genericCollection.Contains(item); - else - return _list.Contains(item); - } - - public virtual void CopyTo(T[] array, int arrayIndex) - { - if (_genericCollection != null) - _genericCollection.CopyTo(array, arrayIndex); - else - _list.CopyTo(array, arrayIndex); - } - - public virtual int Count - { - get - { - if (_genericCollection != null) - return _genericCollection.Count; - else - return _list.Count; - } - } - - public virtual bool IsReadOnly - { - get - { - if (_genericCollection != null) - return _genericCollection.IsReadOnly; - else - return _list.IsReadOnly; - } - } - - public virtual bool Remove(T item) - { - if (_genericCollection != null) - { - return _genericCollection.Remove(item); - } - else - { - bool contains = _list.Contains(item); - - if (contains) - _list.Remove(item); - - return contains; - } - } - - public virtual IEnumerator GetEnumerator() - { - if (_genericCollection != null) - return _genericCollection.GetEnumerator(); - - return _list.Cast().GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - if (_genericCollection != null) - return _genericCollection.GetEnumerator(); - else - return _list.GetEnumerator(); - } - - int IList.Add(object value) - { - VerifyValueType(value); - Add((T)value); - - return (Count - 1); - } - - bool IList.Contains(object value) - { - if (IsCompatibleObject(value)) - return Contains((T)value); - - return false; - } - - int IList.IndexOf(object value) - { - if (_genericCollection != null) - throw new InvalidOperationException("Wrapped ICollection does not support IndexOf."); - - if (IsCompatibleObject(value)) - return _list.IndexOf((T)value); - - return -1; - } - - void IList.RemoveAt(int index) - { - if (_genericCollection != null) - throw new InvalidOperationException("Wrapped ICollection does not support RemoveAt."); - - _list.RemoveAt(index); - } - - void IList.Insert(int index, object value) - { - if (_genericCollection != null) - throw new InvalidOperationException("Wrapped ICollection does not support Insert."); - - VerifyValueType(value); - _list.Insert(index, (T)value); - } - - bool IList.IsFixedSize - { - get - { - if (_genericCollection != null) - // ICollection only has IsReadOnly - return _genericCollection.IsReadOnly; - else - return _list.IsFixedSize; - } - } - - void IList.Remove(object value) - { - if (IsCompatibleObject(value)) - Remove((T)value); - } - - object IList.this[int index] - { - get - { - if (_genericCollection != null) - throw new InvalidOperationException("Wrapped ICollection does not support indexer."); - - return _list[index]; - } - set - { - if (_genericCollection != null) - throw new InvalidOperationException("Wrapped ICollection does not support indexer."); - - VerifyValueType(value); - _list[index] = (T)value; - } - } - - void ICollection.CopyTo(Array array, int arrayIndex) - { - CopyTo((T[])array, arrayIndex); - } - - bool ICollection.IsSynchronized - { - get { return false; } - } - - object ICollection.SyncRoot - { - get - { - if (_syncRoot == null) - Interlocked.CompareExchange(ref _syncRoot, new object(), null); - - return _syncRoot; - } - } - - private static void VerifyValueType(object value) - { - if (!IsCompatibleObject(value)) - throw new ArgumentException("The value '{0}' is not of type '{1}' and cannot be used in this generic collection.".FormatWith(CultureInfo.InvariantCulture, value, typeof(T)), "value"); - } - - private static bool IsCompatibleObject(object value) - { - if (!(value is T) && (value != null || (typeof(T).IsValueType() && !ReflectionUtils.IsNullableType(typeof(T))))) - return false; - - return true; - } - - public object UnderlyingCollection - { - get - { - if (_genericCollection != null) - return _genericCollection; - else - return _list; - } - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs b/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs index 510f8505..16c811d5 100644 --- a/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs +++ b/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs @@ -35,679 +35,672 @@ using System.Reflection; #if NET20 using Newtonsoft.Json.Utilities.LinqBridge; #endif - #if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) using System.Data.SqlTypes; + #endif namespace Newtonsoft.Json.Utilities { - internal enum PrimitiveTypeCode - { - Empty, - Object, - Char, - CharNullable, - Boolean, - BooleanNullable, - SByte, - SByteNullable, - Int16, - Int16Nullable, - UInt16, - UInt16Nullable, - Int32, - Int32Nullable, - Byte, - ByteNullable, - UInt32, - UInt32Nullable, - Int64, - Int64Nullable, - UInt64, - UInt64Nullable, - Single, - SingleNullable, - Double, - DoubleNullable, - DateTime, - DateTimeNullable, + internal enum PrimitiveTypeCode + { + Empty, + Object, + Char, + CharNullable, + Boolean, + BooleanNullable, + SByte, + SByteNullable, + Int16, + Int16Nullable, + UInt16, + UInt16Nullable, + Int32, + Int32Nullable, + Byte, + ByteNullable, + UInt32, + UInt32Nullable, + Int64, + Int64Nullable, + UInt64, + UInt64Nullable, + Single, + SingleNullable, + Double, + DoubleNullable, + DateTime, + DateTimeNullable, #if !NET20 - DateTimeOffset, - DateTimeOffsetNullable, + DateTimeOffset, + DateTimeOffsetNullable, #endif - Decimal, - DecimalNullable, - Guid, - GuidNullable, - TimeSpan, - TimeSpanNullable, + Decimal, + DecimalNullable, + Guid, + GuidNullable, + TimeSpan, + TimeSpanNullable, #if !(PORTABLE || NET35 || NET20 || WINDOWS_PHONE || SILVERLIGHT) - BigInteger, - BigIntegerNullable, + BigInteger, + BigIntegerNullable, #endif - Uri, - String, - Bytes, - DBNull - } + Uri, + String, + Bytes, + DBNull + } - internal class TypeInformation - { - public Type Type { get; set; } - public PrimitiveTypeCode TypeCode { get; set; } - } + internal class TypeInformation + { + public Type Type { get; set; } + public PrimitiveTypeCode TypeCode { get; set; } + } - internal enum ParseResult - { - None, - Success, - Overflow, - Invalid - } + internal enum ParseResult + { + None, + Success, + Overflow, + Invalid + } - internal static class ConvertUtils - { - private static readonly Dictionary TypeCodeMap = - new Dictionary - { - { typeof(char), PrimitiveTypeCode.Char }, - { typeof(char?), PrimitiveTypeCode.CharNullable }, - { typeof(bool), PrimitiveTypeCode.Boolean }, - { typeof(bool?), PrimitiveTypeCode.BooleanNullable }, - { typeof(sbyte), PrimitiveTypeCode.SByte }, - { typeof(sbyte?), PrimitiveTypeCode.SByteNullable }, - { typeof(short), PrimitiveTypeCode.Int16 }, - { typeof(short?), PrimitiveTypeCode.Int16Nullable }, - { typeof(ushort), PrimitiveTypeCode.UInt16 }, - { typeof(ushort?), PrimitiveTypeCode.UInt16Nullable }, - { typeof(int), PrimitiveTypeCode.Int32 }, - { typeof(int?), PrimitiveTypeCode.Int32Nullable }, - { typeof(byte), PrimitiveTypeCode.Byte }, - { typeof(byte?), PrimitiveTypeCode.ByteNullable }, - { typeof(uint), PrimitiveTypeCode.UInt32 }, - { typeof(uint?), PrimitiveTypeCode.UInt32Nullable }, - { typeof(long), PrimitiveTypeCode.Int64 }, - { typeof(long?), PrimitiveTypeCode.Int64Nullable }, - { typeof(ulong), PrimitiveTypeCode.UInt64 }, - { typeof(ulong?), PrimitiveTypeCode.UInt64Nullable }, - { typeof(float), PrimitiveTypeCode.Single }, - { typeof(float?), PrimitiveTypeCode.SingleNullable }, - { typeof(double), PrimitiveTypeCode.Double }, - { typeof(double?), PrimitiveTypeCode.DoubleNullable }, - { typeof(DateTime), PrimitiveTypeCode.DateTime }, - { typeof(DateTime?), PrimitiveTypeCode.DateTimeNullable }, + internal static class ConvertUtils + { + private static readonly Dictionary TypeCodeMap = + new Dictionary + { + { typeof(char), PrimitiveTypeCode.Char }, + { typeof(char?), PrimitiveTypeCode.CharNullable }, + { typeof(bool), PrimitiveTypeCode.Boolean }, + { typeof(bool?), PrimitiveTypeCode.BooleanNullable }, + { typeof(sbyte), PrimitiveTypeCode.SByte }, + { typeof(sbyte?), PrimitiveTypeCode.SByteNullable }, + { typeof(short), PrimitiveTypeCode.Int16 }, + { typeof(short?), PrimitiveTypeCode.Int16Nullable }, + { typeof(ushort), PrimitiveTypeCode.UInt16 }, + { typeof(ushort?), PrimitiveTypeCode.UInt16Nullable }, + { typeof(int), PrimitiveTypeCode.Int32 }, + { typeof(int?), PrimitiveTypeCode.Int32Nullable }, + { typeof(byte), PrimitiveTypeCode.Byte }, + { typeof(byte?), PrimitiveTypeCode.ByteNullable }, + { typeof(uint), PrimitiveTypeCode.UInt32 }, + { typeof(uint?), PrimitiveTypeCode.UInt32Nullable }, + { typeof(long), PrimitiveTypeCode.Int64 }, + { typeof(long?), PrimitiveTypeCode.Int64Nullable }, + { typeof(ulong), PrimitiveTypeCode.UInt64 }, + { typeof(ulong?), PrimitiveTypeCode.UInt64Nullable }, + { typeof(float), PrimitiveTypeCode.Single }, + { typeof(float?), PrimitiveTypeCode.SingleNullable }, + { typeof(double), PrimitiveTypeCode.Double }, + { typeof(double?), PrimitiveTypeCode.DoubleNullable }, + { typeof(DateTime), PrimitiveTypeCode.DateTime }, + { typeof(DateTime?), PrimitiveTypeCode.DateTimeNullable }, #if !NET20 - { typeof(DateTimeOffset), PrimitiveTypeCode.DateTimeOffset }, - { typeof(DateTimeOffset?), PrimitiveTypeCode.DateTimeOffsetNullable }, + { typeof(DateTimeOffset), PrimitiveTypeCode.DateTimeOffset }, + { typeof(DateTimeOffset?), PrimitiveTypeCode.DateTimeOffsetNullable }, #endif - { typeof(decimal), PrimitiveTypeCode.Decimal }, - { typeof(decimal?), PrimitiveTypeCode.DecimalNullable }, - { typeof(Guid), PrimitiveTypeCode.Guid }, - { typeof(Guid?), PrimitiveTypeCode.GuidNullable }, - { typeof(TimeSpan), PrimitiveTypeCode.TimeSpan }, - { typeof(TimeSpan?), PrimitiveTypeCode.TimeSpanNullable }, + { typeof(decimal), PrimitiveTypeCode.Decimal }, + { typeof(decimal?), PrimitiveTypeCode.DecimalNullable }, + { typeof(Guid), PrimitiveTypeCode.Guid }, + { typeof(Guid?), PrimitiveTypeCode.GuidNullable }, + { typeof(TimeSpan), PrimitiveTypeCode.TimeSpan }, + { typeof(TimeSpan?), PrimitiveTypeCode.TimeSpanNullable }, #if !(PORTABLE || PORTABLE40 || NET35 || NET20 || WINDOWS_PHONE || SILVERLIGHT) - { typeof(BigInteger), PrimitiveTypeCode.BigInteger }, - { typeof(BigInteger?), PrimitiveTypeCode.BigIntegerNullable }, + { typeof(BigInteger), PrimitiveTypeCode.BigInteger }, + { typeof(BigInteger?), PrimitiveTypeCode.BigIntegerNullable }, #endif - { typeof(Uri), PrimitiveTypeCode.Uri }, - { typeof(string), PrimitiveTypeCode.String }, - { typeof(byte[]), PrimitiveTypeCode.Bytes }, + { typeof(Uri), PrimitiveTypeCode.Uri }, + { typeof(string), PrimitiveTypeCode.String }, + { typeof(byte[]), PrimitiveTypeCode.Bytes }, #if !(PORTABLE || PORTABLE40 || NETFX_CORE) - { typeof(DBNull), PrimitiveTypeCode.DBNull } + { typeof(DBNull), PrimitiveTypeCode.DBNull } #endif + }; + + private static readonly List PrimitiveTypeCodes = new List + { + new TypeInformation { Type = typeof(object), TypeCode = PrimitiveTypeCode.Empty }, + new TypeInformation { Type = typeof(object), TypeCode = PrimitiveTypeCode.Object }, + new TypeInformation { Type = typeof(object), TypeCode = PrimitiveTypeCode.DBNull }, + new TypeInformation { Type = typeof(bool), TypeCode = PrimitiveTypeCode.Boolean }, + new TypeInformation { Type = typeof(char), TypeCode = PrimitiveTypeCode.Char }, + new TypeInformation { Type = typeof(sbyte), TypeCode = PrimitiveTypeCode.SByte }, + new TypeInformation { Type = typeof(byte), TypeCode = PrimitiveTypeCode.Byte }, + new TypeInformation { Type = typeof(short), TypeCode = PrimitiveTypeCode.Int16 }, + new TypeInformation { Type = typeof(ushort), TypeCode = PrimitiveTypeCode.UInt16 }, + new TypeInformation { Type = typeof(int), TypeCode = PrimitiveTypeCode.Int32 }, + new TypeInformation { Type = typeof(uint), TypeCode = PrimitiveTypeCode.UInt32 }, + new TypeInformation { Type = typeof(long), TypeCode = PrimitiveTypeCode.Int64 }, + new TypeInformation { Type = typeof(ulong), TypeCode = PrimitiveTypeCode.UInt64 }, + new TypeInformation { Type = typeof(float), TypeCode = PrimitiveTypeCode.Single }, + new TypeInformation { Type = typeof(double), TypeCode = PrimitiveTypeCode.Double }, + new TypeInformation { Type = typeof(decimal), TypeCode = PrimitiveTypeCode.Decimal }, + new TypeInformation { Type = typeof(DateTime), TypeCode = PrimitiveTypeCode.DateTime }, + new TypeInformation { Type = typeof(object), TypeCode = PrimitiveTypeCode.Empty }, // no 17 in TypeCode for some reason + new TypeInformation { Type = typeof(string), TypeCode = PrimitiveTypeCode.String } }; - private static readonly List PrimitiveTypeCodes = new List - { - new TypeInformation { Type = typeof(object), TypeCode = PrimitiveTypeCode.Empty }, - new TypeInformation { Type = typeof(object), TypeCode = PrimitiveTypeCode.Object }, - new TypeInformation { Type = typeof(object), TypeCode = PrimitiveTypeCode.DBNull }, - new TypeInformation { Type = typeof(bool), TypeCode = PrimitiveTypeCode.Boolean }, - new TypeInformation { Type = typeof(char), TypeCode = PrimitiveTypeCode.Char }, - new TypeInformation { Type = typeof(sbyte), TypeCode = PrimitiveTypeCode.SByte }, - new TypeInformation { Type = typeof(byte), TypeCode = PrimitiveTypeCode.Byte }, - new TypeInformation { Type = typeof(short), TypeCode = PrimitiveTypeCode.Int16 }, - new TypeInformation { Type = typeof(ushort), TypeCode = PrimitiveTypeCode.UInt16 }, - new TypeInformation { Type = typeof(int), TypeCode = PrimitiveTypeCode.Int32 }, - new TypeInformation { Type = typeof(uint), TypeCode = PrimitiveTypeCode.UInt32 }, - new TypeInformation { Type = typeof(long), TypeCode = PrimitiveTypeCode.Int64 }, - new TypeInformation { Type = typeof(ulong), TypeCode = PrimitiveTypeCode.UInt64 }, - new TypeInformation { Type = typeof(float), TypeCode = PrimitiveTypeCode.Single }, - new TypeInformation { Type = typeof(double), TypeCode = PrimitiveTypeCode.Double }, - new TypeInformation { Type = typeof(decimal), TypeCode = PrimitiveTypeCode.Decimal }, - new TypeInformation { Type = typeof(DateTime), TypeCode = PrimitiveTypeCode.DateTime }, - new TypeInformation { Type = typeof(object), TypeCode = PrimitiveTypeCode.Empty }, // no 17 in TypeCode for some reason - new TypeInformation { Type = typeof(string), TypeCode = PrimitiveTypeCode.String } - }; - - public static PrimitiveTypeCode GetTypeCode(Type t) - { - PrimitiveTypeCode typeCode; - if (TypeCodeMap.TryGetValue(t, out typeCode)) - return typeCode; - - if (t.IsEnum()) - return GetTypeCode(Enum.GetUnderlyingType(t)); - - // performance? - if (ReflectionUtils.IsNullableType(t)) - { - Type nonNullable = Nullable.GetUnderlyingType(t); - if (nonNullable.IsEnum()) + public static PrimitiveTypeCode GetTypeCode(Type t) { - Type nullableUnderlyingType = typeof(Nullable<>).MakeGenericType(Enum.GetUnderlyingType(nonNullable)); - return GetTypeCode(nullableUnderlyingType); + PrimitiveTypeCode typeCode; + if (TypeCodeMap.TryGetValue(t, out typeCode)) + return typeCode; + + if (t.IsEnum()) + return GetTypeCode(Enum.GetUnderlyingType(t)); + + // performance? + if (ReflectionUtils.IsNullableType(t)) + { + Type nonNullable = Nullable.GetUnderlyingType(t); + if (nonNullable.IsEnum()) + { + Type nullableUnderlyingType = typeof(Nullable<>).MakeGenericType(Enum.GetUnderlyingType(nonNullable)); + return GetTypeCode(nullableUnderlyingType); + } + } + + return PrimitiveTypeCode.Object; } - } - return PrimitiveTypeCode.Object; - } - - public static PrimitiveTypeCode GetTypeCode(object o) - { - return GetTypeCode(o.GetType()); - } + public static PrimitiveTypeCode GetTypeCode(object o) + { + return GetTypeCode(o.GetType()); + } #if !(NETFX_CORE || PORTABLE) - public static TypeInformation GetTypeInformation(IConvertible convertable) - { - TypeInformation typeInformation = PrimitiveTypeCodes[(int)convertable.GetTypeCode()]; - return typeInformation; - } + public static TypeInformation GetTypeInformation(IConvertible convertable) + { + TypeInformation typeInformation = PrimitiveTypeCodes[(int)convertable.GetTypeCode()]; + return typeInformation; + } #endif - public static bool IsConvertible(Type t) - { + public static bool IsConvertible(Type t) + { #if !(NETFX_CORE || PORTABLE) - return typeof(IConvertible).IsAssignableFrom(t); + return typeof(IConvertible).IsAssignableFrom(t); #else return ( t == typeof(bool) || t == typeof(byte) || t == typeof(char) || t == typeof(DateTime) || t == typeof(decimal) || t == typeof(double) || t == typeof(short) || t == typeof(int) || t == typeof(long) || t == typeof(sbyte) || t == typeof(float) || t == typeof(string) || t == typeof(ushort) || t == typeof(uint) || t == typeof(ulong) || t.IsEnum()); #endif - } - - public static TimeSpan ParseTimeSpan(string input) - { -#if !(NET35 || NET20 || PORTABLE40) - return TimeSpan.Parse((string)input, CultureInfo.InvariantCulture); -#else - return TimeSpan.Parse((string)input); -#endif - } - - internal struct TypeConvertKey : IEquatable - { - private readonly Type _initialType; - private readonly Type _targetType; - - public Type InitialType - { - get { return _initialType; } - } - - public Type TargetType - { - get { return _targetType; } - } - - public TypeConvertKey(Type initialType, Type targetType) - { - _initialType = initialType; - _targetType = targetType; - } - - public override int GetHashCode() - { - return _initialType.GetHashCode() ^ _targetType.GetHashCode(); - } - - public override bool Equals(object obj) - { - if (!(obj is TypeConvertKey)) - return false; - - return Equals((TypeConvertKey)obj); - } - - public bool Equals(TypeConvertKey other) - { - return (_initialType == other._initialType && _targetType == other._targetType); - } - } - - private static readonly ThreadSafeStore> CastConverters = - new ThreadSafeStore>(CreateCastConverter); - - private static Func CreateCastConverter(TypeConvertKey t) - { - MethodInfo castMethodInfo = t.TargetType.GetMethod("op_Implicit", new[] { t.InitialType }); - if (castMethodInfo == null) - castMethodInfo = t.TargetType.GetMethod("op_Explicit", new[] { t.InitialType }); - - if (castMethodInfo == null) - return null; - - MethodCall call = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(castMethodInfo); - - return o => call(null, o); - } - -#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE || PORTABLE40) - internal static BigInteger ToBigInteger(object value) - { - if (value is BigInteger) - return (BigInteger)value; - if (value is string) - return BigInteger.Parse((string)value, CultureInfo.InvariantCulture); - if (value is float) - return new BigInteger((float)value); - if (value is double) - return new BigInteger((double)value); - if (value is decimal) - return new BigInteger((decimal)value); - if (value is int) - return new BigInteger((int)value); - if (value is long) - return new BigInteger((long)value); - if (value is uint) - return new BigInteger((uint)value); - if (value is ulong) - return new BigInteger((ulong)value); - if (value is byte[]) - return new BigInteger((byte[])value); - - throw new InvalidCastException("Cannot convert {0} to BigInteger.".FormatWith(CultureInfo.InvariantCulture, value.GetType())); - } - - public static object FromBigInteger(BigInteger i, Type targetType) - { - if (targetType == typeof(decimal)) - return (decimal)i; - if (targetType == typeof(double)) - return (double)i; - if (targetType == typeof(float)) - return (float)i; - if (targetType == typeof(ulong)) - return (ulong)i; - - try - { - return System.Convert.ChangeType((long)i, targetType, CultureInfo.InvariantCulture); - } - catch (Exception ex) - { - throw new InvalidOperationException("Can not convert from BigInteger to {0}.".FormatWith(CultureInfo.InvariantCulture, targetType), ex); - } - } -#endif - - #region Convert - - /// - /// Converts the value to the specified type. - /// - /// The value to convert. - /// The culture to use when converting. - /// The type to convert the value to. - /// The converted type. - public static object Convert(object initialValue, CultureInfo culture, Type targetType) - { - if (initialValue == null) - throw new ArgumentNullException("initialValue"); - - if (ReflectionUtils.IsNullableType(targetType)) - targetType = Nullable.GetUnderlyingType(targetType); - - Type initialType = initialValue.GetType(); - - if (targetType == initialType) - return initialValue; - - // use Convert.ChangeType if both types are IConvertible - if (ConvertUtils.IsConvertible(initialValue.GetType()) && ConvertUtils.IsConvertible(targetType)) - { - if (targetType.IsEnum()) - { - if (initialValue is string) - return Enum.Parse(targetType, initialValue.ToString(), true); - else if (IsInteger(initialValue)) - return Enum.ToObject(targetType, initialValue); } - return System.Convert.ChangeType(initialValue, targetType, culture); - } + public static TimeSpan ParseTimeSpan(string input) + { +#if !(NET35 || NET20 || PORTABLE40) + return TimeSpan.Parse((string)input, CultureInfo.InvariantCulture); +#else + return TimeSpan.Parse((string)input); +#endif + } -#if !NET20 - if (initialValue is DateTime && targetType == typeof(DateTimeOffset)) - return new DateTimeOffset((DateTime)initialValue); + internal struct TypeConvertKey : IEquatable + { + private readonly Type _initialType; + private readonly Type _targetType; + + public Type InitialType + { + get { return _initialType; } + } + + public Type TargetType + { + get { return _targetType; } + } + + public TypeConvertKey(Type initialType, Type targetType) + { + _initialType = initialType; + _targetType = targetType; + } + + public override int GetHashCode() + { + return _initialType.GetHashCode() ^ _targetType.GetHashCode(); + } + + public override bool Equals(object obj) + { + if (!(obj is TypeConvertKey)) + return false; + + return Equals((TypeConvertKey)obj); + } + + public bool Equals(TypeConvertKey other) + { + return (_initialType == other._initialType && _targetType == other._targetType); + } + } + + private static readonly ThreadSafeStore> CastConverters = + new ThreadSafeStore>(CreateCastConverter); + + private static Func CreateCastConverter(TypeConvertKey t) + { + MethodInfo castMethodInfo = t.TargetType.GetMethod("op_Implicit", new[] { t.InitialType }); + if (castMethodInfo == null) + castMethodInfo = t.TargetType.GetMethod("op_Explicit", new[] { t.InitialType }); + + if (castMethodInfo == null) + return null; + + MethodCall call = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(castMethodInfo); + + return o => call(null, o); + } + +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE || PORTABLE40) + internal static BigInteger ToBigInteger(object value) + { + if (value is BigInteger) + return (BigInteger)value; + if (value is string) + return BigInteger.Parse((string)value, CultureInfo.InvariantCulture); + if (value is float) + return new BigInteger((float)value); + if (value is double) + return new BigInteger((double)value); + if (value is decimal) + return new BigInteger((decimal)value); + if (value is int) + return new BigInteger((int)value); + if (value is long) + return new BigInteger((long)value); + if (value is uint) + return new BigInteger((uint)value); + if (value is ulong) + return new BigInteger((ulong)value); + if (value is byte[]) + return new BigInteger((byte[])value); + + throw new InvalidCastException("Cannot convert {0} to BigInteger.".FormatWith(CultureInfo.InvariantCulture, value.GetType())); + } + + public static object FromBigInteger(BigInteger i, Type targetType) + { + if (targetType == typeof(decimal)) + return (decimal)i; + if (targetType == typeof(double)) + return (double)i; + if (targetType == typeof(float)) + return (float)i; + if (targetType == typeof(ulong)) + return (ulong)i; + + try + { + return System.Convert.ChangeType((long)i, targetType, CultureInfo.InvariantCulture); + } + catch (Exception ex) + { + throw new InvalidOperationException("Can not convert from BigInteger to {0}.".FormatWith(CultureInfo.InvariantCulture, targetType), ex); + } + } #endif - if (initialValue is byte[] && targetType == typeof(Guid)) - return new Guid((byte[])initialValue); + #region Convert + /// + /// Converts the value to the specified type. + /// + /// The value to convert. + /// The culture to use when converting. + /// The type to convert the value to. + /// The converted type. + public static object Convert(object initialValue, CultureInfo culture, Type targetType) + { + if (initialValue == null) + throw new ArgumentNullException("initialValue"); - if (initialValue is string) - { - if (targetType == typeof(Guid)) - return new Guid((string)initialValue); - if (targetType == typeof(Uri)) - return new Uri((string)initialValue, UriKind.RelativeOrAbsolute); - if (targetType == typeof(TimeSpan)) - return ParseTimeSpan((string)initialValue); - if (typeof(Type).IsAssignableFrom(targetType)) - return Type.GetType((string)initialValue, true); - } + if (ReflectionUtils.IsNullableType(targetType)) + targetType = Nullable.GetUnderlyingType(targetType); + + Type initialType = initialValue.GetType(); + + if (targetType == initialType) + return initialValue; + + // use Convert.ChangeType if both types are IConvertible + if (ConvertUtils.IsConvertible(initialValue.GetType()) && ConvertUtils.IsConvertible(targetType)) + { + if (targetType.IsEnum()) + { + if (initialValue is string) + return Enum.Parse(targetType, initialValue.ToString(), true); + else if (IsInteger(initialValue)) + return Enum.ToObject(targetType, initialValue); + } + + return System.Convert.ChangeType(initialValue, targetType, culture); + } + +#if !NET20 + if (initialValue is DateTime && targetType == typeof(DateTimeOffset)) + return new DateTimeOffset((DateTime)initialValue); +#endif + + if (initialValue is byte[] && targetType == typeof(Guid)) + return new Guid((byte[])initialValue); + + if (initialValue is string) + { + if (targetType == typeof(Guid)) + return new Guid((string)initialValue); + if (targetType == typeof(Uri)) + return new Uri((string)initialValue, UriKind.RelativeOrAbsolute); + if (targetType == typeof(TimeSpan)) + return ParseTimeSpan((string)initialValue); + if (typeof(Type).IsAssignableFrom(targetType)) + return Type.GetType((string)initialValue, true); + } #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - if (targetType == typeof(BigInteger)) - return ToBigInteger(initialValue); - if (initialValue is BigInteger) - return FromBigInteger((BigInteger)initialValue, targetType); + if (targetType == typeof(BigInteger)) + return ToBigInteger(initialValue); + if (initialValue is BigInteger) + return FromBigInteger((BigInteger)initialValue, targetType); #endif #if !(NETFX_CORE || PORTABLE40 || PORTABLE) - // see if source or target types have a TypeConverter that converts between the two - TypeConverter toConverter = GetConverter(initialType); + // see if source or target types have a TypeConverter that converts between the two + TypeConverter toConverter = GetConverter(initialType); - if (toConverter != null && toConverter.CanConvertTo(targetType)) - { + if (toConverter != null && toConverter.CanConvertTo(targetType)) + { #if !SILVERLIGHT - return toConverter.ConvertTo(null, culture, initialValue, targetType); + return toConverter.ConvertTo(null, culture, initialValue, targetType); #else return toConverter.ConvertTo(initialValue, targetType); #endif - } + } - TypeConverter fromConverter = GetConverter(targetType); + TypeConverter fromConverter = GetConverter(targetType); - if (fromConverter != null && fromConverter.CanConvertFrom(initialType)) - { + if (fromConverter != null && fromConverter.CanConvertFrom(initialType)) + { #if !SILVERLIGHT - return fromConverter.ConvertFrom(null, culture, initialValue); + return fromConverter.ConvertFrom(null, culture, initialValue); #else return fromConverter.ConvertFrom(initialValue); #endif - } + } #endif #if !(NETFX_CORE || PORTABLE40 || PORTABLE) - // handle DBNull and INullable - if (initialValue == DBNull.Value) - { - if (ReflectionUtils.IsNullable(targetType)) - return EnsureTypeAssignable(null, initialType, targetType); + // handle DBNull and INullable + if (initialValue == DBNull.Value) + { + if (ReflectionUtils.IsNullable(targetType)) + return EnsureTypeAssignable(null, initialType, targetType); - throw new Exception("Can not convert null {0} into non-nullable {1}.".FormatWith(CultureInfo.InvariantCulture, initialType, targetType)); - } + throw new Exception("Can not convert null {0} into non-nullable {1}.".FormatWith(CultureInfo.InvariantCulture, initialType, targetType)); + } #endif #if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) - if (initialValue is INullable) - return EnsureTypeAssignable(ToValue((INullable)initialValue), initialType, targetType); + if (initialValue is INullable) + return EnsureTypeAssignable(ToValue((INullable)initialValue), initialType, targetType); #endif - if (targetType.IsInterface() || targetType.IsGenericTypeDefinition() || targetType.IsAbstract()) - throw new ArgumentException("Target type {0} is not a value type or a non-abstract class.".FormatWith(CultureInfo.InvariantCulture, targetType), "targetType"); + if (targetType.IsInterface() || targetType.IsGenericTypeDefinition() || targetType.IsAbstract()) + throw new ArgumentException("Target type {0} is not a value type or a non-abstract class.".FormatWith(CultureInfo.InvariantCulture, targetType), "targetType"); - throw new InvalidOperationException("Can not convert from {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, initialType, targetType)); - } + throw new InvalidOperationException("Can not convert from {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, initialType, targetType)); + } + #endregion - #endregion + #region TryConvert + /// + /// Converts the value to the specified type. + /// + /// The value to convert. + /// The culture to use when converting. + /// The type to convert the value to. + /// The converted value if the conversion was successful or the default value of T if it failed. + /// + /// true if initialValue was converted successfully; otherwise, false. + /// + public static bool TryConvert(object initialValue, CultureInfo culture, Type targetType, out object convertedValue) + { + try + { + convertedValue = Convert(initialValue, culture, targetType); + return true; + } + catch + { + convertedValue = null; + return false; + } + } + #endregion - #region TryConvert + #region ConvertOrCast + /// + /// Converts the value to the specified type. If the value is unable to be converted, the + /// value is checked whether it assignable to the specified type. + /// + /// The value to convert. + /// The culture to use when converting. + /// The type to convert or cast the value to. + /// + /// The converted type. If conversion was unsuccessful, the initial value + /// is returned if assignable to the target type. + /// + public static object ConvertOrCast(object initialValue, CultureInfo culture, Type targetType) + { + object convertedValue; - /// - /// Converts the value to the specified type. - /// - /// The value to convert. - /// The culture to use when converting. - /// The type to convert the value to. - /// The converted value if the conversion was successful or the default value of T if it failed. - /// - /// true if initialValue was converted successfully; otherwise, false. - /// - public static bool TryConvert(object initialValue, CultureInfo culture, Type targetType, out object convertedValue) - { - try - { - convertedValue = Convert(initialValue, culture, targetType); - return true; - } - catch - { - convertedValue = null; - return false; - } - } + if (targetType == typeof(object)) + return initialValue; - #endregion + if (initialValue == null && ReflectionUtils.IsNullable(targetType)) + return null; - #region ConvertOrCast + if (TryConvert(initialValue, culture, targetType, out convertedValue)) + return convertedValue; - /// - /// Converts the value to the specified type. If the value is unable to be converted, the - /// value is checked whether it assignable to the specified type. - /// - /// The value to convert. - /// The culture to use when converting. - /// The type to convert or cast the value to. - /// - /// The converted type. If conversion was unsuccessful, the initial value - /// is returned if assignable to the target type. - /// - public static object ConvertOrCast(object initialValue, CultureInfo culture, Type targetType) - { - object convertedValue; + return EnsureTypeAssignable(initialValue, ReflectionUtils.GetObjectType(initialValue), targetType); + } + #endregion - if (targetType == typeof(object)) - return initialValue; + private static object EnsureTypeAssignable(object value, Type initialType, Type targetType) + { + Type valueType = (value != null) ? value.GetType() : null; - if (initialValue == null && ReflectionUtils.IsNullable(targetType)) - return null; + if (value != null) + { + if (targetType.IsAssignableFrom(valueType)) + return value; - if (TryConvert(initialValue, culture, targetType, out convertedValue)) - return convertedValue; + Func castConverter = CastConverters.Get(new TypeConvertKey(valueType, targetType)); + if (castConverter != null) + return castConverter(value); + } + else + { + if (ReflectionUtils.IsNullable(targetType)) + return null; + } - return EnsureTypeAssignable(initialValue, ReflectionUtils.GetObjectType(initialValue), targetType); - } - - #endregion - - private static object EnsureTypeAssignable(object value, Type initialType, Type targetType) - { - Type valueType = (value != null) ? value.GetType() : null; - - if (value != null) - { - if (targetType.IsAssignableFrom(valueType)) - return value; - - Func castConverter = CastConverters.Get(new TypeConvertKey(valueType, targetType)); - if (castConverter != null) - return castConverter(value); - } - else - { - if (ReflectionUtils.IsNullable(targetType)) - return null; - } - - throw new ArgumentException("Could not cast or convert from {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, (initialType != null) ? initialType.ToString() : "{null}", targetType)); - } + throw new ArgumentException("Could not cast or convert from {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, (initialType != null) ? initialType.ToString() : "{null}", targetType)); + } #if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) - public static object ToValue(INullable nullableValue) - { - if (nullableValue == null) - return null; - else if (nullableValue is SqlInt32) - return ToValue((SqlInt32)nullableValue); - else if (nullableValue is SqlInt64) - return ToValue((SqlInt64)nullableValue); - else if (nullableValue is SqlBoolean) - return ToValue((SqlBoolean)nullableValue); - else if (nullableValue is SqlString) - return ToValue((SqlString)nullableValue); - else if (nullableValue is SqlDateTime) - return ToValue((SqlDateTime)nullableValue); + public static object ToValue(INullable nullableValue) + { + if (nullableValue == null) + return null; + else if (nullableValue is SqlInt32) + return ToValue((SqlInt32)nullableValue); + else if (nullableValue is SqlInt64) + return ToValue((SqlInt64)nullableValue); + else if (nullableValue is SqlBoolean) + return ToValue((SqlBoolean)nullableValue); + else if (nullableValue is SqlString) + return ToValue((SqlString)nullableValue); + else if (nullableValue is SqlDateTime) + return ToValue((SqlDateTime)nullableValue); - throw new ArgumentException("Unsupported INullable type: {0}".FormatWith(CultureInfo.InvariantCulture, nullableValue.GetType())); - } + throw new ArgumentException("Unsupported INullable type: {0}".FormatWith(CultureInfo.InvariantCulture, nullableValue.GetType())); + } #endif #if !(NETFX_CORE || PORTABLE40 || PORTABLE) - internal static TypeConverter GetConverter(Type t) - { - return JsonTypeReflector.GetTypeConverter(t); - } + internal static TypeConverter GetConverter(Type t) + { + return JsonTypeReflector.GetTypeConverter(t); + } #endif - public static bool IsInteger(object value) - { - switch (GetTypeCode(value)) - { - case PrimitiveTypeCode.SByte: - case PrimitiveTypeCode.Byte: - case PrimitiveTypeCode.Int16: - case PrimitiveTypeCode.UInt16: - case PrimitiveTypeCode.Int32: - case PrimitiveTypeCode.UInt32: - case PrimitiveTypeCode.Int64: - case PrimitiveTypeCode.UInt64: - return true; - default: - return false; - } - } - - public static int Int32Parse(char[] chars, int start, int length) - { - if (length == 0) - throw new FormatException("Input string was not in a correct format."); - - bool isNegative = (chars[start] == '-'); - - if (isNegative) - { - // text just a negative sign - if (length == 1) - throw new FormatException("Input string was not in a correct format."); - - start++; - length--; - } - - int result = 0; - int end = start + length; - - for (int i = start; i < end; i++) - { - int c = chars[i] - '0'; - - if (c < 0 || c > 9) - throw new FormatException("Input string was not in a correct format."); - - int newValue = (10*result) - c; - - // overflow has caused the number to loop around - if (newValue > result) + public static bool IsInteger(object value) { - i++; - - // double check the rest of the string that there wasn't anything invalid - // invalid result takes precedence over overflow result - for (; i < end; i++) - { - c = chars[i] - '0'; - - if (c < 0 || c > 9) - throw new FormatException("Input string was not in a correct format."); - } - - throw new OverflowException(); + switch (GetTypeCode(value)) + { + case PrimitiveTypeCode.SByte: + case PrimitiveTypeCode.Byte: + case PrimitiveTypeCode.Int16: + case PrimitiveTypeCode.UInt16: + case PrimitiveTypeCode.Int32: + case PrimitiveTypeCode.UInt32: + case PrimitiveTypeCode.Int64: + case PrimitiveTypeCode.UInt64: + return true; + default: + return false; + } } - result = newValue; - } - - // go from negative to positive to avoids overflow - // negative can be slightly bigger than positive - if (!isNegative) - { - // negative integer can be one bigger than positive - if (result == int.MinValue) - throw new OverflowException(); - - result = -result; - } - - return result; - } - - public static ParseResult Int64TryParse(char[] chars, int start, int length, out long value) - { - value = 0; - - if (length == 0) - return ParseResult.Invalid; - - bool isNegative = (chars[start] == '-'); - - if (isNegative) - { - // text just a negative sign - if (length == 1) - return ParseResult.Invalid; - - start++; - length--; - } - - int end = start + length; - - for (int i = start; i < end; i++) - { - int c = chars[i] - '0'; - - if (c < 0 || c > 9) - return ParseResult.Invalid; - - long newValue = (10*value) - c; - - // overflow has caused the number to loop around - if (newValue > value) + public static int Int32Parse(char[] chars, int start, int length) { - i++; + if (length == 0) + throw new FormatException("Input string was not in a correct format."); - // double check the rest of the string that there wasn't anything invalid - // invalid result takes precedence over overflow result - for (; i < end; i++) - { - c = chars[i] - '0'; + bool isNegative = (chars[start] == '-'); - if (c < 0 || c > 9) - return ParseResult.Invalid; - } + if (isNegative) + { + // text just a negative sign + if (length == 1) + throw new FormatException("Input string was not in a correct format."); - return ParseResult.Overflow; - + start++; + length--; + } + + int result = 0; + int end = start + length; + + for (int i = start; i < end; i++) + { + int c = chars[i] - '0'; + + if (c < 0 || c > 9) + throw new FormatException("Input string was not in a correct format."); + + int newValue = (10 * result) - c; + + // overflow has caused the number to loop around + if (newValue > result) + { + i++; + + // double check the rest of the string that there wasn't anything invalid + // invalid result takes precedence over overflow result + for (; i < end; i++) + { + c = chars[i] - '0'; + + if (c < 0 || c > 9) + throw new FormatException("Input string was not in a correct format."); + } + + throw new OverflowException(); + } + + result = newValue; + } + + // go from negative to positive to avoids overflow + // negative can be slightly bigger than positive + if (!isNegative) + { + // negative integer can be one bigger than positive + if (result == int.MinValue) + throw new OverflowException(); + + result = -result; + } + + return result; } - value = newValue; - } + public static ParseResult Int64TryParse(char[] chars, int start, int length, out long value) + { + value = 0; - // go from negative to positive to avoids overflow - // negative can be slightly bigger than positive - if (!isNegative) - { - // negative integer can be one bigger than positive - if (value == long.MinValue) - return ParseResult.Overflow; + if (length == 0) + return ParseResult.Invalid; - value = -value; - } + bool isNegative = (chars[start] == '-'); - return ParseResult.Success; + if (isNegative) + { + // text just a negative sign + if (length == 1) + return ParseResult.Invalid; + + start++; + length--; + } + + int end = start + length; + + for (int i = start; i < end; i++) + { + int c = chars[i] - '0'; + + if (c < 0 || c > 9) + return ParseResult.Invalid; + + long newValue = (10 * value) - c; + + // overflow has caused the number to loop around + if (newValue > value) + { + i++; + + // double check the rest of the string that there wasn't anything invalid + // invalid result takes precedence over overflow result + for (; i < end; i++) + { + c = chars[i] - '0'; + + if (c < 0 || c > 9) + return ParseResult.Invalid; + } + + return ParseResult.Overflow; + } + + value = newValue; + } + + // go from negative to positive to avoids overflow + // negative can be slightly bigger than positive + if (!isNegative) + { + // negative integer can be one bigger than positive + if (value == long.MinValue) + return ParseResult.Overflow; + + value = -value; + } + + return ParseResult.Success; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/DateTimeParser.cs b/Src/Newtonsoft.Json/Utilities/DateTimeParser.cs index 8ae6fa91..d09ff097 100644 --- a/Src/Newtonsoft.Json/Utilities/DateTimeParser.cs +++ b/Src/Newtonsoft.Json/Utilities/DateTimeParser.cs @@ -27,243 +27,243 @@ using System; namespace Newtonsoft.Json.Utilities { - internal enum ParserTimeZone - { - Unspecified, - Utc, - LocalWestOfUtc, - LocalEastOfUtc - } - - internal struct DateTimeParser - { - static DateTimeParser() + internal enum ParserTimeZone { - Power10 = new[] { -1, 10, 100, 1000, 10000, 100000, 1000000 }; - - Lzyyyy = "yyyy".Length; - Lzyyyy_ = "yyyy-".Length; - Lzyyyy_MM = "yyyy-MM".Length; - Lzyyyy_MM_ = "yyyy-MM-".Length; - Lzyyyy_MM_dd = "yyyy-MM-dd".Length; - Lzyyyy_MM_ddT = "yyyy-MM-ddT".Length; - LzHH = "HH".Length; - LzHH_ = "HH:".Length; - LzHH_mm = "HH:mm".Length; - LzHH_mm_ = "HH:mm:".Length; - LzHH_mm_ss = "HH:mm:ss".Length; - Lz_ = "-".Length; - Lz_zz = "-zz".Length; - Lz_zz_ = "-zz:".Length; - Lz_zz_zz = "-zz:zz".Length; + Unspecified, + Utc, + LocalWestOfUtc, + LocalEastOfUtc } - public int Year; - public int Month; - public int Day; - public int Hour; - public int Minute; - public int Second; - public int Fraction; - public int ZoneHour; - public int ZoneMinute; - public ParserTimeZone Zone; - - private string _text; - private int _length; - - private static readonly int[] Power10; - - private static readonly int Lzyyyy; - private static readonly int Lzyyyy_; - private static readonly int Lzyyyy_MM; - private static readonly int Lzyyyy_MM_; - private static readonly int Lzyyyy_MM_dd; - private static readonly int Lzyyyy_MM_ddT; - private static readonly int LzHH; - private static readonly int LzHH_; - private static readonly int LzHH_mm; - private static readonly int LzHH_mm_; - private static readonly int LzHH_mm_ss; - private static readonly int Lz_; - private static readonly int Lz_zz; - private static readonly int Lz_zz_; - private static readonly int Lz_zz_zz; - - private const short MaxFractionDigits = 7; - - public bool Parse(string text) + internal struct DateTimeParser { - _text = text; - _length = text.Length; - - if (ParseDate(0) && ParseChar(Lzyyyy_MM_dd, 'T') && ParseTimeAndZoneAndWhitespace(Lzyyyy_MM_ddT)) - return true; - - return false; - } - - private bool ParseDate(int start) - { - return (Parse4Digit(start, out Year) - && 1 <= Year - && ParseChar(start + Lzyyyy, '-') - && Parse2Digit(start + Lzyyyy_, out Month) - && 1 <= Month - && Month <= 12 - && ParseChar(start + Lzyyyy_MM, '-') - && Parse2Digit(start + Lzyyyy_MM_, out Day) - && 1 <= Day - && Day <= DateTime.DaysInMonth(Year, Month)); - } - - private bool ParseTimeAndZoneAndWhitespace(int start) - { - return (ParseTime(ref start) && ParseZone(start)); - } - - private bool ParseTime(ref int start) - { - if (!(Parse2Digit(start, out Hour) - && Hour < 24 - && ParseChar(start + LzHH, ':') - && Parse2Digit(start + LzHH_, out Minute) - && Minute < 60 - && ParseChar(start + LzHH_mm, ':') - && Parse2Digit(start + LzHH_mm_, out Second) - && Second < 60)) - { - return false; - } - - start += LzHH_mm_ss; - if (ParseChar(start, '.')) - { - Fraction = 0; - int numberOfDigits = 0; - - while (++start < _length && numberOfDigits < MaxFractionDigits) + static DateTimeParser() { - int digit = _text[start] - '0'; - if (digit < 0 || digit > 9) - break; + Power10 = new[] { -1, 10, 100, 1000, 10000, 100000, 1000000 }; - Fraction = (Fraction*10) + digit; - - numberOfDigits++; + Lzyyyy = "yyyy".Length; + Lzyyyy_ = "yyyy-".Length; + Lzyyyy_MM = "yyyy-MM".Length; + Lzyyyy_MM_ = "yyyy-MM-".Length; + Lzyyyy_MM_dd = "yyyy-MM-dd".Length; + Lzyyyy_MM_ddT = "yyyy-MM-ddT".Length; + LzHH = "HH".Length; + LzHH_ = "HH:".Length; + LzHH_mm = "HH:mm".Length; + LzHH_mm_ = "HH:mm:".Length; + LzHH_mm_ss = "HH:mm:ss".Length; + Lz_ = "-".Length; + Lz_zz = "-zz".Length; + Lz_zz_ = "-zz:".Length; + Lz_zz_zz = "-zz:zz".Length; } - if (numberOfDigits < MaxFractionDigits) + public int Year; + public int Month; + public int Day; + public int Hour; + public int Minute; + public int Second; + public int Fraction; + public int ZoneHour; + public int ZoneMinute; + public ParserTimeZone Zone; + + private string _text; + private int _length; + + private static readonly int[] Power10; + + private static readonly int Lzyyyy; + private static readonly int Lzyyyy_; + private static readonly int Lzyyyy_MM; + private static readonly int Lzyyyy_MM_; + private static readonly int Lzyyyy_MM_dd; + private static readonly int Lzyyyy_MM_ddT; + private static readonly int LzHH; + private static readonly int LzHH_; + private static readonly int LzHH_mm; + private static readonly int LzHH_mm_; + private static readonly int LzHH_mm_ss; + private static readonly int Lz_; + private static readonly int Lz_zz; + private static readonly int Lz_zz_; + private static readonly int Lz_zz_zz; + + private const short MaxFractionDigits = 7; + + public bool Parse(string text) { - if (numberOfDigits == 0) + _text = text; + _length = text.Length; + + if (ParseDate(0) && ParseChar(Lzyyyy_MM_dd, 'T') && ParseTimeAndZoneAndWhitespace(Lzyyyy_MM_ddT)) + return true; + return false; - - Fraction *= Power10[MaxFractionDigits - numberOfDigits]; } - } - return true; - } - private bool ParseZone(int start) - { - if (start < _length) - { - char ch = _text[start]; - if (ch == 'Z' || ch == 'z') + private bool ParseDate(int start) { - Zone = ParserTimeZone.Utc; - start++; + return (Parse4Digit(start, out Year) + && 1 <= Year + && ParseChar(start + Lzyyyy, '-') + && Parse2Digit(start + Lzyyyy_, out Month) + && 1 <= Month + && Month <= 12 + && ParseChar(start + Lzyyyy_MM, '-') + && Parse2Digit(start + Lzyyyy_MM_, out Day) + && 1 <= Day + && Day <= DateTime.DaysInMonth(Year, Month)); } - else + + private bool ParseTimeAndZoneAndWhitespace(int start) { - if (start + 2 < _length - && Parse2Digit(start + Lz_, out ZoneHour) - && ZoneHour <= 99) - { - switch (ch) + return (ParseTime(ref start) && ParseZone(start)); + } + + private bool ParseTime(ref int start) + { + if (!(Parse2Digit(start, out Hour) + && Hour < 24 + && ParseChar(start + LzHH, ':') + && Parse2Digit(start + LzHH_, out Minute) + && Minute < 60 + && ParseChar(start + LzHH_mm, ':') + && Parse2Digit(start + LzHH_mm_, out Second) + && Second < 60)) { - case '-': - Zone = ParserTimeZone.LocalWestOfUtc; - start += Lz_zz; - break; - - case '+': - Zone = ParserTimeZone.LocalEastOfUtc; - start += Lz_zz; - break; + return false; } - } - if (start < _length) - { - if (ParseChar(start, ':')) + start += LzHH_mm_ss; + if (ParseChar(start, '.')) { - start += 1; + Fraction = 0; + int numberOfDigits = 0; - if (start + 1 < _length - && Parse2Digit(start, out ZoneMinute) - && ZoneMinute <= 99) - { - start += 2; - } + while (++start < _length && numberOfDigits < MaxFractionDigits) + { + int digit = _text[start] - '0'; + if (digit < 0 || digit > 9) + break; + + Fraction = (Fraction * 10) + digit; + + numberOfDigits++; + } + + if (numberOfDigits < MaxFractionDigits) + { + if (numberOfDigits == 0) + return false; + + Fraction *= Power10[MaxFractionDigits - numberOfDigits]; + } } - else + return true; + } + + private bool ParseZone(int start) + { + if (start < _length) { - if (start + 1 < _length - && Parse2Digit(start, out ZoneMinute) - && ZoneMinute <= 99) - { - start += 2; - } + char ch = _text[start]; + if (ch == 'Z' || ch == 'z') + { + Zone = ParserTimeZone.Utc; + start++; + } + else + { + if (start + 2 < _length + && Parse2Digit(start + Lz_, out ZoneHour) + && ZoneHour <= 99) + { + switch (ch) + { + case '-': + Zone = ParserTimeZone.LocalWestOfUtc; + start += Lz_zz; + break; + + case '+': + Zone = ParserTimeZone.LocalEastOfUtc; + start += Lz_zz; + break; + } + } + + if (start < _length) + { + if (ParseChar(start, ':')) + { + start += 1; + + if (start + 1 < _length + && Parse2Digit(start, out ZoneMinute) + && ZoneMinute <= 99) + { + start += 2; + } + } + else + { + if (start + 1 < _length + && Parse2Digit(start, out ZoneMinute) + && ZoneMinute <= 99) + { + start += 2; + } + } + } + } } - } + + return (start == _length); } - } - return (start == _length); - } - - private bool Parse4Digit(int start, out int num) - { - if (start + 3 < _length) - { - int digit1 = _text[start] - '0'; - int digit2 = _text[start + 1] - '0'; - int digit3 = _text[start + 2] - '0'; - int digit4 = _text[start + 3] - '0'; - if (0 <= digit1 && digit1 < 10 - && 0 <= digit2 && digit2 < 10 - && 0 <= digit3 && digit3 < 10 - && 0 <= digit4 && digit4 < 10) + private bool Parse4Digit(int start, out int num) { - num = (((((digit1*10) + digit2)*10) + digit3)*10) + digit4; - return true; + if (start + 3 < _length) + { + int digit1 = _text[start] - '0'; + int digit2 = _text[start + 1] - '0'; + int digit3 = _text[start + 2] - '0'; + int digit4 = _text[start + 3] - '0'; + if (0 <= digit1 && digit1 < 10 + && 0 <= digit2 && digit2 < 10 + && 0 <= digit3 && digit3 < 10 + && 0 <= digit4 && digit4 < 10) + { + num = (((((digit1 * 10) + digit2) * 10) + digit3) * 10) + digit4; + return true; + } + } + num = 0; + return false; } - } - num = 0; - return false; - } - private bool Parse2Digit(int start, out int num) - { - if (start + 1 < _length) - { - int digit1 = _text[start] - '0'; - int digit2 = _text[start + 1] - '0'; - if (0 <= digit1 && digit1 < 10 - && 0 <= digit2 && digit2 < 10) + private bool Parse2Digit(int start, out int num) { - num = (digit1*10) + digit2; - return true; + if (start + 1 < _length) + { + int digit1 = _text[start] - '0'; + int digit2 = _text[start + 1] - '0'; + if (0 <= digit1 && digit1 < 10 + && 0 <= digit2 && digit2 < 10) + { + num = (digit1 * 10) + digit2; + return true; + } + } + num = 0; + return false; } - } - num = 0; - return false; - } - private bool ParseChar(int start, char ch) - { - return (start < _length && _text[start] == ch); + private bool ParseChar(int start, char ch) + { + return (start < _length && _text[start] == ch); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/DateTimeUtils.cs b/Src/Newtonsoft.Json/Utilities/DateTimeUtils.cs index 6e7a7a83..5343e238 100644 --- a/Src/Newtonsoft.Json/Utilities/DateTimeUtils.cs +++ b/Src/Newtonsoft.Json/Utilities/DateTimeUtils.cs @@ -1,5 +1,4 @@ #region License - // Copyright (c) 2007 James Newton-King // // Permission is hereby granted, free of charge, to any person @@ -22,7 +21,6 @@ // 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 using System; @@ -32,549 +30,548 @@ using System.Globalization; namespace Newtonsoft.Json.Utilities { - internal static class DateTimeUtils - { - internal static readonly long InitialJavaScriptDateTicks = 621355968000000000; - - private const int DaysPer100Years = 36524; - private const int DaysPer400Years = 146097; - private const int DaysPer4Years = 1461; - private const int DaysPerYear = 365; - private const long TicksPerDay = 864000000000L; - private static readonly int[] DaysToMonth365; - private static readonly int[] DaysToMonth366; - - static DateTimeUtils() + internal static class DateTimeUtils { - DaysToMonth365 = new[] { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }; - DaysToMonth366 = new[] { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }; - } + internal static readonly long InitialJavaScriptDateTicks = 621355968000000000; - public static TimeSpan GetUtcOffset(this DateTime d) - { + private const int DaysPer100Years = 36524; + private const int DaysPer400Years = 146097; + private const int DaysPer4Years = 1461; + private const int DaysPerYear = 365; + private const long TicksPerDay = 864000000000L; + private static readonly int[] DaysToMonth365; + private static readonly int[] DaysToMonth366; + + static DateTimeUtils() + { + DaysToMonth365 = new[] { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }; + DaysToMonth366 = new[] { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }; + } + + public static TimeSpan GetUtcOffset(this DateTime d) + { #if NET20 return TimeZone.CurrentTimeZone.GetUtcOffset(d); #else - return TimeZoneInfo.Local.GetUtcOffset(d); + return TimeZoneInfo.Local.GetUtcOffset(d); #endif - } + } #if !(NETFX_CORE || PORTABLE40 || PORTABLE) - public static XmlDateTimeSerializationMode ToSerializationMode(DateTimeKind kind) - { - switch (kind) - { - case DateTimeKind.Local: - return XmlDateTimeSerializationMode.Local; - case DateTimeKind.Unspecified: - return XmlDateTimeSerializationMode.Unspecified; - case DateTimeKind.Utc: - return XmlDateTimeSerializationMode.Utc; - default: - throw MiscellaneousUtils.CreateArgumentOutOfRangeException("kind", kind, "Unexpected DateTimeKind value."); - } - } + public static XmlDateTimeSerializationMode ToSerializationMode(DateTimeKind kind) + { + switch (kind) + { + case DateTimeKind.Local: + return XmlDateTimeSerializationMode.Local; + case DateTimeKind.Unspecified: + return XmlDateTimeSerializationMode.Unspecified; + case DateTimeKind.Utc: + return XmlDateTimeSerializationMode.Utc; + default: + throw MiscellaneousUtils.CreateArgumentOutOfRangeException("kind", kind, "Unexpected DateTimeKind value."); + } + } #endif - internal static DateTime EnsureDateTime(DateTime value, DateTimeZoneHandling timeZone) - { - switch (timeZone) - { - case DateTimeZoneHandling.Local: - value = SwitchToLocalTime(value); - break; - case DateTimeZoneHandling.Utc: - value = SwitchToUtcTime(value); - break; - case DateTimeZoneHandling.Unspecified: - value = new DateTime(value.Ticks, DateTimeKind.Unspecified); - break; - case DateTimeZoneHandling.RoundtripKind: - break; - default: - throw new ArgumentException("Invalid date time handling value."); - } + internal static DateTime EnsureDateTime(DateTime value, DateTimeZoneHandling timeZone) + { + switch (timeZone) + { + case DateTimeZoneHandling.Local: + value = SwitchToLocalTime(value); + break; + case DateTimeZoneHandling.Utc: + value = SwitchToUtcTime(value); + break; + case DateTimeZoneHandling.Unspecified: + value = new DateTime(value.Ticks, DateTimeKind.Unspecified); + break; + case DateTimeZoneHandling.RoundtripKind: + break; + default: + throw new ArgumentException("Invalid date time handling value."); + } - return value; - } + return value; + } - private static DateTime SwitchToLocalTime(DateTime value) - { - switch (value.Kind) - { - case DateTimeKind.Unspecified: - return new DateTime(value.Ticks, DateTimeKind.Local); + private static DateTime SwitchToLocalTime(DateTime value) + { + switch (value.Kind) + { + case DateTimeKind.Unspecified: + return new DateTime(value.Ticks, DateTimeKind.Local); - case DateTimeKind.Utc: - return value.ToLocalTime(); + case DateTimeKind.Utc: + return value.ToLocalTime(); - case DateTimeKind.Local: - return value; - } - return value; - } + case DateTimeKind.Local: + return value; + } + return value; + } - private static DateTime SwitchToUtcTime(DateTime value) - { - switch (value.Kind) - { - case DateTimeKind.Unspecified: - return new DateTime(value.Ticks, DateTimeKind.Utc); + private static DateTime SwitchToUtcTime(DateTime value) + { + switch (value.Kind) + { + case DateTimeKind.Unspecified: + return new DateTime(value.Ticks, DateTimeKind.Utc); - case DateTimeKind.Utc: - return value; + case DateTimeKind.Utc: + return value; - case DateTimeKind.Local: - return value.ToUniversalTime(); - } - return value; - } + case DateTimeKind.Local: + return value.ToUniversalTime(); + } + return value; + } - private static long ToUniversalTicks(DateTime dateTime) - { - if (dateTime.Kind == DateTimeKind.Utc) - return dateTime.Ticks; + private static long ToUniversalTicks(DateTime dateTime) + { + if (dateTime.Kind == DateTimeKind.Utc) + return dateTime.Ticks; - return ToUniversalTicks(dateTime, dateTime.GetUtcOffset()); - } + return ToUniversalTicks(dateTime, dateTime.GetUtcOffset()); + } - private static long ToUniversalTicks(DateTime dateTime, TimeSpan offset) - { - // special case min and max value - // they never have a timezone appended to avoid issues - if (dateTime.Kind == DateTimeKind.Utc || dateTime == DateTime.MaxValue || dateTime == DateTime.MinValue) - return dateTime.Ticks; + private static long ToUniversalTicks(DateTime dateTime, TimeSpan offset) + { + // special case min and max value + // they never have a timezone appended to avoid issues + if (dateTime.Kind == DateTimeKind.Utc || dateTime == DateTime.MaxValue || dateTime == DateTime.MinValue) + return dateTime.Ticks; - long ticks = dateTime.Ticks - offset.Ticks; - if (ticks > 3155378975999999999L) - return 3155378975999999999L; + long ticks = dateTime.Ticks - offset.Ticks; + if (ticks > 3155378975999999999L) + return 3155378975999999999L; - if (ticks < 0L) - return 0L; + if (ticks < 0L) + return 0L; - return ticks; - } + return ticks; + } - internal static long ConvertDateTimeToJavaScriptTicks(DateTime dateTime, TimeSpan offset) - { - long universialTicks = ToUniversalTicks(dateTime, offset); + internal static long ConvertDateTimeToJavaScriptTicks(DateTime dateTime, TimeSpan offset) + { + long universialTicks = ToUniversalTicks(dateTime, offset); - return UniversialTicksToJavaScriptTicks(universialTicks); - } + return UniversialTicksToJavaScriptTicks(universialTicks); + } - internal static long ConvertDateTimeToJavaScriptTicks(DateTime dateTime) - { - return ConvertDateTimeToJavaScriptTicks(dateTime, true); - } + internal static long ConvertDateTimeToJavaScriptTicks(DateTime dateTime) + { + return ConvertDateTimeToJavaScriptTicks(dateTime, true); + } - internal static long ConvertDateTimeToJavaScriptTicks(DateTime dateTime, bool convertToUtc) - { - long ticks = (convertToUtc) ? ToUniversalTicks(dateTime) : dateTime.Ticks; + internal static long ConvertDateTimeToJavaScriptTicks(DateTime dateTime, bool convertToUtc) + { + long ticks = (convertToUtc) ? ToUniversalTicks(dateTime) : dateTime.Ticks; - return UniversialTicksToJavaScriptTicks(ticks); - } + return UniversialTicksToJavaScriptTicks(ticks); + } - private static long UniversialTicksToJavaScriptTicks(long universialTicks) - { - long javaScriptTicks = (universialTicks - InitialJavaScriptDateTicks)/10000; + private static long UniversialTicksToJavaScriptTicks(long universialTicks) + { + long javaScriptTicks = (universialTicks - InitialJavaScriptDateTicks) / 10000; - return javaScriptTicks; - } + return javaScriptTicks; + } - internal static DateTime ConvertJavaScriptTicksToDateTime(long javaScriptTicks) - { - DateTime dateTime = new DateTime((javaScriptTicks*10000) + InitialJavaScriptDateTicks, DateTimeKind.Utc); + internal static DateTime ConvertJavaScriptTicksToDateTime(long javaScriptTicks) + { + DateTime dateTime = new DateTime((javaScriptTicks * 10000) + InitialJavaScriptDateTicks, DateTimeKind.Utc); - return dateTime; - } + return dateTime; + } -#region Parse + #region Parse + internal static bool TryParseDateIso(string text, DateParseHandling dateParseHandling, DateTimeZoneHandling dateTimeZoneHandling, out object dt) + { + DateTimeParser dateTimeParser = new DateTimeParser(); + if (!dateTimeParser.Parse(text)) + { + dt = null; + return false; + } - internal static bool TryParseDateIso(string text, DateParseHandling dateParseHandling, DateTimeZoneHandling dateTimeZoneHandling, out object dt) - { - DateTimeParser dateTimeParser = new DateTimeParser(); - if (!dateTimeParser.Parse(text)) - { - dt = null; - return false; - } - - DateTime d = new DateTime(dateTimeParser.Year, dateTimeParser.Month, dateTimeParser.Day, dateTimeParser.Hour, dateTimeParser.Minute, dateTimeParser.Second); - d = d.AddTicks(dateTimeParser.Fraction); + DateTime d = new DateTime(dateTimeParser.Year, dateTimeParser.Month, dateTimeParser.Day, dateTimeParser.Hour, dateTimeParser.Minute, dateTimeParser.Second); + d = d.AddTicks(dateTimeParser.Fraction); #if !NET20 - if (dateParseHandling == DateParseHandling.DateTimeOffset) - { - TimeSpan offset; - - switch (dateTimeParser.Zone) - { - case ParserTimeZone.Utc: - offset = new TimeSpan(0L); - break; - case ParserTimeZone.LocalWestOfUtc: - offset = new TimeSpan(-dateTimeParser.ZoneHour, -dateTimeParser.ZoneMinute, 0); - break; - case ParserTimeZone.LocalEastOfUtc: - offset = new TimeSpan(dateTimeParser.ZoneHour, dateTimeParser.ZoneMinute, 0); - break; - default: - offset = TimeZoneInfo.Local.GetUtcOffset(d); - break; - } - - long ticks = d.Ticks - offset.Ticks; - if (ticks < 0 || ticks > 3155378975999999999) - { - dt = null; - return false; - } - - dt = new DateTimeOffset(d, offset); - return true; - } - else -#endif - { - long ticks; - - switch (dateTimeParser.Zone) - { - case ParserTimeZone.Utc: - d = new DateTime(d.Ticks, DateTimeKind.Utc); - break; - - case ParserTimeZone.LocalWestOfUtc: + if (dateParseHandling == DateParseHandling.DateTimeOffset) { - TimeSpan offset = new TimeSpan(dateTimeParser.ZoneHour, dateTimeParser.ZoneMinute, 0); - ticks = d.Ticks + offset.Ticks; - if (ticks <= DateTime.MaxValue.Ticks) - { - d = new DateTime(ticks, DateTimeKind.Utc).ToLocalTime(); - } - else - { - ticks += d.GetUtcOffset().Ticks; - if (ticks > DateTime.MaxValue.Ticks) - ticks = DateTime.MaxValue.Ticks; + TimeSpan offset; - d = new DateTime(ticks, DateTimeKind.Local); - } - break; + switch (dateTimeParser.Zone) + { + case ParserTimeZone.Utc: + offset = new TimeSpan(0L); + break; + case ParserTimeZone.LocalWestOfUtc: + offset = new TimeSpan(-dateTimeParser.ZoneHour, -dateTimeParser.ZoneMinute, 0); + break; + case ParserTimeZone.LocalEastOfUtc: + offset = new TimeSpan(dateTimeParser.ZoneHour, dateTimeParser.ZoneMinute, 0); + break; + default: + offset = TimeZoneInfo.Local.GetUtcOffset(d); + break; + } + + long ticks = d.Ticks - offset.Ticks; + if (ticks < 0 || ticks > 3155378975999999999) + { + dt = null; + return false; + } + + dt = new DateTimeOffset(d, offset); + return true; } - case ParserTimeZone.LocalEastOfUtc: + else +#endif { - TimeSpan offset = new TimeSpan(dateTimeParser.ZoneHour, dateTimeParser.ZoneMinute, 0); - ticks = d.Ticks - offset.Ticks; - if (ticks >= DateTime.MinValue.Ticks) - { - d = new DateTime(ticks, DateTimeKind.Utc).ToLocalTime(); - } - else - { - ticks += d.GetUtcOffset().Ticks; - if (ticks < DateTime.MinValue.Ticks) - ticks = DateTime.MinValue.Ticks; + long ticks; - d = new DateTime(ticks, DateTimeKind.Local); - } - break; + switch (dateTimeParser.Zone) + { + case ParserTimeZone.Utc: + d = new DateTime(d.Ticks, DateTimeKind.Utc); + break; + + case ParserTimeZone.LocalWestOfUtc: + { + TimeSpan offset = new TimeSpan(dateTimeParser.ZoneHour, dateTimeParser.ZoneMinute, 0); + ticks = d.Ticks + offset.Ticks; + if (ticks <= DateTime.MaxValue.Ticks) + { + d = new DateTime(ticks, DateTimeKind.Utc).ToLocalTime(); + } + else + { + ticks += d.GetUtcOffset().Ticks; + if (ticks > DateTime.MaxValue.Ticks) + ticks = DateTime.MaxValue.Ticks; + + d = new DateTime(ticks, DateTimeKind.Local); + } + break; + } + case ParserTimeZone.LocalEastOfUtc: + { + TimeSpan offset = new TimeSpan(dateTimeParser.ZoneHour, dateTimeParser.ZoneMinute, 0); + ticks = d.Ticks - offset.Ticks; + if (ticks >= DateTime.MinValue.Ticks) + { + d = new DateTime(ticks, DateTimeKind.Utc).ToLocalTime(); + } + else + { + ticks += d.GetUtcOffset().Ticks; + if (ticks < DateTime.MinValue.Ticks) + ticks = DateTime.MinValue.Ticks; + + d = new DateTime(ticks, DateTimeKind.Local); + } + break; + } + } + + dt = EnsureDateTime(d, dateTimeZoneHandling); + return true; } } - dt = EnsureDateTime(d, dateTimeZoneHandling); - return true; - } - } - - internal static bool TryParseDateTime(string s, DateParseHandling dateParseHandling, DateTimeZoneHandling dateTimeZoneHandling, out object dt) - { - if (s.Length > 0) - { - if (s[0] == '/') + internal static bool TryParseDateTime(string s, DateParseHandling dateParseHandling, DateTimeZoneHandling dateTimeZoneHandling, out object dt) { - if (s.StartsWith("/Date(", StringComparison.Ordinal) && s.EndsWith(")/", StringComparison.Ordinal)) - { - return TryParseDateMicrosoft(s, dateParseHandling, dateTimeZoneHandling, out dt); - } + if (s.Length > 0) + { + if (s[0] == '/') + { + if (s.StartsWith("/Date(", StringComparison.Ordinal) && s.EndsWith(")/", StringComparison.Ordinal)) + { + return TryParseDateMicrosoft(s, dateParseHandling, dateTimeZoneHandling, out dt); + } + } + else if (s.Length >= 19 && s.Length <= 40 && char.IsDigit(s[0]) && s[10] == 'T') + { + return TryParseDateIso(s, dateParseHandling, dateTimeZoneHandling, out dt); + } + } + + dt = null; + return false; } - else if (s.Length >= 19 && s.Length <= 40 && char.IsDigit(s[0]) && s[10] == 'T') + + private static bool TryParseDateMicrosoft(string text, DateParseHandling dateParseHandling, DateTimeZoneHandling dateTimeZoneHandling, out object dt) { - return TryParseDateIso(s, dateParseHandling, dateTimeZoneHandling, out dt); - } - } + string value = text.Substring(6, text.Length - 8); + DateTimeKind kind = DateTimeKind.Utc; - dt = null; - return false; - } + int index = value.IndexOf('+', 1); - private static bool TryParseDateMicrosoft(string text, DateParseHandling dateParseHandling, DateTimeZoneHandling dateTimeZoneHandling, out object dt) - { - string value = text.Substring(6, text.Length - 8); - DateTimeKind kind = DateTimeKind.Utc; + if (index == -1) + index = value.IndexOf('-', 1); - int index = value.IndexOf('+', 1); + TimeSpan offset = TimeSpan.Zero; - if (index == -1) - index = value.IndexOf('-', 1); + if (index != -1) + { + kind = DateTimeKind.Local; + offset = ReadOffset(value.Substring(index)); + value = value.Substring(0, index); + } - TimeSpan offset = TimeSpan.Zero; + long javaScriptTicks = long.Parse(value, NumberStyles.Integer, CultureInfo.InvariantCulture); - if (index != -1) - { - kind = DateTimeKind.Local; - offset = ReadOffset(value.Substring(index)); - value = value.Substring(0, index); - } - - long javaScriptTicks = long.Parse(value, NumberStyles.Integer, CultureInfo.InvariantCulture); - - DateTime utcDateTime = ConvertJavaScriptTicksToDateTime(javaScriptTicks); + DateTime utcDateTime = ConvertJavaScriptTicksToDateTime(javaScriptTicks); #if !NET20 - if (dateParseHandling == DateParseHandling.DateTimeOffset) - { - dt = new DateTimeOffset(utcDateTime.Add(offset).Ticks, offset); - return true; - } - else + if (dateParseHandling == DateParseHandling.DateTimeOffset) + { + dt = new DateTimeOffset(utcDateTime.Add(offset).Ticks, offset); + return true; + } + else #endif - { - DateTime dateTime; + { + DateTime dateTime; - switch (kind) - { - case DateTimeKind.Unspecified: - dateTime = DateTime.SpecifyKind(utcDateTime.ToLocalTime(), DateTimeKind.Unspecified); - break; - case DateTimeKind.Local: - dateTime = utcDateTime.ToLocalTime(); - break; - default: - dateTime = utcDateTime; - break; + switch (kind) + { + case DateTimeKind.Unspecified: + dateTime = DateTime.SpecifyKind(utcDateTime.ToLocalTime(), DateTimeKind.Unspecified); + break; + case DateTimeKind.Local: + dateTime = utcDateTime.ToLocalTime(); + break; + default: + dateTime = utcDateTime; + break; + } + + dt = EnsureDateTime(dateTime, dateTimeZoneHandling); + return true; + } } - dt = EnsureDateTime(dateTime, dateTimeZoneHandling); - return true; - } - } - - private static TimeSpan ReadOffset(string offsetText) - { - bool negative = (offsetText[0] == '-'); - - int hours = int.Parse(offsetText.Substring(1, 2), NumberStyles.Integer, CultureInfo.InvariantCulture); - int minutes = 0; - if (offsetText.Length >= 5) - minutes = int.Parse(offsetText.Substring(3, 2), NumberStyles.Integer, CultureInfo.InvariantCulture); - - TimeSpan offset = TimeSpan.FromHours(hours) + TimeSpan.FromMinutes(minutes); - if (negative) - offset = offset.Negate(); - - return offset; - } -#endregion - -#region Write - internal static void WriteDateTimeString(TextWriter writer, DateTime value, DateFormatHandling format, string formatString, CultureInfo culture) - { - if (string.IsNullOrEmpty(formatString)) - { - char[] chars = new char[64]; - int pos = WriteDateTimeString(chars, 0, value, null, value.Kind, format); - writer.Write(chars, 0, pos); - } - else - { - writer.Write(value.ToString(formatString, culture)); - } - } - - internal static int WriteDateTimeString(char[] chars, int start, DateTime value, TimeSpan? offset, DateTimeKind kind, DateFormatHandling format) - { - int pos = start; - - if (format == DateFormatHandling.MicrosoftDateFormat) - { - TimeSpan o = offset ?? value.GetUtcOffset(); - - long javaScriptTicks = ConvertDateTimeToJavaScriptTicks(value, o); - - @"\/Date(".CopyTo(0, chars, pos, 7); - pos += 7; - - string ticksText = javaScriptTicks.ToString(CultureInfo.InvariantCulture); - ticksText.CopyTo(0, chars, pos, ticksText.Length); - pos += ticksText.Length; - - switch (kind) + private static TimeSpan ReadOffset(string offsetText) { - case DateTimeKind.Unspecified: - if (value != DateTime.MaxValue && value != DateTime.MinValue) - pos = WriteDateTimeOffset(chars, pos, o, format); - break; - case DateTimeKind.Local: - pos = WriteDateTimeOffset(chars, pos, o, format); - break; + bool negative = (offsetText[0] == '-'); + + int hours = int.Parse(offsetText.Substring(1, 2), NumberStyles.Integer, CultureInfo.InvariantCulture); + int minutes = 0; + if (offsetText.Length >= 5) + minutes = int.Parse(offsetText.Substring(3, 2), NumberStyles.Integer, CultureInfo.InvariantCulture); + + TimeSpan offset = TimeSpan.FromHours(hours) + TimeSpan.FromMinutes(minutes); + if (negative) + offset = offset.Negate(); + + return offset; + } + #endregion + + #region Write + internal static void WriteDateTimeString(TextWriter writer, DateTime value, DateFormatHandling format, string formatString, CultureInfo culture) + { + if (string.IsNullOrEmpty(formatString)) + { + char[] chars = new char[64]; + int pos = WriteDateTimeString(chars, 0, value, null, value.Kind, format); + writer.Write(chars, 0, pos); + } + else + { + writer.Write(value.ToString(formatString, culture)); + } } - @")\/".CopyTo(0, chars, pos, 3); - pos += 3; - } - else - { - pos = WriteDefaultIsoDate(chars, pos, value); - - switch (kind) + internal static int WriteDateTimeString(char[] chars, int start, DateTime value, TimeSpan? offset, DateTimeKind kind, DateFormatHandling format) { - case DateTimeKind.Local: - pos = WriteDateTimeOffset(chars, pos, offset ?? value.GetUtcOffset(), format); - break; - case DateTimeKind.Utc: - chars[pos++] = 'Z'; - break; - } - } + int pos = start; - return pos; - } + if (format == DateFormatHandling.MicrosoftDateFormat) + { + TimeSpan o = offset ?? value.GetUtcOffset(); - internal static int WriteDefaultIsoDate(char[] chars, int start, DateTime dt) - { - int length = 19; + long javaScriptTicks = ConvertDateTimeToJavaScriptTicks(value, o); - int year; - int month; - int day; - GetDateValues(dt, out year, out month, out day); + @"\/Date(".CopyTo(0, chars, pos, 7); + pos += 7; - CopyIntToCharArray(chars, start, year, 4); - chars[start + 4] = '-'; - CopyIntToCharArray(chars, start + 5, month, 2); - chars[start + 7] = '-'; - CopyIntToCharArray(chars, start + 8, day, 2); - chars[start + 10] = 'T'; - CopyIntToCharArray(chars, start + 11, dt.Hour, 2); - chars[start + 13] = ':'; - CopyIntToCharArray(chars, start + 14, dt.Minute, 2); - chars[start + 16] = ':'; - CopyIntToCharArray(chars, start + 17, dt.Second, 2); + string ticksText = javaScriptTicks.ToString(CultureInfo.InvariantCulture); + ticksText.CopyTo(0, chars, pos, ticksText.Length); + pos += ticksText.Length; - int fraction = (int)(dt.Ticks % 10000000L); + switch (kind) + { + case DateTimeKind.Unspecified: + if (value != DateTime.MaxValue && value != DateTime.MinValue) + pos = WriteDateTimeOffset(chars, pos, o, format); + break; + case DateTimeKind.Local: + pos = WriteDateTimeOffset(chars, pos, o, format); + break; + } - if (fraction != 0) - { - int digits = 7; - while ((fraction%10) == 0) - { - digits--; - fraction /= 10; + @")\/".CopyTo(0, chars, pos, 3); + pos += 3; + } + else + { + pos = WriteDefaultIsoDate(chars, pos, value); + + switch (kind) + { + case DateTimeKind.Local: + pos = WriteDateTimeOffset(chars, pos, offset ?? value.GetUtcOffset(), format); + break; + case DateTimeKind.Utc: + chars[pos++] = 'Z'; + break; + } + } + + return pos; } - chars[start + 19] = '.'; - CopyIntToCharArray(chars, start + 20, fraction, digits); + internal static int WriteDefaultIsoDate(char[] chars, int start, DateTime dt) + { + int length = 19; - length += digits + 1; - } + int year; + int month; + int day; + GetDateValues(dt, out year, out month, out day); - return start + length; - } + CopyIntToCharArray(chars, start, year, 4); + chars[start + 4] = '-'; + CopyIntToCharArray(chars, start + 5, month, 2); + chars[start + 7] = '-'; + CopyIntToCharArray(chars, start + 8, day, 2); + chars[start + 10] = 'T'; + CopyIntToCharArray(chars, start + 11, dt.Hour, 2); + chars[start + 13] = ':'; + CopyIntToCharArray(chars, start + 14, dt.Minute, 2); + chars[start + 16] = ':'; + CopyIntToCharArray(chars, start + 17, dt.Second, 2); - private static void CopyIntToCharArray(char[] chars, int start, int value, int digits) - { - while (digits-- != 0) - { - chars[start + digits] = (char) ((value%10) + 48); - value /= 10; - } - } + int fraction = (int)(dt.Ticks % 10000000L); - internal static int WriteDateTimeOffset(char[] chars, int start, TimeSpan offset, DateFormatHandling format) - { - chars[start++] = (offset.Ticks >= 0L) ? '+' : '-'; + if (fraction != 0) + { + int digits = 7; + while ((fraction % 10) == 0) + { + digits--; + fraction /= 10; + } - int absHours = Math.Abs(offset.Hours); - CopyIntToCharArray(chars, start, absHours, 2); - start += 2; + chars[start + 19] = '.'; + CopyIntToCharArray(chars, start + 20, fraction, digits); - if (format == DateFormatHandling.IsoDateFormat) - chars[start++] = ':'; + length += digits + 1; + } - int absMinutes = Math.Abs(offset.Minutes); - CopyIntToCharArray(chars, start, absMinutes, 2); - start += 2; + return start + length; + } - return start; - } + private static void CopyIntToCharArray(char[] chars, int start, int value, int digits) + { + while (digits-- != 0) + { + chars[start + digits] = (char)((value % 10) + 48); + value /= 10; + } + } + + internal static int WriteDateTimeOffset(char[] chars, int start, TimeSpan offset, DateFormatHandling format) + { + chars[start++] = (offset.Ticks >= 0L) ? '+' : '-'; + + int absHours = Math.Abs(offset.Hours); + CopyIntToCharArray(chars, start, absHours, 2); + start += 2; + + if (format == DateFormatHandling.IsoDateFormat) + chars[start++] = ':'; + + int absMinutes = Math.Abs(offset.Minutes); + CopyIntToCharArray(chars, start, absMinutes, 2); + start += 2; + + return start; + } #if !NET20 - internal static void WriteDateTimeOffsetString(TextWriter writer, DateTimeOffset value, DateFormatHandling format, string formatString, CultureInfo culture) - { - if (string.IsNullOrEmpty(formatString)) - { - char[] chars = new char[64]; - int pos = WriteDateTimeString(chars, 0, (format == DateFormatHandling.IsoDateFormat) ? value.DateTime : value.UtcDateTime, value.Offset, DateTimeKind.Local, format); + internal static void WriteDateTimeOffsetString(TextWriter writer, DateTimeOffset value, DateFormatHandling format, string formatString, CultureInfo culture) + { + if (string.IsNullOrEmpty(formatString)) + { + char[] chars = new char[64]; + int pos = WriteDateTimeString(chars, 0, (format == DateFormatHandling.IsoDateFormat) ? value.DateTime : value.UtcDateTime, value.Offset, DateTimeKind.Local, format); - writer.Write(chars, 0, pos); - } - else - { - writer.Write(value.ToString(formatString, culture)); - } - } + writer.Write(chars, 0, pos); + } + else + { + writer.Write(value.ToString(formatString, culture)); + } + } #endif -#endregion + #endregion - private static void GetDateValues(DateTime td, out int year, out int month, out int day) - { - long ticks = td.Ticks; - // n = number of days since 1/1/0001 - int n = (int) (ticks/TicksPerDay); - // y400 = number of whole 400-year periods since 1/1/0001 - int y400 = n/DaysPer400Years; - // n = day number within 400-year period - n -= y400*DaysPer400Years; - // y100 = number of whole 100-year periods within 400-year period - int y100 = n/DaysPer100Years; - // Last 100-year period has an extra day, so decrement result if 4 - if (y100 == 4) - y100 = 3; - // n = day number within 100-year period - n -= y100*DaysPer100Years; - // y4 = number of whole 4-year periods within 100-year period - int y4 = n/DaysPer4Years; - // n = day number within 4-year period - n -= y4*DaysPer4Years; - // y1 = number of whole years within 4-year period - int y1 = n/DaysPerYear; - // Last year has an extra day, so decrement result if 4 - if (y1 == 4) - y1 = 3; + private static void GetDateValues(DateTime td, out int year, out int month, out int day) + { + long ticks = td.Ticks; + // n = number of days since 1/1/0001 + int n = (int)(ticks / TicksPerDay); + // y400 = number of whole 400-year periods since 1/1/0001 + int y400 = n / DaysPer400Years; + // n = day number within 400-year period + n -= y400 * DaysPer400Years; + // y100 = number of whole 100-year periods within 400-year period + int y100 = n / DaysPer100Years; + // Last 100-year period has an extra day, so decrement result if 4 + if (y100 == 4) + y100 = 3; + // n = day number within 100-year period + n -= y100 * DaysPer100Years; + // y4 = number of whole 4-year periods within 100-year period + int y4 = n / DaysPer4Years; + // n = day number within 4-year period + n -= y4 * DaysPer4Years; + // y1 = number of whole years within 4-year period + int y1 = n / DaysPerYear; + // Last year has an extra day, so decrement result if 4 + if (y1 == 4) + y1 = 3; - year = y400*400 + y100*100 + y4*4 + y1 + 1; + year = y400 * 400 + y100 * 100 + y4 * 4 + y1 + 1; - // n = day number within year - n -= y1*DaysPerYear; + // n = day number within year + n -= y1 * DaysPerYear; - // Leap year calculation looks different from IsLeapYear since y1, y4, - // and y100 are relative to year 1, not year 0 - bool leapYear = y1 == 3 && (y4 != 24 || y100 == 3); - int[] days = leapYear ? DaysToMonth366 : DaysToMonth365; - // All months have less than 32 days, so n >> 5 is a good conservative - // estimate for the month - int m = n >> 5 + 1; - // m = 1-based month number - while (n >= days[m]) - { - m++; - } + // Leap year calculation looks different from IsLeapYear since y1, y4, + // and y100 are relative to year 1, not year 0 + bool leapYear = y1 == 3 && (y4 != 24 || y100 == 3); + int[] days = leapYear ? DaysToMonth366 : DaysToMonth365; + // All months have less than 32 days, so n >> 5 is a good conservative + // estimate for the month + int m = n >> 5 + 1; + // m = 1-based month number + while (n >= days[m]) + { + m++; + } - month = m; + month = m; - // Return 1-based day-of-month - day = n - days[m - 1] + 1; + // Return 1-based day-of-month + day = n - days[m - 1] + 1; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/DictionaryWrapper.cs b/Src/Newtonsoft.Json/Utilities/DictionaryWrapper.cs index d8954f82..ba69ab96 100644 --- a/Src/Newtonsoft.Json/Utilities/DictionaryWrapper.cs +++ b/Src/Newtonsoft.Json/Utilities/DictionaryWrapper.cs @@ -31,525 +31,526 @@ using System.Threading; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json.Utilities { - internal interface IWrappedDictionary - : IDictionary - { - object UnderlyingDictionary { get; } - } + internal interface IWrappedDictionary + : IDictionary + { + object UnderlyingDictionary { get; } + } - internal class DictionaryWrapper : IDictionary, IWrappedDictionary - { - private readonly IDictionary _dictionary; - private readonly IDictionary _genericDictionary; + internal class DictionaryWrapper : IDictionary, IWrappedDictionary + { + private readonly IDictionary _dictionary; + private readonly IDictionary _genericDictionary; #if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - private readonly IReadOnlyDictionary _readOnlyDictionary; + private readonly IReadOnlyDictionary _readOnlyDictionary; #endif - private object _syncRoot; + private object _syncRoot; - public DictionaryWrapper(IDictionary dictionary) - { - ValidationUtils.ArgumentNotNull(dictionary, "dictionary"); - - _dictionary = dictionary; - } - - public DictionaryWrapper(IDictionary dictionary) - { - ValidationUtils.ArgumentNotNull(dictionary, "dictionary"); - - _genericDictionary = dictionary; - } - -#if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - public DictionaryWrapper(IReadOnlyDictionary dictionary) - { - ValidationUtils.ArgumentNotNull(dictionary, "dictionary"); - - _readOnlyDictionary = dictionary; - } -#endif - - public void Add(TKey key, TValue value) - { - if (_dictionary != null) - _dictionary.Add(key, value); - else if (_genericDictionary != null) - _genericDictionary.Add(key, value); - else - throw new NotSupportedException(); - } - - public bool ContainsKey(TKey key) - { - if (_dictionary != null) - return _dictionary.Contains(key); -#if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - else if (_readOnlyDictionary != null) - return _readOnlyDictionary.ContainsKey(key); -#endif - else - return _genericDictionary.ContainsKey(key); - } - - public ICollection Keys - { - get - { - if (_dictionary != null) - return _dictionary.Keys.Cast().ToList(); -#if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - else if (_readOnlyDictionary != null) - return _readOnlyDictionary.Keys.ToList(); -#endif - else - return _genericDictionary.Keys; - } - } - - public bool Remove(TKey key) - { - if (_dictionary != null) - { - if (_dictionary.Contains(key)) + public DictionaryWrapper(IDictionary dictionary) { - _dictionary.Remove(key); - return true; + ValidationUtils.ArgumentNotNull(dictionary, "dictionary"); + + _dictionary = dictionary; } - else + + public DictionaryWrapper(IDictionary dictionary) { - return false; - } - } -#if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - else if (_readOnlyDictionary != null) - { - throw new NotSupportedException(); - } -#endif - else - { - return _genericDictionary.Remove(key); - } - } + ValidationUtils.ArgumentNotNull(dictionary, "dictionary"); - public bool TryGetValue(TKey key, out TValue value) - { - if (_dictionary != null) - { - if (!_dictionary.Contains(key)) + _genericDictionary = dictionary; + } + +#if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) + public DictionaryWrapper(IReadOnlyDictionary dictionary) { - value = default(TValue); - return false; + ValidationUtils.ArgumentNotNull(dictionary, "dictionary"); + + _readOnlyDictionary = dictionary; } - else +#endif + + public void Add(TKey key, TValue value) { - value = (TValue)_dictionary[key]; - return true; + if (_dictionary != null) + _dictionary.Add(key, value); + else if (_genericDictionary != null) + _genericDictionary.Add(key, value); + else + throw new NotSupportedException(); } - } -#if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - else if (_readOnlyDictionary != null) - { - throw new NotSupportedException(); - } -#endif - else - { - return _genericDictionary.TryGetValue(key, out value); - } - } - public ICollection Values - { - get - { - if (_dictionary != null) - return _dictionary.Values.Cast().ToList(); -#if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - else if (_readOnlyDictionary != null) - return _readOnlyDictionary.Values.ToList(); -#endif - else - return _genericDictionary.Values; - } - } - - public TValue this[TKey key] - { - get - { - if (_dictionary != null) - return (TValue)_dictionary[key]; -#if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - else if (_readOnlyDictionary != null) - return _readOnlyDictionary[key]; -#endif - else - return _genericDictionary[key]; - } - set - { - if (_dictionary != null) - _dictionary[key] = value; -#if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - else if (_readOnlyDictionary != null) - throw new NotSupportedException(); -#endif - else - _genericDictionary[key] = value; - } - } - - public void Add(KeyValuePair item) - { - if (_dictionary != null) - ((IList)_dictionary).Add(item); -#if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - else if (_readOnlyDictionary != null) - throw new NotSupportedException(); -#endif - else if (_genericDictionary != null) - _genericDictionary.Add(item); - } - - public void Clear() - { - if (_dictionary != null) - _dictionary.Clear(); -#if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - else if (_readOnlyDictionary != null) - throw new NotSupportedException(); -#endif - else - _genericDictionary.Clear(); - } - - public bool Contains(KeyValuePair item) - { - if (_dictionary != null) - return ((IList)_dictionary).Contains(item); -#if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - else if (_readOnlyDictionary != null) - return _readOnlyDictionary.Contains(item); -#endif - else - return _genericDictionary.Contains(item); - } - - public void CopyTo(KeyValuePair[] array, int arrayIndex) - { - if (_dictionary != null) - { - foreach (DictionaryEntry item in _dictionary) + public bool ContainsKey(TKey key) { - array[arrayIndex++] = new KeyValuePair((TKey)item.Key, (TValue)item.Value); + if (_dictionary != null) + return _dictionary.Contains(key); +#if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) + else if (_readOnlyDictionary != null) + return _readOnlyDictionary.ContainsKey(key); +#endif + else + return _genericDictionary.ContainsKey(key); } - } -#if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - else if (_readOnlyDictionary != null) - { - throw new NotSupportedException(); - } -#endif - else - { - _genericDictionary.CopyTo(array, arrayIndex); - } - } - public int Count - { - get - { - if (_dictionary != null) - return _dictionary.Count; -#if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - else if (_readOnlyDictionary != null) - return _readOnlyDictionary.Count; -#endif - else - return _genericDictionary.Count; - } - } - - public bool IsReadOnly - { - get - { - if (_dictionary != null) - return _dictionary.IsReadOnly; -#if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - else if (_readOnlyDictionary != null) - return true; -#endif - else - return _genericDictionary.IsReadOnly; - } - } - - public bool Remove(KeyValuePair item) - { - if (_dictionary != null) - { - if (_dictionary.Contains(item.Key)) + public ICollection Keys { - object value = _dictionary[item.Key]; - - if (object.Equals(value, item.Value)) - { - _dictionary.Remove(item.Key); - return true; - } - else - { - return false; - } + get + { + if (_dictionary != null) + return _dictionary.Keys.Cast().ToList(); +#if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) + else if (_readOnlyDictionary != null) + return _readOnlyDictionary.Keys.ToList(); +#endif + else + return _genericDictionary.Keys; + } } - else + + public bool Remove(TKey key) { - return true; + if (_dictionary != null) + { + if (_dictionary.Contains(key)) + { + _dictionary.Remove(key); + return true; + } + else + { + return false; + } + } +#if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) + else if (_readOnlyDictionary != null) + { + throw new NotSupportedException(); + } +#endif + else + { + return _genericDictionary.Remove(key); + } } - } + + public bool TryGetValue(TKey key, out TValue value) + { + if (_dictionary != null) + { + if (!_dictionary.Contains(key)) + { + value = default(TValue); + return false; + } + else + { + value = (TValue)_dictionary[key]; + return true; + } + } #if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - else if (_readOnlyDictionary != null) - { - throw new NotSupportedException(); - } + else if (_readOnlyDictionary != null) + { + throw new NotSupportedException(); + } #endif - else - { - return _genericDictionary.Remove(item); - } - } + else + { + return _genericDictionary.TryGetValue(key, out value); + } + } - public IEnumerator> GetEnumerator() - { - if (_dictionary != null) - return _dictionary.Cast().Select(de => new KeyValuePair((TKey)de.Key, (TValue)de.Value)).GetEnumerator(); + public ICollection Values + { + get + { + if (_dictionary != null) + return _dictionary.Values.Cast().ToList(); #if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - else if (_readOnlyDictionary != null) - return _readOnlyDictionary.GetEnumerator(); + else if (_readOnlyDictionary != null) + return _readOnlyDictionary.Values.ToList(); #endif - else - return _genericDictionary.GetEnumerator(); - } + else + return _genericDictionary.Values; + } + } - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - void IDictionary.Add(object key, object value) - { - if (_dictionary != null) - _dictionary.Add(key, value); + public TValue this[TKey key] + { + get + { + if (_dictionary != null) + return (TValue)_dictionary[key]; #if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - else if (_readOnlyDictionary != null) - throw new NotSupportedException(); + else if (_readOnlyDictionary != null) + return _readOnlyDictionary[key]; #endif - else - _genericDictionary.Add((TKey)key, (TValue)value); - } - - object IDictionary.this[object key] - { - get - { - if (_dictionary != null) - return _dictionary[key]; + else + return _genericDictionary[key]; + } + set + { + if (_dictionary != null) + _dictionary[key] = value; #if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - else if (_readOnlyDictionary != null) - return _readOnlyDictionary[(TKey)key]; + else if (_readOnlyDictionary != null) + throw new NotSupportedException(); #endif - else - return _genericDictionary[(TKey)key]; - } - set - { - if (_dictionary != null) - _dictionary[key] = value; + else + _genericDictionary[key] = value; + } + } + + public void Add(KeyValuePair item) + { + if (_dictionary != null) + ((IList)_dictionary).Add(item); #if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - else if (_readOnlyDictionary != null) - throw new NotSupportedException(); + else if (_readOnlyDictionary != null) + throw new NotSupportedException(); #endif - else - _genericDictionary[(TKey)key] = (TValue)value; - } - } + else if (_genericDictionary != null) + _genericDictionary.Add(item); + } - private struct DictionaryEnumerator : IDictionaryEnumerator - { - private readonly IEnumerator> _e; - - public DictionaryEnumerator(IEnumerator> e) - { - ValidationUtils.ArgumentNotNull(e, "e"); - _e = e; - } - - public DictionaryEntry Entry - { - get { return (DictionaryEntry)Current; } - } - - public object Key - { - get { return Entry.Key; } - } - - public object Value - { - get { return Entry.Value; } - } - - public object Current - { - get { return new DictionaryEntry(_e.Current.Key, _e.Current.Value); } - } - - public bool MoveNext() - { - return _e.MoveNext(); - } - - public void Reset() - { - _e.Reset(); - } - } - - IDictionaryEnumerator IDictionary.GetEnumerator() - { - if (_dictionary != null) - return _dictionary.GetEnumerator(); + public void Clear() + { + if (_dictionary != null) + _dictionary.Clear(); #if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - else if (_readOnlyDictionary != null) - return new DictionaryEnumerator(_readOnlyDictionary.GetEnumerator()); + else if (_readOnlyDictionary != null) + throw new NotSupportedException(); #endif - else - return new DictionaryEnumerator(_genericDictionary.GetEnumerator()); - } + else + _genericDictionary.Clear(); + } - bool IDictionary.Contains(object key) - { - if (_genericDictionary != null) - return _genericDictionary.ContainsKey((TKey)key); + public bool Contains(KeyValuePair item) + { + if (_dictionary != null) + return ((IList)_dictionary).Contains(item); #if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - else if (_readOnlyDictionary != null) - return _readOnlyDictionary.ContainsKey((TKey)key); + else if (_readOnlyDictionary != null) + return _readOnlyDictionary.Contains(item); #endif - else - return _dictionary.Contains(key); - } + else + return _genericDictionary.Contains(item); + } - bool IDictionary.IsFixedSize - { - get - { - if (_genericDictionary != null) - return false; + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + if (_dictionary != null) + { + foreach (DictionaryEntry item in _dictionary) + { + array[arrayIndex++] = new KeyValuePair((TKey)item.Key, (TValue)item.Value); + } + } #if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - else if (_readOnlyDictionary != null) - return true; + else if (_readOnlyDictionary != null) + { + throw new NotSupportedException(); + } #endif - else - return _dictionary.IsFixedSize; - } - } + else + { + _genericDictionary.CopyTo(array, arrayIndex); + } + } - ICollection IDictionary.Keys - { - get - { - if (_genericDictionary != null) - return _genericDictionary.Keys.ToList(); + public int Count + { + get + { + if (_dictionary != null) + return _dictionary.Count; #if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - else if (_readOnlyDictionary != null) - return _readOnlyDictionary.Keys.ToList(); + else if (_readOnlyDictionary != null) + return _readOnlyDictionary.Count; #endif - else - return _dictionary.Keys; - } - } + else + return _genericDictionary.Count; + } + } - public void Remove(object key) - { - if (_dictionary != null) - _dictionary.Remove(key); + public bool IsReadOnly + { + get + { + if (_dictionary != null) + return _dictionary.IsReadOnly; #if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - else if (_readOnlyDictionary != null) - throw new NotSupportedException(); + else if (_readOnlyDictionary != null) + return true; #endif - else - _genericDictionary.Remove((TKey)key); - } + else + return _genericDictionary.IsReadOnly; + } + } - ICollection IDictionary.Values - { - get - { - if (_genericDictionary != null) - return _genericDictionary.Values.ToList(); + public bool Remove(KeyValuePair item) + { + if (_dictionary != null) + { + if (_dictionary.Contains(item.Key)) + { + object value = _dictionary[item.Key]; + + if (object.Equals(value, item.Value)) + { + _dictionary.Remove(item.Key); + return true; + } + else + { + return false; + } + } + else + { + return true; + } + } #if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - else if (_readOnlyDictionary != null) - return _readOnlyDictionary.Values.ToList(); + else if (_readOnlyDictionary != null) + { + throw new NotSupportedException(); + } #endif - else - return _dictionary.Values; - } - } + else + { + return _genericDictionary.Remove(item); + } + } - void ICollection.CopyTo(Array array, int index) - { - if (_dictionary != null) - _dictionary.CopyTo(array, index); + public IEnumerator> GetEnumerator() + { + if (_dictionary != null) + return _dictionary.Cast().Select(de => new KeyValuePair((TKey)de.Key, (TValue)de.Value)).GetEnumerator(); #if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - else if (_readOnlyDictionary != null) - throw new NotSupportedException(); + else if (_readOnlyDictionary != null) + return _readOnlyDictionary.GetEnumerator(); #endif - else - _genericDictionary.CopyTo((KeyValuePair[])array, index); - } + else + return _genericDictionary.GetEnumerator(); + } - bool ICollection.IsSynchronized - { - get - { - if (_dictionary != null) - return _dictionary.IsSynchronized; - else - return false; - } - } + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } - object ICollection.SyncRoot - { - get - { - if (_syncRoot == null) - Interlocked.CompareExchange(ref _syncRoot, new object(), null); - - return _syncRoot; - } - } - - public object UnderlyingDictionary - { - get - { - if (_dictionary != null) - return _dictionary; + void IDictionary.Add(object key, object value) + { + if (_dictionary != null) + _dictionary.Add(key, value); #if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) - else if (_readOnlyDictionary != null) - return _readOnlyDictionary; + else if (_readOnlyDictionary != null) + throw new NotSupportedException(); #endif - else - return _genericDictionary; - } + else + _genericDictionary.Add((TKey)key, (TValue)value); + } + + object IDictionary.this[object key] + { + get + { + if (_dictionary != null) + return _dictionary[key]; +#if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) + else if (_readOnlyDictionary != null) + return _readOnlyDictionary[(TKey)key]; +#endif + else + return _genericDictionary[(TKey)key]; + } + set + { + if (_dictionary != null) + _dictionary[key] = value; +#if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) + else if (_readOnlyDictionary != null) + throw new NotSupportedException(); +#endif + else + _genericDictionary[(TKey)key] = (TValue)value; + } + } + + private struct DictionaryEnumerator : IDictionaryEnumerator + { + private readonly IEnumerator> _e; + + public DictionaryEnumerator(IEnumerator> e) + { + ValidationUtils.ArgumentNotNull(e, "e"); + _e = e; + } + + public DictionaryEntry Entry + { + get { return (DictionaryEntry)Current; } + } + + public object Key + { + get { return Entry.Key; } + } + + public object Value + { + get { return Entry.Value; } + } + + public object Current + { + get { return new DictionaryEntry(_e.Current.Key, _e.Current.Value); } + } + + public bool MoveNext() + { + return _e.MoveNext(); + } + + public void Reset() + { + _e.Reset(); + } + } + + IDictionaryEnumerator IDictionary.GetEnumerator() + { + if (_dictionary != null) + return _dictionary.GetEnumerator(); +#if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) + else if (_readOnlyDictionary != null) + return new DictionaryEnumerator(_readOnlyDictionary.GetEnumerator()); +#endif + else + return new DictionaryEnumerator(_genericDictionary.GetEnumerator()); + } + + bool IDictionary.Contains(object key) + { + if (_genericDictionary != null) + return _genericDictionary.ContainsKey((TKey)key); +#if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) + else if (_readOnlyDictionary != null) + return _readOnlyDictionary.ContainsKey((TKey)key); +#endif + else + return _dictionary.Contains(key); + } + + bool IDictionary.IsFixedSize + { + get + { + if (_genericDictionary != null) + return false; +#if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) + else if (_readOnlyDictionary != null) + return true; +#endif + else + return _dictionary.IsFixedSize; + } + } + + ICollection IDictionary.Keys + { + get + { + if (_genericDictionary != null) + return _genericDictionary.Keys.ToList(); +#if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) + else if (_readOnlyDictionary != null) + return _readOnlyDictionary.Keys.ToList(); +#endif + else + return _dictionary.Keys; + } + } + + public void Remove(object key) + { + if (_dictionary != null) + _dictionary.Remove(key); +#if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) + else if (_readOnlyDictionary != null) + throw new NotSupportedException(); +#endif + else + _genericDictionary.Remove((TKey)key); + } + + ICollection IDictionary.Values + { + get + { + if (_genericDictionary != null) + return _genericDictionary.Values.ToList(); +#if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) + else if (_readOnlyDictionary != null) + return _readOnlyDictionary.Values.ToList(); +#endif + else + return _dictionary.Values; + } + } + + void ICollection.CopyTo(Array array, int index) + { + if (_dictionary != null) + _dictionary.CopyTo(array, index); +#if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) + else if (_readOnlyDictionary != null) + throw new NotSupportedException(); +#endif + else + _genericDictionary.CopyTo((KeyValuePair[])array, index); + } + + bool ICollection.IsSynchronized + { + get + { + if (_dictionary != null) + return _dictionary.IsSynchronized; + else + return false; + } + } + + object ICollection.SyncRoot + { + get + { + if (_syncRoot == null) + Interlocked.CompareExchange(ref _syncRoot, new object(), null); + + return _syncRoot; + } + } + + public object UnderlyingDictionary + { + get + { + if (_dictionary != null) + return _dictionary; +#if !(NET40 || NET35 || NET20 || SILVERLIGHT || WINDOWS_PHONE || PORTABLE40) + else if (_readOnlyDictionary != null) + return _readOnlyDictionary; +#endif + else + return _genericDictionary; + } + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/DynamicProxy.cs b/Src/Newtonsoft.Json/Utilities/DynamicProxy.cs index ca049e8a..7fb0100d 100644 --- a/Src/Newtonsoft.Json/Utilities/DynamicProxy.cs +++ b/Src/Newtonsoft.Json/Utilities/DynamicProxy.cs @@ -33,80 +33,81 @@ using System.Text; namespace Newtonsoft.Json.Utilities { - internal class DynamicProxy - { - public virtual IEnumerable GetDynamicMemberNames(T instance) + internal class DynamicProxy { - return new string[0]; - } + public virtual IEnumerable GetDynamicMemberNames(T instance) + { + return new string[0]; + } - public virtual bool TryBinaryOperation(T instance, BinaryOperationBinder binder, object arg, out object result) - { - result = null; - return false; - } + public virtual bool TryBinaryOperation(T instance, BinaryOperationBinder binder, object arg, out object result) + { + result = null; + return false; + } - public virtual bool TryConvert(T instance, ConvertBinder binder, out object result) - { - result = null; - return false; - } + public virtual bool TryConvert(T instance, ConvertBinder binder, out object result) + { + result = null; + return false; + } - public virtual bool TryCreateInstance(T instance, CreateInstanceBinder binder, object[] args, out object result) - { - result = null; - return false; - } + public virtual bool TryCreateInstance(T instance, CreateInstanceBinder binder, object[] args, out object result) + { + result = null; + return false; + } - public virtual bool TryDeleteIndex(T instance, DeleteIndexBinder binder, object[] indexes) - { - return false; - } + public virtual bool TryDeleteIndex(T instance, DeleteIndexBinder binder, object[] indexes) + { + return false; + } - public virtual bool TryDeleteMember(T instance, DeleteMemberBinder binder) - { - return false; - } + public virtual bool TryDeleteMember(T instance, DeleteMemberBinder binder) + { + return false; + } - public virtual bool TryGetIndex(T instance, GetIndexBinder binder, object[] indexes, out object result) - { - result = null; - return false; - } + public virtual bool TryGetIndex(T instance, GetIndexBinder binder, object[] indexes, out object result) + { + result = null; + return false; + } - public virtual bool TryGetMember(T instance, GetMemberBinder binder, out object result) - { - result = null; - return false; - } + public virtual bool TryGetMember(T instance, GetMemberBinder binder, out object result) + { + result = null; + return false; + } - public virtual bool TryInvoke(T instance, InvokeBinder binder, object[] args, out object result) - { - result = null; - return false; - } + public virtual bool TryInvoke(T instance, InvokeBinder binder, object[] args, out object result) + { + result = null; + return false; + } - public virtual bool TryInvokeMember(T instance, InvokeMemberBinder binder, object[] args, out object result) - { - result = null; - return false; - } + public virtual bool TryInvokeMember(T instance, InvokeMemberBinder binder, object[] args, out object result) + { + result = null; + return false; + } - public virtual bool TrySetIndex(T instance, SetIndexBinder binder, object[] indexes, object value) - { - return false; - } + public virtual bool TrySetIndex(T instance, SetIndexBinder binder, object[] indexes, object value) + { + return false; + } - public virtual bool TrySetMember(T instance, SetMemberBinder binder, object value) - { - return false; - } + public virtual bool TrySetMember(T instance, SetMemberBinder binder, object value) + { + return false; + } - public virtual bool TryUnaryOperation(T instance, UnaryOperationBinder binder, out object result) - { - result = null; - return false; + public virtual bool TryUnaryOperation(T instance, UnaryOperationBinder binder, out object result) + { + result = null; + return false; + } } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/DynamicProxyMetaObject.cs b/Src/Newtonsoft.Json/Utilities/DynamicProxyMetaObject.cs index e20d7b6e..b326899e 100644 --- a/Src/Newtonsoft.Json/Utilities/DynamicProxyMetaObject.cs +++ b/Src/Newtonsoft.Json/Utilities/DynamicProxyMetaObject.cs @@ -33,387 +33,391 @@ using System.Reflection; namespace Newtonsoft.Json.Utilities { - internal sealed class DynamicProxyMetaObject : DynamicMetaObject - { - private readonly DynamicProxy _proxy; - private readonly bool _dontFallbackFirst; - - internal DynamicProxyMetaObject(Expression expression, T value, DynamicProxy proxy, bool dontFallbackFirst) - : base(expression, BindingRestrictions.Empty, value) + internal sealed class DynamicProxyMetaObject : DynamicMetaObject { - _proxy = proxy; - _dontFallbackFirst = dontFallbackFirst; - } + private readonly DynamicProxy _proxy; + private readonly bool _dontFallbackFirst; - private new T Value { get { return (T)base.Value; } } + internal DynamicProxyMetaObject(Expression expression, T value, DynamicProxy proxy, bool dontFallbackFirst) + : base(expression, BindingRestrictions.Empty, value) + { + _proxy = proxy; + _dontFallbackFirst = dontFallbackFirst; + } - private bool IsOverridden(string method) - { - return ReflectionUtils.IsMethodOverridden(_proxy.GetType(), typeof (DynamicProxy), method); - } + private new T Value + { + get { return (T)base.Value; } + } - public override DynamicMetaObject BindGetMember(GetMemberBinder binder) - { - return IsOverridden("TryGetMember") - ? CallMethodWithResult("TryGetMember", binder, NoArgs, e => binder.FallbackGetMember(this, e)) - : base.BindGetMember(binder); - } + private bool IsOverridden(string method) + { + return ReflectionUtils.IsMethodOverridden(_proxy.GetType(), typeof(DynamicProxy), method); + } - public override DynamicMetaObject BindSetMember(SetMemberBinder binder, DynamicMetaObject value) - { - return IsOverridden("TrySetMember") - ? CallMethodReturnLast("TrySetMember", binder, GetArgs(value), e => binder.FallbackSetMember(this, value, e)) - : base.BindSetMember(binder, value); - } + public override DynamicMetaObject BindGetMember(GetMemberBinder binder) + { + return IsOverridden("TryGetMember") + ? CallMethodWithResult("TryGetMember", binder, NoArgs, e => binder.FallbackGetMember(this, e)) + : base.BindGetMember(binder); + } - public override DynamicMetaObject BindDeleteMember(DeleteMemberBinder binder) - { - return IsOverridden("TryDeleteMember") - ? CallMethodNoResult("TryDeleteMember", binder, NoArgs, e => binder.FallbackDeleteMember(this, e)) - : base.BindDeleteMember(binder); - } + public override DynamicMetaObject BindSetMember(SetMemberBinder binder, DynamicMetaObject value) + { + return IsOverridden("TrySetMember") + ? CallMethodReturnLast("TrySetMember", binder, GetArgs(value), e => binder.FallbackSetMember(this, value, e)) + : base.BindSetMember(binder, value); + } + + public override DynamicMetaObject BindDeleteMember(DeleteMemberBinder binder) + { + return IsOverridden("TryDeleteMember") + ? CallMethodNoResult("TryDeleteMember", binder, NoArgs, e => binder.FallbackDeleteMember(this, e)) + : base.BindDeleteMember(binder); + } - public override DynamicMetaObject BindConvert(ConvertBinder binder) - { - return IsOverridden("TryConvert") - ? CallMethodWithResult("TryConvert", binder, NoArgs, e => binder.FallbackConvert(this, e)) - : base.BindConvert(binder); - } + public override DynamicMetaObject BindConvert(ConvertBinder binder) + { + return IsOverridden("TryConvert") + ? CallMethodWithResult("TryConvert", binder, NoArgs, e => binder.FallbackConvert(this, e)) + : base.BindConvert(binder); + } - public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args) - { - if (!IsOverridden("TryInvokeMember")) - return base.BindInvokeMember(binder, args); + public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args) + { + if (!IsOverridden("TryInvokeMember")) + return base.BindInvokeMember(binder, args); - // - // Generate a tree like: - // - // { - // object result; - // TryInvokeMember(payload, out result) - // ? result - // : TryGetMember(payload, out result) - // ? FallbackInvoke(result) - // : fallbackResult - // } - // - // Then it calls FallbackInvokeMember with this tree as the - // "error", giving the language the option of using this - // tree or doing .NET binding. - // - Fallback fallback = e => binder.FallbackInvokeMember(this, args, e); + // + // Generate a tree like: + // + // { + // object result; + // TryInvokeMember(payload, out result) + // ? result + // : TryGetMember(payload, out result) + // ? FallbackInvoke(result) + // : fallbackResult + // } + // + // Then it calls FallbackInvokeMember with this tree as the + // "error", giving the language the option of using this + // tree or doing .NET binding. + // + Fallback fallback = e => binder.FallbackInvokeMember(this, args, e); - DynamicMetaObject call = BuildCallMethodWithResult( - "TryInvokeMember", - binder, - GetArgArray(args), - BuildCallMethodWithResult( - "TryGetMember", - new GetBinderAdapter(binder), - NoArgs, - fallback(null), - e => binder.FallbackInvoke(e, args, null) - ), - null - ); + DynamicMetaObject call = BuildCallMethodWithResult( + "TryInvokeMember", + binder, + GetArgArray(args), + BuildCallMethodWithResult( + "TryGetMember", + new GetBinderAdapter(binder), + NoArgs, + fallback(null), + e => binder.FallbackInvoke(e, args, null) + ), + null + ); - return _dontFallbackFirst ? call : fallback(call); - } + return _dontFallbackFirst ? call : fallback(call); + } - public override DynamicMetaObject BindCreateInstance(CreateInstanceBinder binder, DynamicMetaObject[] args) - { - return IsOverridden("TryCreateInstance") - ? CallMethodWithResult("TryCreateInstance", binder, GetArgArray(args), e => binder.FallbackCreateInstance(this, args, e)) - : base.BindCreateInstance(binder, args); - } + public override DynamicMetaObject BindCreateInstance(CreateInstanceBinder binder, DynamicMetaObject[] args) + { + return IsOverridden("TryCreateInstance") + ? CallMethodWithResult("TryCreateInstance", binder, GetArgArray(args), e => binder.FallbackCreateInstance(this, args, e)) + : base.BindCreateInstance(binder, args); + } - public override DynamicMetaObject BindInvoke(InvokeBinder binder, DynamicMetaObject[] args) - { - return IsOverridden("TryInvoke") - ? CallMethodWithResult("TryInvoke", binder, GetArgArray(args), e => binder.FallbackInvoke(this, args, e)) - : base.BindInvoke(binder, args); - } + public override DynamicMetaObject BindInvoke(InvokeBinder binder, DynamicMetaObject[] args) + { + return IsOverridden("TryInvoke") + ? CallMethodWithResult("TryInvoke", binder, GetArgArray(args), e => binder.FallbackInvoke(this, args, e)) + : base.BindInvoke(binder, args); + } - public override DynamicMetaObject BindBinaryOperation(BinaryOperationBinder binder, DynamicMetaObject arg) - { - return IsOverridden("TryBinaryOperation") - ? CallMethodWithResult("TryBinaryOperation", binder, GetArgs(arg), e => binder.FallbackBinaryOperation(this, arg, e)) - : base.BindBinaryOperation(binder, arg); - } + public override DynamicMetaObject BindBinaryOperation(BinaryOperationBinder binder, DynamicMetaObject arg) + { + return IsOverridden("TryBinaryOperation") + ? CallMethodWithResult("TryBinaryOperation", binder, GetArgs(arg), e => binder.FallbackBinaryOperation(this, arg, e)) + : base.BindBinaryOperation(binder, arg); + } - public override DynamicMetaObject BindUnaryOperation(UnaryOperationBinder binder) - { - return IsOverridden("TryUnaryOperation") - ? CallMethodWithResult("TryUnaryOperation", binder, NoArgs, e => binder.FallbackUnaryOperation(this, e)) - : base.BindUnaryOperation(binder); - } + public override DynamicMetaObject BindUnaryOperation(UnaryOperationBinder binder) + { + return IsOverridden("TryUnaryOperation") + ? CallMethodWithResult("TryUnaryOperation", binder, NoArgs, e => binder.FallbackUnaryOperation(this, e)) + : base.BindUnaryOperation(binder); + } - public override DynamicMetaObject BindGetIndex(GetIndexBinder binder, DynamicMetaObject[] indexes) - { - return IsOverridden("TryGetIndex") - ? CallMethodWithResult("TryGetIndex", binder, GetArgArray(indexes), e => binder.FallbackGetIndex(this, indexes, e)) - : base.BindGetIndex(binder, indexes); - } + public override DynamicMetaObject BindGetIndex(GetIndexBinder binder, DynamicMetaObject[] indexes) + { + return IsOverridden("TryGetIndex") + ? CallMethodWithResult("TryGetIndex", binder, GetArgArray(indexes), e => binder.FallbackGetIndex(this, indexes, e)) + : base.BindGetIndex(binder, indexes); + } - public override DynamicMetaObject BindSetIndex(SetIndexBinder binder, DynamicMetaObject[] indexes, DynamicMetaObject value) - { - return IsOverridden("TrySetIndex") - ? CallMethodReturnLast("TrySetIndex", binder, GetArgArray(indexes, value), e => binder.FallbackSetIndex(this, indexes, value, e)) - : base.BindSetIndex(binder, indexes, value); - } + public override DynamicMetaObject BindSetIndex(SetIndexBinder binder, DynamicMetaObject[] indexes, DynamicMetaObject value) + { + return IsOverridden("TrySetIndex") + ? CallMethodReturnLast("TrySetIndex", binder, GetArgArray(indexes, value), e => binder.FallbackSetIndex(this, indexes, value, e)) + : base.BindSetIndex(binder, indexes, value); + } - public override DynamicMetaObject BindDeleteIndex(DeleteIndexBinder binder, DynamicMetaObject[] indexes) - { - return IsOverridden("TryDeleteIndex") - ? CallMethodNoResult("TryDeleteIndex", binder, GetArgArray(indexes), e => binder.FallbackDeleteIndex(this, indexes, e)) - : base.BindDeleteIndex(binder, indexes); - } + public override DynamicMetaObject BindDeleteIndex(DeleteIndexBinder binder, DynamicMetaObject[] indexes) + { + return IsOverridden("TryDeleteIndex") + ? CallMethodNoResult("TryDeleteIndex", binder, GetArgArray(indexes), e => binder.FallbackDeleteIndex(this, indexes, e)) + : base.BindDeleteIndex(binder, indexes); + } - private delegate DynamicMetaObject Fallback(DynamicMetaObject errorSuggestion); + private delegate DynamicMetaObject Fallback(DynamicMetaObject errorSuggestion); - private readonly static Expression[] NoArgs = new Expression[0]; + private static readonly Expression[] NoArgs = new Expression[0]; - private static Expression[] GetArgs(params DynamicMetaObject[] args) - { - return args.Select(arg => Expression.Convert(arg.Expression, typeof(object))).ToArray(); - } + private static Expression[] GetArgs(params DynamicMetaObject[] args) + { + return args.Select(arg => Expression.Convert(arg.Expression, typeof(object))).ToArray(); + } - private static Expression[] GetArgArray(DynamicMetaObject[] args) - { - return new[] { Expression.NewArrayInit(typeof(object), GetArgs(args)) }; - } + private static Expression[] GetArgArray(DynamicMetaObject[] args) + { + return new[] { Expression.NewArrayInit(typeof(object), GetArgs(args)) }; + } - private static Expression[] GetArgArray(DynamicMetaObject[] args, DynamicMetaObject value) - { - return new Expression[] + private static Expression[] GetArgArray(DynamicMetaObject[] args, DynamicMetaObject value) + { + return new Expression[] { Expression.NewArrayInit(typeof(object), GetArgs(args)), Expression.Convert(value.Expression, typeof(object)) }; + } + + private static ConstantExpression Constant(DynamicMetaObjectBinder binder) + { + Type t = binder.GetType(); + while (!t.IsVisible()) + t = t.BaseType(); + return Expression.Constant(binder, t); + } + + /// + /// Helper method for generating a MetaObject which calls a + /// specific method on Dynamic that returns a result + /// + private DynamicMetaObject CallMethodWithResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback, Fallback fallbackInvoke = null) + { + // + // First, call fallback to do default binding + // This produces either an error or a call to a .NET member + // + DynamicMetaObject fallbackResult = fallback(null); + + DynamicMetaObject callDynamic = BuildCallMethodWithResult(methodName, binder, args, fallbackResult, fallbackInvoke); + + // + // Now, call fallback again using our new MO as the error + // When we do this, one of two things can happen: + // 1. Binding will succeed, and it will ignore our call to + // the dynamic method, OR + // 2. Binding will fail, and it will use the MO we created + // above. + // + + return _dontFallbackFirst ? callDynamic : fallback(callDynamic); + } + + private DynamicMetaObject BuildCallMethodWithResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, DynamicMetaObject fallbackResult, Fallback fallbackInvoke) + { + // + // Build a new expression like: + // { + // object result; + // TryGetMember(payload, out result) ? fallbackInvoke(result) : fallbackResult + // } + // + ParameterExpression result = Expression.Parameter(typeof(object), null); + + IList callArgs = new List(); + callArgs.Add(Expression.Convert(Expression, typeof(T))); + callArgs.Add(Constant(binder)); + callArgs.AddRange(args); + callArgs.Add(result); + + DynamicMetaObject resultMetaObject = new DynamicMetaObject(result, BindingRestrictions.Empty); + + // Need to add a conversion if calling TryConvert + if (binder.ReturnType != typeof(object)) + { + UnaryExpression convert = Expression.Convert(resultMetaObject.Expression, binder.ReturnType); + // will always be a cast or unbox + + resultMetaObject = new DynamicMetaObject(convert, resultMetaObject.Restrictions); + } + + if (fallbackInvoke != null) + resultMetaObject = fallbackInvoke(resultMetaObject); + + DynamicMetaObject callDynamic = new DynamicMetaObject( + Expression.Block( + new[] { result }, + Expression.Condition( + Expression.Call( + Expression.Constant(_proxy), + typeof(DynamicProxy).GetMethod(methodName), + callArgs + ), + resultMetaObject.Expression, + fallbackResult.Expression, + binder.ReturnType + ) + ), + GetRestrictions().Merge(resultMetaObject.Restrictions).Merge(fallbackResult.Restrictions) + ); + + return callDynamic; + } + + /// + /// Helper method for generating a MetaObject which calls a + /// specific method on Dynamic, but uses one of the arguments for + /// the result. + /// + private DynamicMetaObject CallMethodReturnLast(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback) + { + // + // First, call fallback to do default binding + // This produces either an error or a call to a .NET member + // + DynamicMetaObject fallbackResult = fallback(null); + + // + // Build a new expression like: + // { + // object result; + // TrySetMember(payload, result = value) ? result : fallbackResult + // } + // + ParameterExpression result = Expression.Parameter(typeof(object), null); + + IList callArgs = new List(); + callArgs.Add(Expression.Convert(Expression, typeof(T))); + callArgs.Add(Constant(binder)); + callArgs.AddRange(args); + callArgs[args.Length + 1] = Expression.Assign(result, callArgs[args.Length + 1]); + + DynamicMetaObject callDynamic = new DynamicMetaObject( + Expression.Block( + new[] { result }, + Expression.Condition( + Expression.Call( + Expression.Constant(_proxy), + typeof(DynamicProxy).GetMethod(methodName), + callArgs + ), + result, + fallbackResult.Expression, + typeof(object) + ) + ), + GetRestrictions().Merge(fallbackResult.Restrictions) + ); + + // + // Now, call fallback again using our new MO as the error + // When we do this, one of two things can happen: + // 1. Binding will succeed, and it will ignore our call to + // the dynamic method, OR + // 2. Binding will fail, and it will use the MO we created + // above. + // + return _dontFallbackFirst ? callDynamic : fallback(callDynamic); + } + + /// + /// Helper method for generating a MetaObject which calls a + /// specific method on Dynamic, but uses one of the arguments for + /// the result. + /// + private DynamicMetaObject CallMethodNoResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback) + { + // + // First, call fallback to do default binding + // This produces either an error or a call to a .NET member + // + DynamicMetaObject fallbackResult = fallback(null); + + IList callArgs = new List(); + callArgs.Add(Expression.Convert(Expression, typeof(T))); + callArgs.Add(Constant(binder)); + callArgs.AddRange(args); + + // + // Build a new expression like: + // if (TryDeleteMember(payload)) { } else { fallbackResult } + // + DynamicMetaObject callDynamic = new DynamicMetaObject( + Expression.Condition( + Expression.Call( + Expression.Constant(_proxy), + typeof(DynamicProxy).GetMethod(methodName), + callArgs + ), + Expression.Empty(), + fallbackResult.Expression, + typeof(void) + ), + GetRestrictions().Merge(fallbackResult.Restrictions) + ); + + // + // Now, call fallback again using our new MO as the error + // When we do this, one of two things can happen: + // 1. Binding will succeed, and it will ignore our call to + // the dynamic method, OR + // 2. Binding will fail, and it will use the MO we created + // above. + // + return _dontFallbackFirst ? callDynamic : fallback(callDynamic); + } + + /// + /// Returns a Restrictions object which includes our current restrictions merged + /// with a restriction limiting our type + /// + private BindingRestrictions GetRestrictions() + { + return (Value == null && HasValue) + ? BindingRestrictions.GetInstanceRestriction(Expression, null) + : BindingRestrictions.GetTypeRestriction(Expression, LimitType); + } + + public override IEnumerable GetDynamicMemberNames() + { + return _proxy.GetDynamicMemberNames(Value); + } + + // It is okay to throw NotSupported from this binder. This object + // is only used by DynamicObject.GetMember--it is not expected to + // (and cannot) implement binding semantics. It is just so the DO + // can use the Name and IgnoreCase properties. + private sealed class GetBinderAdapter : GetMemberBinder + { + internal GetBinderAdapter(InvokeMemberBinder binder) : + base(binder.Name, binder.IgnoreCase) + { + } + + public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion) + { + throw new NotSupportedException(); + } + } } - - private static ConstantExpression Constant(DynamicMetaObjectBinder binder) - { - Type t = binder.GetType(); - while (!t.IsVisible()) - t = t.BaseType(); - return Expression.Constant(binder, t); - } - - /// - /// Helper method for generating a MetaObject which calls a - /// specific method on Dynamic that returns a result - /// - private DynamicMetaObject CallMethodWithResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback, Fallback fallbackInvoke = null) - { - // - // First, call fallback to do default binding - // This produces either an error or a call to a .NET member - // - DynamicMetaObject fallbackResult = fallback(null); - - DynamicMetaObject callDynamic = BuildCallMethodWithResult(methodName, binder, args, fallbackResult, fallbackInvoke); - - // - // Now, call fallback again using our new MO as the error - // When we do this, one of two things can happen: - // 1. Binding will succeed, and it will ignore our call to - // the dynamic method, OR - // 2. Binding will fail, and it will use the MO we created - // above. - // - - return _dontFallbackFirst ? callDynamic : fallback(callDynamic); - } - - private DynamicMetaObject BuildCallMethodWithResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, DynamicMetaObject fallbackResult, Fallback fallbackInvoke) - { - // - // Build a new expression like: - // { - // object result; - // TryGetMember(payload, out result) ? fallbackInvoke(result) : fallbackResult - // } - // - ParameterExpression result = Expression.Parameter(typeof(object), null); - - IList callArgs = new List(); - callArgs.Add(Expression.Convert(Expression, typeof(T))); - callArgs.Add(Constant(binder)); - callArgs.AddRange(args); - callArgs.Add(result); - - DynamicMetaObject resultMetaObject = new DynamicMetaObject(result, BindingRestrictions.Empty); - - // Need to add a conversion if calling TryConvert - if (binder.ReturnType != typeof (object)) - { - UnaryExpression convert = Expression.Convert(resultMetaObject.Expression, binder.ReturnType); - // will always be a cast or unbox - - resultMetaObject = new DynamicMetaObject(convert, resultMetaObject.Restrictions); - } - - if (fallbackInvoke != null) - resultMetaObject = fallbackInvoke(resultMetaObject); - - DynamicMetaObject callDynamic = new DynamicMetaObject( - Expression.Block( - new[] {result}, - Expression.Condition( - Expression.Call( - Expression.Constant(_proxy), - typeof(DynamicProxy).GetMethod(methodName), - callArgs - ), - resultMetaObject.Expression, - fallbackResult.Expression, - binder.ReturnType - ) - ), - GetRestrictions().Merge(resultMetaObject.Restrictions).Merge(fallbackResult.Restrictions) - ); - - return callDynamic; - } - - /// - /// Helper method for generating a MetaObject which calls a - /// specific method on Dynamic, but uses one of the arguments for - /// the result. - /// - private DynamicMetaObject CallMethodReturnLast(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback) - { - // - // First, call fallback to do default binding - // This produces either an error or a call to a .NET member - // - DynamicMetaObject fallbackResult = fallback(null); - - // - // Build a new expression like: - // { - // object result; - // TrySetMember(payload, result = value) ? result : fallbackResult - // } - // - ParameterExpression result = Expression.Parameter(typeof(object), null); - - IList callArgs = new List(); - callArgs.Add(Expression.Convert(Expression, typeof (T))); - callArgs.Add(Constant(binder)); - callArgs.AddRange(args); - callArgs[args.Length + 1] = Expression.Assign(result, callArgs[args.Length + 1]); - - DynamicMetaObject callDynamic = new DynamicMetaObject( - Expression.Block( - new[] { result }, - Expression.Condition( - Expression.Call( - Expression.Constant(_proxy), - typeof(DynamicProxy).GetMethod(methodName), - callArgs - ), - result, - fallbackResult.Expression, - typeof(object) - ) - ), - GetRestrictions().Merge(fallbackResult.Restrictions) - ); - - // - // Now, call fallback again using our new MO as the error - // When we do this, one of two things can happen: - // 1. Binding will succeed, and it will ignore our call to - // the dynamic method, OR - // 2. Binding will fail, and it will use the MO we created - // above. - // - return _dontFallbackFirst ? callDynamic : fallback(callDynamic); - } - - /// - /// Helper method for generating a MetaObject which calls a - /// specific method on Dynamic, but uses one of the arguments for - /// the result. - /// - private DynamicMetaObject CallMethodNoResult(string methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback) - { - // - // First, call fallback to do default binding - // This produces either an error or a call to a .NET member - // - DynamicMetaObject fallbackResult = fallback(null); - - IList callArgs = new List(); - callArgs.Add(Expression.Convert(Expression, typeof(T))); - callArgs.Add(Constant(binder)); - callArgs.AddRange(args); - - // - // Build a new expression like: - // if (TryDeleteMember(payload)) { } else { fallbackResult } - // - DynamicMetaObject callDynamic = new DynamicMetaObject( - Expression.Condition( - Expression.Call( - Expression.Constant(_proxy), - typeof(DynamicProxy).GetMethod(methodName), - callArgs - ), - Expression.Empty(), - fallbackResult.Expression, - typeof (void) - ), - GetRestrictions().Merge(fallbackResult.Restrictions) - ); - - // - // Now, call fallback again using our new MO as the error - // When we do this, one of two things can happen: - // 1. Binding will succeed, and it will ignore our call to - // the dynamic method, OR - // 2. Binding will fail, and it will use the MO we created - // above. - // - return _dontFallbackFirst ? callDynamic : fallback(callDynamic); - } - - /// - /// Returns a Restrictions object which includes our current restrictions merged - /// with a restriction limiting our type - /// - private BindingRestrictions GetRestrictions() - { - return (Value == null && HasValue) - ? BindingRestrictions.GetInstanceRestriction(Expression, null) - : BindingRestrictions.GetTypeRestriction(Expression, LimitType); - } - - public override IEnumerable GetDynamicMemberNames() - { - return _proxy.GetDynamicMemberNames(Value); - } - - // It is okay to throw NotSupported from this binder. This object - // is only used by DynamicObject.GetMember--it is not expected to - // (and cannot) implement binding semantics. It is just so the DO - // can use the Name and IgnoreCase properties. - private sealed class GetBinderAdapter : GetMemberBinder - { - internal GetBinderAdapter(InvokeMemberBinder binder) : - base(binder.Name, binder.IgnoreCase) - { - } - - public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion) - { - throw new NotSupportedException(); - } - } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/DynamicReflectionDelegateFactory.cs b/Src/Newtonsoft.Json/Utilities/DynamicReflectionDelegateFactory.cs index cf15db57..05145437 100644 --- a/Src/Newtonsoft.Json/Utilities/DynamicReflectionDelegateFactory.cs +++ b/Src/Newtonsoft.Json/Utilities/DynamicReflectionDelegateFactory.cs @@ -36,194 +36,195 @@ using System.Globalization; namespace Newtonsoft.Json.Utilities { - internal class DynamicReflectionDelegateFactory : ReflectionDelegateFactory - { - public static DynamicReflectionDelegateFactory Instance = new DynamicReflectionDelegateFactory(); - - private static DynamicMethod CreateDynamicMethod(string name, Type returnType, Type[] parameterTypes, Type owner) + internal class DynamicReflectionDelegateFactory : ReflectionDelegateFactory { - DynamicMethod dynamicMethod = !owner.IsInterface() - ? new DynamicMethod(name, returnType, parameterTypes, owner, true) - : new DynamicMethod(name, returnType, parameterTypes, owner.Module, true); + public static DynamicReflectionDelegateFactory Instance = new DynamicReflectionDelegateFactory(); - return dynamicMethod; + private static DynamicMethod CreateDynamicMethod(string name, Type returnType, Type[] parameterTypes, Type owner) + { + DynamicMethod dynamicMethod = !owner.IsInterface() + ? new DynamicMethod(name, returnType, parameterTypes, owner, true) + : new DynamicMethod(name, returnType, parameterTypes, owner.Module, true); + + return dynamicMethod; + } + + public override MethodCall CreateMethodCall(MethodBase method) + { + DynamicMethod dynamicMethod = CreateDynamicMethod(method.ToString(), typeof(object), new[] { typeof(object), typeof(object[]) }, method.DeclaringType); + ILGenerator generator = dynamicMethod.GetILGenerator(); + + GenerateCreateMethodCallIL(method, generator); + + return (MethodCall)dynamicMethod.CreateDelegate(typeof(MethodCall)); + } + + private void GenerateCreateMethodCallIL(MethodBase method, ILGenerator generator) + { + ParameterInfo[] args = method.GetParameters(); + + Label argsOk = generator.DefineLabel(); + + generator.Emit(OpCodes.Ldarg_1); + generator.Emit(OpCodes.Ldlen); + generator.Emit(OpCodes.Ldc_I4, args.Length); + generator.Emit(OpCodes.Beq, argsOk); + + generator.Emit(OpCodes.Newobj, typeof(TargetParameterCountException).GetConstructor(ReflectionUtils.EmptyTypes)); + generator.Emit(OpCodes.Throw); + + generator.MarkLabel(argsOk); + + if (!method.IsConstructor && !method.IsStatic) + generator.PushInstance(method.DeclaringType); + + for (int i = 0; i < args.Length; i++) + { + generator.Emit(OpCodes.Ldarg_1); + generator.Emit(OpCodes.Ldc_I4, i); + generator.Emit(OpCodes.Ldelem_Ref); + + generator.UnboxIfNeeded(args[i].ParameterType); + } + + if (method.IsConstructor) + generator.Emit(OpCodes.Newobj, (ConstructorInfo)method); + else if (method.IsFinal || !method.IsVirtual) + generator.CallMethod((MethodInfo)method); + + Type returnType = method.IsConstructor + ? method.DeclaringType + : ((MethodInfo)method).ReturnType; + + if (returnType != typeof(void)) + generator.BoxIfNeeded(returnType); + else + generator.Emit(OpCodes.Ldnull); + + generator.Return(); + } + + public override Func CreateDefaultConstructor(Type type) + { + DynamicMethod dynamicMethod = CreateDynamicMethod("Create" + type.FullName, typeof(T), ReflectionUtils.EmptyTypes, type); + dynamicMethod.InitLocals = true; + ILGenerator generator = dynamicMethod.GetILGenerator(); + + GenerateCreateDefaultConstructorIL(type, generator); + + return (Func)dynamicMethod.CreateDelegate(typeof(Func)); + } + + private void GenerateCreateDefaultConstructorIL(Type type, ILGenerator generator) + { + if (type.IsValueType()) + { + generator.DeclareLocal(type); + generator.Emit(OpCodes.Ldloc_0); + generator.Emit(OpCodes.Box, type); + } + else + { + ConstructorInfo constructorInfo = + type.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, + ReflectionUtils.EmptyTypes, null); + + if (constructorInfo == null) + throw new ArgumentException("Could not get constructor for {0}.".FormatWith(CultureInfo.InvariantCulture, type)); + + generator.Emit(OpCodes.Newobj, constructorInfo); + } + + generator.Return(); + } + + public override Func CreateGet(PropertyInfo propertyInfo) + { + DynamicMethod dynamicMethod = CreateDynamicMethod("Get" + propertyInfo.Name, typeof(T), new[] { typeof(object) }, propertyInfo.DeclaringType); + ILGenerator generator = dynamicMethod.GetILGenerator(); + + GenerateCreateGetPropertyIL(propertyInfo, generator); + + return (Func)dynamicMethod.CreateDelegate(typeof(Func)); + } + + private void GenerateCreateGetPropertyIL(PropertyInfo propertyInfo, ILGenerator generator) + { + MethodInfo getMethod = propertyInfo.GetGetMethod(true); + if (getMethod == null) + throw new ArgumentException("Property '{0}' does not have a getter.".FormatWith(CultureInfo.InvariantCulture, propertyInfo.Name)); + + if (!getMethod.IsStatic) + generator.PushInstance(propertyInfo.DeclaringType); + + generator.CallMethod(getMethod); + generator.BoxIfNeeded(propertyInfo.PropertyType); + generator.Return(); + } + + public override Func CreateGet(FieldInfo fieldInfo) + { + DynamicMethod dynamicMethod = CreateDynamicMethod("Get" + fieldInfo.Name, typeof(T), new[] { typeof(object) }, fieldInfo.DeclaringType); + ILGenerator generator = dynamicMethod.GetILGenerator(); + + GenerateCreateGetFieldIL(fieldInfo, generator); + + return (Func)dynamicMethod.CreateDelegate(typeof(Func)); + } + + private void GenerateCreateGetFieldIL(FieldInfo fieldInfo, ILGenerator generator) + { + if (!fieldInfo.IsStatic) + generator.PushInstance(fieldInfo.DeclaringType); + + generator.Emit(OpCodes.Ldfld, fieldInfo); + generator.BoxIfNeeded(fieldInfo.FieldType); + generator.Return(); + } + + public override Action CreateSet(FieldInfo fieldInfo) + { + DynamicMethod dynamicMethod = CreateDynamicMethod("Set" + fieldInfo.Name, null, new[] { typeof(T), typeof(object) }, fieldInfo.DeclaringType); + ILGenerator generator = dynamicMethod.GetILGenerator(); + + GenerateCreateSetFieldIL(fieldInfo, generator); + + return (Action)dynamicMethod.CreateDelegate(typeof(Action)); + } + + internal static void GenerateCreateSetFieldIL(FieldInfo fieldInfo, ILGenerator generator) + { + if (!fieldInfo.IsStatic) + generator.PushInstance(fieldInfo.DeclaringType); + + generator.Emit(OpCodes.Ldarg_1); + generator.UnboxIfNeeded(fieldInfo.FieldType); + generator.Emit(OpCodes.Stfld, fieldInfo); + generator.Return(); + } + + public override Action CreateSet(PropertyInfo propertyInfo) + { + DynamicMethod dynamicMethod = CreateDynamicMethod("Set" + propertyInfo.Name, null, new[] { typeof(T), typeof(object) }, propertyInfo.DeclaringType); + ILGenerator generator = dynamicMethod.GetILGenerator(); + + GenerateCreateSetPropertyIL(propertyInfo, generator); + + return (Action)dynamicMethod.CreateDelegate(typeof(Action)); + } + + internal static void GenerateCreateSetPropertyIL(PropertyInfo propertyInfo, ILGenerator generator) + { + MethodInfo setMethod = propertyInfo.GetSetMethod(true); + if (!setMethod.IsStatic) + generator.PushInstance(propertyInfo.DeclaringType); + + generator.Emit(OpCodes.Ldarg_1); + generator.UnboxIfNeeded(propertyInfo.PropertyType); + generator.CallMethod(setMethod); + generator.Return(); + } } - - public override MethodCall CreateMethodCall(MethodBase method) - { - DynamicMethod dynamicMethod = CreateDynamicMethod(method.ToString(), typeof(object), new[] { typeof(object), typeof(object[]) }, method.DeclaringType); - ILGenerator generator = dynamicMethod.GetILGenerator(); - - GenerateCreateMethodCallIL(method, generator); - - return (MethodCall)dynamicMethod.CreateDelegate(typeof(MethodCall)); - } - - private void GenerateCreateMethodCallIL(MethodBase method, ILGenerator generator) - { - ParameterInfo[] args = method.GetParameters(); - - Label argsOk = generator.DefineLabel(); - - generator.Emit(OpCodes.Ldarg_1); - generator.Emit(OpCodes.Ldlen); - generator.Emit(OpCodes.Ldc_I4, args.Length); - generator.Emit(OpCodes.Beq, argsOk); - - generator.Emit(OpCodes.Newobj, typeof(TargetParameterCountException).GetConstructor(ReflectionUtils.EmptyTypes)); - generator.Emit(OpCodes.Throw); - - generator.MarkLabel(argsOk); - - if (!method.IsConstructor && !method.IsStatic) - generator.PushInstance(method.DeclaringType); - - for (int i = 0; i < args.Length; i++) - { - generator.Emit(OpCodes.Ldarg_1); - generator.Emit(OpCodes.Ldc_I4, i); - generator.Emit(OpCodes.Ldelem_Ref); - - generator.UnboxIfNeeded(args[i].ParameterType); - } - - if (method.IsConstructor) - generator.Emit(OpCodes.Newobj, (ConstructorInfo)method); - else if (method.IsFinal || !method.IsVirtual) - generator.CallMethod((MethodInfo)method); - - Type returnType = method.IsConstructor - ? method.DeclaringType - : ((MethodInfo)method).ReturnType; - - if (returnType != typeof(void)) - generator.BoxIfNeeded(returnType); - else - generator.Emit(OpCodes.Ldnull); - - generator.Return(); - } - - public override Func CreateDefaultConstructor(Type type) - { - DynamicMethod dynamicMethod = CreateDynamicMethod("Create" + type.FullName, typeof(T), ReflectionUtils.EmptyTypes, type); - dynamicMethod.InitLocals = true; - ILGenerator generator = dynamicMethod.GetILGenerator(); - - GenerateCreateDefaultConstructorIL(type, generator); - - return (Func)dynamicMethod.CreateDelegate(typeof(Func)); - } - - private void GenerateCreateDefaultConstructorIL(Type type, ILGenerator generator) - { - if (type.IsValueType()) - { - generator.DeclareLocal(type); - generator.Emit(OpCodes.Ldloc_0); - generator.Emit(OpCodes.Box, type); - } - else - { - ConstructorInfo constructorInfo = - type.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, - ReflectionUtils.EmptyTypes, null); - - if (constructorInfo == null) - throw new ArgumentException("Could not get constructor for {0}.".FormatWith(CultureInfo.InvariantCulture, type)); - - generator.Emit(OpCodes.Newobj, constructorInfo); - } - - generator.Return(); - } - - public override Func CreateGet(PropertyInfo propertyInfo) - { - DynamicMethod dynamicMethod = CreateDynamicMethod("Get" + propertyInfo.Name, typeof(T), new[] { typeof(object) }, propertyInfo.DeclaringType); - ILGenerator generator = dynamicMethod.GetILGenerator(); - - GenerateCreateGetPropertyIL(propertyInfo, generator); - - return (Func)dynamicMethod.CreateDelegate(typeof(Func)); - } - - private void GenerateCreateGetPropertyIL(PropertyInfo propertyInfo, ILGenerator generator) - { - MethodInfo getMethod = propertyInfo.GetGetMethod(true); - if (getMethod == null) - throw new ArgumentException("Property '{0}' does not have a getter.".FormatWith(CultureInfo.InvariantCulture, propertyInfo.Name)); - - if (!getMethod.IsStatic) - generator.PushInstance(propertyInfo.DeclaringType); - - generator.CallMethod(getMethod); - generator.BoxIfNeeded(propertyInfo.PropertyType); - generator.Return(); - } - - public override Func CreateGet(FieldInfo fieldInfo) - { - DynamicMethod dynamicMethod = CreateDynamicMethod("Get" + fieldInfo.Name, typeof(T), new[] { typeof(object) }, fieldInfo.DeclaringType); - ILGenerator generator = dynamicMethod.GetILGenerator(); - - GenerateCreateGetFieldIL(fieldInfo, generator); - - return (Func)dynamicMethod.CreateDelegate(typeof(Func)); - } - - private void GenerateCreateGetFieldIL(FieldInfo fieldInfo, ILGenerator generator) - { - if (!fieldInfo.IsStatic) - generator.PushInstance(fieldInfo.DeclaringType); - - generator.Emit(OpCodes.Ldfld, fieldInfo); - generator.BoxIfNeeded(fieldInfo.FieldType); - generator.Return(); - } - - public override Action CreateSet(FieldInfo fieldInfo) - { - DynamicMethod dynamicMethod = CreateDynamicMethod("Set" + fieldInfo.Name, null, new[] { typeof(T), typeof(object) }, fieldInfo.DeclaringType); - ILGenerator generator = dynamicMethod.GetILGenerator(); - - GenerateCreateSetFieldIL(fieldInfo, generator); - - return (Action)dynamicMethod.CreateDelegate(typeof(Action)); - } - - internal static void GenerateCreateSetFieldIL(FieldInfo fieldInfo, ILGenerator generator) - { - if (!fieldInfo.IsStatic) - generator.PushInstance(fieldInfo.DeclaringType); - - generator.Emit(OpCodes.Ldarg_1); - generator.UnboxIfNeeded(fieldInfo.FieldType); - generator.Emit(OpCodes.Stfld, fieldInfo); - generator.Return(); - } - - public override Action CreateSet(PropertyInfo propertyInfo) - { - DynamicMethod dynamicMethod = CreateDynamicMethod("Set" + propertyInfo.Name, null, new[] { typeof(T), typeof(object) }, propertyInfo.DeclaringType); - ILGenerator generator = dynamicMethod.GetILGenerator(); - - GenerateCreateSetPropertyIL(propertyInfo, generator); - - return (Action)dynamicMethod.CreateDelegate(typeof(Action)); - } - - internal static void GenerateCreateSetPropertyIL(PropertyInfo propertyInfo, ILGenerator generator) - { - MethodInfo setMethod = propertyInfo.GetSetMethod(true); - if (!setMethod.IsStatic) - generator.PushInstance(propertyInfo.DeclaringType); - - generator.Emit(OpCodes.Ldarg_1); - generator.UnboxIfNeeded(propertyInfo.PropertyType); - generator.CallMethod(setMethod); - generator.Return(); - } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/DynamicUtils.cs b/Src/Newtonsoft.Json/Utilities/DynamicUtils.cs index cd1a36dd..4690b8a6 100644 --- a/Src/Newtonsoft.Json/Utilities/DynamicUtils.cs +++ b/Src/Newtonsoft.Json/Utilities/DynamicUtils.cs @@ -41,95 +41,95 @@ using Newtonsoft.Json.Serialization; namespace Newtonsoft.Json.Utilities { - internal static class DynamicUtils - { - internal static class BinderWrapper + internal static class DynamicUtils { + internal static class BinderWrapper + { #if !(PORTABLE || WINDOWS_PHONE) #if !SILVERLIGHT - public const string CSharpAssemblyName = "Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; + public const string CSharpAssemblyName = "Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; #else public const string CSharpAssemblyName = "Microsoft.CSharp, Version=5.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; #endif - private const string BinderTypeName = "Microsoft.CSharp.RuntimeBinder.Binder, " + CSharpAssemblyName; - private const string CSharpArgumentInfoTypeName = "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo, " + CSharpAssemblyName; - private const string CSharpArgumentInfoFlagsTypeName = "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, " + CSharpAssemblyName; - private const string CSharpBinderFlagsTypeName = "Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, " + CSharpAssemblyName; + private const string BinderTypeName = "Microsoft.CSharp.RuntimeBinder.Binder, " + CSharpAssemblyName; + private const string CSharpArgumentInfoTypeName = "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo, " + CSharpAssemblyName; + private const string CSharpArgumentInfoFlagsTypeName = "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, " + CSharpAssemblyName; + private const string CSharpBinderFlagsTypeName = "Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, " + CSharpAssemblyName; - private static object _getCSharpArgumentInfoArray; - private static object _setCSharpArgumentInfoArray; - private static MethodCall _getMemberCall; - private static MethodCall _setMemberCall; - private static bool _init; + private static object _getCSharpArgumentInfoArray; + private static object _setCSharpArgumentInfoArray; + private static MethodCall _getMemberCall; + private static MethodCall _setMemberCall; + private static bool _init; - private static void Init() - { - if (!_init) - { - Type binderType = Type.GetType(BinderTypeName, false); - if (binderType == null) - throw new InvalidOperationException("Could not resolve type '{0}'. You may need to add a reference to Microsoft.CSharp.dll to work with dynamic types.".FormatWith(CultureInfo.InvariantCulture, BinderTypeName)); + private static void Init() + { + if (!_init) + { + Type binderType = Type.GetType(BinderTypeName, false); + if (binderType == null) + throw new InvalidOperationException("Could not resolve type '{0}'. You may need to add a reference to Microsoft.CSharp.dll to work with dynamic types.".FormatWith(CultureInfo.InvariantCulture, BinderTypeName)); - // None - _getCSharpArgumentInfoArray = CreateSharpArgumentInfoArray(0); - // None, Constant | UseCompileTimeType - _setCSharpArgumentInfoArray = CreateSharpArgumentInfoArray(0, 3); - CreateMemberCalls(); + // None + _getCSharpArgumentInfoArray = CreateSharpArgumentInfoArray(0); + // None, Constant | UseCompileTimeType + _setCSharpArgumentInfoArray = CreateSharpArgumentInfoArray(0, 3); + CreateMemberCalls(); - _init = true; - } - } + _init = true; + } + } - private static object CreateSharpArgumentInfoArray(params int[] values) - { - Type csharpArgumentInfoType = Type.GetType(CSharpArgumentInfoTypeName); - Type csharpArgumentInfoFlags = Type.GetType(CSharpArgumentInfoFlagsTypeName); + private static object CreateSharpArgumentInfoArray(params int[] values) + { + Type csharpArgumentInfoType = Type.GetType(CSharpArgumentInfoTypeName); + Type csharpArgumentInfoFlags = Type.GetType(CSharpArgumentInfoFlagsTypeName); - Array a = Array.CreateInstance(csharpArgumentInfoType, values.Length); + Array a = Array.CreateInstance(csharpArgumentInfoType, values.Length); - for (int i = 0; i < values.Length; i++) - { - MethodInfo createArgumentInfoMethod = csharpArgumentInfoType.GetMethod("Create", new[] {csharpArgumentInfoFlags, typeof (string)}); - object arg = createArgumentInfoMethod.Invoke(null, new object[] {0, null}); - a.SetValue(arg, i); - } + for (int i = 0; i < values.Length; i++) + { + MethodInfo createArgumentInfoMethod = csharpArgumentInfoType.GetMethod("Create", new[] { csharpArgumentInfoFlags, typeof(string) }); + object arg = createArgumentInfoMethod.Invoke(null, new object[] { 0, null }); + a.SetValue(arg, i); + } - return a; - } + return a; + } - private static void CreateMemberCalls() - { - Type csharpArgumentInfoType = Type.GetType(CSharpArgumentInfoTypeName, true); - Type csharpBinderFlagsType = Type.GetType(CSharpBinderFlagsTypeName, true); - Type binderType = Type.GetType(BinderTypeName, true); + private static void CreateMemberCalls() + { + Type csharpArgumentInfoType = Type.GetType(CSharpArgumentInfoTypeName, true); + Type csharpBinderFlagsType = Type.GetType(CSharpBinderFlagsTypeName, true); + Type binderType = Type.GetType(BinderTypeName, true); - Type csharpArgumentInfoTypeEnumerableType = typeof (IEnumerable<>).MakeGenericType(csharpArgumentInfoType); + Type csharpArgumentInfoTypeEnumerableType = typeof(IEnumerable<>).MakeGenericType(csharpArgumentInfoType); - MethodInfo getMemberMethod = binderType.GetMethod("GetMember", new[] {csharpBinderFlagsType, typeof (string), typeof (Type), csharpArgumentInfoTypeEnumerableType}); - _getMemberCall = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(getMemberMethod); + MethodInfo getMemberMethod = binderType.GetMethod("GetMember", new[] { csharpBinderFlagsType, typeof(string), typeof(Type), csharpArgumentInfoTypeEnumerableType }); + _getMemberCall = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(getMemberMethod); - MethodInfo setMemberMethod = binderType.GetMethod("SetMember", new[] {csharpBinderFlagsType, typeof (string), typeof (Type), csharpArgumentInfoTypeEnumerableType}); - _setMemberCall = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(setMemberMethod); - } + MethodInfo setMemberMethod = binderType.GetMethod("SetMember", new[] { csharpBinderFlagsType, typeof(string), typeof(Type), csharpArgumentInfoTypeEnumerableType }); + _setMemberCall = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(setMemberMethod); + } #endif - public static CallSiteBinder GetMember(string name, Type context) - { + public static CallSiteBinder GetMember(string name, Type context) + { #if !(PORTABLE || WINDOWS_PHONE) - Init(); - return (CallSiteBinder) _getMemberCall(null, 0, name, context, _getCSharpArgumentInfoArray); + Init(); + return (CallSiteBinder)_getMemberCall(null, 0, name, context, _getCSharpArgumentInfoArray); #else return Binder.GetMember( CSharpBinderFlags.None, name, context, new[] {CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)}); #endif - } + } - public static CallSiteBinder SetMember(string name, Type context) - { + public static CallSiteBinder SetMember(string name, Type context) + { #if !(PORTABLE || WINDOWS_PHONE) - Init(); - return (CallSiteBinder) _setMemberCall(null, 0, name, context, _setCSharpArgumentInfoArray); + Init(); + return (CallSiteBinder)_setMemberCall(null, 0, name, context, _setCSharpArgumentInfoArray); #else return Binder.SetMember( CSharpBinderFlags.None, name, context, new[] @@ -138,73 +138,73 @@ namespace Newtonsoft.Json.Utilities CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.Constant, null) }); #endif - } + } + } + + public static IEnumerable GetDynamicMemberNames(this IDynamicMetaObjectProvider dynamicProvider) + { + DynamicMetaObject metaObject = dynamicProvider.GetMetaObject(Expression.Constant(dynamicProvider)); + return metaObject.GetDynamicMemberNames(); + } } - public static IEnumerable GetDynamicMemberNames(this IDynamicMetaObjectProvider dynamicProvider) + internal class NoThrowGetBinderMember : GetMemberBinder { - DynamicMetaObject metaObject = dynamicProvider.GetMetaObject(Expression.Constant(dynamicProvider)); - return metaObject.GetDynamicMemberNames(); + private readonly GetMemberBinder _innerBinder; + + public NoThrowGetBinderMember(GetMemberBinder innerBinder) + : base(innerBinder.Name, innerBinder.IgnoreCase) + { + _innerBinder = innerBinder; + } + + public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion) + { + DynamicMetaObject retMetaObject = _innerBinder.Bind(target, new DynamicMetaObject[] { }); + + NoThrowExpressionVisitor noThrowVisitor = new NoThrowExpressionVisitor(); + Expression resultExpression = noThrowVisitor.Visit(retMetaObject.Expression); + + DynamicMetaObject finalMetaObject = new DynamicMetaObject(resultExpression, retMetaObject.Restrictions); + return finalMetaObject; + } } - } - internal class NoThrowGetBinderMember : GetMemberBinder - { - private readonly GetMemberBinder _innerBinder; - - public NoThrowGetBinderMember(GetMemberBinder innerBinder) - : base(innerBinder.Name, innerBinder.IgnoreCase) + internal class NoThrowSetBinderMember : SetMemberBinder { - _innerBinder = innerBinder; + private readonly SetMemberBinder _innerBinder; + + public NoThrowSetBinderMember(SetMemberBinder innerBinder) + : base(innerBinder.Name, innerBinder.IgnoreCase) + { + _innerBinder = innerBinder; + } + + public override DynamicMetaObject FallbackSetMember(DynamicMetaObject target, DynamicMetaObject value, DynamicMetaObject errorSuggestion) + { + DynamicMetaObject retMetaObject = _innerBinder.Bind(target, new DynamicMetaObject[] { value }); + + NoThrowExpressionVisitor noThrowVisitor = new NoThrowExpressionVisitor(); + Expression resultExpression = noThrowVisitor.Visit(retMetaObject.Expression); + + DynamicMetaObject finalMetaObject = new DynamicMetaObject(resultExpression, retMetaObject.Restrictions); + return finalMetaObject; + } } - public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion) + internal class NoThrowExpressionVisitor : ExpressionVisitor { - DynamicMetaObject retMetaObject = _innerBinder.Bind(target, new DynamicMetaObject[] { }); + internal static readonly object ErrorResult = new object(); - NoThrowExpressionVisitor noThrowVisitor = new NoThrowExpressionVisitor(); - Expression resultExpression = noThrowVisitor.Visit(retMetaObject.Expression); + protected override Expression VisitConditional(ConditionalExpression node) + { + // if the result of a test is to throw an error, rewrite to result an error result value + if (node.IfFalse.NodeType == ExpressionType.Throw) + return Expression.Condition(node.Test, node.IfTrue, Expression.Constant(ErrorResult)); - DynamicMetaObject finalMetaObject = new DynamicMetaObject(resultExpression, retMetaObject.Restrictions); - return finalMetaObject; + return base.VisitConditional(node); + } } - } - - internal class NoThrowSetBinderMember : SetMemberBinder - { - private readonly SetMemberBinder _innerBinder; - - public NoThrowSetBinderMember(SetMemberBinder innerBinder) - : base(innerBinder.Name, innerBinder.IgnoreCase) - { - _innerBinder = innerBinder; - } - - public override DynamicMetaObject FallbackSetMember(DynamicMetaObject target, DynamicMetaObject value, DynamicMetaObject errorSuggestion) - { - DynamicMetaObject retMetaObject = _innerBinder.Bind(target, new DynamicMetaObject[] { value }); - - NoThrowExpressionVisitor noThrowVisitor = new NoThrowExpressionVisitor(); - Expression resultExpression = noThrowVisitor.Visit(retMetaObject.Expression); - - DynamicMetaObject finalMetaObject = new DynamicMetaObject(resultExpression, retMetaObject.Restrictions); - return finalMetaObject; - } - } - - internal class NoThrowExpressionVisitor : ExpressionVisitor - { - internal static readonly object ErrorResult = new object(); - - protected override Expression VisitConditional(ConditionalExpression node) - { - // if the result of a test is to throw an error, rewrite to result an error result value - if (node.IfFalse.NodeType == ExpressionType.Throw) - return Expression.Condition(node.Test, node.IfTrue, Expression.Constant(ErrorResult)); - - return base.VisitConditional(node); - } - } - } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/DynamicWrapper.cs b/Src/Newtonsoft.Json/Utilities/DynamicWrapper.cs index d65edf79..0a1b92af 100644 --- a/Src/Newtonsoft.Json/Utilities/DynamicWrapper.cs +++ b/Src/Newtonsoft.Json/Utilities/DynamicWrapper.cs @@ -35,230 +35,232 @@ using System.Globalization; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json.Utilities { - internal class DynamicWrapperBase - { - internal protected object UnderlyingObject; - } - - internal static class DynamicWrapper - { - private static readonly object _lock = new object(); - private static readonly WrapperDictionary _wrapperDictionary = new WrapperDictionary(); - - private static ModuleBuilder _moduleBuilder; - - private static ModuleBuilder ModuleBuilder + internal class DynamicWrapperBase { - get - { - Init(); - return _moduleBuilder; - } + protected internal object UnderlyingObject; } - private static void Init() + internal static class DynamicWrapper { - if (_moduleBuilder == null) - { - lock (_lock) + private static readonly object _lock = new object(); + private static readonly WrapperDictionary _wrapperDictionary = new WrapperDictionary(); + + private static ModuleBuilder _moduleBuilder; + + private static ModuleBuilder ModuleBuilder { - if (_moduleBuilder == null) - { - AssemblyName assemblyName = new AssemblyName("Newtonsoft.Json.Dynamic"); - assemblyName.KeyPair = new StrongNameKeyPair(GetStrongKey()); - - AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); - _moduleBuilder = assembly.DefineDynamicModule("Newtonsoft.Json.DynamicModule", false); - } + get + { + Init(); + return _moduleBuilder; + } } - } - } - private static byte[] GetStrongKey() - { - const string name = "Newtonsoft.Json.Dynamic.snk"; - - using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name)) - { - if (stream == null) - throw new MissingManifestResourceException("Should have " + name + " as an embedded resource."); - - int length = (int)stream.Length; - byte[] buffer = new byte[length]; - stream.Read(buffer, 0, length); - - return buffer; - } - } - - public static Type GetWrapper(Type interfaceType, Type realObjectType) - { - Type wrapperType = _wrapperDictionary.GetType(interfaceType, realObjectType); - - if (wrapperType == null) - { - lock (_lock) + private static void Init() { - wrapperType = _wrapperDictionary.GetType(interfaceType, realObjectType); + if (_moduleBuilder == null) + { + lock (_lock) + { + if (_moduleBuilder == null) + { + AssemblyName assemblyName = new AssemblyName("Newtonsoft.Json.Dynamic"); + assemblyName.KeyPair = new StrongNameKeyPair(GetStrongKey()); - if (wrapperType == null) - { - wrapperType = GenerateWrapperType(interfaceType, realObjectType); - _wrapperDictionary.SetType(interfaceType, realObjectType, wrapperType); - } + AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); + _moduleBuilder = assembly.DefineDynamicModule("Newtonsoft.Json.DynamicModule", false); + } + } + } } - } - return wrapperType; + private static byte[] GetStrongKey() + { + const string name = "Newtonsoft.Json.Dynamic.snk"; + + using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name)) + { + if (stream == null) + throw new MissingManifestResourceException("Should have " + name + " as an embedded resource."); + + int length = (int)stream.Length; + byte[] buffer = new byte[length]; + stream.Read(buffer, 0, length); + + return buffer; + } + } + + public static Type GetWrapper(Type interfaceType, Type realObjectType) + { + Type wrapperType = _wrapperDictionary.GetType(interfaceType, realObjectType); + + if (wrapperType == null) + { + lock (_lock) + { + wrapperType = _wrapperDictionary.GetType(interfaceType, realObjectType); + + if (wrapperType == null) + { + wrapperType = GenerateWrapperType(interfaceType, realObjectType); + _wrapperDictionary.SetType(interfaceType, realObjectType, wrapperType); + } + } + } + + return wrapperType; + } + + public static object GetUnderlyingObject(object wrapper) + { + DynamicWrapperBase wrapperBase = wrapper as DynamicWrapperBase; + if (wrapperBase == null) + throw new ArgumentException("Object is not a wrapper.", "wrapper"); + + return wrapperBase.UnderlyingObject; + } + + private static Type GenerateWrapperType(Type interfaceType, Type underlyingType) + { + TypeBuilder wrapperBuilder = ModuleBuilder.DefineType( + "{0}_{1}_Wrapper".FormatWith(CultureInfo.InvariantCulture, interfaceType.Name, underlyingType.Name), + TypeAttributes.NotPublic | TypeAttributes.Sealed, + typeof(DynamicWrapperBase), + new[] { interfaceType }); + + WrapperMethodBuilder wrapperMethod = new WrapperMethodBuilder(underlyingType, wrapperBuilder); + + foreach (MethodInfo method in interfaceType.GetAllMethods()) + { + wrapperMethod.Generate(method); + } + + return wrapperBuilder.CreateType(); + } + + public static T CreateWrapper(object realObject) where T : class + { + var dynamicType = GetWrapper(typeof(T), realObject.GetType()); + var dynamicWrapper = (DynamicWrapperBase)Activator.CreateInstance(dynamicType); + + dynamicWrapper.UnderlyingObject = realObject; + + return dynamicWrapper as T; + } } - public static object GetUnderlyingObject(object wrapper) + internal class WrapperMethodBuilder { - DynamicWrapperBase wrapperBase = wrapper as DynamicWrapperBase; - if (wrapperBase == null) - throw new ArgumentException("Object is not a wrapper.", "wrapper"); + private readonly Type _realObjectType; + private readonly TypeBuilder _wrapperBuilder; - return wrapperBase.UnderlyingObject; + public WrapperMethodBuilder(Type realObjectType, TypeBuilder proxyBuilder) + { + _realObjectType = realObjectType; + _wrapperBuilder = proxyBuilder; + } + + public void Generate(MethodInfo newMethod) + { + if (newMethod.IsGenericMethod) + newMethod = newMethod.GetGenericMethodDefinition(); + + FieldInfo srcField = typeof(DynamicWrapperBase).GetField("UnderlyingObject", BindingFlags.Instance | BindingFlags.NonPublic); + + var parameters = newMethod.GetParameters(); + var parameterTypes = parameters.Select(parameter => parameter.ParameterType).ToArray(); + + MethodBuilder methodBuilder = _wrapperBuilder.DefineMethod( + newMethod.Name, + MethodAttributes.Public | MethodAttributes.Virtual, + newMethod.ReturnType, + parameterTypes); + + if (newMethod.IsGenericMethod) + { + methodBuilder.DefineGenericParameters( + newMethod.GetGenericArguments().Select(arg => arg.Name).ToArray()); + } + + ILGenerator ilGenerator = methodBuilder.GetILGenerator(); + + LoadUnderlyingObject(ilGenerator, srcField); + PushParameters(parameters, ilGenerator); + ExecuteMethod(newMethod, parameterTypes, ilGenerator); + Return(ilGenerator); + } + + private static void Return(ILGenerator ilGenerator) + { + ilGenerator.Emit(OpCodes.Ret); + } + + private void ExecuteMethod(MethodBase newMethod, Type[] parameterTypes, ILGenerator ilGenerator) + { + MethodInfo srcMethod = GetMethod(newMethod, parameterTypes); + + if (srcMethod == null) + throw new MissingMethodException("Unable to find method " + newMethod.Name + " on " + _realObjectType.FullName); + + ilGenerator.Emit(OpCodes.Call, srcMethod); + } + + private MethodInfo GetMethod(MethodBase realMethod, Type[] parameterTypes) + { + if (realMethod.IsGenericMethod) + return _realObjectType.GetGenericMethod(realMethod.Name, parameterTypes); + + return _realObjectType.GetMethod(realMethod.Name, parameterTypes); + } + + private static void PushParameters(ICollection parameters, ILGenerator ilGenerator) + { + for (int i = 1; i < parameters.Count + 1; i++) + ilGenerator.Emit(OpCodes.Ldarg, i); + } + + private static void LoadUnderlyingObject(ILGenerator ilGenerator, FieldInfo srcField) + { + ilGenerator.Emit(OpCodes.Ldarg_0); + ilGenerator.Emit(OpCodes.Ldfld, srcField); + } } - private static Type GenerateWrapperType(Type interfaceType, Type underlyingType) + internal class WrapperDictionary { - TypeBuilder wrapperBuilder = ModuleBuilder.DefineType( - "{0}_{1}_Wrapper".FormatWith(CultureInfo.InvariantCulture, interfaceType.Name, underlyingType.Name), - TypeAttributes.NotPublic | TypeAttributes.Sealed, - typeof(DynamicWrapperBase), - new[] { interfaceType }); + private readonly Dictionary _wrapperTypes = new Dictionary(); - WrapperMethodBuilder wrapperMethod = new WrapperMethodBuilder(underlyingType, wrapperBuilder); + private static string GenerateKey(Type interfaceType, Type realObjectType) + { + return interfaceType.Name + "_" + realObjectType.Name; + } - foreach (MethodInfo method in interfaceType.GetAllMethods()) - { - wrapperMethod.Generate(method); - } + public Type GetType(Type interfaceType, Type realObjectType) + { + string key = GenerateKey(interfaceType, realObjectType); - return wrapperBuilder.CreateType(); + if (_wrapperTypes.ContainsKey(key)) + return _wrapperTypes[key]; + + return null; + } + + public void SetType(Type interfaceType, Type realObjectType, Type wrapperType) + { + string key = GenerateKey(interfaceType, realObjectType); + + if (_wrapperTypes.ContainsKey(key)) + _wrapperTypes[key] = wrapperType; + else + _wrapperTypes.Add(key, wrapperType); + } } - - public static T CreateWrapper(object realObject) where T : class - { - var dynamicType = GetWrapper(typeof(T), realObject.GetType()); - var dynamicWrapper = (DynamicWrapperBase)Activator.CreateInstance(dynamicType); - - dynamicWrapper.UnderlyingObject = realObject; - - return dynamicWrapper as T; - } - } - - internal class WrapperMethodBuilder - { - private readonly Type _realObjectType; - private readonly TypeBuilder _wrapperBuilder; - - public WrapperMethodBuilder(Type realObjectType, TypeBuilder proxyBuilder) - { - _realObjectType = realObjectType; - _wrapperBuilder = proxyBuilder; - } - - public void Generate(MethodInfo newMethod) - { - if (newMethod.IsGenericMethod) - newMethod = newMethod.GetGenericMethodDefinition(); - - FieldInfo srcField = typeof(DynamicWrapperBase).GetField("UnderlyingObject", BindingFlags.Instance | BindingFlags.NonPublic); - - var parameters = newMethod.GetParameters(); - var parameterTypes = parameters.Select(parameter => parameter.ParameterType).ToArray(); - - MethodBuilder methodBuilder = _wrapperBuilder.DefineMethod( - newMethod.Name, - MethodAttributes.Public | MethodAttributes.Virtual, - newMethod.ReturnType, - parameterTypes); - - if (newMethod.IsGenericMethod) - { - methodBuilder.DefineGenericParameters( - newMethod.GetGenericArguments().Select(arg => arg.Name).ToArray()); - } - - ILGenerator ilGenerator = methodBuilder.GetILGenerator(); - - LoadUnderlyingObject(ilGenerator, srcField); - PushParameters(parameters, ilGenerator); - ExecuteMethod(newMethod, parameterTypes, ilGenerator); - Return(ilGenerator); - } - - private static void Return(ILGenerator ilGenerator) - { - ilGenerator.Emit(OpCodes.Ret); - } - - private void ExecuteMethod(MethodBase newMethod, Type[] parameterTypes, ILGenerator ilGenerator) - { - MethodInfo srcMethod = GetMethod(newMethod, parameterTypes); - - if (srcMethod == null) - throw new MissingMethodException("Unable to find method " + newMethod.Name + " on " + _realObjectType.FullName); - - ilGenerator.Emit(OpCodes.Call, srcMethod); - } - - private MethodInfo GetMethod(MethodBase realMethod, Type[] parameterTypes) - { - if (realMethod.IsGenericMethod) - return _realObjectType.GetGenericMethod(realMethod.Name, parameterTypes); - - return _realObjectType.GetMethod(realMethod.Name, parameterTypes); - } - - private static void PushParameters(ICollection parameters, ILGenerator ilGenerator) - { - for (int i = 1; i < parameters.Count + 1; i++) - ilGenerator.Emit(OpCodes.Ldarg, i); - } - - private static void LoadUnderlyingObject(ILGenerator ilGenerator, FieldInfo srcField) - { - ilGenerator.Emit(OpCodes.Ldarg_0); - ilGenerator.Emit(OpCodes.Ldfld, srcField); - } - } - - internal class WrapperDictionary - { - private readonly Dictionary _wrapperTypes = new Dictionary(); - - private static string GenerateKey(Type interfaceType, Type realObjectType) - { - return interfaceType.Name + "_" + realObjectType.Name; - } - - public Type GetType(Type interfaceType, Type realObjectType) - { - string key = GenerateKey(interfaceType, realObjectType); - - if (_wrapperTypes.ContainsKey(key)) - return _wrapperTypes[key]; - - return null; - } - - public void SetType(Type interfaceType, Type realObjectType, Type wrapperType) - { - string key = GenerateKey(interfaceType, realObjectType); - - if (_wrapperTypes.ContainsKey(key)) - _wrapperTypes[key] = wrapperType; - else - _wrapperTypes.Add(key, wrapperType); - } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/EnumUtils.cs b/Src/Newtonsoft.Json/Utilities/EnumUtils.cs index bf4e7c6f..5a9e8a43 100644 --- a/Src/Newtonsoft.Json/Utilities/EnumUtils.cs +++ b/Src/Newtonsoft.Json/Utilities/EnumUtils.cs @@ -35,113 +35,113 @@ using System.Reflection; namespace Newtonsoft.Json.Utilities { - internal static class EnumUtils - { - public static IList GetFlagsValues(T value) where T : struct + internal static class EnumUtils { - Type enumType = typeof(T); - - if (!enumType.IsDefined(typeof(FlagsAttribute), false)) - throw new ArgumentException("Enum type {0} is not a set of flags.".FormatWith(CultureInfo.InvariantCulture, enumType)); - - Type underlyingType = Enum.GetUnderlyingType(value.GetType()); - - ulong num = Convert.ToUInt64(value, CultureInfo.InvariantCulture); - EnumValues enumNameValues = GetNamesAndValues(); - IList selectedFlagsValues = new List(); - - foreach (EnumValue enumNameValue in enumNameValues) - { - if ((num & enumNameValue.Value) == enumNameValue.Value && enumNameValue.Value != 0) - selectedFlagsValues.Add((T)Convert.ChangeType(enumNameValue.Value, underlyingType, CultureInfo.CurrentCulture)); - } - - if (selectedFlagsValues.Count == 0 && enumNameValues.SingleOrDefault(v => v.Value == 0) != null) - selectedFlagsValues.Add(default(T)); - - return selectedFlagsValues; - } - - /// - /// Gets a dictionary of the names and values of an Enum type. - /// - /// - public static EnumValues GetNamesAndValues() where T : struct - { - return GetNamesAndValues(typeof(T)); - } - - /// - /// Gets a dictionary of the names and values of an Enum type. - /// - /// The enum type to get names and values for. - /// - public static EnumValues GetNamesAndValues(Type enumType) where TUnderlyingType : struct - { - if (enumType == null) - throw new ArgumentNullException("enumType"); - - ValidationUtils.ArgumentTypeIsEnum(enumType, "enumType"); - - IList enumValues = GetValues(enumType); - IList enumNames = GetNames(enumType); - - EnumValues nameValues = new EnumValues(); - - for (int i = 0; i < enumValues.Count; i++) - { - try + public static IList GetFlagsValues(T value) where T : struct { - nameValues.Add(new EnumValue(enumNames[i], (TUnderlyingType)Convert.ChangeType(enumValues[i], typeof(TUnderlyingType), CultureInfo.CurrentCulture))); + Type enumType = typeof(T); + + if (!enumType.IsDefined(typeof(FlagsAttribute), false)) + throw new ArgumentException("Enum type {0} is not a set of flags.".FormatWith(CultureInfo.InvariantCulture, enumType)); + + Type underlyingType = Enum.GetUnderlyingType(value.GetType()); + + ulong num = Convert.ToUInt64(value, CultureInfo.InvariantCulture); + EnumValues enumNameValues = GetNamesAndValues(); + IList selectedFlagsValues = new List(); + + foreach (EnumValue enumNameValue in enumNameValues) + { + if ((num & enumNameValue.Value) == enumNameValue.Value && enumNameValue.Value != 0) + selectedFlagsValues.Add((T)Convert.ChangeType(enumNameValue.Value, underlyingType, CultureInfo.CurrentCulture)); + } + + if (selectedFlagsValues.Count == 0 && enumNameValues.SingleOrDefault(v => v.Value == 0) != null) + selectedFlagsValues.Add(default(T)); + + return selectedFlagsValues; } - catch (OverflowException e) + + /// + /// Gets a dictionary of the names and values of an Enum type. + /// + /// + public static EnumValues GetNamesAndValues() where T : struct { - throw new InvalidOperationException( - string.Format(CultureInfo.InvariantCulture, "Value from enum with the underlying type of {0} cannot be added to dictionary with a value type of {1}. Value was too large: {2}", - Enum.GetUnderlyingType(enumType), typeof(TUnderlyingType), Convert.ToUInt64(enumValues[i], CultureInfo.InvariantCulture)), e); + return GetNamesAndValues(typeof(T)); } - } - return nameValues; + /// + /// Gets a dictionary of the names and values of an Enum type. + /// + /// The enum type to get names and values for. + /// + public static EnumValues GetNamesAndValues(Type enumType) where TUnderlyingType : struct + { + if (enumType == null) + throw new ArgumentNullException("enumType"); + + ValidationUtils.ArgumentTypeIsEnum(enumType, "enumType"); + + IList enumValues = GetValues(enumType); + IList enumNames = GetNames(enumType); + + EnumValues nameValues = new EnumValues(); + + for (int i = 0; i < enumValues.Count; i++) + { + try + { + nameValues.Add(new EnumValue(enumNames[i], (TUnderlyingType)Convert.ChangeType(enumValues[i], typeof(TUnderlyingType), CultureInfo.CurrentCulture))); + } + catch (OverflowException e) + { + throw new InvalidOperationException( + string.Format(CultureInfo.InvariantCulture, "Value from enum with the underlying type of {0} cannot be added to dictionary with a value type of {1}. Value was too large: {2}", + Enum.GetUnderlyingType(enumType), typeof(TUnderlyingType), Convert.ToUInt64(enumValues[i], CultureInfo.InvariantCulture)), e); + } + } + + return nameValues; + } + + public static IList GetValues(Type enumType) + { + if (!enumType.IsEnum()) + throw new ArgumentException("Type '" + enumType.Name + "' is not an enum."); + + List values = new List(); + + var fields = from field in enumType.GetFields() + where field.IsLiteral + select field; + + foreach (FieldInfo field in fields) + { + object value = field.GetValue(enumType); + values.Add(value); + } + + return values; + } + + public static IList GetNames(Type enumType) + { + if (!enumType.IsEnum()) + throw new ArgumentException("Type '" + enumType.Name + "' is not an enum."); + + List values = new List(); + + var fields = from field in enumType.GetFields() + where field.IsLiteral + select field; + + foreach (FieldInfo field in fields) + { + values.Add(field.Name); + } + + return values; + } } - - public static IList GetValues(Type enumType) - { - if (!enumType.IsEnum()) - throw new ArgumentException("Type '" + enumType.Name + "' is not an enum."); - - List values = new List(); - - var fields = from field in enumType.GetFields() - where field.IsLiteral - select field; - - foreach (FieldInfo field in fields) - { - object value = field.GetValue(enumType); - values.Add(value); - } - - return values; - } - - public static IList GetNames(Type enumType) - { - if (!enumType.IsEnum()) - throw new ArgumentException("Type '" + enumType.Name + "' is not an enum."); - - List values = new List(); - - var fields = from field in enumType.GetFields() - where field.IsLiteral - select field; - - foreach (FieldInfo field in fields) - { - values.Add(field.Name); - } - - return values; - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/EnumValue.cs b/Src/Newtonsoft.Json/Utilities/EnumValue.cs index 51a9f391..c672ead8 100644 --- a/Src/Newtonsoft.Json/Utilities/EnumValue.cs +++ b/Src/Newtonsoft.Json/Utilities/EnumValue.cs @@ -25,24 +25,25 @@ namespace Newtonsoft.Json.Utilities { - internal class EnumValue where T : struct - { - private readonly string _name; - private readonly T _value; + internal class EnumValue where T : struct + { + private readonly string _name; + private readonly T _value; - public string Name - { - get { return _name; } - } - public T Value - { - get { return _value; } - } + public string Name + { + get { return _name; } + } - public EnumValue(string name, T value) - { - _name = name; - _value = value; + public T Value + { + get { return _value; } + } + + public EnumValue(string name, T value) + { + _name = name; + _value = value; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/EnumValues.cs b/Src/Newtonsoft.Json/Utilities/EnumValues.cs index 33e805fb..51de5ff9 100644 --- a/Src/Newtonsoft.Json/Utilities/EnumValues.cs +++ b/Src/Newtonsoft.Json/Utilities/EnumValues.cs @@ -27,11 +27,11 @@ using System.Collections.ObjectModel; namespace Newtonsoft.Json.Utilities { - internal class EnumValues : KeyedCollection> where T : struct - { - protected override string GetKeyForItem(EnumValue item) + internal class EnumValues : KeyedCollection> where T : struct { - return item.Name; + protected override string GetKeyForItem(EnumValue item) + { + return item.Name; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/ExpressionReflectionDelegateFactory.cs b/Src/Newtonsoft.Json/Utilities/ExpressionReflectionDelegateFactory.cs index 920d7002..296e86e3 100644 --- a/Src/Newtonsoft.Json/Utilities/ExpressionReflectionDelegateFactory.cs +++ b/Src/Newtonsoft.Json/Utilities/ExpressionReflectionDelegateFactory.cs @@ -30,239 +30,240 @@ using System.Reflection; namespace Newtonsoft.Json.Utilities { - internal class ExpressionReflectionDelegateFactory : ReflectionDelegateFactory - { - private static readonly ExpressionReflectionDelegateFactory _instance = new ExpressionReflectionDelegateFactory(); - - internal static ReflectionDelegateFactory Instance + internal class ExpressionReflectionDelegateFactory : ReflectionDelegateFactory { - get { return _instance; } + private static readonly ExpressionReflectionDelegateFactory _instance = new ExpressionReflectionDelegateFactory(); + + internal static ReflectionDelegateFactory Instance + { + get { return _instance; } + } + + public override MethodCall CreateMethodCall(MethodBase method) + { + ValidationUtils.ArgumentNotNull(method, "method"); + + Type type = typeof(object); + + ParameterExpression targetParameterExpression = Expression.Parameter(type, "target"); + ParameterExpression argsParameterExpression = Expression.Parameter(typeof(object[]), "args"); + + ParameterInfo[] parametersInfo = method.GetParameters(); + + Expression[] argsExpression = new Expression[parametersInfo.Length]; + + for (int i = 0; i < parametersInfo.Length; i++) + { + Expression indexExpression = Expression.Constant(i); + + Expression paramAccessorExpression = Expression.ArrayIndex(argsParameterExpression, indexExpression); + + paramAccessorExpression = EnsureCastExpression(paramAccessorExpression, parametersInfo[i].ParameterType); + + argsExpression[i] = paramAccessorExpression; + } + + Expression callExpression; + if (method.IsConstructor) + { + callExpression = Expression.New((ConstructorInfo)method, argsExpression); + } + else if (method.IsStatic) + { + callExpression = Expression.Call((MethodInfo)method, argsExpression); + } + else + { + Expression readParameter = EnsureCastExpression(targetParameterExpression, method.DeclaringType); + + callExpression = Expression.Call(readParameter, (MethodInfo)method, argsExpression); + } + + if (method is MethodInfo) + { + MethodInfo m = (MethodInfo)method; + if (m.ReturnType != typeof(void)) + callExpression = EnsureCastExpression(callExpression, type); + else + callExpression = Expression.Block(callExpression, Expression.Constant(null)); + } + else + { + callExpression = EnsureCastExpression(callExpression, type); + } + + LambdaExpression lambdaExpression = Expression.Lambda(typeof(MethodCall), callExpression, targetParameterExpression, argsParameterExpression); + + MethodCall compiled = (MethodCall)lambdaExpression.Compile(); + return compiled; + } + + public override Func CreateDefaultConstructor(Type type) + { + ValidationUtils.ArgumentNotNull(type, "type"); + + // avoid error from expressions compiler because of abstract class + if (type.IsAbstract()) + return () => (T)Activator.CreateInstance(type); + + try + { + Type resultType = typeof(T); + + Expression expression = Expression.New(type); + + expression = EnsureCastExpression(expression, resultType); + + LambdaExpression lambdaExpression = Expression.Lambda(typeof(Func), expression); + + Func compiled = (Func)lambdaExpression.Compile(); + return compiled; + } + catch + { + // an error can be thrown if constructor is not valid on Win8 + // will have INVOCATION_FLAGS_NON_W8P_FX_API invocation flag + return () => (T)Activator.CreateInstance(type); + } + } + + public override Func CreateGet(PropertyInfo propertyInfo) + { + ValidationUtils.ArgumentNotNull(propertyInfo, "propertyInfo"); + + Type instanceType = typeof(T); + Type resultType = typeof(object); + + ParameterExpression parameterExpression = Expression.Parameter(instanceType, "instance"); + Expression resultExpression; + + MethodInfo getMethod = propertyInfo.GetGetMethod(true); + + if (getMethod.IsStatic) + { + resultExpression = Expression.MakeMemberAccess(null, propertyInfo); + } + else + { + Expression readParameter = EnsureCastExpression(parameterExpression, propertyInfo.DeclaringType); + + resultExpression = Expression.MakeMemberAccess(readParameter, propertyInfo); + } + + resultExpression = EnsureCastExpression(resultExpression, resultType); + + LambdaExpression lambdaExpression = Expression.Lambda(typeof(Func), resultExpression, parameterExpression); + + Func compiled = (Func)lambdaExpression.Compile(); + return compiled; + } + + public override Func CreateGet(FieldInfo fieldInfo) + { + ValidationUtils.ArgumentNotNull(fieldInfo, "fieldInfo"); + + ParameterExpression sourceParameter = Expression.Parameter(typeof(T), "source"); + + Expression fieldExpression; + if (fieldInfo.IsStatic) + { + fieldExpression = Expression.Field(null, fieldInfo); + } + else + { + Expression sourceExpression = EnsureCastExpression(sourceParameter, fieldInfo.DeclaringType); + + fieldExpression = Expression.Field(sourceExpression, fieldInfo); + } + + fieldExpression = EnsureCastExpression(fieldExpression, typeof(object)); + + Func compiled = Expression.Lambda>(fieldExpression, sourceParameter).Compile(); + return compiled; + } + + public override Action CreateSet(FieldInfo fieldInfo) + { + ValidationUtils.ArgumentNotNull(fieldInfo, "fieldInfo"); + + // use reflection for structs + // expression doesn't correctly set value + if (fieldInfo.DeclaringType.IsValueType() || fieldInfo.IsInitOnly) + return LateBoundReflectionDelegateFactory.Instance.CreateSet(fieldInfo); + + ParameterExpression sourceParameterExpression = Expression.Parameter(typeof(T), "source"); + ParameterExpression valueParameterExpression = Expression.Parameter(typeof(object), "value"); + + Expression fieldExpression; + if (fieldInfo.IsStatic) + { + fieldExpression = Expression.Field(null, fieldInfo); + } + else + { + Expression sourceExpression = EnsureCastExpression(sourceParameterExpression, fieldInfo.DeclaringType); + + fieldExpression = Expression.Field(sourceExpression, fieldInfo); + } + + Expression valueExpression = EnsureCastExpression(valueParameterExpression, fieldExpression.Type); + + BinaryExpression assignExpression = Expression.Assign(fieldExpression, valueExpression); + + LambdaExpression lambdaExpression = Expression.Lambda(typeof(Action), assignExpression, sourceParameterExpression, valueParameterExpression); + + Action compiled = (Action)lambdaExpression.Compile(); + return compiled; + } + + public override Action CreateSet(PropertyInfo propertyInfo) + { + ValidationUtils.ArgumentNotNull(propertyInfo, "propertyInfo"); + + // use reflection for structs + // expression doesn't correctly set value + if (propertyInfo.DeclaringType.IsValueType()) + return LateBoundReflectionDelegateFactory.Instance.CreateSet(propertyInfo); + + Type instanceType = typeof(T); + Type valueType = typeof(object); + + ParameterExpression instanceParameter = Expression.Parameter(instanceType, "instance"); + + ParameterExpression valueParameter = Expression.Parameter(valueType, "value"); + Expression readValueParameter = EnsureCastExpression(valueParameter, propertyInfo.PropertyType); + + MethodInfo setMethod = propertyInfo.GetSetMethod(true); + + Expression setExpression; + if (setMethod.IsStatic) + { + setExpression = Expression.Call(setMethod, readValueParameter); + } + else + { + Expression readInstanceParameter = EnsureCastExpression(instanceParameter, propertyInfo.DeclaringType); + + setExpression = Expression.Call(readInstanceParameter, setMethod, readValueParameter); + } + + LambdaExpression lambdaExpression = Expression.Lambda(typeof(Action), setExpression, instanceParameter, valueParameter); + + Action compiled = (Action)lambdaExpression.Compile(); + return compiled; + } + + private Expression EnsureCastExpression(Expression expression, Type targetType) + { + Type expressionType = expression.Type; + + // check if a cast or conversion is required + if (expressionType == targetType || (!expressionType.IsValueType() && targetType.IsAssignableFrom(expressionType))) + return expression; + + return Expression.Convert(expression, targetType); + } } - - public override MethodCall CreateMethodCall(MethodBase method) - { - ValidationUtils.ArgumentNotNull(method, "method"); - - Type type = typeof(object); - - ParameterExpression targetParameterExpression = Expression.Parameter(type, "target"); - ParameterExpression argsParameterExpression = Expression.Parameter(typeof(object[]), "args"); - - ParameterInfo[] parametersInfo = method.GetParameters(); - - Expression[] argsExpression = new Expression[parametersInfo.Length]; - - for (int i = 0; i < parametersInfo.Length; i++) - { - Expression indexExpression = Expression.Constant(i); - - Expression paramAccessorExpression = Expression.ArrayIndex(argsParameterExpression, indexExpression); - - paramAccessorExpression = EnsureCastExpression(paramAccessorExpression, parametersInfo[i].ParameterType); - - argsExpression[i] = paramAccessorExpression; - } - - Expression callExpression; - if (method.IsConstructor) - { - callExpression = Expression.New((ConstructorInfo)method, argsExpression); - } - else if (method.IsStatic) - { - callExpression = Expression.Call((MethodInfo)method, argsExpression); - } - else - { - Expression readParameter = EnsureCastExpression(targetParameterExpression, method.DeclaringType); - - callExpression = Expression.Call(readParameter, (MethodInfo)method, argsExpression); - } - - if (method is MethodInfo) - { - MethodInfo m = (MethodInfo)method; - if (m.ReturnType != typeof(void)) - callExpression = EnsureCastExpression(callExpression, type); - else - callExpression = Expression.Block(callExpression, Expression.Constant(null)); - } - else - { - callExpression = EnsureCastExpression(callExpression, type); - } - - LambdaExpression lambdaExpression = Expression.Lambda(typeof(MethodCall), callExpression, targetParameterExpression, argsParameterExpression); - - MethodCall compiled = (MethodCall)lambdaExpression.Compile(); - return compiled; - } - - public override Func CreateDefaultConstructor(Type type) - { - ValidationUtils.ArgumentNotNull(type, "type"); - - // avoid error from expressions compiler because of abstract class - if (type.IsAbstract()) - return () => (T)Activator.CreateInstance(type); - - try - { - Type resultType = typeof(T); - - Expression expression = Expression.New(type); - - expression = EnsureCastExpression(expression, resultType); - - LambdaExpression lambdaExpression = Expression.Lambda(typeof(Func), expression); - - Func compiled = (Func)lambdaExpression.Compile(); - return compiled; - } - catch - { - // an error can be thrown if constructor is not valid on Win8 - // will have INVOCATION_FLAGS_NON_W8P_FX_API invocation flag - return () => (T)Activator.CreateInstance(type); - } - } - - public override Func CreateGet(PropertyInfo propertyInfo) - { - ValidationUtils.ArgumentNotNull(propertyInfo, "propertyInfo"); - - Type instanceType = typeof(T); - Type resultType = typeof(object); - - ParameterExpression parameterExpression = Expression.Parameter(instanceType, "instance"); - Expression resultExpression; - - MethodInfo getMethod = propertyInfo.GetGetMethod(true); - - if (getMethod.IsStatic) - { - resultExpression = Expression.MakeMemberAccess(null, propertyInfo); - } - else - { - Expression readParameter = EnsureCastExpression(parameterExpression, propertyInfo.DeclaringType); - - resultExpression = Expression.MakeMemberAccess(readParameter, propertyInfo); - } - - resultExpression = EnsureCastExpression(resultExpression, resultType); - - LambdaExpression lambdaExpression = Expression.Lambda(typeof(Func), resultExpression, parameterExpression); - - Func compiled = (Func)lambdaExpression.Compile(); - return compiled; - } - - public override Func CreateGet(FieldInfo fieldInfo) - { - ValidationUtils.ArgumentNotNull(fieldInfo, "fieldInfo"); - - ParameterExpression sourceParameter = Expression.Parameter(typeof(T), "source"); - - Expression fieldExpression; - if (fieldInfo.IsStatic) - { - fieldExpression = Expression.Field(null, fieldInfo); - } - else - { - Expression sourceExpression = EnsureCastExpression(sourceParameter, fieldInfo.DeclaringType); - - fieldExpression = Expression.Field(sourceExpression, fieldInfo); - } - - fieldExpression = EnsureCastExpression(fieldExpression, typeof(object)); - - Func compiled = Expression.Lambda>(fieldExpression, sourceParameter).Compile(); - return compiled; - } - - public override Action CreateSet(FieldInfo fieldInfo) - { - ValidationUtils.ArgumentNotNull(fieldInfo, "fieldInfo"); - - // use reflection for structs - // expression doesn't correctly set value - if (fieldInfo.DeclaringType.IsValueType() || fieldInfo.IsInitOnly) - return LateBoundReflectionDelegateFactory.Instance.CreateSet(fieldInfo); - - ParameterExpression sourceParameterExpression = Expression.Parameter(typeof(T), "source"); - ParameterExpression valueParameterExpression = Expression.Parameter(typeof(object), "value"); - - Expression fieldExpression; - if (fieldInfo.IsStatic) - { - fieldExpression = Expression.Field(null, fieldInfo); - } - else - { - Expression sourceExpression = EnsureCastExpression(sourceParameterExpression, fieldInfo.DeclaringType); - - fieldExpression = Expression.Field(sourceExpression, fieldInfo); - } - - Expression valueExpression = EnsureCastExpression(valueParameterExpression, fieldExpression.Type); - - BinaryExpression assignExpression = Expression.Assign(fieldExpression, valueExpression); - - LambdaExpression lambdaExpression = Expression.Lambda(typeof(Action), assignExpression, sourceParameterExpression, valueParameterExpression); - - Action compiled = (Action)lambdaExpression.Compile(); - return compiled; - } - - public override Action CreateSet(PropertyInfo propertyInfo) - { - ValidationUtils.ArgumentNotNull(propertyInfo, "propertyInfo"); - - // use reflection for structs - // expression doesn't correctly set value - if (propertyInfo.DeclaringType.IsValueType()) - return LateBoundReflectionDelegateFactory.Instance.CreateSet(propertyInfo); - - Type instanceType = typeof(T); - Type valueType = typeof(object); - - ParameterExpression instanceParameter = Expression.Parameter(instanceType, "instance"); - - ParameterExpression valueParameter = Expression.Parameter(valueType, "value"); - Expression readValueParameter = EnsureCastExpression(valueParameter, propertyInfo.PropertyType); - - MethodInfo setMethod = propertyInfo.GetSetMethod(true); - - Expression setExpression; - if (setMethod.IsStatic) - { - setExpression = Expression.Call(setMethod, readValueParameter); - } - else - { - Expression readInstanceParameter = EnsureCastExpression(instanceParameter, propertyInfo.DeclaringType); - - setExpression = Expression.Call(readInstanceParameter, setMethod, readValueParameter); - } - - LambdaExpression lambdaExpression = Expression.Lambda(typeof(Action), setExpression, instanceParameter, valueParameter); - - Action compiled = (Action)lambdaExpression.Compile(); - return compiled; - } - - private Expression EnsureCastExpression(Expression expression, Type targetType) - { - Type expressionType = expression.Type; - - // check if a cast or conversion is required - if (expressionType == targetType || (!expressionType.IsValueType() && targetType.IsAssignableFrom(expressionType))) - return expression; - - return Expression.Convert(expression, targetType); - } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/ILGeneratorExtensions.cs b/Src/Newtonsoft.Json/Utilities/ILGeneratorExtensions.cs index 59fb4430..f08ca62b 100644 --- a/Src/Newtonsoft.Json/Utilities/ILGeneratorExtensions.cs +++ b/Src/Newtonsoft.Json/Utilities/ILGeneratorExtensions.cs @@ -30,45 +30,46 @@ using System.Reflection; namespace Newtonsoft.Json.Utilities { - internal static class ILGeneratorExtensions - { - public static void PushInstance(this ILGenerator generator, Type type) + internal static class ILGeneratorExtensions { - generator.Emit(OpCodes.Ldarg_0); - if (type.IsValueType()) - generator.Emit(OpCodes.Unbox, type); - else - generator.Emit(OpCodes.Castclass, type); - } + public static void PushInstance(this ILGenerator generator, Type type) + { + generator.Emit(OpCodes.Ldarg_0); + if (type.IsValueType()) + generator.Emit(OpCodes.Unbox, type); + else + generator.Emit(OpCodes.Castclass, type); + } - public static void BoxIfNeeded(this ILGenerator generator, Type type) - { - if (type.IsValueType()) - generator.Emit(OpCodes.Box, type); - else - generator.Emit(OpCodes.Castclass, type); - } + public static void BoxIfNeeded(this ILGenerator generator, Type type) + { + if (type.IsValueType()) + generator.Emit(OpCodes.Box, type); + else + generator.Emit(OpCodes.Castclass, type); + } - public static void UnboxIfNeeded(this ILGenerator generator, Type type) - { - if (type.IsValueType()) - generator.Emit(OpCodes.Unbox_Any, type); - else - generator.Emit(OpCodes.Castclass, type); - } + public static void UnboxIfNeeded(this ILGenerator generator, Type type) + { + if (type.IsValueType()) + generator.Emit(OpCodes.Unbox_Any, type); + else + generator.Emit(OpCodes.Castclass, type); + } - public static void CallMethod(this ILGenerator generator, MethodInfo methodInfo) - { - if (methodInfo.IsFinal || !methodInfo.IsVirtual) - generator.Emit(OpCodes.Call, methodInfo); - else - generator.Emit(OpCodes.Callvirt, methodInfo); - } + public static void CallMethod(this ILGenerator generator, MethodInfo methodInfo) + { + if (methodInfo.IsFinal || !methodInfo.IsVirtual) + generator.Emit(OpCodes.Call, methodInfo); + else + generator.Emit(OpCodes.Callvirt, methodInfo); + } - public static void Return(this ILGenerator generator) - { - generator.Emit(OpCodes.Ret); + public static void Return(this ILGenerator generator) + { + generator.Emit(OpCodes.Ret); + } } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/ImmutableCollectionsUtils.cs b/Src/Newtonsoft.Json/Utilities/ImmutableCollectionsUtils.cs index 8a343d47..11697dab 100644 --- a/Src/Newtonsoft.Json/Utilities/ImmutableCollectionsUtils.cs +++ b/Src/Newtonsoft.Json/Utilities/ImmutableCollectionsUtils.cs @@ -33,134 +33,135 @@ using System.Threading.Tasks; namespace Newtonsoft.Json.Utilities { - internal static class ImmutableCollectionsUtils - { - internal class ImmutableCollectionTypeInfo + internal static class ImmutableCollectionsUtils { - public ImmutableCollectionTypeInfo(string contractTypeName, string createdTypeName, string builderTypeName) - { - ContractTypeName = contractTypeName; - CreatedTypeName = createdTypeName; - BuilderTypeName = builderTypeName; - } - - public string ContractTypeName { get; set; } - public string CreatedTypeName { get; set; } - public string BuilderTypeName { get; set; } - } - - private const string ImmutableListGenericInterfaceTypeName = "System.Collections.Immutable.IImmutableList`1"; - private const string ImmutableQueueGenericInterfaceTypeName = "System.Collections.Immutable.IImmutableQueue`1"; - private const string ImmutableStackGenericInterfaceTypeName = "System.Collections.Immutable.IImmutableStack`1"; - private const string ImmutableSetGenericInterfaceTypeName = "System.Collections.Immutable.IImmutableSet`1"; - - private const string ImmutableArrayTypeName = "System.Collections.Immutable.ImmutableArray"; - private const string ImmutableArrayGenericTypeName = "System.Collections.Immutable.ImmutableArray`1"; - - private const string ImmutableListTypeName = "System.Collections.Immutable.ImmutableList"; - private const string ImmutableListGenericTypeName = "System.Collections.Immutable.ImmutableList`1"; - - private const string ImmutableQueueTypeName = "System.Collections.Immutable.ImmutableQueue"; - private const string ImmutableQueueGenericTypeName = "System.Collections.Immutable.ImmutableQueue`1"; - - private const string ImmutableStackTypeName = "System.Collections.Immutable.ImmutableStack"; - private const string ImmutableStackGenericTypeName = "System.Collections.Immutable.ImmutableStack`1"; - - private const string ImmutableSortedSetTypeName = "System.Collections.Immutable.ImmutableSortedSet"; - private const string ImmutableSortedSetGenericTypeName = "System.Collections.Immutable.ImmutableSortedSet`1"; - - private const string ImmutableHashSetTypeName = "System.Collections.Immutable.ImmutableHashSet"; - private const string ImmutableHashSetGenericTypeName = "System.Collections.Immutable.ImmutableHashSet`1"; - - private static readonly IList ArrayContractImmutableCollectionDefinitions = new List - { - new ImmutableCollectionTypeInfo(ImmutableListGenericInterfaceTypeName, ImmutableListGenericTypeName, ImmutableListTypeName), - new ImmutableCollectionTypeInfo(ImmutableListGenericTypeName, ImmutableListGenericTypeName, ImmutableListTypeName), - new ImmutableCollectionTypeInfo(ImmutableQueueGenericInterfaceTypeName, ImmutableQueueGenericTypeName, ImmutableQueueTypeName), - new ImmutableCollectionTypeInfo(ImmutableQueueGenericTypeName, ImmutableQueueGenericTypeName, ImmutableQueueTypeName), - new ImmutableCollectionTypeInfo(ImmutableStackGenericInterfaceTypeName, ImmutableStackGenericTypeName, ImmutableStackTypeName), - new ImmutableCollectionTypeInfo(ImmutableStackGenericTypeName, ImmutableStackGenericTypeName, ImmutableStackTypeName), - new ImmutableCollectionTypeInfo(ImmutableSetGenericInterfaceTypeName, ImmutableSortedSetGenericTypeName, ImmutableSortedSetTypeName), - new ImmutableCollectionTypeInfo(ImmutableSortedSetGenericTypeName, ImmutableSortedSetGenericTypeName, ImmutableSortedSetTypeName), - new ImmutableCollectionTypeInfo(ImmutableHashSetGenericTypeName, ImmutableHashSetGenericTypeName, ImmutableHashSetTypeName), - new ImmutableCollectionTypeInfo(ImmutableArrayGenericTypeName, ImmutableArrayGenericTypeName, ImmutableArrayTypeName) - }; - - private const string ImmutableDictionaryGenericInterfaceTypeName = "System.Collections.Immutable.IImmutableDictionary`2"; - - private const string ImmutableDictionaryTypeName = "System.Collections.Immutable.ImmutableDictionary"; - private const string ImmutableDictionaryGenericTypeName = "System.Collections.Immutable.ImmutableDictionary`2"; - - private const string ImmutableSortedDictionaryTypeName = "System.Collections.Immutable.ImmutableSortedDictionary"; - private const string ImmutableSortedDictionaryGenericTypeName = "System.Collections.Immutable.ImmutableSortedDictionary`2"; - - private static readonly IList DictionaryContractImmutableCollectionDefinitions = new List - { - new ImmutableCollectionTypeInfo(ImmutableDictionaryGenericInterfaceTypeName, ImmutableSortedDictionaryGenericTypeName, ImmutableSortedDictionaryTypeName), - new ImmutableCollectionTypeInfo(ImmutableSortedDictionaryGenericTypeName, ImmutableSortedDictionaryGenericTypeName, ImmutableSortedDictionaryTypeName), - new ImmutableCollectionTypeInfo(ImmutableDictionaryGenericTypeName, ImmutableDictionaryGenericTypeName, ImmutableDictionaryTypeName) - }; - - internal static bool TryBuildImmutableForArrayContract(Type underlyingType, Type collectionItemType, out Type createdType, out MethodBase parameterizedCreator) - { - if (underlyingType.IsGenericType()) - { - string name = underlyingType.GetGenericTypeDefinition().FullName; - ImmutableCollectionTypeInfo definition = ArrayContractImmutableCollectionDefinitions.FirstOrDefault(d => d.ContractTypeName == name); - if (definition != null) + internal class ImmutableCollectionTypeInfo { - Type createdTypeDefinition = Type.GetType(definition.CreatedTypeName + ", System.Collections.Immutable"); - Type builderTypeDefinition = Type.GetType(definition.BuilderTypeName + ", System.Collections.Immutable"); - if (createdTypeDefinition != null && builderTypeDefinition != null) - { - MethodInfo mb = builderTypeDefinition.GetMethods().FirstOrDefault(m => m.Name == "CreateRange" && m.GetParameters().Length == 1); - if (mb != null) + public ImmutableCollectionTypeInfo(string contractTypeName, string createdTypeName, string builderTypeName) { - createdType = createdTypeDefinition.MakeGenericType(collectionItemType); - parameterizedCreator = mb.MakeGenericMethod(collectionItemType); - return true; + ContractTypeName = contractTypeName; + CreatedTypeName = createdTypeName; + BuilderTypeName = builderTypeName; } - } + + public string ContractTypeName { get; set; } + public string CreatedTypeName { get; set; } + public string BuilderTypeName { get; set; } } - } - createdType = null; - parameterizedCreator = null; - return false; - } + private const string ImmutableListGenericInterfaceTypeName = "System.Collections.Immutable.IImmutableList`1"; + private const string ImmutableQueueGenericInterfaceTypeName = "System.Collections.Immutable.IImmutableQueue`1"; + private const string ImmutableStackGenericInterfaceTypeName = "System.Collections.Immutable.IImmutableStack`1"; + private const string ImmutableSetGenericInterfaceTypeName = "System.Collections.Immutable.IImmutableSet`1"; - internal static bool TryBuildImmutableForDictionaryContract(Type underlyingType, Type keyItemType, Type valueItemType, out Type createdType, out MethodBase parameterizedCreator) - { - if (underlyingType.IsGenericType()) - { - string name = underlyingType.GetGenericTypeDefinition().FullName; - ImmutableCollectionTypeInfo definition = DictionaryContractImmutableCollectionDefinitions.FirstOrDefault(d => d.ContractTypeName == name); - if (definition != null) + private const string ImmutableArrayTypeName = "System.Collections.Immutable.ImmutableArray"; + private const string ImmutableArrayGenericTypeName = "System.Collections.Immutable.ImmutableArray`1"; + + private const string ImmutableListTypeName = "System.Collections.Immutable.ImmutableList"; + private const string ImmutableListGenericTypeName = "System.Collections.Immutable.ImmutableList`1"; + + private const string ImmutableQueueTypeName = "System.Collections.Immutable.ImmutableQueue"; + private const string ImmutableQueueGenericTypeName = "System.Collections.Immutable.ImmutableQueue`1"; + + private const string ImmutableStackTypeName = "System.Collections.Immutable.ImmutableStack"; + private const string ImmutableStackGenericTypeName = "System.Collections.Immutable.ImmutableStack`1"; + + private const string ImmutableSortedSetTypeName = "System.Collections.Immutable.ImmutableSortedSet"; + private const string ImmutableSortedSetGenericTypeName = "System.Collections.Immutable.ImmutableSortedSet`1"; + + private const string ImmutableHashSetTypeName = "System.Collections.Immutable.ImmutableHashSet"; + private const string ImmutableHashSetGenericTypeName = "System.Collections.Immutable.ImmutableHashSet`1"; + + private static readonly IList ArrayContractImmutableCollectionDefinitions = new List { - Type createdTypeDefinition = Type.GetType(definition.CreatedTypeName + ", System.Collections.Immutable"); - Type builderTypeDefinition = Type.GetType(definition.BuilderTypeName + ", System.Collections.Immutable"); - if (createdTypeDefinition != null && builderTypeDefinition != null) - { - MethodInfo mb = builderTypeDefinition.GetMethods().FirstOrDefault(m => - { - ParameterInfo[] parameters = m.GetParameters(); + new ImmutableCollectionTypeInfo(ImmutableListGenericInterfaceTypeName, ImmutableListGenericTypeName, ImmutableListTypeName), + new ImmutableCollectionTypeInfo(ImmutableListGenericTypeName, ImmutableListGenericTypeName, ImmutableListTypeName), + new ImmutableCollectionTypeInfo(ImmutableQueueGenericInterfaceTypeName, ImmutableQueueGenericTypeName, ImmutableQueueTypeName), + new ImmutableCollectionTypeInfo(ImmutableQueueGenericTypeName, ImmutableQueueGenericTypeName, ImmutableQueueTypeName), + new ImmutableCollectionTypeInfo(ImmutableStackGenericInterfaceTypeName, ImmutableStackGenericTypeName, ImmutableStackTypeName), + new ImmutableCollectionTypeInfo(ImmutableStackGenericTypeName, ImmutableStackGenericTypeName, ImmutableStackTypeName), + new ImmutableCollectionTypeInfo(ImmutableSetGenericInterfaceTypeName, ImmutableSortedSetGenericTypeName, ImmutableSortedSetTypeName), + new ImmutableCollectionTypeInfo(ImmutableSortedSetGenericTypeName, ImmutableSortedSetGenericTypeName, ImmutableSortedSetTypeName), + new ImmutableCollectionTypeInfo(ImmutableHashSetGenericTypeName, ImmutableHashSetGenericTypeName, ImmutableHashSetTypeName), + new ImmutableCollectionTypeInfo(ImmutableArrayGenericTypeName, ImmutableArrayGenericTypeName, ImmutableArrayTypeName) + }; - return m.Name == "CreateRange" && parameters.Length == 1 && parameters[0].ParameterType.IsGenericType() && parameters[0].ParameterType.GetGenericTypeDefinition() == typeof(IEnumerable<>); - }); - if (mb != null) + private const string ImmutableDictionaryGenericInterfaceTypeName = "System.Collections.Immutable.IImmutableDictionary`2"; + + private const string ImmutableDictionaryTypeName = "System.Collections.Immutable.ImmutableDictionary"; + private const string ImmutableDictionaryGenericTypeName = "System.Collections.Immutable.ImmutableDictionary`2"; + + private const string ImmutableSortedDictionaryTypeName = "System.Collections.Immutable.ImmutableSortedDictionary"; + private const string ImmutableSortedDictionaryGenericTypeName = "System.Collections.Immutable.ImmutableSortedDictionary`2"; + + private static readonly IList DictionaryContractImmutableCollectionDefinitions = new List + { + new ImmutableCollectionTypeInfo(ImmutableDictionaryGenericInterfaceTypeName, ImmutableSortedDictionaryGenericTypeName, ImmutableSortedDictionaryTypeName), + new ImmutableCollectionTypeInfo(ImmutableSortedDictionaryGenericTypeName, ImmutableSortedDictionaryGenericTypeName, ImmutableSortedDictionaryTypeName), + new ImmutableCollectionTypeInfo(ImmutableDictionaryGenericTypeName, ImmutableDictionaryGenericTypeName, ImmutableDictionaryTypeName) + }; + + internal static bool TryBuildImmutableForArrayContract(Type underlyingType, Type collectionItemType, out Type createdType, out MethodBase parameterizedCreator) + { + if (underlyingType.IsGenericType()) { - createdType = createdTypeDefinition.MakeGenericType(keyItemType, valueItemType); - parameterizedCreator = mb.MakeGenericMethod(keyItemType, valueItemType); - return true; + string name = underlyingType.GetGenericTypeDefinition().FullName; + ImmutableCollectionTypeInfo definition = ArrayContractImmutableCollectionDefinitions.FirstOrDefault(d => d.ContractTypeName == name); + if (definition != null) + { + Type createdTypeDefinition = Type.GetType(definition.CreatedTypeName + ", System.Collections.Immutable"); + Type builderTypeDefinition = Type.GetType(definition.BuilderTypeName + ", System.Collections.Immutable"); + if (createdTypeDefinition != null && builderTypeDefinition != null) + { + MethodInfo mb = builderTypeDefinition.GetMethods().FirstOrDefault(m => m.Name == "CreateRange" && m.GetParameters().Length == 1); + if (mb != null) + { + createdType = createdTypeDefinition.MakeGenericType(collectionItemType); + parameterizedCreator = mb.MakeGenericMethod(collectionItemType); + return true; + } + } + } } - } - } - } - createdType = null; - parameterizedCreator = null; - return false; + createdType = null; + parameterizedCreator = null; + return false; + } + + internal static bool TryBuildImmutableForDictionaryContract(Type underlyingType, Type keyItemType, Type valueItemType, out Type createdType, out MethodBase parameterizedCreator) + { + if (underlyingType.IsGenericType()) + { + string name = underlyingType.GetGenericTypeDefinition().FullName; + ImmutableCollectionTypeInfo definition = DictionaryContractImmutableCollectionDefinitions.FirstOrDefault(d => d.ContractTypeName == name); + if (definition != null) + { + Type createdTypeDefinition = Type.GetType(definition.CreatedTypeName + ", System.Collections.Immutable"); + Type builderTypeDefinition = Type.GetType(definition.BuilderTypeName + ", System.Collections.Immutable"); + if (createdTypeDefinition != null && builderTypeDefinition != null) + { + MethodInfo mb = builderTypeDefinition.GetMethods().FirstOrDefault(m => + { + ParameterInfo[] parameters = m.GetParameters(); + + return m.Name == "CreateRange" && parameters.Length == 1 && parameters[0].ParameterType.IsGenericType() && parameters[0].ParameterType.GetGenericTypeDefinition() == typeof(IEnumerable<>); + }); + if (mb != null) + { + createdType = createdTypeDefinition.MakeGenericType(keyItemType, valueItemType); + parameterizedCreator = mb.MakeGenericMethod(keyItemType, valueItemType); + return true; + } + } + } + } + + createdType = null; + parameterizedCreator = null; + return false; + } } - } } + #endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/JavaScriptUtils.cs b/Src/Newtonsoft.Json/Utilities/JavaScriptUtils.cs index 15f95e1a..0ec0887f 100644 --- a/Src/Newtonsoft.Json/Utilities/JavaScriptUtils.cs +++ b/Src/Newtonsoft.Json/Utilities/JavaScriptUtils.cs @@ -34,188 +34,189 @@ using System.Collections.Generic; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json.Utilities { - internal static class JavaScriptUtils - { - internal static readonly bool[] SingleQuoteCharEscapeFlags = new bool[128]; - internal static readonly bool[] DoubleQuoteCharEscapeFlags = new bool[128]; - internal static readonly bool[] HtmlCharEscapeFlags = new bool[128]; - - static JavaScriptUtils() + internal static class JavaScriptUtils { - IList escapeChars = new List - { - '\n', '\r', '\t', '\\', '\f', '\b', - }; - for (int i = 0; i < ' '; i++) - { - escapeChars.Add((char)i); - } + internal static readonly bool[] SingleQuoteCharEscapeFlags = new bool[128]; + internal static readonly bool[] DoubleQuoteCharEscapeFlags = new bool[128]; + internal static readonly bool[] HtmlCharEscapeFlags = new bool[128]; - foreach (var escapeChar in escapeChars.Union(new[] { '\'' })) - { - SingleQuoteCharEscapeFlags[escapeChar] = true; - } - foreach (var escapeChar in escapeChars.Union(new[] { '"' })) - { - DoubleQuoteCharEscapeFlags[escapeChar] = true; - } - foreach (var escapeChar in escapeChars.Union(new[] { '"', '\'', '<', '>', '&' })) - { - HtmlCharEscapeFlags[escapeChar] = true; - } - } - - private const string EscapedUnicodeText = "!"; - - public static void WriteEscapedJavaScriptString(TextWriter writer, string s, char delimiter, bool appendDelimiters, - bool[] charEscapeFlags, StringEscapeHandling stringEscapeHandling, ref char[] writeBuffer) - { - // leading delimiter - if (appendDelimiters) - writer.Write(delimiter); - - if (s != null) - { - int lastWritePosition = 0; - - for (int i = 0; i < s.Length; i++) + static JavaScriptUtils() { - var c = s[i]; + IList escapeChars = new List + { + '\n', '\r', '\t', '\\', '\f', '\b', + }; + for (int i = 0; i < ' '; i++) + { + escapeChars.Add((char)i); + } - if (c < charEscapeFlags.Length && !charEscapeFlags[c]) - continue; + foreach (var escapeChar in escapeChars.Union(new[] { '\'' })) + { + SingleQuoteCharEscapeFlags[escapeChar] = true; + } + foreach (var escapeChar in escapeChars.Union(new[] { '"' })) + { + DoubleQuoteCharEscapeFlags[escapeChar] = true; + } + foreach (var escapeChar in escapeChars.Union(new[] { '"', '\'', '<', '>', '&' })) + { + HtmlCharEscapeFlags[escapeChar] = true; + } + } - string escapedValue; + private const string EscapedUnicodeText = "!"; - switch (c) - { - case '\t': - escapedValue = @"\t"; - break; - case '\n': - escapedValue = @"\n"; - break; - case '\r': - escapedValue = @"\r"; - break; - case '\f': - escapedValue = @"\f"; - break; - case '\b': - escapedValue = @"\b"; - break; - case '\\': - escapedValue = @"\\"; - break; - case '\u0085': // Next Line - escapedValue = @"\u0085"; - break; - case '\u2028': // Line Separator - escapedValue = @"\u2028"; - break; - case '\u2029': // Paragraph Separator - escapedValue = @"\u2029"; - break; - default: - if (c < charEscapeFlags.Length || stringEscapeHandling == StringEscapeHandling.EscapeNonAscii) - { - if (c == '\'' && stringEscapeHandling != StringEscapeHandling.EscapeHtml) + public static void WriteEscapedJavaScriptString(TextWriter writer, string s, char delimiter, bool appendDelimiters, + bool[] charEscapeFlags, StringEscapeHandling stringEscapeHandling, ref char[] writeBuffer) + { + // leading delimiter + if (appendDelimiters) + writer.Write(delimiter); + + if (s != null) + { + int lastWritePosition = 0; + + for (int i = 0; i < s.Length; i++) { - escapedValue = @"\'"; + var c = s[i]; + + if (c < charEscapeFlags.Length && !charEscapeFlags[c]) + continue; + + string escapedValue; + + switch (c) + { + case '\t': + escapedValue = @"\t"; + break; + case '\n': + escapedValue = @"\n"; + break; + case '\r': + escapedValue = @"\r"; + break; + case '\f': + escapedValue = @"\f"; + break; + case '\b': + escapedValue = @"\b"; + break; + case '\\': + escapedValue = @"\\"; + break; + case '\u0085': // Next Line + escapedValue = @"\u0085"; + break; + case '\u2028': // Line Separator + escapedValue = @"\u2028"; + break; + case '\u2029': // Paragraph Separator + escapedValue = @"\u2029"; + break; + default: + if (c < charEscapeFlags.Length || stringEscapeHandling == StringEscapeHandling.EscapeNonAscii) + { + if (c == '\'' && stringEscapeHandling != StringEscapeHandling.EscapeHtml) + { + escapedValue = @"\'"; + } + else if (c == '"' && stringEscapeHandling != StringEscapeHandling.EscapeHtml) + { + escapedValue = @"\"""; + } + else + { + if (writeBuffer == null) + writeBuffer = new char[6]; + + StringUtils.ToCharAsUnicode(c, writeBuffer); + + // slightly hacky but it saves multiple conditions in if test + escapedValue = EscapedUnicodeText; + } + } + else + { + escapedValue = null; + } + break; + } + + if (escapedValue == null) + continue; + + bool isEscapedUnicodeText = string.Equals(escapedValue, EscapedUnicodeText); + + if (i > lastWritePosition) + { + int length = i - lastWritePosition + ((isEscapedUnicodeText) ? 6 : 0); + int start = (isEscapedUnicodeText) ? 6 : 0; + + if (writeBuffer == null || writeBuffer.Length < length) + { + char[] newBuffer = new char[length]; + + // the unicode text is already in the buffer + // copy it over when creating new buffer + if (isEscapedUnicodeText) + Array.Copy(writeBuffer, newBuffer, 6); + + writeBuffer = newBuffer; + } + + s.CopyTo(lastWritePosition, writeBuffer, start, length - start); + + // write unchanged chars before writing escaped text + writer.Write(writeBuffer, start, length - start); + } + + lastWritePosition = i + 1; + if (!isEscapedUnicodeText) + writer.Write(escapedValue); + else + writer.Write(writeBuffer, 0, 6); } - else if (c == '"' && stringEscapeHandling != StringEscapeHandling.EscapeHtml) + + if (lastWritePosition == 0) { - escapedValue = @"\"""; + // no escaped text, write entire string + writer.Write(s); } else { - if (writeBuffer == null) - writeBuffer = new char[6]; + int length = s.Length - lastWritePosition; - StringUtils.ToCharAsUnicode(c, writeBuffer); + if (writeBuffer == null || writeBuffer.Length < length) + writeBuffer = new char[length]; - // slightly hacky but it saves multiple conditions in if test - escapedValue = EscapedUnicodeText; + s.CopyTo(lastWritePosition, writeBuffer, 0, length); + + // write remaining text + writer.Write(writeBuffer, 0, length); } - } - else - { - escapedValue = null; - } - break; - } - - if (escapedValue == null) - continue; - - bool isEscapedUnicodeText = string.Equals(escapedValue, EscapedUnicodeText); - - if (i > lastWritePosition) - { - int length = i - lastWritePosition + ((isEscapedUnicodeText) ? 6 : 0); - int start = (isEscapedUnicodeText) ? 6 : 0; - - if (writeBuffer == null || writeBuffer.Length < length) - { - char[] newBuffer = new char[length]; - - // the unicode text is already in the buffer - // copy it over when creating new buffer - if (isEscapedUnicodeText) - Array.Copy(writeBuffer, newBuffer, 6); - - writeBuffer = newBuffer; } - s.CopyTo(lastWritePosition, writeBuffer, start, length - start); - - // write unchanged chars before writing escaped text - writer.Write(writeBuffer, start, length - start); - } - - lastWritePosition = i + 1; - if (!isEscapedUnicodeText) - writer.Write(escapedValue); - else - writer.Write(writeBuffer, 0, 6); + // trailing delimiter + if (appendDelimiters) + writer.Write(delimiter); } - if (lastWritePosition == 0) + public static string ToEscapedJavaScriptString(string value, char delimiter, bool appendDelimiters) { - // no escaped text, write entire string - writer.Write(s); + using (StringWriter w = StringUtils.CreateStringWriter(StringUtils.GetLength(value) ?? 16)) + { + char[] buffer = null; + WriteEscapedJavaScriptString(w, value, delimiter, appendDelimiters, (delimiter == '"') ? DoubleQuoteCharEscapeFlags : SingleQuoteCharEscapeFlags, StringEscapeHandling.Default, ref buffer); + return w.ToString(); + } } - else - { - int length = s.Length - lastWritePosition; - - if (writeBuffer == null || writeBuffer.Length < length) - writeBuffer = new char[length]; - - s.CopyTo(lastWritePosition, writeBuffer, 0, length); - - // write remaining text - writer.Write(writeBuffer, 0, length); - } - } - - // trailing delimiter - if (appendDelimiters) - writer.Write(delimiter); } - - public static string ToEscapedJavaScriptString(string value, char delimiter, bool appendDelimiters) - { - using (StringWriter w = StringUtils.CreateStringWriter(StringUtils.GetLength(value) ?? 16)) - { - char[] buffer = null; - WriteEscapedJavaScriptString(w, value, delimiter, appendDelimiters, (delimiter == '"') ? DoubleQuoteCharEscapeFlags : SingleQuoteCharEscapeFlags, StringEscapeHandling.Default, ref buffer); - return w.ToString(); - } - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/LateBoundReflectionDelegateFactory.cs b/Src/Newtonsoft.Json/Utilities/LateBoundReflectionDelegateFactory.cs index c2ba265e..a7e2dc46 100644 --- a/Src/Newtonsoft.Json/Utilities/LateBoundReflectionDelegateFactory.cs +++ b/Src/Newtonsoft.Json/Utilities/LateBoundReflectionDelegateFactory.cs @@ -26,70 +26,71 @@ using System; using Newtonsoft.Json.Serialization; using System.Reflection; + #if NET20 using Newtonsoft.Json.Utilities.LinqBridge; #endif namespace Newtonsoft.Json.Utilities { - internal class LateBoundReflectionDelegateFactory : ReflectionDelegateFactory - { - private static readonly LateBoundReflectionDelegateFactory _instance = new LateBoundReflectionDelegateFactory(); - - internal static ReflectionDelegateFactory Instance + internal class LateBoundReflectionDelegateFactory : ReflectionDelegateFactory { - get { return _instance; } + private static readonly LateBoundReflectionDelegateFactory _instance = new LateBoundReflectionDelegateFactory(); + + internal static ReflectionDelegateFactory Instance + { + get { return _instance; } + } + + public override MethodCall CreateMethodCall(MethodBase method) + { + ValidationUtils.ArgumentNotNull(method, "method"); + + ConstructorInfo c = method as ConstructorInfo; + if (c != null) + return (o, a) => c.Invoke(a); + + return (o, a) => method.Invoke(o, a); + } + + public override Func CreateDefaultConstructor(Type type) + { + ValidationUtils.ArgumentNotNull(type, "type"); + + if (type.IsValueType()) + return () => (T)Activator.CreateInstance(type); + + ConstructorInfo constructorInfo = ReflectionUtils.GetDefaultConstructor(type, true); + + return () => (T)constructorInfo.Invoke(null); + } + + public override Func CreateGet(PropertyInfo propertyInfo) + { + ValidationUtils.ArgumentNotNull(propertyInfo, "propertyInfo"); + + return o => propertyInfo.GetValue(o, null); + } + + public override Func CreateGet(FieldInfo fieldInfo) + { + ValidationUtils.ArgumentNotNull(fieldInfo, "fieldInfo"); + + return o => fieldInfo.GetValue(o); + } + + public override Action CreateSet(FieldInfo fieldInfo) + { + ValidationUtils.ArgumentNotNull(fieldInfo, "fieldInfo"); + + return (o, v) => fieldInfo.SetValue(o, v); + } + + public override Action CreateSet(PropertyInfo propertyInfo) + { + ValidationUtils.ArgumentNotNull(propertyInfo, "propertyInfo"); + + return (o, v) => propertyInfo.SetValue(o, v, null); + } } - - public override MethodCall CreateMethodCall(MethodBase method) - { - ValidationUtils.ArgumentNotNull(method, "method"); - - ConstructorInfo c = method as ConstructorInfo; - if (c != null) - return (o, a) => c.Invoke(a); - - return (o, a) => method.Invoke(o, a); - } - - public override Func CreateDefaultConstructor(Type type) - { - ValidationUtils.ArgumentNotNull(type, "type"); - - if (type.IsValueType()) - return () => (T)Activator.CreateInstance(type); - - ConstructorInfo constructorInfo = ReflectionUtils.GetDefaultConstructor(type, true); - - return () => (T)constructorInfo.Invoke(null); - } - - public override Func CreateGet(PropertyInfo propertyInfo) - { - ValidationUtils.ArgumentNotNull(propertyInfo, "propertyInfo"); - - return o => propertyInfo.GetValue(o, null); - } - - public override Func CreateGet(FieldInfo fieldInfo) - { - ValidationUtils.ArgumentNotNull(fieldInfo, "fieldInfo"); - - return o => fieldInfo.GetValue(o); - } - - public override Action CreateSet(FieldInfo fieldInfo) - { - ValidationUtils.ArgumentNotNull(fieldInfo, "fieldInfo"); - - return (o, v) => fieldInfo.SetValue(o, v); - } - - public override Action CreateSet(PropertyInfo propertyInfo) - { - ValidationUtils.ArgumentNotNull(propertyInfo, "propertyInfo"); - - return (o, v) => propertyInfo.SetValue(o, v, null); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/LinqBridge.cs b/Src/Newtonsoft.Json/Utilities/LinqBridge.cs index f5e2d299..f1a08073 100644 --- a/Src/Newtonsoft.Json/Utilities/LinqBridge.cs +++ b/Src/Newtonsoft.Json/Utilities/LinqBridge.cs @@ -1,4 +1,5 @@ -#if NET20 + +#if NET20 #region License, Terms and Author(s) // diff --git a/Src/Newtonsoft.Json/Utilities/MathUtils.cs b/Src/Newtonsoft.Json/Utilities/MathUtils.cs index 438c5e46..753b4c2c 100644 --- a/Src/Newtonsoft.Json/Utilities/MathUtils.cs +++ b/Src/Newtonsoft.Json/Utilities/MathUtils.cs @@ -29,89 +29,89 @@ using System.Text; namespace Newtonsoft.Json.Utilities { - internal static class MathUtils - { - public static int IntLength(ulong i) + internal static class MathUtils { - if (i < 10000000000) - { - if (i < 10) return 1; - if (i < 100) return 2; - if (i < 1000) return 3; - if (i < 10000) return 4; - if (i < 100000) return 5; - if (i < 1000000) return 6; - if (i < 10000000) return 7; - if (i < 100000000) return 8; - if (i < 1000000000) return 9; + public static int IntLength(ulong i) + { + if (i < 10000000000) + { + if (i < 10) return 1; + if (i < 100) return 2; + if (i < 1000) return 3; + if (i < 10000) return 4; + if (i < 100000) return 5; + if (i < 1000000) return 6; + if (i < 10000000) return 7; + if (i < 100000000) return 8; + if (i < 1000000000) return 9; - return 10; - } - else - { - if (i < 100000000000) return 11; - if (i < 1000000000000) return 12; - if (i < 10000000000000) return 13; - if (i < 100000000000000) return 14; - if (i < 1000000000000000) return 15; - if (i < 10000000000000000) return 16; - if (i < 100000000000000000) return 17; - if (i < 1000000000000000000) return 18; - if (i < 10000000000000000000) return 19; + return 10; + } + else + { + if (i < 100000000000) return 11; + if (i < 1000000000000) return 12; + if (i < 10000000000000) return 13; + if (i < 100000000000000) return 14; + if (i < 1000000000000000) return 15; + if (i < 10000000000000000) return 16; + if (i < 100000000000000000) return 17; + if (i < 1000000000000000000) return 18; + if (i < 10000000000000000000) return 19; - return 20; - } + return 20; + } + } + + public static char IntToHex(int n) + { + if (n <= 9) + return (char)(n + 48); + + return (char)((n - 10) + 97); + } + + public static int? Min(int? val1, int? val2) + { + if (val1 == null) + return val2; + if (val2 == null) + return val1; + + return Math.Min(val1.Value, val2.Value); + } + + public static int? Max(int? val1, int? val2) + { + if (val1 == null) + return val2; + if (val2 == null) + return val1; + + return Math.Max(val1.Value, val2.Value); + } + + public static double? Max(double? val1, double? val2) + { + if (val1 == null) + return val2; + if (val2 == null) + return val1; + + return Math.Max(val1.Value, val2.Value); + } + + public static bool ApproxEquals(double d1, double d2) + { + const double epsilon = 2.2204460492503131E-16; + + if (d1 == d2) + return true; + + double tolerance = ((Math.Abs(d1) + Math.Abs(d2)) + 10.0) * epsilon; + double difference = d1 - d2; + + return (-tolerance < difference && tolerance > difference); + } } - - public static char IntToHex(int n) - { - if (n <= 9) - return (char)(n + 48); - - return (char)((n - 10) + 97); - } - - public static int? Min(int? val1, int? val2) - { - if (val1 == null) - return val2; - if (val2 == null) - return val1; - - return Math.Min(val1.Value, val2.Value); - } - - public static int? Max(int? val1, int? val2) - { - if (val1 == null) - return val2; - if (val2 == null) - return val1; - - return Math.Max(val1.Value, val2.Value); - } - - public static double? Max(double? val1, double? val2) - { - if (val1 == null) - return val2; - if (val2 == null) - return val1; - - return Math.Max(val1.Value, val2.Value); - } - - public static bool ApproxEquals(double d1, double d2) - { - const double epsilon = 2.2204460492503131E-16; - - if (d1 == d2) - return true; - - double tolerance = ((Math.Abs(d1) + Math.Abs(d2)) + 10.0) * epsilon; - double difference = d1 - d2; - - return (-tolerance < difference && tolerance > difference); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/MethodCall.cs b/Src/Newtonsoft.Json/Utilities/MethodCall.cs index 6305dca2..8b16e28f 100644 --- a/Src/Newtonsoft.Json/Utilities/MethodCall.cs +++ b/Src/Newtonsoft.Json/Utilities/MethodCall.cs @@ -25,5 +25,5 @@ namespace Newtonsoft.Json.Utilities { - internal delegate TResult MethodCall(T target, params object[] args); + internal delegate TResult MethodCall(T target, params object[] args); } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/MiscellaneousUtils.cs b/Src/Newtonsoft.Json/Utilities/MiscellaneousUtils.cs index a6fd8fc8..76f000b6 100644 --- a/Src/Newtonsoft.Json/Utilities/MiscellaneousUtils.cs +++ b/Src/Newtonsoft.Json/Utilities/MiscellaneousUtils.cs @@ -33,108 +33,108 @@ using System.Globalization; namespace Newtonsoft.Json.Utilities { - internal delegate T Creator(); + internal delegate T Creator(); - internal static class MiscellaneousUtils - { - public static bool ValueEquals(object objA, object objB) + internal static class MiscellaneousUtils { - if (objA == null && objB == null) - return true; - if (objA != null && objB == null) - return false; - if (objA == null && objB != null) - return false; + public static bool ValueEquals(object objA, object objB) + { + if (objA == null && objB == null) + return true; + if (objA != null && objB == null) + return false; + if (objA == null && objB != null) + return false; - // comparing an Int32 and Int64 both of the same value returns false - // make types the same then compare - if (objA.GetType() != objB.GetType()) - { - if (ConvertUtils.IsInteger(objA) && ConvertUtils.IsInteger(objB)) - return Convert.ToDecimal(objA, CultureInfo.CurrentCulture).Equals(Convert.ToDecimal(objB, CultureInfo.CurrentCulture)); - else if ((objA is double || objA is float || objA is decimal) && (objB is double || objB is float || objB is decimal)) - return MathUtils.ApproxEquals(Convert.ToDouble(objA, CultureInfo.CurrentCulture), Convert.ToDouble(objB, CultureInfo.CurrentCulture)); - else - return false; - } + // comparing an Int32 and Int64 both of the same value returns false + // make types the same then compare + if (objA.GetType() != objB.GetType()) + { + if (ConvertUtils.IsInteger(objA) && ConvertUtils.IsInteger(objB)) + return Convert.ToDecimal(objA, CultureInfo.CurrentCulture).Equals(Convert.ToDecimal(objB, CultureInfo.CurrentCulture)); + else if ((objA is double || objA is float || objA is decimal) && (objB is double || objB is float || objB is decimal)) + return MathUtils.ApproxEquals(Convert.ToDouble(objA, CultureInfo.CurrentCulture), Convert.ToDouble(objB, CultureInfo.CurrentCulture)); + else + return false; + } - return objA.Equals(objB); + return objA.Equals(objB); + } + + public static ArgumentOutOfRangeException CreateArgumentOutOfRangeException(string paramName, object actualValue, string message) + { + string newMessage = message + Environment.NewLine + @"Actual value was {0}.".FormatWith(CultureInfo.InvariantCulture, actualValue); + + return new ArgumentOutOfRangeException(paramName, newMessage); + } + + public static string ToString(object value) + { + if (value == null) + return "{null}"; + + return (value is string) ? @"""" + value.ToString() + @"""" : value.ToString(); + } + + public static int ByteArrayCompare(byte[] a1, byte[] a2) + { + int lengthCompare = a1.Length.CompareTo(a2.Length); + if (lengthCompare != 0) + return lengthCompare; + + for (int i = 0; i < a1.Length; i++) + { + int valueCompare = a1[i].CompareTo(a2[i]); + if (valueCompare != 0) + return valueCompare; + } + + return 0; + } + + public static string GetPrefix(string qualifiedName) + { + string prefix; + string localName; + GetQualifiedNameParts(qualifiedName, out prefix, out localName); + + return prefix; + } + + public static string GetLocalName(string qualifiedName) + { + string prefix; + string localName; + GetQualifiedNameParts(qualifiedName, out prefix, out localName); + + return localName; + } + + public static void GetQualifiedNameParts(string qualifiedName, out string prefix, out string localName) + { + int colonPosition = qualifiedName.IndexOf(':'); + + if ((colonPosition == -1 || colonPosition == 0) || (qualifiedName.Length - 1) == colonPosition) + { + prefix = null; + localName = qualifiedName; + } + else + { + prefix = qualifiedName.Substring(0, colonPosition); + localName = qualifiedName.Substring(colonPosition + 1); + } + } + + internal static string FormatValueForPrint(object value) + { + if (value == null) + return "{null}"; + + if (value is string) + return @"""" + value + @""""; + + return value.ToString(); + } } - - public static ArgumentOutOfRangeException CreateArgumentOutOfRangeException(string paramName, object actualValue, string message) - { - string newMessage = message + Environment.NewLine + @"Actual value was {0}.".FormatWith(CultureInfo.InvariantCulture, actualValue); - - return new ArgumentOutOfRangeException(paramName, newMessage); - } - - public static string ToString(object value) - { - if (value == null) - return "{null}"; - - return (value is string) ? @"""" + value.ToString() + @"""" : value.ToString(); - } - - public static int ByteArrayCompare(byte[] a1, byte[] a2) - { - int lengthCompare = a1.Length.CompareTo(a2.Length); - if (lengthCompare != 0) - return lengthCompare; - - for (int i = 0; i < a1.Length; i++) - { - int valueCompare = a1[i].CompareTo(a2[i]); - if (valueCompare != 0) - return valueCompare; - } - - return 0; - } - - public static string GetPrefix(string qualifiedName) - { - string prefix; - string localName; - GetQualifiedNameParts(qualifiedName, out prefix, out localName); - - return prefix; - } - - public static string GetLocalName(string qualifiedName) - { - string prefix; - string localName; - GetQualifiedNameParts(qualifiedName, out prefix, out localName); - - return localName; - } - - public static void GetQualifiedNameParts(string qualifiedName, out string prefix, out string localName) - { - int colonPosition = qualifiedName.IndexOf(':'); - - if ((colonPosition == -1 || colonPosition == 0) || (qualifiedName.Length - 1) == colonPosition) - { - prefix = null; - localName = qualifiedName; - } - else - { - prefix = qualifiedName.Substring(0, colonPosition); - localName = qualifiedName.Substring(colonPosition + 1); - } - } - - internal static string FormatValueForPrint(object value) - { - if (value == null) - return "{null}"; - - if (value is string) - return @"""" + value + @""""; - - return value.ToString(); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/ReflectionDelegateFactory.cs b/Src/Newtonsoft.Json/Utilities/ReflectionDelegateFactory.cs index 47f1cf3f..cef1f29a 100644 --- a/Src/Newtonsoft.Json/Utilities/ReflectionDelegateFactory.cs +++ b/Src/Newtonsoft.Json/Utilities/ReflectionDelegateFactory.cs @@ -27,45 +27,46 @@ using System; using System.Globalization; using System.Reflection; using Newtonsoft.Json.Serialization; + #if NET20 using Newtonsoft.Json.Utilities.LinqBridge; #endif namespace Newtonsoft.Json.Utilities { - internal abstract class ReflectionDelegateFactory - { - public Func CreateGet(MemberInfo memberInfo) + internal abstract class ReflectionDelegateFactory { - PropertyInfo propertyInfo = memberInfo as PropertyInfo; - if (propertyInfo != null) - return CreateGet(propertyInfo); + public Func CreateGet(MemberInfo memberInfo) + { + PropertyInfo propertyInfo = memberInfo as PropertyInfo; + if (propertyInfo != null) + return CreateGet(propertyInfo); - FieldInfo fieldInfo = memberInfo as FieldInfo; - if (fieldInfo != null) - return CreateGet(fieldInfo); + FieldInfo fieldInfo = memberInfo as FieldInfo; + if (fieldInfo != null) + return CreateGet(fieldInfo); - throw new Exception("Could not create getter for {0}.".FormatWith(CultureInfo.InvariantCulture, memberInfo)); + throw new Exception("Could not create getter for {0}.".FormatWith(CultureInfo.InvariantCulture, memberInfo)); + } + + public Action CreateSet(MemberInfo memberInfo) + { + PropertyInfo propertyInfo = memberInfo as PropertyInfo; + if (propertyInfo != null) + return CreateSet(propertyInfo); + + FieldInfo fieldInfo = memberInfo as FieldInfo; + if (fieldInfo != null) + return CreateSet(fieldInfo); + + throw new Exception("Could not create setter for {0}.".FormatWith(CultureInfo.InvariantCulture, memberInfo)); + } + + public abstract MethodCall CreateMethodCall(MethodBase method); + public abstract Func CreateDefaultConstructor(Type type); + public abstract Func CreateGet(PropertyInfo propertyInfo); + public abstract Func CreateGet(FieldInfo fieldInfo); + public abstract Action CreateSet(FieldInfo fieldInfo); + public abstract Action CreateSet(PropertyInfo propertyInfo); } - - public Action CreateSet(MemberInfo memberInfo) - { - PropertyInfo propertyInfo = memberInfo as PropertyInfo; - if (propertyInfo != null) - return CreateSet(propertyInfo); - - FieldInfo fieldInfo = memberInfo as FieldInfo; - if (fieldInfo != null) - return CreateSet(fieldInfo); - - throw new Exception("Could not create setter for {0}.".FormatWith(CultureInfo.InvariantCulture, memberInfo)); - } - - public abstract MethodCall CreateMethodCall(MethodBase method); - public abstract Func CreateDefaultConstructor(Type type); - public abstract Func CreateGet(PropertyInfo propertyInfo); - public abstract Func CreateGet(FieldInfo fieldInfo); - public abstract Action CreateSet(FieldInfo fieldInfo); - public abstract Action CreateSet(PropertyInfo propertyInfo); - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs b/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs index 47823fb1..9eb8a6d5 100644 --- a/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs +++ b/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs @@ -44,14 +44,14 @@ using Newtonsoft.Json.Serialization; namespace Newtonsoft.Json.Utilities { #if (NETFX_CORE || PORTABLE || PORTABLE40) - internal enum MemberTypes - { - Property, - Field, - Event, - Method, - Other - } + internal enum MemberTypes + { + Property, + Field, + Event, + Method, + Other + } #endif #if NETFX_CORE || PORTABLE @@ -81,614 +81,614 @@ namespace Newtonsoft.Json.Utilities } #endif - internal static class ReflectionUtils - { - public static readonly Type[] EmptyTypes; - - static ReflectionUtils() + internal static class ReflectionUtils { + public static readonly Type[] EmptyTypes; + + static ReflectionUtils() + { #if !(NETFX_CORE || PORTABLE40 || PORTABLE) - EmptyTypes = Type.EmptyTypes; + EmptyTypes = Type.EmptyTypes; #else - EmptyTypes = new Type[0]; + EmptyTypes = new Type[0]; #endif - } + } - public static bool IsVirtual(this PropertyInfo propertyInfo) - { - ValidationUtils.ArgumentNotNull(propertyInfo, "propertyInfo"); + public static bool IsVirtual(this PropertyInfo propertyInfo) + { + ValidationUtils.ArgumentNotNull(propertyInfo, "propertyInfo"); - MethodInfo m = propertyInfo.GetGetMethod(); - if (m != null && m.IsVirtual) - return true; + MethodInfo m = propertyInfo.GetGetMethod(); + if (m != null && m.IsVirtual) + return true; - m = propertyInfo.GetSetMethod(); - if (m != null && m.IsVirtual) - return true; + m = propertyInfo.GetSetMethod(); + if (m != null && m.IsVirtual) + return true; - return false; - } + return false; + } - public static MethodInfo GetBaseDefinition(this PropertyInfo propertyInfo) - { - ValidationUtils.ArgumentNotNull(propertyInfo, "propertyInfo"); + public static MethodInfo GetBaseDefinition(this PropertyInfo propertyInfo) + { + ValidationUtils.ArgumentNotNull(propertyInfo, "propertyInfo"); - MethodInfo m = propertyInfo.GetGetMethod(); - if (m != null) - return m.GetBaseDefinition(); + MethodInfo m = propertyInfo.GetGetMethod(); + if (m != null) + return m.GetBaseDefinition(); - m = propertyInfo.GetSetMethod(); - if (m != null) - return m.GetBaseDefinition(); + m = propertyInfo.GetSetMethod(); + if (m != null) + return m.GetBaseDefinition(); - return null; - } + return null; + } - public static bool IsPublic(PropertyInfo property) - { - if (property.GetGetMethod() != null && property.GetGetMethod().IsPublic) - return true; - if (property.GetSetMethod() != null && property.GetSetMethod().IsPublic) - return true; + public static bool IsPublic(PropertyInfo property) + { + if (property.GetGetMethod() != null && property.GetGetMethod().IsPublic) + return true; + if (property.GetSetMethod() != null && property.GetSetMethod().IsPublic) + return true; - return false; - } + return false; + } - public static Type GetObjectType(object v) - { - return (v != null) ? v.GetType() : null; - } + public static Type GetObjectType(object v) + { + return (v != null) ? v.GetType() : null; + } - public static string GetTypeName(Type t, FormatterAssemblyStyle assemblyFormat, SerializationBinder binder) - { - string fullyQualifiedTypeName; + public static string GetTypeName(Type t, FormatterAssemblyStyle assemblyFormat, SerializationBinder binder) + { + string fullyQualifiedTypeName; #if !(NET20 || NET35) - if (binder != null) - { - string assemblyName, typeName; - binder.BindToName(t, out assemblyName, out typeName); - fullyQualifiedTypeName = typeName + (assemblyName == null ? "" : ", " + assemblyName); - } - else - { - fullyQualifiedTypeName = t.AssemblyQualifiedName; - } + if (binder != null) + { + string assemblyName, typeName; + binder.BindToName(t, out assemblyName, out typeName); + fullyQualifiedTypeName = typeName + (assemblyName == null ? "" : ", " + assemblyName); + } + else + { + fullyQualifiedTypeName = t.AssemblyQualifiedName; + } #else fullyQualifiedTypeName = t.AssemblyQualifiedName; #endif - switch (assemblyFormat) - { - case FormatterAssemblyStyle.Simple: - return RemoveAssemblyDetails(fullyQualifiedTypeName); - case FormatterAssemblyStyle.Full: - return fullyQualifiedTypeName; - default: - throw new ArgumentOutOfRangeException(); - } - } - - private static string RemoveAssemblyDetails(string fullyQualifiedTypeName) - { - StringBuilder builder = new StringBuilder(); - - // loop through the type name and filter out qualified assembly details from nested type names - bool writingAssemblyName = false; - bool skippingAssemblyDetails = false; - for (int i = 0; i < fullyQualifiedTypeName.Length; i++) - { - char current = fullyQualifiedTypeName[i]; - switch (current) - { - case '[': - writingAssemblyName = false; - skippingAssemblyDetails = false; - builder.Append(current); - break; - case ']': - writingAssemblyName = false; - skippingAssemblyDetails = false; - builder.Append(current); - break; - case ',': - if (!writingAssemblyName) + switch (assemblyFormat) { - writingAssemblyName = true; - builder.Append(current); + case FormatterAssemblyStyle.Simple: + return RemoveAssemblyDetails(fullyQualifiedTypeName); + case FormatterAssemblyStyle.Full: + return fullyQualifiedTypeName; + default: + throw new ArgumentOutOfRangeException(); + } + } + + private static string RemoveAssemblyDetails(string fullyQualifiedTypeName) + { + StringBuilder builder = new StringBuilder(); + + // loop through the type name and filter out qualified assembly details from nested type names + bool writingAssemblyName = false; + bool skippingAssemblyDetails = false; + for (int i = 0; i < fullyQualifiedTypeName.Length; i++) + { + char current = fullyQualifiedTypeName[i]; + switch (current) + { + case '[': + writingAssemblyName = false; + skippingAssemblyDetails = false; + builder.Append(current); + break; + case ']': + writingAssemblyName = false; + skippingAssemblyDetails = false; + builder.Append(current); + break; + case ',': + if (!writingAssemblyName) + { + writingAssemblyName = true; + builder.Append(current); + } + else + { + skippingAssemblyDetails = true; + } + break; + default: + if (!skippingAssemblyDetails) + builder.Append(current); + break; + } + } + + return builder.ToString(); + } + + public static bool HasDefaultConstructor(Type t, bool nonPublic) + { + ValidationUtils.ArgumentNotNull(t, "t"); + + if (t.IsValueType()) + return true; + + return (GetDefaultConstructor(t, nonPublic) != null); + } + + public static ConstructorInfo GetDefaultConstructor(Type t) + { + return GetDefaultConstructor(t, false); + } + + public static ConstructorInfo GetDefaultConstructor(Type t, bool nonPublic) + { + BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public; + if (nonPublic) + bindingFlags = bindingFlags | BindingFlags.NonPublic; + + return t.GetConstructors(bindingFlags).SingleOrDefault(c => !c.GetParameters().Any()); + } + + public static bool IsNullable(Type t) + { + ValidationUtils.ArgumentNotNull(t, "t"); + + if (t.IsValueType()) + return IsNullableType(t); + + return true; + } + + public static bool IsNullableType(Type t) + { + ValidationUtils.ArgumentNotNull(t, "t"); + + return (t.IsGenericType() && t.GetGenericTypeDefinition() == typeof(Nullable<>)); + } + + public static Type EnsureNotNullableType(Type t) + { + return (IsNullableType(t)) + ? Nullable.GetUnderlyingType(t) + : t; + } + + public static bool IsGenericDefinition(Type type, Type genericInterfaceDefinition) + { + if (!type.IsGenericType()) + return false; + + Type t = type.GetGenericTypeDefinition(); + return (t == genericInterfaceDefinition); + } + + public static bool ImplementsGenericDefinition(Type type, Type genericInterfaceDefinition) + { + Type implementingType; + return ImplementsGenericDefinition(type, genericInterfaceDefinition, out implementingType); + } + + public static bool ImplementsGenericDefinition(Type type, Type genericInterfaceDefinition, out Type implementingType) + { + ValidationUtils.ArgumentNotNull(type, "type"); + ValidationUtils.ArgumentNotNull(genericInterfaceDefinition, "genericInterfaceDefinition"); + + if (!genericInterfaceDefinition.IsInterface() || !genericInterfaceDefinition.IsGenericTypeDefinition()) + throw new ArgumentNullException("'{0}' is not a generic interface definition.".FormatWith(CultureInfo.InvariantCulture, genericInterfaceDefinition)); + + if (type.IsInterface()) + { + if (type.IsGenericType()) + { + Type interfaceDefinition = type.GetGenericTypeDefinition(); + + if (genericInterfaceDefinition == interfaceDefinition) + { + implementingType = type; + return true; + } + } + } + + foreach (Type i in type.GetInterfaces()) + { + if (i.IsGenericType()) + { + Type interfaceDefinition = i.GetGenericTypeDefinition(); + + if (genericInterfaceDefinition == interfaceDefinition) + { + implementingType = i; + return true; + } + } + } + + implementingType = null; + return false; + } + + public static bool InheritsGenericDefinition(Type type, Type genericClassDefinition) + { + Type implementingType; + return InheritsGenericDefinition(type, genericClassDefinition, out implementingType); + } + + public static bool InheritsGenericDefinition(Type type, Type genericClassDefinition, out Type implementingType) + { + ValidationUtils.ArgumentNotNull(type, "type"); + ValidationUtils.ArgumentNotNull(genericClassDefinition, "genericClassDefinition"); + + if (!genericClassDefinition.IsClass() || !genericClassDefinition.IsGenericTypeDefinition()) + throw new ArgumentNullException("'{0}' is not a generic class definition.".FormatWith(CultureInfo.InvariantCulture, genericClassDefinition)); + + return InheritsGenericDefinitionInternal(type, genericClassDefinition, out implementingType); + } + + private static bool InheritsGenericDefinitionInternal(Type currentType, Type genericClassDefinition, out Type implementingType) + { + if (currentType.IsGenericType()) + { + Type currentGenericClassDefinition = currentType.GetGenericTypeDefinition(); + + if (genericClassDefinition == currentGenericClassDefinition) + { + implementingType = currentType; + return true; + } + } + + if (currentType.BaseType() == null) + { + implementingType = null; + return false; + } + + return InheritsGenericDefinitionInternal(currentType.BaseType(), genericClassDefinition, out implementingType); + } + + /// + /// Gets the type of the typed collection's items. + /// + /// The type. + /// The type of the typed collection's items. + public static Type GetCollectionItemType(Type type) + { + ValidationUtils.ArgumentNotNull(type, "type"); + Type genericListType; + + if (type.IsArray) + { + return type.GetElementType(); + } + else if (ImplementsGenericDefinition(type, typeof(IEnumerable<>), out genericListType)) + { + if (genericListType.IsGenericTypeDefinition()) + throw new Exception("Type {0} is not a collection.".FormatWith(CultureInfo.InvariantCulture, type)); + + return genericListType.GetGenericArguments()[0]; + } + else if (typeof(IEnumerable).IsAssignableFrom(type)) + { + return null; } else { - skippingAssemblyDetails = true; + throw new Exception("Type {0} is not a collection.".FormatWith(CultureInfo.InvariantCulture, type)); } - break; - default: - if (!skippingAssemblyDetails) - builder.Append(current); - break; } - } - return builder.ToString(); - } - - public static bool HasDefaultConstructor(Type t, bool nonPublic) - { - ValidationUtils.ArgumentNotNull(t, "t"); - - if (t.IsValueType()) - return true; - - return (GetDefaultConstructor(t, nonPublic) != null); - } - - public static ConstructorInfo GetDefaultConstructor(Type t) - { - return GetDefaultConstructor(t, false); - } - - public static ConstructorInfo GetDefaultConstructor(Type t, bool nonPublic) - { - BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public; - if (nonPublic) - bindingFlags = bindingFlags | BindingFlags.NonPublic; - - return t.GetConstructors(bindingFlags).SingleOrDefault(c => !c.GetParameters().Any()); - } - - public static bool IsNullable(Type t) - { - ValidationUtils.ArgumentNotNull(t, "t"); - - if (t.IsValueType()) - return IsNullableType(t); - - return true; - } - - public static bool IsNullableType(Type t) - { - ValidationUtils.ArgumentNotNull(t, "t"); - - return (t.IsGenericType() && t.GetGenericTypeDefinition() == typeof(Nullable<>)); - } - - public static Type EnsureNotNullableType(Type t) - { - return (IsNullableType(t)) - ? Nullable.GetUnderlyingType(t) - : t; - } - - public static bool IsGenericDefinition(Type type, Type genericInterfaceDefinition) - { - if (!type.IsGenericType()) - return false; - - Type t = type.GetGenericTypeDefinition(); - return (t == genericInterfaceDefinition); - } - - public static bool ImplementsGenericDefinition(Type type, Type genericInterfaceDefinition) - { - Type implementingType; - return ImplementsGenericDefinition(type, genericInterfaceDefinition, out implementingType); - } - - public static bool ImplementsGenericDefinition(Type type, Type genericInterfaceDefinition, out Type implementingType) - { - ValidationUtils.ArgumentNotNull(type, "type"); - ValidationUtils.ArgumentNotNull(genericInterfaceDefinition, "genericInterfaceDefinition"); - - if (!genericInterfaceDefinition.IsInterface() || !genericInterfaceDefinition.IsGenericTypeDefinition()) - throw new ArgumentNullException("'{0}' is not a generic interface definition.".FormatWith(CultureInfo.InvariantCulture, genericInterfaceDefinition)); - - if (type.IsInterface()) - { - if (type.IsGenericType()) + public static void GetDictionaryKeyValueTypes(Type dictionaryType, out Type keyType, out Type valueType) { - Type interfaceDefinition = type.GetGenericTypeDefinition(); + ValidationUtils.ArgumentNotNull(dictionaryType, "type"); - if (genericInterfaceDefinition == interfaceDefinition) - { - implementingType = type; - return true; - } + Type genericDictionaryType; + if (ImplementsGenericDefinition(dictionaryType, typeof(IDictionary<,>), out genericDictionaryType)) + { + if (genericDictionaryType.IsGenericTypeDefinition()) + throw new Exception("Type {0} is not a dictionary.".FormatWith(CultureInfo.InvariantCulture, dictionaryType)); + + Type[] dictionaryGenericArguments = genericDictionaryType.GetGenericArguments(); + + keyType = dictionaryGenericArguments[0]; + valueType = dictionaryGenericArguments[1]; + return; + } + else if (typeof(IDictionary).IsAssignableFrom(dictionaryType)) + { + keyType = null; + valueType = null; + return; + } + else + { + throw new Exception("Type {0} is not a dictionary.".FormatWith(CultureInfo.InvariantCulture, dictionaryType)); + } } - } - foreach (Type i in type.GetInterfaces()) - { - if (i.IsGenericType()) + /// + /// Gets the member's underlying type. + /// + /// The member. + /// The underlying type of the member. + public static Type GetMemberUnderlyingType(MemberInfo member) { - Type interfaceDefinition = i.GetGenericTypeDefinition(); + ValidationUtils.ArgumentNotNull(member, "member"); - if (genericInterfaceDefinition == interfaceDefinition) - { - implementingType = i; - return true; - } + switch (member.MemberType()) + { + case MemberTypes.Field: + return ((FieldInfo)member).FieldType; + case MemberTypes.Property: + return ((PropertyInfo)member).PropertyType; + case MemberTypes.Event: + return ((EventInfo)member).EventHandlerType; + default: + throw new ArgumentException("MemberInfo must be of type FieldInfo, PropertyInfo or EventInfo", "member"); + } } - } - implementingType = null; - return false; - } - - public static bool InheritsGenericDefinition(Type type, Type genericClassDefinition) - { - Type implementingType; - return InheritsGenericDefinition(type, genericClassDefinition, out implementingType); - } - - public static bool InheritsGenericDefinition(Type type, Type genericClassDefinition, out Type implementingType) - { - ValidationUtils.ArgumentNotNull(type, "type"); - ValidationUtils.ArgumentNotNull(genericClassDefinition, "genericClassDefinition"); - - if (!genericClassDefinition.IsClass() || !genericClassDefinition.IsGenericTypeDefinition()) - throw new ArgumentNullException("'{0}' is not a generic class definition.".FormatWith(CultureInfo.InvariantCulture, genericClassDefinition)); - - return InheritsGenericDefinitionInternal(type, genericClassDefinition, out implementingType); - } - - private static bool InheritsGenericDefinitionInternal(Type currentType, Type genericClassDefinition, out Type implementingType) - { - if (currentType.IsGenericType()) - { - Type currentGenericClassDefinition = currentType.GetGenericTypeDefinition(); - - if (genericClassDefinition == currentGenericClassDefinition) + /// + /// Determines whether the member is an indexed property. + /// + /// The member. + /// + /// true if the member is an indexed property; otherwise, false. + /// + public static bool IsIndexedProperty(MemberInfo member) { - implementingType = currentType; - return true; + ValidationUtils.ArgumentNotNull(member, "member"); + + PropertyInfo propertyInfo = member as PropertyInfo; + + if (propertyInfo != null) + return IsIndexedProperty(propertyInfo); + else + return false; } - } - if (currentType.BaseType() == null) - { - implementingType = null; - return false; - } - - return InheritsGenericDefinitionInternal(currentType.BaseType(), genericClassDefinition, out implementingType); - } - - /// - /// Gets the type of the typed collection's items. - /// - /// The type. - /// The type of the typed collection's items. - public static Type GetCollectionItemType(Type type) - { - ValidationUtils.ArgumentNotNull(type, "type"); - Type genericListType; - - if (type.IsArray) - { - return type.GetElementType(); - } - else if (ImplementsGenericDefinition(type, typeof(IEnumerable<>), out genericListType)) - { - if (genericListType.IsGenericTypeDefinition()) - throw new Exception("Type {0} is not a collection.".FormatWith(CultureInfo.InvariantCulture, type)); - - return genericListType.GetGenericArguments()[0]; - } - else if (typeof(IEnumerable).IsAssignableFrom(type)) - { - return null; - } - else - { - throw new Exception("Type {0} is not a collection.".FormatWith(CultureInfo.InvariantCulture, type)); - } - } - - public static void GetDictionaryKeyValueTypes(Type dictionaryType, out Type keyType, out Type valueType) - { - ValidationUtils.ArgumentNotNull(dictionaryType, "type"); - - Type genericDictionaryType; - if (ImplementsGenericDefinition(dictionaryType, typeof(IDictionary<,>), out genericDictionaryType)) - { - if (genericDictionaryType.IsGenericTypeDefinition()) - throw new Exception("Type {0} is not a dictionary.".FormatWith(CultureInfo.InvariantCulture, dictionaryType)); - - Type[] dictionaryGenericArguments = genericDictionaryType.GetGenericArguments(); - - keyType = dictionaryGenericArguments[0]; - valueType = dictionaryGenericArguments[1]; - return; - } - else if (typeof(IDictionary).IsAssignableFrom(dictionaryType)) - { - keyType = null; - valueType = null; - return; - } - else - { - throw new Exception("Type {0} is not a dictionary.".FormatWith(CultureInfo.InvariantCulture, dictionaryType)); - } - } - - /// - /// Gets the member's underlying type. - /// - /// The member. - /// The underlying type of the member. - public static Type GetMemberUnderlyingType(MemberInfo member) - { - ValidationUtils.ArgumentNotNull(member, "member"); - - switch (member.MemberType()) - { - case MemberTypes.Field: - return ((FieldInfo)member).FieldType; - case MemberTypes.Property: - return ((PropertyInfo)member).PropertyType; - case MemberTypes.Event: - return ((EventInfo)member).EventHandlerType; - default: - throw new ArgumentException("MemberInfo must be of type FieldInfo, PropertyInfo or EventInfo", "member"); - } - } - - /// - /// Determines whether the member is an indexed property. - /// - /// The member. - /// - /// true if the member is an indexed property; otherwise, false. - /// - public static bool IsIndexedProperty(MemberInfo member) - { - ValidationUtils.ArgumentNotNull(member, "member"); - - PropertyInfo propertyInfo = member as PropertyInfo; - - if (propertyInfo != null) - return IsIndexedProperty(propertyInfo); - else - return false; - } - - /// - /// Determines whether the property is an indexed property. - /// - /// The property. - /// - /// true if the property is an indexed property; otherwise, false. - /// - public static bool IsIndexedProperty(PropertyInfo property) - { - ValidationUtils.ArgumentNotNull(property, "property"); - - return (property.GetIndexParameters().Length > 0); - } - - /// - /// Gets the member's value on the object. - /// - /// The member. - /// The target object. - /// The member's value on the object. - public static object GetMemberValue(MemberInfo member, object target) - { - ValidationUtils.ArgumentNotNull(member, "member"); - ValidationUtils.ArgumentNotNull(target, "target"); - - switch (member.MemberType()) - { - case MemberTypes.Field: - return ((FieldInfo)member).GetValue(target); - case MemberTypes.Property: - try - { - return ((PropertyInfo)member).GetValue(target, null); - } - catch (TargetParameterCountException e) - { - throw new ArgumentException("MemberInfo '{0}' has index parameters".FormatWith(CultureInfo.InvariantCulture, member.Name), e); - } - default: - throw new ArgumentException("MemberInfo '{0}' is not of type FieldInfo or PropertyInfo".FormatWith(CultureInfo.InvariantCulture, CultureInfo.InvariantCulture, member.Name), "member"); - } - } - - /// - /// Sets the member's value on the target object. - /// - /// The member. - /// The target. - /// The value. - public static void SetMemberValue(MemberInfo member, object target, object value) - { - ValidationUtils.ArgumentNotNull(member, "member"); - ValidationUtils.ArgumentNotNull(target, "target"); - - switch (member.MemberType()) - { - case MemberTypes.Field: - ((FieldInfo)member).SetValue(target, value); - break; - case MemberTypes.Property: - ((PropertyInfo)member).SetValue(target, value, null); - break; - default: - throw new ArgumentException("MemberInfo '{0}' must be of type FieldInfo or PropertyInfo".FormatWith(CultureInfo.InvariantCulture, member.Name), "member"); - } - } - - /// - /// Determines whether the specified MemberInfo can be read. - /// - /// The MemberInfo to determine whether can be read. - /// /// if set to true then allow the member to be gotten non-publicly. - /// - /// true if the specified MemberInfo can be read; otherwise, false. - /// - public static bool CanReadMemberValue(MemberInfo member, bool nonPublic) - { - switch (member.MemberType()) - { - case MemberTypes.Field: - FieldInfo fieldInfo = (FieldInfo)member; - - if (nonPublic) - return true; - else if (fieldInfo.IsPublic) - return true; - return false; - case MemberTypes.Property: - PropertyInfo propertyInfo = (PropertyInfo)member; - - if (!propertyInfo.CanRead) - return false; - if (nonPublic) - return true; - return (propertyInfo.GetGetMethod(nonPublic) != null); - default: - return false; - } - } - - /// - /// Determines whether the specified MemberInfo can be set. - /// - /// The MemberInfo to determine whether can be set. - /// if set to true then allow the member to be set non-publicly. - /// if set to true then allow the member to be set if read-only. - /// - /// true if the specified MemberInfo can be set; otherwise, false. - /// - public static bool CanSetMemberValue(MemberInfo member, bool nonPublic, bool canSetReadOnly) - { - switch (member.MemberType()) - { - case MemberTypes.Field: - FieldInfo fieldInfo = (FieldInfo)member; - - if (fieldInfo.IsInitOnly && !canSetReadOnly) - return false; - if (nonPublic) - return true; - else if (fieldInfo.IsPublic) - return true; - return false; - case MemberTypes.Property: - PropertyInfo propertyInfo = (PropertyInfo)member; - - if (!propertyInfo.CanWrite) - return false; - if (nonPublic) - return true; - return (propertyInfo.GetSetMethod(nonPublic) != null); - default: - return false; - } - } - - public static List GetFieldsAndProperties(Type type, BindingFlags bindingAttr) - { - List targetMembers = new List(); - - targetMembers.AddRange(GetFields(type, bindingAttr)); - targetMembers.AddRange(GetProperties(type, bindingAttr)); - - // for some reason .NET returns multiple members when overriding a generic member on a base class - // http://forums.msdn.microsoft.com/en-US/netfxbcl/thread/b5abbfee-e292-4a64-8907-4e3f0fb90cd9/ - // filter members to only return the override on the topmost class - // update: I think this is fixed in .NET 3.5 SP1 - leave this in for now... - List distinctMembers = new List(targetMembers.Count); - - foreach (var groupedMember in targetMembers.GroupBy(m => m.Name)) - { - int count = groupedMember.Count(); - IList members = groupedMember.ToList(); - - if (count == 1) + /// + /// Determines whether the property is an indexed property. + /// + /// The property. + /// + /// true if the property is an indexed property; otherwise, false. + /// + public static bool IsIndexedProperty(PropertyInfo property) { - distinctMembers.Add(members.First()); + ValidationUtils.ArgumentNotNull(property, "property"); + + return (property.GetIndexParameters().Length > 0); } - else + + /// + /// Gets the member's value on the object. + /// + /// The member. + /// The target object. + /// The member's value on the object. + public static object GetMemberValue(MemberInfo member, object target) { - var resolvedMembers = members.Where(m => !IsOverridenGenericMember(m, bindingAttr) || m.Name == "Item"); + ValidationUtils.ArgumentNotNull(member, "member"); + ValidationUtils.ArgumentNotNull(target, "target"); - distinctMembers.AddRange(resolvedMembers); + switch (member.MemberType()) + { + case MemberTypes.Field: + return ((FieldInfo)member).GetValue(target); + case MemberTypes.Property: + try + { + return ((PropertyInfo)member).GetValue(target, null); + } + catch (TargetParameterCountException e) + { + throw new ArgumentException("MemberInfo '{0}' has index parameters".FormatWith(CultureInfo.InvariantCulture, member.Name), e); + } + default: + throw new ArgumentException("MemberInfo '{0}' is not of type FieldInfo or PropertyInfo".FormatWith(CultureInfo.InvariantCulture, CultureInfo.InvariantCulture, member.Name), "member"); + } } - } - return distinctMembers; - } + /// + /// Sets the member's value on the target object. + /// + /// The member. + /// The target. + /// The value. + public static void SetMemberValue(MemberInfo member, object target, object value) + { + ValidationUtils.ArgumentNotNull(member, "member"); + ValidationUtils.ArgumentNotNull(target, "target"); + + switch (member.MemberType()) + { + case MemberTypes.Field: + ((FieldInfo)member).SetValue(target, value); + break; + case MemberTypes.Property: + ((PropertyInfo)member).SetValue(target, value, null); + break; + default: + throw new ArgumentException("MemberInfo '{0}' must be of type FieldInfo or PropertyInfo".FormatWith(CultureInfo.InvariantCulture, member.Name), "member"); + } + } + + /// + /// Determines whether the specified MemberInfo can be read. + /// + /// The MemberInfo to determine whether can be read. + /// /// if set to true then allow the member to be gotten non-publicly. + /// + /// true if the specified MemberInfo can be read; otherwise, false. + /// + public static bool CanReadMemberValue(MemberInfo member, bool nonPublic) + { + switch (member.MemberType()) + { + case MemberTypes.Field: + FieldInfo fieldInfo = (FieldInfo)member; + + if (nonPublic) + return true; + else if (fieldInfo.IsPublic) + return true; + return false; + case MemberTypes.Property: + PropertyInfo propertyInfo = (PropertyInfo)member; + + if (!propertyInfo.CanRead) + return false; + if (nonPublic) + return true; + return (propertyInfo.GetGetMethod(nonPublic) != null); + default: + return false; + } + } + + /// + /// Determines whether the specified MemberInfo can be set. + /// + /// The MemberInfo to determine whether can be set. + /// if set to true then allow the member to be set non-publicly. + /// if set to true then allow the member to be set if read-only. + /// + /// true if the specified MemberInfo can be set; otherwise, false. + /// + public static bool CanSetMemberValue(MemberInfo member, bool nonPublic, bool canSetReadOnly) + { + switch (member.MemberType()) + { + case MemberTypes.Field: + FieldInfo fieldInfo = (FieldInfo)member; + + if (fieldInfo.IsInitOnly && !canSetReadOnly) + return false; + if (nonPublic) + return true; + else if (fieldInfo.IsPublic) + return true; + return false; + case MemberTypes.Property: + PropertyInfo propertyInfo = (PropertyInfo)member; + + if (!propertyInfo.CanWrite) + return false; + if (nonPublic) + return true; + return (propertyInfo.GetSetMethod(nonPublic) != null); + default: + return false; + } + } + + public static List GetFieldsAndProperties(Type type, BindingFlags bindingAttr) + { + List targetMembers = new List(); + + targetMembers.AddRange(GetFields(type, bindingAttr)); + targetMembers.AddRange(GetProperties(type, bindingAttr)); + + // for some reason .NET returns multiple members when overriding a generic member on a base class + // http://forums.msdn.microsoft.com/en-US/netfxbcl/thread/b5abbfee-e292-4a64-8907-4e3f0fb90cd9/ + // filter members to only return the override on the topmost class + // update: I think this is fixed in .NET 3.5 SP1 - leave this in for now... + List distinctMembers = new List(targetMembers.Count); + + foreach (var groupedMember in targetMembers.GroupBy(m => m.Name)) + { + int count = groupedMember.Count(); + IList members = groupedMember.ToList(); + + if (count == 1) + { + distinctMembers.Add(members.First()); + } + else + { + var resolvedMembers = members.Where(m => !IsOverridenGenericMember(m, bindingAttr) || m.Name == "Item"); + + distinctMembers.AddRange(resolvedMembers); + } + } + + return distinctMembers; + } - private static bool IsOverridenGenericMember(MemberInfo memberInfo, BindingFlags bindingAttr) - { - MemberTypes memberType = memberInfo.MemberType(); - if (memberType != MemberTypes.Field && memberType != MemberTypes.Property) - throw new ArgumentException("Member must be a field or property."); + private static bool IsOverridenGenericMember(MemberInfo memberInfo, BindingFlags bindingAttr) + { + MemberTypes memberType = memberInfo.MemberType(); + if (memberType != MemberTypes.Field && memberType != MemberTypes.Property) + throw new ArgumentException("Member must be a field or property."); - Type declaringType = memberInfo.DeclaringType; - if (!declaringType.IsGenericType()) - return false; - Type genericTypeDefinition = declaringType.GetGenericTypeDefinition(); - if (genericTypeDefinition == null) - return false; - MemberInfo[] members = genericTypeDefinition.GetMember(memberInfo.Name, bindingAttr); - if (members.Length == 0) - return false; - Type memberUnderlyingType = GetMemberUnderlyingType(members[0]); - if (!memberUnderlyingType.IsGenericParameter) - return false; + Type declaringType = memberInfo.DeclaringType; + if (!declaringType.IsGenericType()) + return false; + Type genericTypeDefinition = declaringType.GetGenericTypeDefinition(); + if (genericTypeDefinition == null) + return false; + MemberInfo[] members = genericTypeDefinition.GetMember(memberInfo.Name, bindingAttr); + if (members.Length == 0) + return false; + Type memberUnderlyingType = GetMemberUnderlyingType(members[0]); + if (!memberUnderlyingType.IsGenericParameter) + return false; - return true; - } + return true; + } - public static T GetAttribute(object attributeProvider) where T : Attribute - { - return GetAttribute(attributeProvider, true); - } + public static T GetAttribute(object attributeProvider) where T : Attribute + { + return GetAttribute(attributeProvider, true); + } - public static T GetAttribute(object attributeProvider, bool inherit) where T : Attribute - { - T[] attributes = GetAttributes(attributeProvider, inherit); + public static T GetAttribute(object attributeProvider, bool inherit) where T : Attribute + { + T[] attributes = GetAttributes(attributeProvider, inherit); - return (attributes != null) ? attributes.SingleOrDefault() : null; - } + return (attributes != null) ? attributes.SingleOrDefault() : null; + } #if !(NETFX_CORE || PORTABLE) - public static T[] GetAttributes(object attributeProvider, bool inherit) where T : Attribute - { - ValidationUtils.ArgumentNotNull(attributeProvider, "attributeProvider"); + public static T[] GetAttributes(object attributeProvider, bool inherit) where T : Attribute + { + ValidationUtils.ArgumentNotNull(attributeProvider, "attributeProvider"); - object provider = attributeProvider; + object provider = attributeProvider; - // http://hyperthink.net/blog/getcustomattributes-gotcha/ - // ICustomAttributeProvider doesn't do inheritance + // http://hyperthink.net/blog/getcustomattributes-gotcha/ + // ICustomAttributeProvider doesn't do inheritance - if (provider is Type) - return (T[])((Type)provider).GetCustomAttributes(typeof(T), inherit); + if (provider is Type) + return (T[])((Type)provider).GetCustomAttributes(typeof(T), inherit); - if (provider is Assembly) - return (T[])Attribute.GetCustomAttributes((Assembly)provider, typeof(T)); + if (provider is Assembly) + return (T[])Attribute.GetCustomAttributes((Assembly)provider, typeof(T)); - if (provider is MemberInfo) - return (T[])Attribute.GetCustomAttributes((MemberInfo)provider, typeof(T), inherit); + if (provider is MemberInfo) + return (T[])Attribute.GetCustomAttributes((MemberInfo)provider, typeof(T), inherit); #if !PORTABLE40 - if (provider is Module) - return (T[])Attribute.GetCustomAttributes((Module)provider, typeof(T), inherit); + if (provider is Module) + return (T[])Attribute.GetCustomAttributes((Module)provider, typeof(T), inherit); #endif - if (provider is ParameterInfo) - return (T[])Attribute.GetCustomAttributes((ParameterInfo)provider, typeof(T), inherit); + if (provider is ParameterInfo) + return (T[])Attribute.GetCustomAttributes((ParameterInfo)provider, typeof(T), inherit); #if !PORTABLE40 - return (T[])((ICustomAttributeProvider)attributeProvider).GetCustomAttributes(typeof(T), inherit); + return (T[])((ICustomAttributeProvider)attributeProvider).GetCustomAttributes(typeof(T), inherit); #endif - throw new Exception("Cannot get attributes from '{0}'.".FormatWith(CultureInfo.InvariantCulture, provider)); - } + throw new Exception("Cannot get attributes from '{0}'.".FormatWith(CultureInfo.InvariantCulture, provider)); + } #else public static T[] GetAttributes(object provider, bool inherit) where T : Attribute { @@ -711,242 +711,240 @@ namespace Newtonsoft.Json.Utilities } #endif - public static void SplitFullyQualifiedTypeName(string fullyQualifiedTypeName, out string typeName, out string assemblyName) - { - int? assemblyDelimiterIndex = GetAssemblyDelimiterIndex(fullyQualifiedTypeName); - - if (assemblyDelimiterIndex != null) - { - typeName = fullyQualifiedTypeName.Substring(0, assemblyDelimiterIndex.Value).Trim(); - assemblyName = fullyQualifiedTypeName.Substring(assemblyDelimiterIndex.Value + 1, fullyQualifiedTypeName.Length - assemblyDelimiterIndex.Value - 1).Trim(); - } - else - { - typeName = fullyQualifiedTypeName; - assemblyName = null; - } - - } - - private static int? GetAssemblyDelimiterIndex(string fullyQualifiedTypeName) - { - // we need to get the first comma following all surrounded in brackets because of generic types - // e.g. System.Collections.Generic.Dictionary`2[[System.String, mscorlib,Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - int scope = 0; - for (int i = 0; i < fullyQualifiedTypeName.Length; i++) - { - char current = fullyQualifiedTypeName[i]; - switch (current) + public static void SplitFullyQualifiedTypeName(string fullyQualifiedTypeName, out string typeName, out string assemblyName) { - case '[': - scope++; - break; - case ']': - scope--; - break; - case ',': - if (scope == 0) - return i; - break; + int? assemblyDelimiterIndex = GetAssemblyDelimiterIndex(fullyQualifiedTypeName); + + if (assemblyDelimiterIndex != null) + { + typeName = fullyQualifiedTypeName.Substring(0, assemblyDelimiterIndex.Value).Trim(); + assemblyName = fullyQualifiedTypeName.Substring(assemblyDelimiterIndex.Value + 1, fullyQualifiedTypeName.Length - assemblyDelimiterIndex.Value - 1).Trim(); + } + else + { + typeName = fullyQualifiedTypeName; + assemblyName = null; + } } - } - return null; - } + private static int? GetAssemblyDelimiterIndex(string fullyQualifiedTypeName) + { + // we need to get the first comma following all surrounded in brackets because of generic types + // e.g. System.Collections.Generic.Dictionary`2[[System.String, mscorlib,Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + int scope = 0; + for (int i = 0; i < fullyQualifiedTypeName.Length; i++) + { + char current = fullyQualifiedTypeName[i]; + switch (current) + { + case '[': + scope++; + break; + case ']': + scope--; + break; + case ',': + if (scope == 0) + return i; + break; + } + } - public static MemberInfo GetMemberInfoFromType(Type targetType, MemberInfo memberInfo) - { - const BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; + return null; + } - switch (memberInfo.MemberType()) - { - case MemberTypes.Property: - PropertyInfo propertyInfo = (PropertyInfo)memberInfo; + public static MemberInfo GetMemberInfoFromType(Type targetType, MemberInfo memberInfo) + { + const BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; - Type[] types = propertyInfo.GetIndexParameters().Select(p => p.ParameterType).ToArray(); + switch (memberInfo.MemberType()) + { + case MemberTypes.Property: + PropertyInfo propertyInfo = (PropertyInfo)memberInfo; - return targetType.GetProperty(propertyInfo.Name, bindingAttr, null, propertyInfo.PropertyType, types, null); - default: - return targetType.GetMember(memberInfo.Name, memberInfo.MemberType(), bindingAttr).SingleOrDefault(); - } - } + Type[] types = propertyInfo.GetIndexParameters().Select(p => p.ParameterType).ToArray(); - public static IEnumerable GetFields(Type targetType, BindingFlags bindingAttr) - { - ValidationUtils.ArgumentNotNull(targetType, "targetType"); + return targetType.GetProperty(propertyInfo.Name, bindingAttr, null, propertyInfo.PropertyType, types, null); + default: + return targetType.GetMember(memberInfo.Name, memberInfo.MemberType(), bindingAttr).SingleOrDefault(); + } + } - List fieldInfos = new List(targetType.GetFields(bindingAttr)); + public static IEnumerable GetFields(Type targetType, BindingFlags bindingAttr) + { + ValidationUtils.ArgumentNotNull(targetType, "targetType"); + + List fieldInfos = new List(targetType.GetFields(bindingAttr)); #if !(NETFX_CORE || PORTABLE) - // Type.GetFields doesn't return inherited private fields - // manually find private fields from base class - GetChildPrivateFields(fieldInfos, targetType, bindingAttr); + // Type.GetFields doesn't return inherited private fields + // manually find private fields from base class + GetChildPrivateFields(fieldInfos, targetType, bindingAttr); #endif - return fieldInfos.Cast(); - } - - private static void GetChildPrivateFields(IList initialFields, Type targetType, BindingFlags bindingAttr) - { - // fix weirdness with private FieldInfos only being returned for the current Type - // find base type fields and add them to result - if ((bindingAttr & BindingFlags.NonPublic) != 0) - { - // modify flags to not search for public fields - BindingFlags nonPublicBindingAttr = bindingAttr.RemoveFlag(BindingFlags.Public); - - while ((targetType = targetType.BaseType()) != null) - { - // filter out protected fields - IEnumerable childPrivateFields = - targetType.GetFields(nonPublicBindingAttr).Where(f => f.IsPrivate).Cast(); - - initialFields.AddRange(childPrivateFields); + return fieldInfos.Cast(); } - } - } - public static IEnumerable GetProperties(Type targetType, BindingFlags bindingAttr) - { - ValidationUtils.ArgumentNotNull(targetType, "targetType"); - - List propertyInfos = new List(targetType.GetProperties(bindingAttr)); - GetChildPrivateProperties(propertyInfos, targetType, bindingAttr); - - // a base class private getter/setter will be inaccessable unless the property was gotten from the base class - for (int i = 0; i < propertyInfos.Count; i++) - { - PropertyInfo member = propertyInfos[i]; - if (member.DeclaringType != targetType) + private static void GetChildPrivateFields(IList initialFields, Type targetType, BindingFlags bindingAttr) { - PropertyInfo declaredMember = (PropertyInfo)GetMemberInfoFromType(member.DeclaringType, member); - propertyInfos[i] = declaredMember; + // fix weirdness with private FieldInfos only being returned for the current Type + // find base type fields and add them to result + if ((bindingAttr & BindingFlags.NonPublic) != 0) + { + // modify flags to not search for public fields + BindingFlags nonPublicBindingAttr = bindingAttr.RemoveFlag(BindingFlags.Public); + + while ((targetType = targetType.BaseType()) != null) + { + // filter out protected fields + IEnumerable childPrivateFields = + targetType.GetFields(nonPublicBindingAttr).Where(f => f.IsPrivate).Cast(); + + initialFields.AddRange(childPrivateFields); + } + } } - } - return propertyInfos; - } - - public static BindingFlags RemoveFlag(this BindingFlags bindingAttr, BindingFlags flag) - { - return ((bindingAttr & flag) == flag) - ? bindingAttr ^ flag - : bindingAttr; - } - - private static void GetChildPrivateProperties(IList initialProperties, Type targetType, BindingFlags bindingAttr) - { - // fix weirdness with private PropertyInfos only being returned for the current Type - // find base type properties and add them to result - - // also find base properties that have been hidden by subtype properties with the same name - - while ((targetType = targetType.BaseType()) != null) - { - foreach (PropertyInfo propertyInfo in targetType.GetProperties(bindingAttr)) + public static IEnumerable GetProperties(Type targetType, BindingFlags bindingAttr) { - PropertyInfo subTypeProperty = propertyInfo; + ValidationUtils.ArgumentNotNull(targetType, "targetType"); - if (!IsPublic(subTypeProperty)) - { - // have to test on name rather than reference because instances are different - // depending on the type that GetProperties was called on - int index = initialProperties.IndexOf(p => p.Name == subTypeProperty.Name); - if (index == -1) - { - initialProperties.Add(subTypeProperty); - } - else - { - // replace nonpublic properties for a child, but gotten from - // the parent with the one from the child - // the property gotten from the child will have access to private getter/setter - initialProperties[index] = subTypeProperty; - } - } - else - { - if (!subTypeProperty.IsVirtual()) - { - int index = initialProperties.IndexOf(p => p.Name == subTypeProperty.Name - && p.DeclaringType == subTypeProperty.DeclaringType); + List propertyInfos = new List(targetType.GetProperties(bindingAttr)); + GetChildPrivateProperties(propertyInfos, targetType, bindingAttr); - if (index == -1) - initialProperties.Add(subTypeProperty); - } - else + // a base class private getter/setter will be inaccessable unless the property was gotten from the base class + for (int i = 0; i < propertyInfos.Count; i++) { - int index = initialProperties.IndexOf(p => p.Name == subTypeProperty.Name - && p.IsVirtual() - && p.GetBaseDefinition() != null - && p.GetBaseDefinition().DeclaringType.IsAssignableFrom(subTypeProperty.DeclaringType)); - - if (index == -1) - initialProperties.Add(subTypeProperty); + PropertyInfo member = propertyInfos[i]; + if (member.DeclaringType != targetType) + { + PropertyInfo declaredMember = (PropertyInfo)GetMemberInfoFromType(member.DeclaringType, member); + propertyInfos[i] = declaredMember; + } } - } + + return propertyInfos; } - } - } - public static bool IsMethodOverridden(Type currentType, Type methodDeclaringType, string method) - { - bool isMethodOverriden = currentType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) - .Any(info => - info.Name == method && - // check that the method overrides the original on DynamicObjectProxy - info.DeclaringType != methodDeclaringType - && info.GetBaseDefinition().DeclaringType == methodDeclaringType - ); + public static BindingFlags RemoveFlag(this BindingFlags bindingAttr, BindingFlags flag) + { + return ((bindingAttr & flag) == flag) + ? bindingAttr ^ flag + : bindingAttr; + } - return isMethodOverriden; - } + private static void GetChildPrivateProperties(IList initialProperties, Type targetType, BindingFlags bindingAttr) + { + // fix weirdness with private PropertyInfos only being returned for the current Type + // find base type properties and add them to result - public static object GetDefaultValue(Type type) - { - if (!type.IsValueType()) - return null; + // also find base properties that have been hidden by subtype properties with the same name - switch (ConvertUtils.GetTypeCode(type)) - { - case PrimitiveTypeCode.Boolean: - return false; - case PrimitiveTypeCode.Char: - case PrimitiveTypeCode.SByte: - case PrimitiveTypeCode.Byte: - case PrimitiveTypeCode.Int16: - case PrimitiveTypeCode.UInt16: - case PrimitiveTypeCode.Int32: - case PrimitiveTypeCode.UInt32: - return 0; - case PrimitiveTypeCode.Int64: - case PrimitiveTypeCode.UInt64: - return 0L; - case PrimitiveTypeCode.Single: - return 0f; - case PrimitiveTypeCode.Double: - return 0.0; - case PrimitiveTypeCode.Decimal: - return 0m; - case PrimitiveTypeCode.DateTime: - return new DateTime(); + while ((targetType = targetType.BaseType()) != null) + { + foreach (PropertyInfo propertyInfo in targetType.GetProperties(bindingAttr)) + { + PropertyInfo subTypeProperty = propertyInfo; + + if (!IsPublic(subTypeProperty)) + { + // have to test on name rather than reference because instances are different + // depending on the type that GetProperties was called on + int index = initialProperties.IndexOf(p => p.Name == subTypeProperty.Name); + if (index == -1) + { + initialProperties.Add(subTypeProperty); + } + else + { + // replace nonpublic properties for a child, but gotten from + // the parent with the one from the child + // the property gotten from the child will have access to private getter/setter + initialProperties[index] = subTypeProperty; + } + } + else + { + if (!subTypeProperty.IsVirtual()) + { + int index = initialProperties.IndexOf(p => p.Name == subTypeProperty.Name + && p.DeclaringType == subTypeProperty.DeclaringType); + + if (index == -1) + initialProperties.Add(subTypeProperty); + } + else + { + int index = initialProperties.IndexOf(p => p.Name == subTypeProperty.Name + && p.IsVirtual() + && p.GetBaseDefinition() != null + && p.GetBaseDefinition().DeclaringType.IsAssignableFrom(subTypeProperty.DeclaringType)); + + if (index == -1) + initialProperties.Add(subTypeProperty); + } + } + } + } + } + + public static bool IsMethodOverridden(Type currentType, Type methodDeclaringType, string method) + { + bool isMethodOverriden = currentType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) + .Any(info => + info.Name == method && + // check that the method overrides the original on DynamicObjectProxy + info.DeclaringType != methodDeclaringType + && info.GetBaseDefinition().DeclaringType == methodDeclaringType + ); + + return isMethodOverriden; + } + + public static object GetDefaultValue(Type type) + { + if (!type.IsValueType()) + return null; + + switch (ConvertUtils.GetTypeCode(type)) + { + case PrimitiveTypeCode.Boolean: + return false; + case PrimitiveTypeCode.Char: + case PrimitiveTypeCode.SByte: + case PrimitiveTypeCode.Byte: + case PrimitiveTypeCode.Int16: + case PrimitiveTypeCode.UInt16: + case PrimitiveTypeCode.Int32: + case PrimitiveTypeCode.UInt32: + return 0; + case PrimitiveTypeCode.Int64: + case PrimitiveTypeCode.UInt64: + return 0L; + case PrimitiveTypeCode.Single: + return 0f; + case PrimitiveTypeCode.Double: + return 0.0; + case PrimitiveTypeCode.Decimal: + return 0m; + case PrimitiveTypeCode.DateTime: + return new DateTime(); #if !(PORTABLE || PORTABLE40 || NET35 || NET20 || WINDOWS_PHONE || SILVERLIGHT) - case PrimitiveTypeCode.BigInteger: - return new BigInteger(); + case PrimitiveTypeCode.BigInteger: + return new BigInteger(); #endif - case PrimitiveTypeCode.Guid: - return new Guid(); + case PrimitiveTypeCode.Guid: + return new Guid(); #if !NET20 - case PrimitiveTypeCode.DateTimeOffset: - return new DateTimeOffset(); + case PrimitiveTypeCode.DateTimeOffset: + return new DateTimeOffset(); #endif + } - } + if (IsNullable(type)) + return null; - if (IsNullable(type)) - return null; - - // possibly use IL initobj for perf here? - return Activator.CreateInstance(type); + // possibly use IL initobj for perf here? + return Activator.CreateInstance(type); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/StringBuffer.cs b/Src/Newtonsoft.Json/Utilities/StringBuffer.cs index 0b28fc3c..05022391 100644 --- a/Src/Newtonsoft.Json/Utilities/StringBuffer.cs +++ b/Src/Newtonsoft.Json/Utilities/StringBuffer.cs @@ -27,81 +27,81 @@ using System; namespace Newtonsoft.Json.Utilities { - /// - /// Builds a string. Unlike StringBuilder this class lets you reuse it's internal buffer. - /// - internal class StringBuffer - { - private char[] _buffer; - private int _position; - - private static readonly char[] EmptyBuffer = new char[0]; - - public int Position + /// + /// Builds a string. Unlike StringBuilder this class lets you reuse it's internal buffer. + /// + internal class StringBuffer { - get { return _position; } - set { _position = value; } + private char[] _buffer; + private int _position; + + private static readonly char[] EmptyBuffer = new char[0]; + + public int Position + { + get { return _position; } + set { _position = value; } + } + + public StringBuffer() + { + _buffer = EmptyBuffer; + } + + public StringBuffer(int initalSize) + { + _buffer = new char[initalSize]; + } + + public void Append(char value) + { + // test if the buffer array is large enough to take the value + if (_position == _buffer.Length) + EnsureSize(1); + + // set value and increment poisition + _buffer[_position++] = value; + } + + public void Append(char[] buffer, int startIndex, int count) + { + if (_position + count >= _buffer.Length) + EnsureSize(count); + + Array.Copy(buffer, startIndex, _buffer, _position, count); + + _position += count; + } + + public void Clear() + { + _buffer = EmptyBuffer; + _position = 0; + } + + private void EnsureSize(int appendLength) + { + char[] newBuffer = new char[(_position + appendLength) * 2]; + + Array.Copy(_buffer, newBuffer, _position); + + _buffer = newBuffer; + } + + public override string ToString() + { + return ToString(0, _position); + } + + public string ToString(int start, int length) + { + // TODO: validation + return new string(_buffer, start, length); + } + + public char[] GetInternalBuffer() + { + return _buffer; + } } - - public StringBuffer() - { - _buffer = EmptyBuffer; - } - - public StringBuffer(int initalSize) - { - _buffer = new char[initalSize]; - } - - public void Append(char value) - { - // test if the buffer array is large enough to take the value - if (_position == _buffer.Length) - EnsureSize(1); - - // set value and increment poisition - _buffer[_position++] = value; - } - - public void Append(char[] buffer, int startIndex, int count) - { - if (_position + count >= _buffer.Length) - EnsureSize(count); - - Array.Copy(buffer, startIndex, _buffer, _position, count); - - _position += count; - } - - public void Clear() - { - _buffer = EmptyBuffer; - _position = 0; - } - - private void EnsureSize(int appendLength) - { - char[] newBuffer = new char[(_position + appendLength) * 2]; - - Array.Copy(_buffer, newBuffer, _position); - - _buffer = newBuffer; - } - - public override string ToString() - { - return ToString(0, _position); - } - - public string ToString(int start, int length) - { - // TODO: validation - return new string(_buffer, start, length); - } - - public char[] GetInternalBuffer() - { - return _buffer; - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/StringReference.cs b/Src/Newtonsoft.Json/Utilities/StringReference.cs index a4a9f2e3..0feaa490 100644 --- a/Src/Newtonsoft.Json/Utilities/StringReference.cs +++ b/Src/Newtonsoft.Json/Utilities/StringReference.cs @@ -25,37 +25,37 @@ namespace Newtonsoft.Json.Utilities { - internal struct StringReference - { - private readonly char[] _chars; - private readonly int _startIndex; - private readonly int _length; - - public char[] Chars + internal struct StringReference { - get { return _chars; } - } + private readonly char[] _chars; + private readonly int _startIndex; + private readonly int _length; - public int StartIndex - { - get { return _startIndex; } - } + public char[] Chars + { + get { return _chars; } + } - public int Length - { - get { return _length; } - } + public int StartIndex + { + get { return _startIndex; } + } - public StringReference(char[] chars, int startIndex, int length) - { - _chars = chars; - _startIndex = startIndex; - _length = length; - } + public int Length + { + get { return _length; } + } - public override string ToString() - { - return new string(_chars, _startIndex, _length); + public StringReference(char[] chars, int startIndex, int length) + { + _chars = chars; + _startIndex = startIndex; + _length = length; + } + + public override string ToString() + { + return new string(_chars, _startIndex, _length); + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/StringUtils.cs b/Src/Newtonsoft.Json/Utilities/StringUtils.cs index 974afdae..21f09a6f 100644 --- a/Src/Newtonsoft.Json/Utilities/StringUtils.cs +++ b/Src/Newtonsoft.Json/Utilities/StringUtils.cs @@ -37,165 +37,165 @@ using Newtonsoft.Json.Serialization; namespace Newtonsoft.Json.Utilities { - internal static class StringUtils - { - public const string CarriageReturnLineFeed = "\r\n"; - public const string Empty = ""; - public const char CarriageReturn = '\r'; - public const char LineFeed = '\n'; - public const char Tab = '\t'; - - public static string FormatWith(this string format, IFormatProvider provider, object arg0) + internal static class StringUtils { - return format.FormatWith(provider, new[] { arg0 }); - } + public const string CarriageReturnLineFeed = "\r\n"; + public const string Empty = ""; + public const char CarriageReturn = '\r'; + public const char LineFeed = '\n'; + public const char Tab = '\t'; - public static string FormatWith(this string format, IFormatProvider provider, object arg0, object arg1) - { - return format.FormatWith(provider, new[] { arg0, arg1 }); - } - - public static string FormatWith(this string format, IFormatProvider provider, object arg0, object arg1, object arg2) - { - return format.FormatWith(provider, new[] { arg0, arg1, arg2 }); - } - - public static string FormatWith(this string format, IFormatProvider provider, params object[] args) - { - ValidationUtils.ArgumentNotNull(format, "format"); - - return string.Format(provider, format, args); - } - - /// - /// Determines whether the string is all white space. Empty string will return false. - /// - /// The string to test whether it is all white space. - /// - /// true if the string is all white space; otherwise, false. - /// - public static bool IsWhiteSpace(string s) - { - if (s == null) - throw new ArgumentNullException("s"); - - if (s.Length == 0) - return false; - - for (int i = 0; i < s.Length; i++) - { - if (!char.IsWhiteSpace(s[i])) - return false; - } - - return true; - } - - /// - /// Nulls an empty string. - /// - /// The string. - /// Null if the string was null, otherwise the string unchanged. - public static string NullEmptyString(string s) - { - return (string.IsNullOrEmpty(s)) ? null : s; - } - - public static StringWriter CreateStringWriter(int capacity) - { - StringBuilder sb = new StringBuilder(capacity); - StringWriter sw = new StringWriter(sb, CultureInfo.InvariantCulture); - - return sw; - } - - public static int? GetLength(string value) - { - if (value == null) - return null; - else - return value.Length; - } - - public static void ToCharAsUnicode(char c, char[] buffer) - { - buffer[0] = '\\'; - buffer[1] = 'u'; - buffer[2] = MathUtils.IntToHex((c >> 12) & '\x000f'); - buffer[3] = MathUtils.IntToHex((c >> 8) & '\x000f'); - buffer[4] = MathUtils.IntToHex((c >> 4) & '\x000f'); - buffer[5] = MathUtils.IntToHex(c & '\x000f'); - } - - public static TSource ForgivingCaseSensitiveFind(this IEnumerable source, Func valueSelector, string testValue) - { - if (source == null) - throw new ArgumentNullException("source"); - if (valueSelector == null) - throw new ArgumentNullException("valueSelector"); - - var caseInsensitiveResults = source.Where(s => string.Equals(valueSelector(s), testValue, StringComparison.OrdinalIgnoreCase)); - if (caseInsensitiveResults.Count() <= 1) - { - return caseInsensitiveResults.SingleOrDefault(); - } - else - { - // multiple results returned. now filter using case sensitivity - var caseSensitiveResults = source.Where(s => string.Equals(valueSelector(s), testValue, StringComparison.Ordinal)); - return caseSensitiveResults.SingleOrDefault(); - } - } - - public static string ToCamelCase(string s) - { - if (string.IsNullOrEmpty(s)) - return s; - - if (!char.IsUpper(s[0])) - return s; - - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < s.Length; i++) - { - bool hasNext = (i + 1 < s.Length); - if ((i == 0 || !hasNext) || char.IsUpper(s[i + 1])) + public static string FormatWith(this string format, IFormatProvider provider, object arg0) { - char lowerCase; + return format.FormatWith(provider, new[] { arg0 }); + } + + public static string FormatWith(this string format, IFormatProvider provider, object arg0, object arg1) + { + return format.FormatWith(provider, new[] { arg0, arg1 }); + } + + public static string FormatWith(this string format, IFormatProvider provider, object arg0, object arg1, object arg2) + { + return format.FormatWith(provider, new[] { arg0, arg1, arg2 }); + } + + public static string FormatWith(this string format, IFormatProvider provider, params object[] args) + { + ValidationUtils.ArgumentNotNull(format, "format"); + + return string.Format(provider, format, args); + } + + /// + /// Determines whether the string is all white space. Empty string will return false. + /// + /// The string to test whether it is all white space. + /// + /// true if the string is all white space; otherwise, false. + /// + public static bool IsWhiteSpace(string s) + { + if (s == null) + throw new ArgumentNullException("s"); + + if (s.Length == 0) + return false; + + for (int i = 0; i < s.Length; i++) + { + if (!char.IsWhiteSpace(s[i])) + return false; + } + + return true; + } + + /// + /// Nulls an empty string. + /// + /// The string. + /// Null if the string was null, otherwise the string unchanged. + public static string NullEmptyString(string s) + { + return (string.IsNullOrEmpty(s)) ? null : s; + } + + public static StringWriter CreateStringWriter(int capacity) + { + StringBuilder sb = new StringBuilder(capacity); + StringWriter sw = new StringWriter(sb, CultureInfo.InvariantCulture); + + return sw; + } + + public static int? GetLength(string value) + { + if (value == null) + return null; + else + return value.Length; + } + + public static void ToCharAsUnicode(char c, char[] buffer) + { + buffer[0] = '\\'; + buffer[1] = 'u'; + buffer[2] = MathUtils.IntToHex((c >> 12) & '\x000f'); + buffer[3] = MathUtils.IntToHex((c >> 8) & '\x000f'); + buffer[4] = MathUtils.IntToHex((c >> 4) & '\x000f'); + buffer[5] = MathUtils.IntToHex(c & '\x000f'); + } + + public static TSource ForgivingCaseSensitiveFind(this IEnumerable source, Func valueSelector, string testValue) + { + if (source == null) + throw new ArgumentNullException("source"); + if (valueSelector == null) + throw new ArgumentNullException("valueSelector"); + + var caseInsensitiveResults = source.Where(s => string.Equals(valueSelector(s), testValue, StringComparison.OrdinalIgnoreCase)); + if (caseInsensitiveResults.Count() <= 1) + { + return caseInsensitiveResults.SingleOrDefault(); + } + else + { + // multiple results returned. now filter using case sensitivity + var caseSensitiveResults = source.Where(s => string.Equals(valueSelector(s), testValue, StringComparison.Ordinal)); + return caseSensitiveResults.SingleOrDefault(); + } + } + + public static string ToCamelCase(string s) + { + if (string.IsNullOrEmpty(s)) + return s; + + if (!char.IsUpper(s[0])) + return s; + + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < s.Length; i++) + { + bool hasNext = (i + 1 < s.Length); + if ((i == 0 || !hasNext) || char.IsUpper(s[i + 1])) + { + char lowerCase; #if !(NETFX_CORE || PORTABLE) - lowerCase = char.ToLower(s[i], CultureInfo.InvariantCulture); + lowerCase = char.ToLower(s[i], CultureInfo.InvariantCulture); #else lowerCase = char.ToLower(s[i]); #endif - sb.Append(lowerCase); + sb.Append(lowerCase); + } + else + { + sb.Append(s.Substring(i)); + break; + } + } + + return sb.ToString(); } - else + + public static bool IsHighSurrogate(char c) { - sb.Append(s.Substring(i)); - break; +#if !(SILVERLIGHT || PORTABLE40 || PORTABLE) + return char.IsHighSurrogate(c); +#else + return (c >= 55296 && c <= 56319); +#endif } - } - return sb.ToString(); - } - - public static bool IsHighSurrogate(char c) - { + public static bool IsLowSurrogate(char c) + { #if !(SILVERLIGHT || PORTABLE40 || PORTABLE) - return char.IsHighSurrogate(c); + return char.IsLowSurrogate(c); #else - return (c >= 55296 && c <= 56319); + return (c >= 56320 && c <= 57343); #endif + } } - - public static bool IsLowSurrogate(char c) - { -#if !(SILVERLIGHT || PORTABLE40 || PORTABLE) - return char.IsLowSurrogate(c); -#else - return (c >= 56320 && c <= 57343); -#endif - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/ThreadSafeStore.cs b/Src/Newtonsoft.Json/Utilities/ThreadSafeStore.cs index dbd0a96f..d961126a 100644 --- a/Src/Newtonsoft.Json/Utilities/ThreadSafeStore.cs +++ b/Src/Newtonsoft.Json/Utilities/ThreadSafeStore.cs @@ -33,59 +33,59 @@ using Newtonsoft.Json.Serialization; namespace Newtonsoft.Json.Utilities { - internal class ThreadSafeStore - { - private readonly object _lock = new object(); - private Dictionary _store; - private readonly Func _creator; - - public ThreadSafeStore(Func creator) + internal class ThreadSafeStore { - if (creator == null) - throw new ArgumentNullException("creator"); + private readonly object _lock = new object(); + private Dictionary _store; + private readonly Func _creator; - _creator = creator; - _store = new Dictionary(); - } - - public TValue Get(TKey key) - { - TValue value; - if (!_store.TryGetValue(key, out value)) - return AddValue(key); - - return value; - } - - private TValue AddValue(TKey key) - { - TValue value = _creator(key); - - lock (_lock) - { - if (_store == null) + public ThreadSafeStore(Func creator) { - _store = new Dictionary(); - _store[key] = value; + if (creator == null) + throw new ArgumentNullException("creator"); + + _creator = creator; + _store = new Dictionary(); } - else - { - // double check locking - TValue checkValue; - if (_store.TryGetValue(key, out checkValue)) - return checkValue; - Dictionary newStore = new Dictionary(_store); - newStore[key] = value; + public TValue Get(TKey key) + { + TValue value; + if (!_store.TryGetValue(key, out value)) + return AddValue(key); + + return value; + } + + private TValue AddValue(TKey key) + { + TValue value = _creator(key); + + lock (_lock) + { + if (_store == null) + { + _store = new Dictionary(); + _store[key] = value; + } + else + { + // double check locking + TValue checkValue; + if (_store.TryGetValue(key, out checkValue)) + return checkValue; + + Dictionary newStore = new Dictionary(_store); + newStore[key] = value; #if !(NETFX_CORE || PORTABLE) - Thread.MemoryBarrier(); + Thread.MemoryBarrier(); #endif - _store = newStore; - } + _store = newStore; + } - return value; - } + return value; + } + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/TypeExtensions.cs b/Src/Newtonsoft.Json/Utilities/TypeExtensions.cs index 4f4aa5c5..333f6f01 100644 --- a/Src/Newtonsoft.Json/Utilities/TypeExtensions.cs +++ b/Src/Newtonsoft.Json/Utilities/TypeExtensions.cs @@ -30,12 +30,13 @@ using System.Reflection; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; + #endif namespace Newtonsoft.Json.Utilities { - internal static class TypeExtensions - { + internal static class TypeExtensions + { #if NETFX_CORE || PORTABLE private static BindingFlags DefaultFlags = BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance; @@ -78,138 +79,138 @@ namespace Newtonsoft.Json.Utilities } #endif - public static MethodInfo Method(this Delegate d) - { + public static MethodInfo Method(this Delegate d) + { #if !(NETFX_CORE || PORTABLE) - return d.Method; + return d.Method; #else return d.GetMethodInfo(); #endif - } + } - public static MemberTypes MemberType(this MemberInfo memberInfo) - { + public static MemberTypes MemberType(this MemberInfo memberInfo) + { #if !(NETFX_CORE || PORTABLE || PORTABLE40) - return memberInfo.MemberType; + return memberInfo.MemberType; #else - if (memberInfo is PropertyInfo) - return MemberTypes.Property; - else if (memberInfo is FieldInfo) - return MemberTypes.Field; - else if (memberInfo is EventInfo) - return MemberTypes.Event; - else if (memberInfo is MethodInfo) - return MemberTypes.Method; - else - return MemberTypes.Other; + if (memberInfo is PropertyInfo) + return MemberTypes.Property; + else if (memberInfo is FieldInfo) + return MemberTypes.Field; + else if (memberInfo is EventInfo) + return MemberTypes.Event; + else if (memberInfo is MethodInfo) + return MemberTypes.Method; + else + return MemberTypes.Other; #endif - } + } - public static bool ContainsGenericParameters(this Type type) - { + public static bool ContainsGenericParameters(this Type type) + { #if !(NETFX_CORE || PORTABLE) - return type.ContainsGenericParameters; + return type.ContainsGenericParameters; #else return type.GetTypeInfo().ContainsGenericParameters; #endif - } + } - public static bool IsInterface(this Type type) - { + public static bool IsInterface(this Type type) + { #if !(NETFX_CORE || PORTABLE) - return type.IsInterface; + return type.IsInterface; #else return type.GetTypeInfo().IsInterface; #endif - } + } - public static bool IsGenericType(this Type type) - { + public static bool IsGenericType(this Type type) + { #if !(NETFX_CORE || PORTABLE) - return type.IsGenericType; + return type.IsGenericType; #else return type.GetTypeInfo().IsGenericType; #endif - } + } - public static bool IsGenericTypeDefinition(this Type type) - { + public static bool IsGenericTypeDefinition(this Type type) + { #if !(NETFX_CORE || PORTABLE) - return type.IsGenericTypeDefinition; + return type.IsGenericTypeDefinition; #else return type.GetTypeInfo().IsGenericTypeDefinition; #endif - } + } - public static Type BaseType(this Type type) - { + public static Type BaseType(this Type type) + { #if !(NETFX_CORE || PORTABLE) - return type.BaseType; + return type.BaseType; #else return type.GetTypeInfo().BaseType; #endif - } + } - public static bool IsEnum(this Type type) - { + public static bool IsEnum(this Type type) + { #if !(NETFX_CORE || PORTABLE) - return type.IsEnum; + return type.IsEnum; #else return type.GetTypeInfo().IsEnum; #endif - } + } - public static bool IsClass(this Type type) - { + public static bool IsClass(this Type type) + { #if !(NETFX_CORE || PORTABLE) - return type.IsClass; + return type.IsClass; #else return type.GetTypeInfo().IsClass; #endif - } + } - public static bool IsSealed(this Type type) - { + public static bool IsSealed(this Type type) + { #if !(NETFX_CORE || PORTABLE) - return type.IsSealed; + return type.IsSealed; #else return type.GetTypeInfo().IsSealed; #endif - } - -#if PORTABLE40 - public static PropertyInfo GetProperty(this Type type, string name, BindingFlags bindingFlags, object placeholder1, Type propertyType, IList indexParameters, object placeholder2) - { - IList propertyInfos = type.GetProperties(bindingFlags); - - return propertyInfos.Where(p => - { - if (name != null && name != p.Name) - return false; - if (propertyType != null && propertyType != p.PropertyType) - return false; - if (indexParameters != null) - { - if (!p.GetIndexParameters().Select(ip => ip.ParameterType).SequenceEqual(indexParameters)) - return false; } - return true; - }).SingleOrDefault(); - } - - public static IEnumerable GetMember(this Type type, string name, MemberTypes memberType, BindingFlags bindingFlags) - { - return type.GetMembers(bindingFlags).Where(m => +#if PORTABLE40 + public static PropertyInfo GetProperty(this Type type, string name, BindingFlags bindingFlags, object placeholder1, Type propertyType, IList indexParameters, object placeholder2) { - if (name != null && name != m.Name) - return false; - if (m.MemberType() != memberType) - return false; + IList propertyInfos = type.GetProperties(bindingFlags); - return true; - }); - } + return propertyInfos.Where(p => + { + if (name != null && name != p.Name) + return false; + if (propertyType != null && propertyType != p.PropertyType) + return false; + if (indexParameters != null) + { + if (!p.GetIndexParameters().Select(ip => ip.ParameterType).SequenceEqual(indexParameters)) + return false; + } + + return true; + }).SingleOrDefault(); + } + + public static IEnumerable GetMember(this Type type, string name, MemberTypes memberType, BindingFlags bindingFlags) + { + return type.GetMembers(bindingFlags).Where(m => + { + if (name != null && name != m.Name) + return false; + if (m.MemberType() != memberType) + return false; + + return true; + }); + } #endif #if (NETFX_CORE || PORTABLE) @@ -502,114 +503,114 @@ namespace Newtonsoft.Json.Utilities } #endif - public static bool IsAbstract(this Type type) - { + public static bool IsAbstract(this Type type) + { #if !(NETFX_CORE || PORTABLE) - return type.IsAbstract; + return type.IsAbstract; #else return type.GetTypeInfo().IsAbstract; #endif - } + } - public static bool IsVisible(this Type type) - { + public static bool IsVisible(this Type type) + { #if !(NETFX_CORE || PORTABLE) - return type.IsVisible; + return type.IsVisible; #else return type.GetTypeInfo().IsVisible; #endif - } + } - public static bool IsValueType(this Type type) - { + public static bool IsValueType(this Type type) + { #if !(NETFX_CORE || PORTABLE) - return type.IsValueType; + return type.IsValueType; #else return type.GetTypeInfo().IsValueType; #endif - } - - public static bool AssignableToTypeName(this Type type, string fullTypeName, out Type match) - { - Type current = type; - - while (current != null) - { - if (string.Equals(current.FullName, fullTypeName, StringComparison.Ordinal)) - { - match = current; - return true; } - current = current.BaseType(); - } - - foreach (Type i in type.GetInterfaces()) - { - if (string.Equals(i.Name, fullTypeName, StringComparison.Ordinal)) + public static bool AssignableToTypeName(this Type type, string fullTypeName, out Type match) { - match = type; - return true; + Type current = type; + + while (current != null) + { + if (string.Equals(current.FullName, fullTypeName, StringComparison.Ordinal)) + { + match = current; + return true; + } + + current = current.BaseType(); + } + + foreach (Type i in type.GetInterfaces()) + { + if (string.Equals(i.Name, fullTypeName, StringComparison.Ordinal)) + { + match = type; + return true; + } + } + + match = null; + return false; } - } - match = null; - return false; - } - - public static bool AssignableToTypeName(this Type type, string fullTypeName) - { - Type match; - return type.AssignableToTypeName(fullTypeName, out match); - } - - public static MethodInfo GetGenericMethod(this Type type, string name, params Type[] parameterTypes) - { - var methods = type.GetMethods().Where(method => method.Name == name); - - foreach (var method in methods) - { - if (method.HasParameters(parameterTypes)) - return method; - } - - return null; - } - - public static bool HasParameters(this MethodInfo method, params Type[] parameterTypes) - { - var methodParameters = method.GetParameters().Select(parameter => parameter.ParameterType).ToArray(); - - if (methodParameters.Length != parameterTypes.Length) - return false; - - for (int i = 0; i < methodParameters.Length; i++) - if (methodParameters[i].ToString() != parameterTypes[i].ToString()) - return false; - - return true; - } - - public static IEnumerable GetAllInterfaces(this Type target) - { - foreach (var i in target.GetInterfaces()) - { - yield return i; - foreach (var ci in i.GetInterfaces()) + public static bool AssignableToTypeName(this Type type, string fullTypeName) { - yield return ci; + Type match; + return type.AssignableToTypeName(fullTypeName, out match); } - } - } - public static IEnumerable GetAllMethods(this Type target) - { - var allTypes = target.GetAllInterfaces().ToList(); - allTypes.Add(target); + public static MethodInfo GetGenericMethod(this Type type, string name, params Type[] parameterTypes) + { + var methods = type.GetMethods().Where(method => method.Name == name); - return from type in allTypes - from method in type.GetMethods() - select method; + foreach (var method in methods) + { + if (method.HasParameters(parameterTypes)) + return method; + } + + return null; + } + + public static bool HasParameters(this MethodInfo method, params Type[] parameterTypes) + { + var methodParameters = method.GetParameters().Select(parameter => parameter.ParameterType).ToArray(); + + if (methodParameters.Length != parameterTypes.Length) + return false; + + for (int i = 0; i < methodParameters.Length; i++) + if (methodParameters[i].ToString() != parameterTypes[i].ToString()) + return false; + + return true; + } + + public static IEnumerable GetAllInterfaces(this Type target) + { + foreach (var i in target.GetInterfaces()) + { + yield return i; + foreach (var ci in i.GetInterfaces()) + { + yield return ci; + } + } + } + + public static IEnumerable GetAllMethods(this Type target) + { + var allTypes = target.GetAllInterfaces().ToList(); + allTypes.Add(target); + + return from type in allTypes + from method in type.GetMethods() + select method; + } } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/ValidationUtils.cs b/Src/Newtonsoft.Json/Utilities/ValidationUtils.cs index 9b187af9..c27874e7 100644 --- a/Src/Newtonsoft.Json/Utilities/ValidationUtils.cs +++ b/Src/Newtonsoft.Json/Utilities/ValidationUtils.cs @@ -31,29 +31,29 @@ using System.Globalization; namespace Newtonsoft.Json.Utilities { - internal static class ValidationUtils - { - public static void ArgumentNotNullOrEmpty(string value, string parameterName) + internal static class ValidationUtils { - if (value == null) - throw new ArgumentNullException(parameterName); + public static void ArgumentNotNullOrEmpty(string value, string parameterName) + { + if (value == null) + throw new ArgumentNullException(parameterName); - if (value.Length == 0) - throw new ArgumentException("'{0}' cannot be empty.".FormatWith(CultureInfo.InvariantCulture, parameterName), parameterName); + if (value.Length == 0) + throw new ArgumentException("'{0}' cannot be empty.".FormatWith(CultureInfo.InvariantCulture, parameterName), parameterName); + } + + public static void ArgumentTypeIsEnum(Type enumType, string parameterName) + { + ArgumentNotNull(enumType, "enumType"); + + if (!enumType.IsEnum()) + throw new ArgumentException("Type {0} is not an Enum.".FormatWith(CultureInfo.InvariantCulture, enumType), parameterName); + } + + public static void ArgumentNotNull(object value, string parameterName) + { + if (value == null) + throw new ArgumentNullException(parameterName); + } } - - public static void ArgumentTypeIsEnum(Type enumType, string parameterName) - { - ArgumentNotNull(enumType, "enumType"); - - if (!enumType.IsEnum()) - throw new ArgumentException("Type {0} is not an Enum.".FormatWith(CultureInfo.InvariantCulture, enumType), parameterName); - } - - public static void ArgumentNotNull(object value, string parameterName) - { - if (value == null) - throw new ArgumentNullException(parameterName); - } - } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/WriteState.cs b/Src/Newtonsoft.Json/WriteState.cs index 609a394d..c5352a53 100644 --- a/Src/Newtonsoft.Json/WriteState.cs +++ b/Src/Newtonsoft.Json/WriteState.cs @@ -27,40 +27,46 @@ using System; namespace Newtonsoft.Json { - /// - /// Specifies the state of the . - /// - public enum WriteState - { /// - /// An exception has been thrown, which has left the in an invalid state. - /// You may call the method to put the in the Closed state. - /// Any other method calls results in an being thrown. + /// Specifies the state of the . /// - Error, - /// - /// The method has been called. - /// - Closed, - /// - /// An object is being written. - /// - Object, - /// - /// A array is being written. - /// - Array, - /// - /// A constructor is being written. - /// - Constructor, - /// - /// A property is being written. - /// - Property, - /// - /// A write method has not been called. - /// - Start - } + public enum WriteState + { + /// + /// An exception has been thrown, which has left the in an invalid state. + /// You may call the method to put the in the Closed state. + /// Any other method calls results in an being thrown. + /// + Error, + + /// + /// The method has been called. + /// + Closed, + + /// + /// An object is being written. + /// + Object, + + /// + /// A array is being written. + /// + Array, + + /// + /// A constructor is being written. + /// + Constructor, + + /// + /// A property is being written. + /// + Property, + + /// + /// A write method has not been called. + /// + Start + } } \ No newline at end of file