PageRenderTime 304ms CodeModel.GetById 8ms app.highlight 242ms RepoModel.GetById 1ms app.codeStats 2ms

/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs

https://github.com/dmgores/Newtonsoft.Json
C# | 7989 lines | 7047 code | 841 blank | 101 comment | 61 complexity | 47375c7d5e276f3ea785fa4217096b31 MD5 | raw file
   1#region License
   2// Copyright (c) 2007 James Newton-King
   3//
   4// Permission is hereby granted, free of charge, to any person
   5// obtaining a copy of this software and associated documentation
   6// files (the "Software"), to deal in the Software without
   7// restriction, including without limitation the rights to use,
   8// copy, modify, merge, publish, distribute, sublicense, and/or sell
   9// copies of the Software, and to permit persons to whom the
  10// Software is furnished to do so, subject to the following
  11// conditions:
  12//
  13// The above copyright notice and this permission notice shall be
  14// included in all copies or substantial portions of the Software.
  15//
  16// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  18// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  20// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  21// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  23// OTHER DEALINGS IN THE SOFTWARE.
  24#endregion
  25
  26using System;
  27using System.ComponentModel;
  28#if !(NET35 || NET20)
  29using System.Collections.Concurrent;
  30#endif
  31using System.Collections.Generic;
  32#if !(NET20 || NET35 || PORTABLE)
  33using System.Numerics;
  34#endif
  35#if !NET20 && !NETFX_CORE
  36using System.ComponentModel.DataAnnotations;
  37using System.Configuration;
  38using System.Runtime.CompilerServices;
  39using System.Runtime.Serialization.Formatters;
  40using System.Threading;
  41using System.Web.Script.Serialization;
  42#endif
  43using System.Text;
  44using System.Text.RegularExpressions;
  45#if !NETFX_CORE
  46using NUnit.Framework;
  47#else
  48using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
  49using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute;
  50using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute;
  51#endif
  52using Newtonsoft.Json;
  53using System.IO;
  54using System.Collections;
  55using System.Xml;
  56using System.Xml.Serialization;
  57using System.Collections.ObjectModel;
  58using Newtonsoft.Json.Bson;
  59using Newtonsoft.Json.Linq;
  60using Newtonsoft.Json.Converters;
  61#if !NET20
  62using System.Runtime.Serialization.Json;
  63#endif
  64using Newtonsoft.Json.Serialization;
  65using Newtonsoft.Json.Tests.Linq;
  66using Newtonsoft.Json.Tests.TestObjects;
  67using System.Runtime.Serialization;
  68using System.Globalization;
  69using Newtonsoft.Json.Utilities;
  70using System.Reflection;
  71#if !NET20
  72using System.Xml.Linq;
  73using System.Collections.Specialized;
  74using System.Linq.Expressions;
  75#endif
  76#if !(NET35 || NET20)
  77using System.Dynamic;
  78#endif
  79#if NET20
  80using Newtonsoft.Json.Utilities.LinqBridge;
  81#else
  82using System.Linq;
  83#endif
  84#if !(NETFX_CORE)
  85using System.Drawing;
  86using System.Diagnostics;
  87#endif
  88
  89namespace Newtonsoft.Json.Tests.Serialization
  90{
  91    [TestFixture]
  92    public class JsonSerializerTest : TestFixtureBase
  93    {
  94        public class BaseClass
  95        {
  96            internal bool IsTransient { get; set; }
  97        }
  98
  99        public class ChildClass : BaseClass
 100        {
 101            public new bool IsTransient { get; set; }
 102        }
 103
 104        [Test]
 105        public void NewProperty()
 106        {
 107            Assert.AreEqual(@"{""IsTransient"":true}", JsonConvert.SerializeObject(new ChildClass { IsTransient = true }));
 108
 109            var childClass = JsonConvert.DeserializeObject<ChildClass>(@"{""IsTransient"":true}");
 110            Assert.AreEqual(true, childClass.IsTransient);
 111        }
 112
 113        public class BaseClassVirtual
 114        {
 115            internal virtual bool IsTransient { get; set; }
 116        }
 117
 118        public class ChildClassVirtual : BaseClassVirtual
 119        {
 120            public virtual new bool IsTransient { get; set; }
 121        }
 122
 123        [Test]
 124        public void NewPropertyVirtual()
 125        {
 126            Assert.AreEqual(@"{""IsTransient"":true}", JsonConvert.SerializeObject(new ChildClassVirtual { IsTransient = true }));
 127
 128            var childClass = JsonConvert.DeserializeObject<ChildClassVirtual>(@"{""IsTransient"":true}");
 129            Assert.AreEqual(true, childClass.IsTransient);
 130        }
 131
 132        public class ResponseWithNewGenericProperty<T> : SimpleResponse
 133        {
 134            public new T Data { get; set; }
 135        }
 136
 137        public class ResponseWithNewGenericPropertyVirtual<T> : SimpleResponse
 138        {
 139            public virtual new T Data { get; set; }
 140        }
 141
 142        public class ResponseWithNewGenericPropertyOverride<T> : ResponseWithNewGenericPropertyVirtual<T>
 143        {
 144            public override T Data { get; set; }
 145        }
 146
 147        public abstract class SimpleResponse
 148        {
 149            public string Result { get; set; }
 150            public string Message { get; set; }
 151            public object Data { get; set; }
 152
 153            protected SimpleResponse()
 154            {
 155
 156            }
 157
 158            protected SimpleResponse(string message)
 159            {
 160                Message = message;
 161            }
 162        }
 163
 164        [Test]
 165        public void CanSerializeWithBuiltInTypeAsGenericArgument()
 166        {
 167            var input = new ResponseWithNewGenericProperty<int>()
 168            {
 169                Message = "Trying out integer as type parameter",
 170                Data = 25,
 171                Result = "This should be fine"
 172            };
 173
 174            var json = JsonConvert.SerializeObject(input);
 175            var deserialized = JsonConvert.DeserializeObject<ResponseWithNewGenericProperty<int>>(json);
 176
 177            Assert.AreEqual(input.Data, deserialized.Data);
 178            Assert.AreEqual(input.Message, deserialized.Message);
 179            Assert.AreEqual(input.Result, deserialized.Result);
 180        }
 181
 182        [Test]
 183        public void CanSerializeWithBuiltInTypeAsGenericArgumentVirtual()
 184        {
 185            var input = new ResponseWithNewGenericPropertyVirtual<int>()
 186            {
 187                Message = "Trying out integer as type parameter",
 188                Data = 25,
 189                Result = "This should be fine"
 190            };
 191
 192            var json = JsonConvert.SerializeObject(input);
 193            var deserialized = JsonConvert.DeserializeObject<ResponseWithNewGenericPropertyVirtual<int>>(json);
 194
 195            Assert.AreEqual(input.Data, deserialized.Data);
 196            Assert.AreEqual(input.Message, deserialized.Message);
 197            Assert.AreEqual(input.Result, deserialized.Result);
 198        }
 199
 200        [Test]
 201        public void CanSerializeWithBuiltInTypeAsGenericArgumentOverride()
 202        {
 203            var input = new ResponseWithNewGenericPropertyOverride<int>()
 204            {
 205                Message = "Trying out integer as type parameter",
 206                Data = 25,
 207                Result = "This should be fine"
 208            };
 209
 210            var json = JsonConvert.SerializeObject(input);
 211            var deserialized = JsonConvert.DeserializeObject<ResponseWithNewGenericPropertyOverride<int>>(json);
 212
 213            Assert.AreEqual(input.Data, deserialized.Data);
 214            Assert.AreEqual(input.Message, deserialized.Message);
 215            Assert.AreEqual(input.Result, deserialized.Result);
 216        }
 217
 218        [Test]
 219        public void CanSerializedWithGenericClosedTypeAsArgument()
 220        {
 221            var input = new ResponseWithNewGenericProperty<List<int>>()
 222            {
 223                Message = "More complex case - generic list of int",
 224                Data = Enumerable.Range(50, 70).ToList(),
 225                Result = "This should be fine too"
 226            };
 227
 228            var json = JsonConvert.SerializeObject(input);
 229            var deserialized = JsonConvert.DeserializeObject<ResponseWithNewGenericProperty<List<int>>>(json);
 230
 231            CollectionAssert.AreEqual(input.Data, deserialized.Data);
 232            Assert.AreEqual(input.Message, deserialized.Message);
 233            Assert.AreEqual(input.Result, deserialized.Result);
 234        }
 235
 236        [Test]
 237        public void JsonSerializerProperties()
 238        {
 239            JsonSerializer serializer = new JsonSerializer();
 240
 241            DefaultSerializationBinder customBinder = new DefaultSerializationBinder();
 242            serializer.Binder = customBinder;
 243            Assert.AreEqual(customBinder, serializer.Binder);
 244
 245            serializer.CheckAdditionalContent = true;
 246            Assert.AreEqual(true, serializer.CheckAdditionalContent);
 247
 248            serializer.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor;
 249            Assert.AreEqual(ConstructorHandling.AllowNonPublicDefaultConstructor, serializer.ConstructorHandling);
 250
 251#if !NETFX_CORE
 252            serializer.Context = new StreamingContext(StreamingContextStates.Other);
 253            Assert.AreEqual(new StreamingContext(StreamingContextStates.Other), serializer.Context);
 254#endif
 255
 256            CamelCasePropertyNamesContractResolver resolver = new CamelCasePropertyNamesContractResolver();
 257            serializer.ContractResolver = resolver;
 258            Assert.AreEqual(resolver, serializer.ContractResolver);
 259
 260            serializer.Converters.Add(new StringEnumConverter());
 261            Assert.AreEqual(1, serializer.Converters.Count);
 262
 263            serializer.Culture = new CultureInfo("en-nz");
 264            Assert.AreEqual("en-NZ", serializer.Culture.ToString());
 265
 266            serializer.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat;
 267            Assert.AreEqual(DateFormatHandling.MicrosoftDateFormat, serializer.DateFormatHandling);
 268
 269            serializer.DateFormatString = "yyyy";
 270            Assert.AreEqual("yyyy", serializer.DateFormatString);
 271
 272            serializer.DateParseHandling = DateParseHandling.None;
 273            Assert.AreEqual(DateParseHandling.None, serializer.DateParseHandling);
 274
 275            serializer.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
 276            Assert.AreEqual(DateTimeZoneHandling.Utc, serializer.DateTimeZoneHandling);
 277
 278            serializer.DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate;
 279            Assert.AreEqual(DefaultValueHandling.IgnoreAndPopulate, serializer.DefaultValueHandling);
 280
 281            serializer.FloatFormatHandling = FloatFormatHandling.Symbol;
 282            Assert.AreEqual(FloatFormatHandling.Symbol, serializer.FloatFormatHandling);
 283
 284            serializer.FloatParseHandling = FloatParseHandling.Decimal;
 285            Assert.AreEqual(FloatParseHandling.Decimal, serializer.FloatParseHandling);
 286
 287            serializer.Formatting = Formatting.Indented;
 288            Assert.AreEqual(Formatting.Indented, serializer.Formatting);
 289
 290            serializer.MaxDepth = 9001;
 291            Assert.AreEqual(9001, serializer.MaxDepth);
 292
 293            serializer.MissingMemberHandling = MissingMemberHandling.Error;
 294            Assert.AreEqual(MissingMemberHandling.Error, serializer.MissingMemberHandling);
 295
 296            serializer.NullValueHandling = NullValueHandling.Ignore;
 297            Assert.AreEqual(NullValueHandling.Ignore, serializer.NullValueHandling);
 298
 299            serializer.ObjectCreationHandling = ObjectCreationHandling.Replace;
 300            Assert.AreEqual(ObjectCreationHandling.Replace, serializer.ObjectCreationHandling);
 301
 302            serializer.PreserveReferencesHandling = PreserveReferencesHandling.All;
 303            Assert.AreEqual(PreserveReferencesHandling.All, serializer.PreserveReferencesHandling);
 304
 305            serializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
 306            Assert.AreEqual(ReferenceLoopHandling.Ignore, serializer.ReferenceLoopHandling);
 307
 308            IdReferenceResolver referenceResolver = new IdReferenceResolver();
 309            serializer.ReferenceResolver = referenceResolver;
 310            Assert.AreEqual(referenceResolver, serializer.ReferenceResolver);
 311
 312            serializer.StringEscapeHandling = StringEscapeHandling.EscapeNonAscii;
 313            Assert.AreEqual(StringEscapeHandling.EscapeNonAscii, serializer.StringEscapeHandling);
 314
 315            MemoryTraceWriter traceWriter = new MemoryTraceWriter();
 316            serializer.TraceWriter = traceWriter;
 317            Assert.AreEqual(traceWriter, serializer.TraceWriter);
 318
 319#if !(PORTABLE || PORTABLE40 || NETFX_CORE || NET20)
 320            serializer.TypeNameAssemblyFormat = FormatterAssemblyStyle.Full;
 321            Assert.AreEqual(FormatterAssemblyStyle.Full, serializer.TypeNameAssemblyFormat);
 322#endif
 323
 324            serializer.TypeNameHandling = TypeNameHandling.All;
 325            Assert.AreEqual(TypeNameHandling.All, serializer.TypeNameHandling);
 326        }
 327
 328        [Test]
 329        public void JsonSerializerSettingsProperties()
 330        {
 331            JsonSerializerSettings settings = new JsonSerializerSettings();
 332
 333            DefaultSerializationBinder customBinder = new DefaultSerializationBinder();
 334            settings.Binder = customBinder;
 335            Assert.AreEqual(customBinder, settings.Binder);
 336
 337            settings.CheckAdditionalContent = true;
 338            Assert.AreEqual(true, settings.CheckAdditionalContent);
 339
 340            settings.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor;
 341            Assert.AreEqual(ConstructorHandling.AllowNonPublicDefaultConstructor, settings.ConstructorHandling);
 342
 343#if !NETFX_CORE
 344            settings.Context = new StreamingContext(StreamingContextStates.Other);
 345            Assert.AreEqual(new StreamingContext(StreamingContextStates.Other), settings.Context);
 346#endif
 347
 348            CamelCasePropertyNamesContractResolver resolver = new CamelCasePropertyNamesContractResolver();
 349            settings.ContractResolver = resolver;
 350            Assert.AreEqual(resolver, settings.ContractResolver);
 351
 352            settings.Converters.Add(new StringEnumConverter());
 353            Assert.AreEqual(1, settings.Converters.Count);
 354
 355            settings.Culture = new CultureInfo("en-nz");
 356            Assert.AreEqual("en-NZ", settings.Culture.ToString());
 357
 358            settings.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat;
 359            Assert.AreEqual(DateFormatHandling.MicrosoftDateFormat, settings.DateFormatHandling);
 360
 361            settings.DateFormatString = "yyyy";
 362            Assert.AreEqual("yyyy", settings.DateFormatString);
 363
 364            settings.DateParseHandling = DateParseHandling.None;
 365            Assert.AreEqual(DateParseHandling.None, settings.DateParseHandling);
 366
 367            settings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
 368            Assert.AreEqual(DateTimeZoneHandling.Utc, settings.DateTimeZoneHandling);
 369
 370            settings.DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate;
 371            Assert.AreEqual(DefaultValueHandling.IgnoreAndPopulate, settings.DefaultValueHandling);
 372
 373            settings.FloatFormatHandling = FloatFormatHandling.Symbol;
 374            Assert.AreEqual(FloatFormatHandling.Symbol, settings.FloatFormatHandling);
 375
 376            settings.FloatParseHandling = FloatParseHandling.Decimal;
 377            Assert.AreEqual(FloatParseHandling.Decimal, settings.FloatParseHandling);
 378
 379            settings.Formatting = Formatting.Indented;
 380            Assert.AreEqual(Formatting.Indented, settings.Formatting);
 381
 382            settings.MaxDepth = 9001;
 383            Assert.AreEqual(9001, settings.MaxDepth);
 384
 385            settings.MissingMemberHandling = MissingMemberHandling.Error;
 386            Assert.AreEqual(MissingMemberHandling.Error, settings.MissingMemberHandling);
 387
 388            settings.NullValueHandling = NullValueHandling.Ignore;
 389            Assert.AreEqual(NullValueHandling.Ignore, settings.NullValueHandling);
 390
 391            settings.ObjectCreationHandling = ObjectCreationHandling.Replace;
 392            Assert.AreEqual(ObjectCreationHandling.Replace, settings.ObjectCreationHandling);
 393
 394            settings.PreserveReferencesHandling = PreserveReferencesHandling.All;
 395            Assert.AreEqual(PreserveReferencesHandling.All, settings.PreserveReferencesHandling);
 396
 397            settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
 398            Assert.AreEqual(ReferenceLoopHandling.Ignore, settings.ReferenceLoopHandling);
 399
 400            IdReferenceResolver referenceResolver = new IdReferenceResolver();
 401            settings.ReferenceResolver = referenceResolver;
 402            Assert.AreEqual(referenceResolver, settings.ReferenceResolver);
 403
 404            settings.StringEscapeHandling = StringEscapeHandling.EscapeNonAscii;
 405            Assert.AreEqual(StringEscapeHandling.EscapeNonAscii, settings.StringEscapeHandling);
 406
 407            MemoryTraceWriter traceWriter = new MemoryTraceWriter();
 408            settings.TraceWriter = traceWriter;
 409            Assert.AreEqual(traceWriter, settings.TraceWriter);
 410
 411#if !(PORTABLE || PORTABLE40 || NETFX_CORE || NET20)
 412            settings.TypeNameAssemblyFormat = FormatterAssemblyStyle.Full;
 413            Assert.AreEqual(FormatterAssemblyStyle.Full, settings.TypeNameAssemblyFormat);
 414#endif
 415
 416            settings.TypeNameHandling = TypeNameHandling.All;
 417            Assert.AreEqual(TypeNameHandling.All, settings.TypeNameHandling);
 418        }
 419
 420        [Test]
 421        public void JsonSerializerProxyProperties()
 422        {
 423            JsonSerializerProxy serializerProxy = new JsonSerializerProxy(new JsonSerializerInternalReader(new JsonSerializer()));
 424
 425            DefaultSerializationBinder customBinder = new DefaultSerializationBinder();
 426            serializerProxy.Binder = customBinder;
 427            Assert.AreEqual(customBinder, serializerProxy.Binder);
 428
 429            serializerProxy.CheckAdditionalContent = true;
 430            Assert.AreEqual(true, serializerProxy.CheckAdditionalContent);
 431
 432            serializerProxy.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor;
 433            Assert.AreEqual(ConstructorHandling.AllowNonPublicDefaultConstructor, serializerProxy.ConstructorHandling);
 434
 435#if !NETFX_CORE
 436            serializerProxy.Context = new StreamingContext(StreamingContextStates.Other);
 437            Assert.AreEqual(new StreamingContext(StreamingContextStates.Other), serializerProxy.Context);
 438#endif
 439
 440            CamelCasePropertyNamesContractResolver resolver = new CamelCasePropertyNamesContractResolver();
 441            serializerProxy.ContractResolver = resolver;
 442            Assert.AreEqual(resolver, serializerProxy.ContractResolver);
 443
 444            serializerProxy.Converters.Add(new StringEnumConverter());
 445            Assert.AreEqual(1, serializerProxy.Converters.Count);
 446
 447            serializerProxy.Culture = new CultureInfo("en-nz");
 448            Assert.AreEqual("en-NZ", serializerProxy.Culture.ToString());
 449
 450            serializerProxy.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat;
 451            Assert.AreEqual(DateFormatHandling.MicrosoftDateFormat, serializerProxy.DateFormatHandling);
 452
 453            serializerProxy.DateFormatString = "yyyy";
 454            Assert.AreEqual("yyyy", serializerProxy.DateFormatString);
 455
 456            serializerProxy.DateParseHandling = DateParseHandling.None;
 457            Assert.AreEqual(DateParseHandling.None, serializerProxy.DateParseHandling);
 458
 459            serializerProxy.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
 460            Assert.AreEqual(DateTimeZoneHandling.Utc, serializerProxy.DateTimeZoneHandling);
 461
 462            serializerProxy.DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate;
 463            Assert.AreEqual(DefaultValueHandling.IgnoreAndPopulate, serializerProxy.DefaultValueHandling);
 464
 465            serializerProxy.FloatFormatHandling = FloatFormatHandling.Symbol;
 466            Assert.AreEqual(FloatFormatHandling.Symbol, serializerProxy.FloatFormatHandling);
 467
 468            serializerProxy.FloatParseHandling = FloatParseHandling.Decimal;
 469            Assert.AreEqual(FloatParseHandling.Decimal, serializerProxy.FloatParseHandling);
 470
 471            serializerProxy.Formatting = Formatting.Indented;
 472            Assert.AreEqual(Formatting.Indented, serializerProxy.Formatting);
 473
 474            serializerProxy.MaxDepth = 9001;
 475            Assert.AreEqual(9001, serializerProxy.MaxDepth);
 476
 477            serializerProxy.MissingMemberHandling = MissingMemberHandling.Error;
 478            Assert.AreEqual(MissingMemberHandling.Error, serializerProxy.MissingMemberHandling);
 479
 480            serializerProxy.NullValueHandling = NullValueHandling.Ignore;
 481            Assert.AreEqual(NullValueHandling.Ignore, serializerProxy.NullValueHandling);
 482
 483            serializerProxy.ObjectCreationHandling = ObjectCreationHandling.Replace;
 484            Assert.AreEqual(ObjectCreationHandling.Replace, serializerProxy.ObjectCreationHandling);
 485
 486            serializerProxy.PreserveReferencesHandling = PreserveReferencesHandling.All;
 487            Assert.AreEqual(PreserveReferencesHandling.All, serializerProxy.PreserveReferencesHandling);
 488
 489            serializerProxy.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
 490            Assert.AreEqual(ReferenceLoopHandling.Ignore, serializerProxy.ReferenceLoopHandling);
 491
 492            IdReferenceResolver referenceResolver = new IdReferenceResolver();
 493            serializerProxy.ReferenceResolver = referenceResolver;
 494            Assert.AreEqual(referenceResolver, serializerProxy.ReferenceResolver);
 495
 496            serializerProxy.StringEscapeHandling = StringEscapeHandling.EscapeNonAscii;
 497            Assert.AreEqual(StringEscapeHandling.EscapeNonAscii, serializerProxy.StringEscapeHandling);
 498
 499            MemoryTraceWriter traceWriter = new MemoryTraceWriter();
 500            serializerProxy.TraceWriter = traceWriter;
 501            Assert.AreEqual(traceWriter, serializerProxy.TraceWriter);
 502
 503#if !(PORTABLE || PORTABLE40 || NETFX_CORE || NET20)
 504            serializerProxy.TypeNameAssemblyFormat = FormatterAssemblyStyle.Full;
 505            Assert.AreEqual(FormatterAssemblyStyle.Full, serializerProxy.TypeNameAssemblyFormat);
 506#endif
 507
 508            serializerProxy.TypeNameHandling = TypeNameHandling.All;
 509            Assert.AreEqual(TypeNameHandling.All, serializerProxy.TypeNameHandling);
 510        }
 511
 512#if !(NETFX_CORE || PORTABLE || PORTABLE40)
 513        [Test]
 514        public void DeserializeISerializableIConvertible()
 515        {
 516            Ratio ratio = new Ratio(2, 1);
 517            string json = JsonConvert.SerializeObject(ratio);
 518
 519            Assert.AreEqual(@"{""n"":2,""d"":1}", json);
 520
 521            Ratio ratio2 = JsonConvert.DeserializeObject<Ratio>(json);
 522
 523            Assert.AreEqual(ratio.Denominator, ratio2.Denominator);
 524            Assert.AreEqual(ratio.Numerator, ratio2.Numerator);
 525        }
 526#endif
 527
 528        [Test]
 529        public void DeserializeLargeFloat()
 530        {
 531            object o = JsonConvert.DeserializeObject("100000000000000000000000000000000000000.0");
 532
 533            CustomAssert.IsInstanceOfType(typeof(double), o);
 534
 535            Assert.IsTrue(MathUtils.ApproxEquals(1E+38, (double)o));
 536        }
 537
 538        [Test]
 539        public void SerializeDeserializeRegex()
 540        {
 541            Regex regex = new Regex("(hi)", RegexOptions.CultureInvariant);
 542
 543            string json = JsonConvert.SerializeObject(regex, Formatting.Indented);
 544
 545            Regex r2 = JsonConvert.DeserializeObject<Regex>(json);
 546
 547            Assert.AreEqual("(hi)", r2.ToString());
 548            Assert.AreEqual(RegexOptions.CultureInvariant, r2.Options);
 549        }
 550
 551        [Test]
 552        public void EmbedJValueStringInNewJObject()
 553        {
 554            string s = null;
 555            var v = new JValue(s);
 556            var o = JObject.FromObject(new { title = v });
 557
 558            JObject oo = new JObject
 559            {
 560                {"title", v}
 561            };
 562
 563            string output = o.ToString();
 564
 565            Assert.AreEqual(null, v.Value);
 566            Assert.AreEqual(JTokenType.String, v.Type);
 567            
 568            Assert.AreEqual(@"{
 569  ""title"": null
 570}", output);
 571        }
 572
 573        // bug: the generic member (T) that hides the base member will not
 574        // be used when serializing and deserializing the object,
 575        // resulting in unexpected behavior during serialization and deserialization.
 576
 577        public class Foo1
 578        {
 579            public object foo { get; set; }
 580        }
 581
 582        public class Bar1
 583        {
 584            public object bar { get; set; }
 585        }
 586
 587        public class Foo1<T> : Foo1
 588        {
 589            public new T foo { get; set; }
 590
 591            public T foo2 { get; set; }
 592        }
 593
 594        public class FooBar1 : Foo1
 595        {
 596            public new Bar1 foo { get; set; }
 597        }
 598
 599        [Test]
 600        public void BaseClassSerializesAsExpected()
 601        {
 602            var original = new Foo1 { foo = "value" };
 603            var json = JsonConvert.SerializeObject(original);
 604            var expectedJson = @"{""foo"":""value""}";
 605            Assert.AreEqual(expectedJson, json); // passes
 606        }
 607
 608        [Test]
 609        public void BaseClassDeserializesAsExpected()
 610        {
 611            var json = @"{""foo"":""value""}";
 612            var deserialized = JsonConvert.DeserializeObject<Foo1>(json);
 613            Assert.AreEqual("value", deserialized.foo); // passes
 614        }
 615
 616        [Test]
 617        public void DerivedClassHidingBasePropertySerializesAsExpected()
 618        {
 619            var original = new FooBar1 { foo = new Bar1 { bar = "value" } };
 620            var json = JsonConvert.SerializeObject(original);
 621            var expectedJson = @"{""foo"":{""bar"":""value""}}";
 622            Assert.AreEqual(expectedJson, json); // passes
 623        }
 624
 625        [Test]
 626        public void DerivedClassHidingBasePropertyDeserializesAsExpected()
 627        {
 628            var json = @"{""foo"":{""bar"":""value""}}";
 629            var deserialized = JsonConvert.DeserializeObject<FooBar1>(json);
 630            Assert.IsNotNull(deserialized.foo); // passes
 631            Assert.AreEqual("value", deserialized.foo.bar); // passes
 632        }
 633
 634        [Test]
 635        public void DerivedGenericClassHidingBasePropertySerializesAsExpected()
 636        {
 637            var original = new Foo1<Bar1> { foo = new Bar1 { bar = "value" }, foo2 = new Bar1 { bar = "value2" } };
 638            var json = JsonConvert.SerializeObject(original);
 639            var expectedJson = @"{""foo"":{""bar"":""value""},""foo2"":{""bar"":""value2""}}";
 640            Assert.AreEqual(expectedJson, json);
 641        }
 642
 643        [Test]
 644        public void DerivedGenericClassHidingBasePropertyDeserializesAsExpected()
 645        {
 646            var json = @"{""foo"":{""bar"":""value""},""foo2"":{""bar"":""value2""}}";
 647            var deserialized = JsonConvert.DeserializeObject<Foo1<Bar1>>(json);
 648            Assert.IsNotNull(deserialized.foo2); // passes (bug only occurs for generics that /hide/ another property)
 649            Assert.AreEqual("value2", deserialized.foo2.bar); // also passes, with no issue
 650            Assert.IsNotNull(deserialized.foo);
 651            Assert.AreEqual("value", deserialized.foo.bar);
 652        }
 653
 654#if !NETFX_CORE
 655        [Test]
 656        public void ConversionOperator()
 657        {
 658            // Creating a simple dictionary that has a non-string key
 659            var dictStore = new Dictionary<DictionaryKeyCast, int>();
 660            for (var i = 0; i < 800; i++)
 661            {
 662                dictStore.Add(new DictionaryKeyCast(i.ToString(CultureInfo.InvariantCulture), i), i);
 663            }
 664            var settings = new JsonSerializerSettings { Formatting = Formatting.Indented };
 665            var jsonSerializer = JsonSerializer.Create(settings);
 666            var ms = new MemoryStream();
 667
 668            var streamWriter = new StreamWriter(ms);
 669            jsonSerializer.Serialize(streamWriter, dictStore);
 670            streamWriter.Flush();
 671
 672            ms.Seek(0, SeekOrigin.Begin);
 673
 674            var stopWatch = Stopwatch.StartNew();
 675            var deserialize = jsonSerializer.Deserialize(new StreamReader(ms), typeof(Dictionary<DictionaryKeyCast, int>));
 676            stopWatch.Stop();
 677
 678            Console.WriteLine("Time elapsed: " + stopWatch.ElapsedMilliseconds);
 679        }
 680#endif
 681
 682        internal class DictionaryKeyCast
 683        {
 684            private String _name;
 685            private int _number;
 686
 687            public DictionaryKeyCast(String name, int number)
 688            {
 689                _name = name;
 690                _number = number;
 691            }
 692
 693            public override string ToString()
 694            {
 695                return _name + " " + _number;
 696            }
 697
 698            public static implicit operator DictionaryKeyCast(string dictionaryKey)
 699            {
 700                var strings = dictionaryKey.Split(' ');
 701                return new DictionaryKeyCast(strings[0], Convert.ToInt32(strings[1]));
 702            }
 703        }
 704
 705#if !NET20
 706        [DataContract]
 707        public class BaseDataContractWithHidden
 708        {
 709            [DataMember(Name = "virtualMember")]
 710            public virtual string VirtualMember { get; set; }
 711
 712            [DataMember(Name = "nonVirtualMember")]
 713            public string NonVirtualMember { get; set; }
 714
 715            public virtual object NewMember { get; set; }
 716        }
 717
 718        public class ChildDataContractWithHidden : BaseDataContractWithHidden
 719        {
 720            [DataMember(Name = "NewMember")]
 721            public new virtual string NewMember { get; set; }
 722
 723            public override string VirtualMember { get; set; }
 724            public string AddedMember { get; set; }
 725        }
 726
 727        [Test]
 728        public void ChildDataContractTestWithHidden()
 729        {
 730            var cc = new ChildDataContractWithHidden
 731            {
 732                VirtualMember = "VirtualMember!",
 733                NonVirtualMember = "NonVirtualMember!",
 734                NewMember = "NewMember!"
 735            };
 736
 737            string result = JsonConvert.SerializeObject(cc);
 738            Assert.AreEqual(@"{""NewMember"":""NewMember!"",""virtualMember"":""VirtualMember!"",""nonVirtualMember"":""NonVirtualMember!""}", result);
 739        }
 740
 741        // ignore hiding members compiler warning
 742#pragma warning disable 108,114
 743        [DataContract]
 744        public class BaseWithContract
 745        {
 746            [DataMember(Name = "VirtualWithDataMemberBase")]
 747            public virtual string VirtualWithDataMember { get; set; }
 748
 749            [DataMember]
 750            public virtual string Virtual { get; set; }
 751
 752            [DataMember(Name = "WithDataMemberBase")]
 753            public string WithDataMember { get; set; }
 754
 755            [DataMember]
 756            public string JustAProperty { get; set; }
 757        }
 758
 759        [DataContract]
 760        public class BaseWithoutContract
 761        {
 762            [DataMember(Name = "VirtualWithDataMemberBase")]
 763            public virtual string VirtualWithDataMember { get; set; }
 764
 765            [DataMember]
 766            public virtual string Virtual { get; set; }
 767
 768            [DataMember(Name = "WithDataMemberBase")]
 769            public string WithDataMember { get; set; }
 770
 771            [DataMember]
 772            public string JustAProperty { get; set; }
 773        }
 774
 775        [DataContract]
 776        public class SubWithoutContractNewProperties : BaseWithContract
 777        {
 778            [DataMember(Name = "VirtualWithDataMemberSub")]
 779            public string VirtualWithDataMember { get; set; }
 780
 781            public string Virtual { get; set; }
 782
 783            [DataMember(Name = "WithDataMemberSub")]
 784            public string WithDataMember { get; set; }
 785
 786            public string JustAProperty { get; set; }
 787        }
 788
 789        [DataContract]
 790        public class SubWithoutContractVirtualProperties : BaseWithContract
 791        {
 792            public override string VirtualWithDataMember { get; set; }
 793
 794            [DataMember(Name = "VirtualSub")]
 795            public override string Virtual { get; set; }
 796        }
 797
 798        [DataContract]
 799        public class SubWithContractNewProperties : BaseWithContract
 800        {
 801            [DataMember(Name = "VirtualWithDataMemberSub")]
 802            public string VirtualWithDataMember { get; set; }
 803
 804            [DataMember(Name = "Virtual2")]
 805            public string Virtual { get; set; }
 806
 807            [DataMember(Name = "WithDataMemberSub")]
 808            public string WithDataMember { get; set; }
 809
 810            [DataMember(Name = "JustAProperty2")]
 811            public string JustAProperty { get; set; }
 812        }
 813
 814        [DataContract]
 815        public class SubWithContractVirtualProperties : BaseWithContract
 816        {
 817            [DataMember(Name = "VirtualWithDataMemberSub")]
 818            public virtual string VirtualWithDataMember { get; set; }
 819        }
 820#pragma warning restore 108,114
 821
 822        [Test]
 823        public void SubWithoutContractNewPropertiesTest()
 824        {
 825            BaseWithContract baseWith = new SubWithoutContractNewProperties
 826            {
 827                JustAProperty = "JustAProperty!",
 828                Virtual = "Virtual!",
 829                VirtualWithDataMember = "VirtualWithDataMember!",
 830                WithDataMember = "WithDataMember!"
 831            };
 832
 833            baseWith.JustAProperty = "JustAProperty2!";
 834            baseWith.Virtual = "Virtual2!";
 835            baseWith.VirtualWithDataMember = "VirtualWithDataMember2!";
 836            baseWith.WithDataMember = "WithDataMember2!";
 837
 838            string json = AssertSerializeDeserializeEqual(baseWith);
 839
 840            Assert.AreEqual(@"{
 841  ""JustAProperty"": ""JustAProperty2!"",
 842  ""Virtual"": ""Virtual2!"",
 843  ""VirtualWithDataMemberBase"": ""VirtualWithDataMember2!"",
 844  ""VirtualWithDataMemberSub"": ""VirtualWithDataMember!"",
 845  ""WithDataMemberBase"": ""WithDataMember2!"",
 846  ""WithDataMemberSub"": ""WithDataMember!""
 847}", json);
 848        }
 849
 850        [Test]
 851        public void SubWithoutContractVirtualPropertiesTest()
 852        {
 853            BaseWithContract baseWith = new SubWithoutContractVirtualProperties
 854            {
 855                JustAProperty = "JustAProperty!",
 856                Virtual = "Virtual!",
 857                VirtualWithDataMember = "VirtualWithDataMember!",
 858                WithDataMember = "WithDataMember!"
 859            };
 860
 861            baseWith.JustAProperty = "JustAProperty2!";
 862            baseWith.Virtual = "Virtual2!";
 863            baseWith.VirtualWithDataMember = "VirtualWithDataMember2!";
 864            baseWith.WithDataMember = "WithDataMember2!";
 865
 866            string json = JsonConvert.SerializeObject(baseWith, Formatting.Indented);
 867
 868            Console.WriteLine(json);
 869
 870            Assert.AreEqual(@"{
 871  ""VirtualWithDataMemberBase"": ""VirtualWithDataMember2!"",
 872  ""VirtualSub"": ""Virtual2!"",
 873  ""WithDataMemberBase"": ""WithDataMember2!"",
 874  ""JustAProperty"": ""JustAProperty2!""
 875}", json);
 876        }
 877
 878        [Test]
 879        public void SubWithContractNewPropertiesTest()
 880        {
 881            BaseWithContract baseWith = new SubWithContractNewProperties
 882            {
 883                JustAProperty = "JustAProperty!",
 884                Virtual = "Virtual!",
 885                VirtualWithDataMember = "VirtualWithDataMember!",
 886                WithDataMember = "WithDataMember!"
 887            };
 888
 889            baseWith.JustAProperty = "JustAProperty2!";
 890            baseWith.Virtual = "Virtual2!";
 891            baseWith.VirtualWithDataMember = "VirtualWithDataMember2!";
 892            baseWith.WithDataMember = "WithDataMember2!";
 893
 894            string json = AssertSerializeDeserializeEqual(baseWith);
 895
 896            Assert.AreEqual(@"{
 897  ""JustAProperty"": ""JustAProperty2!"",
 898  ""JustAProperty2"": ""JustAProperty!"",
 899  ""Virtual"": ""Virtual2!"",
 900  ""Virtual2"": ""Virtual!"",
 901  ""VirtualWithDataMemberBase"": ""VirtualWithDataMember2!"",
 902  ""VirtualWithDataMemberSub"": ""VirtualWithDataMember!"",
 903  ""WithDataMemberBase"": ""WithDataMember2!"",
 904  ""WithDataMemberSub"": ""WithDataMember!""
 905}", json);
 906        }
 907
 908        [Test]
 909        public void SubWithContractVirtualPropertiesTest()
 910        {
 911            BaseWithContract baseWith = new SubWithContractVirtualProperties
 912            {
 913                JustAProperty = "JustAProperty!",
 914                Virtual = "Virtual!",
 915                VirtualWithDataMember = "VirtualWithDataMember!",
 916                WithDataMember = "WithDataMember!"
 917            };
 918
 919            baseWith.JustAProperty = "JustAProperty2!";
 920            baseWith.Virtual = "Virtual2!";
 921            baseWith.VirtualWithDataMember = "VirtualWithDataMember2!";
 922            baseWith.WithDataMember = "WithDataMember2!";
 923
 924            string json = AssertSerializeDeserializeEqual(baseWith);
 925
 926            Assert.AreEqual(@"{
 927  ""JustAProperty"": ""JustAProperty2!"",
 928  ""Virtual"": ""Virtual2!"",
 929  ""VirtualWithDataMemberBase"": ""VirtualWithDataMember2!"",
 930  ""VirtualWithDataMemberSub"": ""VirtualWithDataMember!"",
 931  ""WithDataMemberBase"": ""WithDataMember2!""
 932}", json);
 933        }
 934
 935        private string AssertSerializeDeserializeEqual(object o)
 936        {
 937            MemoryStream ms = new MemoryStream();
 938            DataContractJsonSerializer s = new DataContractJsonSerializer(o.GetType());
 939            s.WriteObject(ms, o);
 940
 941            var data = ms.ToArray();
 942            JObject dataContractJson = JObject.Parse(Encoding.UTF8.GetString(data, 0, data.Length));
 943            dataContractJson = new JObject(dataContractJson.Properties().OrderBy(p => p.Name));
 944
 945            JObject jsonNetJson = JObject.Parse(JsonConvert.SerializeObject(o));
 946            jsonNetJson = new JObject(jsonNetJson.Properties().OrderBy(p => p.Name));
 947
 948            Console.WriteLine("Results for " + o.GetType().Name);
 949            Console.WriteLine("DataContractJsonSerializer: " + dataContractJson);
 950            Console.WriteLine("JsonDotNetSerializer      : " + jsonNetJson);
 951
 952            Assert.AreEqual(dataContractJson.Count, jsonNetJson.Count);
 953            foreach (KeyValuePair<string, JToken> property in dataContractJson)
 954            {
 955                Assert.IsTrue(JToken.DeepEquals(jsonNetJson[property.Key], property.Value), "Property not equal: " + property.Key);
 956            }
 957
 958            return jsonNetJson.ToString();
 959        }
 960#endif
 961
 962        [Test]
 963        public void PersonTypedObjectDeserialization()
 964        {
 965            Store store = new Store();
 966
 967            string jsonText = JsonConvert.SerializeObject(store);
 968
 969            Store deserializedStore = (Store)JsonConvert.DeserializeObject(jsonText, typeof(Store));
 970
 971            Assert.AreEqual(store.Establised, deserializedStore.Establised);
 972            Assert.AreEqual(store.product.Count, deserializedStore.product.Count);
 973
 974            Console.WriteLine(jsonText);
 975        }
 976
 977        [Test]
 978        public void TypedObjectDeserialization()
 979        {
 980            Product product = new Product();
 981
 982            product.Name = "Apple";
 983            product.ExpiryDate = new DateTime(2008, 12, 28);
 984            product.Price = 3.99M;
 985            product.Sizes = new string[] { "Small", "Medium", "Large" };
 986
 987            string output = JsonConvert.SerializeObject(product);
 988            //{
 989            //  "Name": "Apple",
 990            //  "ExpiryDate": "\/Date(1230375600000+1300)\/",
 991            //  "Price": 3.99,
 992            //  "Sizes": [
 993            //    "Small",
 994            //    "Medium",
 995            //    "Large"
 996            //  ]
 997            //}
 998
 999            Product deserializedProduct = (Product)JsonConvert.DeserializeObject(output, typeof(Product));
1000
1001            Assert.AreEqual("Apple", deserializedProduct.Name);
1002            Assert.AreEqual(new DateTime(2008, 12, 28), deserializedProduct.ExpiryDate);
1003            Assert.AreEqual(3.99m, deserializedProduct.Price);
1004            Assert.AreEqual("Small", deserializedProduct.Sizes[0]);
1005            Assert.AreEqual("Medium", deserializedProduct.Sizes[1]);
1006            Assert.AreEqual("Large", deserializedProduct.Sizes[2]);
1007        }
1008
1009        //[Test]
1010        //public void Advanced()
1011        //{
1012        //  Product product = new Product();
1013        //  product.ExpiryDate = new DateTime(2008, 12, 28);
1014
1015        //  JsonSerializer serializer = new JsonSerializer();
1016        //  serializer.Converters.Add(new JavaScriptDateTimeConverter());
1017        //  serializer.NullValueHandling = NullValueHandling.Ignore;
1018
1019        //  using (StreamWriter sw = new StreamWriter(@"c:\json.txt"))
1020        //  using (JsonWriter writer = new JsonTextWriter(sw))
1021        //  {
1022        //    serializer.Serialize(writer, product);
1023        //    // {"ExpiryDate":new Date(1230375600000),"Price":0}
1024        //  }
1025        //}
1026
1027        [Test]
1028        public void JsonConvertSerializer()
1029        {
1030            string value = @"{""Name"":""Orange"", ""Price"":3.99, ""ExpiryDate"":""01/24/2010 12:00:00""}";
1031
1032            Product p = JsonConvert.DeserializeObject(value, typeof(Product)) as Product;
1033
1034            Assert.AreEqual("Orange", p.Name);
1035            Assert.AreEqual(new DateTime(2010, 1, 24, 12, 0, 0), p.ExpiryDate);
1036            Assert.AreEqual(3.99m, p.Price);
1037        }
1038
1039        [Test]
1040        public void DeserializeJavaScriptDate()
1041        {
1042            DateTime dateValue = new DateTime(2010, 3, 30);
1043            Dictionary<string, object> testDictionary = new Dictionary<string, object>();
1044            testDictionary["date"] = dateValue;
1045
1046            string jsonText = JsonConvert.SerializeObject(testDictionary);
1047
1048#if !NET20
1049            MemoryStream ms = new MemoryStream();
1050            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Dictionary<string, object>));
1051            serializer.WriteObject(ms, testDictionary);
1052
1053            byte[] data = ms.ToArray();
1054            string output = Encoding.UTF8.GetString(data, 0, data.Length);
1055#endif
1056
1057            Dictionary<string, object> deserializedDictionary = (Dictionary<string, object>)JsonConvert.DeserializeObject(jsonText, typeof(Dictionary<string, object>));
1058            DateTime deserializedDate = (DateTime)deserializedDictionary["date"];
1059
1060            Assert.AreEqual(dateValue, deserializedDate);
1061        }
1062
1063        [Test]
1064        public void TestMethodExecutorObject()
1065        {
1066            MethodExecutorObject executorObject = new MethodExecutorObject();
1067            executorObject.serverClassName = "BanSubs";
1068            executorObject.serverMethodParams = new object[] { "21321546", "101", "1236", "D:\\1.txt" };
1069            executorObject.clientGetResultFunction = "ClientBanSubsCB";
1070
1071            string output = JsonConvert.SerializeObject(executorObject);
1072
1073            MethodExecutorObject executorObject2 = JsonConvert.DeserializeObject(output, typeof(MethodExecutorObject)) as MethodExecutorObject;
1074
1075            Assert.AreNotSame(executorObject, executorObject2);
1076            Assert.AreEqual(executorObject2.serverClassName, "BanSubs");
1077            Assert.AreEqual(executorObject2.serverMethodParams.Length, 4);
1078            CustomAssert.Contains(executorObject2.serverMethodParams, "101");
1079            Assert.AreEqual(executorObject2.clientGetResultFunction, "ClientBanSubsCB");
1080        }
1081
1082#if !NETFX_CORE
1083        [Test]
1084        public void HashtableDeserialization()
1085        {
1086            string value = @"{""Name"":""Orange"", ""Price"":3.99, ""ExpiryDate"":""01/24/2010 12:00:00""}";
1087
1088            Hashtable p = JsonConvert.DeserializeObject(value, typeof(Hashtable)) as Hashtable;
1089
1090            Assert.AreEqual("Orange", p["Name"].ToString());
1091        }
1092
1093        [Test]
1094        public void TypedHashtableDeserialization()
1095        {
1096            string value = @"{""Name"":""Orange"", ""Hash"":{""ExpiryDate"":""01/24/2010 12:00:00"",""UntypedArray"":[""01/24/2010 12:00:00""]}}";
1097
1098            TypedSubHashtable p = JsonConvert.DeserializeObject(value, typeof(TypedSubHashtable)) as TypedSubHashtable;
1099
1100            Assert.AreEqual("01/24/2010 12:00:00", p.Hash["ExpiryDate"].ToString());
1101            Assert.AreEqual(@"[
1102  ""01/24/2010 12:00:00""
1103]", p.Hash["UntypedArray"].ToString());
1104        }
1105#endif
1106
1107        [Test]
1108        public void SerializeDeserializeGetOnlyProperty()
1109        {
1110            string value = JsonConvert.SerializeObject(new GetOnlyPropertyClass());
1111
1112            GetOnlyPropertyClass c = JsonConvert.DeserializeObject<GetOnlyPropertyClass>(value);
1113
1114            Assert.AreEqual(c.Field, "Field");
1115            Assert.AreEqual(c.GetOnlyProperty, "GetOnlyProperty");
1116        }
1117
1118        [Test]
1119        public void SerializeDeserializeSetOnlyProperty()
1120        {
1121            string value = JsonConvert.SerializeObject(new SetOnlyPropertyClass());
1122
1123            SetOnlyPropertyClass c = JsonConvert.DeserializeObject<SetOnlyPropertyClass>(value);
1124
1125            Assert.AreEqual(c.Field, "Field");
1126        }
1127
1128        [Test]
1129        public void JsonIgnoreAttributeTest()
1130        {
1131            string json = JsonConvert.SerializeObject(new JsonIgnoreAttributeTestClass());
1132
1133            Assert.AreEqual(@"{""Field"":0,""Property"":21}", json);
1134
1135            JsonIgnoreAttributeTestClass c = JsonConvert.DeserializeObject<JsonIgnoreAttributeTestClass>(@"{""Field"":99,""Property"":-1,""IgnoredField"":-1,""IgnoredObject"":[1,2,3,4,5]}");
1136
1137            Assert.AreEqual(0, c.IgnoredField);
1138            Assert.AreEqual(99, c.Field);
1139        }
1140
1141        [Test]
1142        public void GoogleSearchAPI()
1143        {
1144            string json = @"{
1145    results:
1146        [
1147            {
1148                GsearchResultClass:""GwebSearch"",
1149                unescapedUrl : ""http://www.google.com/"",
1150                url : ""http://www.google.com/"",
1151                visibleUrl : ""www.google.com"",
1152                cacheUrl : 
1153""http://www.google.com/search?q=cache:zhool8dxBV4J:www.google.com"",
1154                title : ""Google"",
1155                titleNoFormatting : ""Google"",
1156                content : ""Enables users to search the Web, Usenet, and 
1157images. Features include PageRank,   caching and translation of 
1158results, and an option to find similar pages.""
1159            },
1160            {
1161                GsearchResultClass:""GwebSearch"",
1162                unescapedUrl : ""http://news.google.com/"",
1163                url : ""http://news.google.com/"",
1164                visibleUrl : ""news.google.com"",
1165                cacheUrl : 
1166""http://www.google.com/search?q=cache:Va_XShOz_twJ:news.google.com"",
1167                title : ""Google News"",
1168                titleNoFormatting : ""Google News"",
1169                content : ""Aggregated headlines and a search engine of many of the world's news sources.""
1170            },
1171            
1172            {
1173                GsearchResultClass:""GwebSearch"",
1174                unescapedUrl : ""http://groups.google.com/"",
1175                url : ""http://groups.google.com/"",
1176                visibleUrl : ""groups.google.com"",
1177                cacheUrl : 
1178""http://www.google.com/search?q=cache:x2uPD3hfkn0J:groups.google.com"",
1179                title : ""Google Groups"",
1180                titleNoFormatting : ""Google Groups"",
1181                content : ""Enables users to search and browse the Usenet 
1182archives which consist of over 700   million messages, and post new 
1183comments.""
1184            },
1185            
1186            {
1187                GsearchResultClass:""GwebSearch"",
1188                unescapedUrl : ""http://maps.google.com/"",
1189                url : ""http://maps.google.com/"",
1190                visibleUrl : ""maps.google.com"",
1191                cacheUrl : 
1192""http://www.google.com/search?q=cache:dkf5u2twBXIJ:maps.google.com"",
1193                title : ""Google Maps"",
1194                titleNoFormatting : ""Google Maps"",
1195                content : ""Provides directions, interactive maps, and 
1196satellite/aerial imagery of the United   States. Can also search by 
1197keyword such as type of business.""
1198            }
1199        ],
1200        
1201    adResults:
1202        [
1203            {
1204                GsearchResultClass:""GwebSearch.ad"",
1205                title : ""Gartner Symposium/ITxpo"",
1206                content1 : ""Meet brilliant Gartner IT analysts"",
1207                content2 : ""20-23 May 2007- Barcelona, Spain"",
1208                url : 
1209""http://www.google.com/url?sa=L&ai=BVualExYGRo3hD5ianAPJvejjD8-s6ye7kdTwArbI4gTAlrECEAEYASDXtMMFOAFQubWAjvr_____AWDXw_4EiAEBmAEAyAEBgAIB&num=1&q=http://www.gartner.com/it/sym/2007/spr8/spr8.jsp%3Fsrc%3D_spain_07_%26WT.srch%3D1&usg=__CxRH06E4Xvm9Muq13S4MgMtnziY="", 
1210
1211                impressionUrl : 
1212""http://www.google.com/uds/css/ad-indicator-on.gif?ai=BVualExYGRo3hD5ianAPJvejjD8-s6ye7kdTwArbI4gTAlrECEAEYASDXtMMFOAFQubWAjvr_____AWDXw_4EiAEBmAEAyAEBgAIB"", 
1213
1214                unescapedUrl : 
1215""http://www.google.com/url?sa=L&ai=BVualExYGRo3hD5ianAPJvejjD8-s6ye7kdTwArbI4gTAlrECEAEYASDXtMMFOAFQubWAjvr_____AWDXw_4EiAEBmAEAyAEBgAIB&num=1&q=http://www.gartner.com/it/sym/2007/spr8/spr8.jsp%3Fsrc%3D_spain_07_%26WT.srch%3D1&usg=__CxRH06E4Xvm9Muq13S4MgMtnziY="", 
1216
1217                visibleUrl : ""www.gartner.com""
1218            }
1219        ]
1220}
1221";
1222            object o = JsonConvert.DeserializeObject(json);
1223            string s = string.Empty;
1224            s += s;
1225        }
1226
1227        [Test]
1228        public void TorrentDeserializeTest()
1229        {
1230            string jsonText = @"{
1231"""":"""",
1232""label"": [
1233       [""SomeName"",6]
1234],
1235""torrents"": [
1236       [""192D99A5C943555CB7F00A852821CF6D6DB3008A"",201,""filename.avi"",178311826,1000,178311826,72815250,408,1603,7,121430,""NameOfLabelPrevioslyDefined"",3,6,0,8,128954,-1,0],
1237],
1238""torrentc"": ""1816000723""
1239}";
1240
1241            JObject o = (JObject)JsonConvert.DeserializeObject(jsonText);
1242            Assert.AreEqual(4, o.Children().Count());
1243
1244            JToken torrentsArray = (JToken)o["torrents"];
1245            JToken nestedTorrentsArray = (JToken)torrentsArray[0];
1246            Assert.AreEqual(nestedTorrentsArray.Children().Count(), 19);
1247        }
1248
1249        [Test]
1250        public void JsonPropertyClassSerialize()
1251        {
1252            JsonPropertyClass test = new JsonPropertyClass();
1253            test.Pie = "Delicious";
1254            test.SweetCakesCount = int.MaxValue;
1255
1256            string jsonText = JsonConvert.SerializeObject(test);
1257
1258            Assert.AreEqual(@"{""pie"":""Delicious"",""pie1"":""PieChart!"",""sweet_cakes_count"":2147483647}", jsonText);
1259
1260            JsonPropertyClass test2 = JsonConvert.DeserializeObject<JsonPropertyClass>(jsonText);
1261
1262            Assert.AreEqual(test.Pie, test2.Pie);
1263            Assert.AreEqual(test.SweetCakesCount, test2.SweetCakesCount);
1264        }
1265
1266        [Test]
1267        public void BadJsonPropertyClassSerialize()
1268        {
1269            ExceptionAssert.Throws<JsonSerializationException>(
1270                @"A member with the name 'pie' already exists on 'Newtonsoft.Json.Tests.TestObjects.BadJsonPropertyClass'. Use the JsonPropertyAttribute to specify another name.",
1271                () => { JsonConvert.SerializeObject(new BadJsonPropertyClass()); });
1272        }
1273#if !NET20
1274        [Test]
1275        public void Unicode()
1276        {
1277            string json = @"[""PRE\u003cPOST""]";
1278
1279            DataContractJsonSerializer s = new DataContractJsonSerializer(typeof(List<string>));
1280            List<string> dataContractResult = (List<string>)s.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(json)));
1281
1282            List<string> jsonNetResult = JsonConvert.DeserializeObject<List<string>>(json);
1283
1284            Assert.AreEqual(1, jsonNetResult.Count);
1285            Assert.AreEqual(dataContractResult[0], jsonNetResult[0]);
1286        }
1287
1288        [Test]
1289        public void BackslashEqivilence()
1290        {
1291            string json = @"[""vvv\/vvv\tvvv\""vvv\bvvv\nvvv\rvvv\\vvv\fvvv""]";
1292
1293#if !NETFX_CORE
1294            JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
1295            List<string> javaScriptSerializerResult = javaScriptSerializer.Deserialize<List<string>>(json);
1296#endif
1297
1298            DataContractJsonSerializer s = new DataContractJsonSerializer(typeof(List<string>));
1299            List<string> dataContractResult = (List<string>)s.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(json)));
1300
1301            List<string> jsonNetResult = JsonConvert.DeserializeObject<List<string>>(json);
1302
1303            Assert.AreEqual(1, jsonNetResult.Count);
1304            Assert.AreEqual(dataContractResult[0], jsonNetResult[0]);
1305#if !NETFX_CORE
1306            Assert.AreEqual(javaScriptSerializerResult[0], jsonNetResult[0]);
1307#endif
1308        }
1309
1310        [Test]
1311        public void InvalidBackslash()
1312        {
1313            string json = @"[""vvv\jvvv""]";
1314
1315            ExceptionAssert.Throws<JsonReaderException>(
1316                @"Bad JSON escape sequence: \j. Path '', line 1, position 7.",
1317                () => { JsonConvert.DeserializeObject<List<string>>(json); });
1318        }
1319
1320        [Test]
1321        public void DateTimeTest()
1322        {
1323            List<DateTime> testDates = new List<DateTime>
1324            {
1325                new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Local),
1326                new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Unspecified),
1327                new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Utc),
1328                new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Local),
1329                new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Unspecified),
1330                new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc),
1331            };
1332
1333            MemoryStream ms = new MemoryStream();
1334            DataContractJsonSerializer s = new DataContractJsonSerializer(typeof(List<DateTime>));
1335            s.WriteObject(ms, testDates);
1336            ms.Seek(0, SeekOrigin.Begin);
1337            StreamReader sr = new StreamReader(ms);
1338
1339            string expected = sr.ReadToEnd();
1340
1341            string result = JsonConvert.SerializeObject(testDates, new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.MicrosoftDateFormat });
1342            Assert.AreEqual(expected, result);
1343        }
1344
1345        [Test]
1346        public void DateTimeOffsetIso()
1347        {
1348            List<DateTimeOffset> testDates = new List<DateTimeOffset>
1349            {
1350                new DateTimeOffset(new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Utc)),
1351                new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero),
1352                new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(13)),
1353                new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(-3.5)),
1354            };
1355
1356            string result = JsonConvert.SerializeObject(testDates);
1357            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);
1358        }
1359
1360        [Test]
1361        public void DateTimeOffsetMsAjax()
1362        {
1363            List<DateTimeOffset> testDates = new List<DateTimeOffset>
1364            {
1365                new DateTimeOffset(new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Utc)),
1366                new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero),
1367                new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(13)),
1368                new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(-3.5)),
1369            };
1370
1371            string result = JsonConvert.SerializeObject(testDates, new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.MicrosoftDateFormat });
1372            Assert.AreEqual(@"[""\/Date(-59011455539000+0000)\/"",""\/Date(946688461000+0000)\/"",""\/Date(946641661000+1300)\/"",""\/Date(946701061000-0330)\/""]", result);
1373        }
1374#endif
1375
1376        [Test]
1377        public void NonStringKeyDictionary()
1378        {
1379            Dictionary<int, int> values = new Dictionary<int, int>();
1380            values.Add(-5, 6);
1381            values.Add(int.MinValue, int.MaxValue);
1382
1383            string json = JsonConvert.SerializeObject(values);
1384
1385            Assert.AreEqual(@"{""-5"":6,""-2147483648"":2147483647}", json);
1386
1387            Dictionary<int, int> newValues = JsonConvert.DeserializeObject<Dictionary<int, int>>(json);
1388
1389            CollectionAssert.AreEqual(values, newValues);
1390        }
1391
1392        [Test]
1393        public void AnonymousObjectSerialization()
1394        {
1395            var anonymous =
1396                new
1397                {
1398                    StringValue = "I am a string",
1399                    IntValue = int.MaxValue,
1400                    NestedAnonymous = new { NestedValue = byte.MaxValue },
1401                    NestedArray = new[] { 1, 2 },
1402                    Product = new Product() { Name = "TestProduct" }
1403                };
1404
1405            string json = JsonConvert.SerializeObject(anonymous);
1406            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);
1407
1408            anonymous = JsonConvert.DeserializeAnonymousType(json, anonymous);
1409            Assert.AreEqual("I am a string", anonymous.StringValue);
1410            Assert.AreEqual(int.MaxValue, anonymous.IntValue);
1411            Assert.AreEqual(255, anonymous.NestedAnonymous.NestedValue);
1412            Assert.AreEqual(2, anonymous.NestedArray.Length);
1413            Assert.AreEqual(1, anonymous.NestedArray[0]);
1414            Assert.AreEqual(2, anonymous.NestedArray[1]);
1415            Assert.AreEqual("TestProduct", anonymous.Product.Name);
1416        }
1417
1418        [Test]
1419        public void AnonymousObjectSerializationWithSetting()
1420        {
1421            DateTime d = new DateTime(2000, 1, 1);
1422
1423            var anonymous =
1424                new
1425                {
1426                    DateValue = d
1427                };
1428
1429            JsonSerializerSettings settings = new JsonSerializerSettings();
1430            settings.Converters.Add(new IsoDateTimeConverter
1431            {
1432                DateTimeFormat = "yyyy"
1433            });
1434
1435            string json = JsonConvert.SerializeObject(anonymous, settings);
1436            Assert.AreEqual(@"{""DateValue"":""2000""}", json);
1437
1438            anonymous = JsonConvert.DeserializeAnonymousType(json, anonymous, settings);
1439            Assert.AreEqual(d, anonymous.DateValue);
1440        }
1441
1442        [Test]
1443        public void SerializeObject()
1444        {
1445            string json = JsonConvert.SerializeObject(new object());
1446            Assert.AreEqual("{}", json);
1447        }
1448
1449        [Test]
1450        public void SerializeNull()
1451        {
1452            string json = JsonConvert.SerializeObject(null);
1453            Assert.AreEqual("null", json);
1454        }
1455
1456        [Test]
1457        public void CanDeserializeIntArrayWhenNotFirstPropertyInJson()
1458        {
1459            string json = "{foo:'hello',bar:[1,2,3]}";
1460            ClassWithArray wibble = JsonConvert.DeserializeObject<ClassWithArray>(json);
1461            Assert.AreEqual("hello", wibble.Foo);
1462
1463            Assert.AreEqual(4, wibble.Bar.Count);
1464            Assert.AreEqual(int.MaxValue, wibble.Bar[0]);
1465            Assert.AreEqual(1, wibble.Bar[1]);
1466            Assert.AreEqual(2, wibble.Bar[2]);
1467            Assert.AreEqual(3, wibble.Bar[3]);
1468        }
1469
1470        [Test]
1471        public void CanDeserializeIntArray_WhenArrayIsFirstPropertyInJson()
1472        {
1473            string json = "{bar:[1,2,3], foo:'hello'}";
1474            ClassWithArray wibble = JsonConvert.DeserializeObject<ClassWithArray>(json);
1475            Assert.AreEqual("hello", wibble.Foo);
1476
1477            Assert.AreEqual(4, wibble.Bar.Count);
1478            Assert.AreEqual(int.MaxValue, wibble.Bar[0]);
1479            Assert.AreEqual(1, wibble.Bar[1]);
1480            Assert.AreEqual(2, wibble.Bar[2]);
1481            Assert.AreEqual(3, wibble.Bar[3]);
1482        }
1483
1484        [Test]
1485        public void ObjectCreationHandlingReplace()
1486        {
1487            string json = "{bar:[1,2,3], foo:'hello'}";
1488
1489            JsonSerializer s = new JsonSerializer();
1490            s.ObjectCreationHandling = ObjectCreationHandling.Replace;
1491
1492            ClassWithArray wibble = (ClassWithArray)s.Deserialize(new StringReader(json), typeof(ClassWithArray));
1493
1494            Assert.AreEqual("hello", wibble.Foo);
1495
1496            Assert.AreEqual(1, wibble.Bar.Count);
1497        }
1498
1499        [Test]
1500        public void CanDeserializeSerializedJson()
1501        {
1502            ClassWithArray wibble = new ClassWithArray();
1503            wibble.Foo = "hello";
1504            wibble.Bar.Add(1);
1505            wibble.Bar.Add(2);
1506            wibble.Bar.Add(3);
1507            string json = JsonConvert.SerializeObject(wibble);
1508
1509            ClassWithArray wibbleOut = JsonConvert.DeserializeObject<ClassWithArray>(json);
1510            Assert.AreEqual("hello", wibbleOut.Foo);
1511
1512            Assert.AreEqual(5, wibbleOut.Bar.Count);
1513            Assert.AreEqual(int.MaxValue, wibbleOut.Bar[0]);
1514            Assert.AreEqual(int.MaxValue, wibbleOut.Bar[1]);
1515            Assert.AreEqual(1, wibbleOut.Bar[2]);
1516            Assert.AreEqual(2, wibbleOut.Bar[3]);
1517            Assert.AreEqual(3, wibbleOut.Bar[4]);
1518        }
1519
1520        [Test]
1521        public void SerializeConverableObjects()
1522        {
1523            string json = JsonConvert.SerializeObject(new ConverableMembers(), Formatting.Indented);
1524
1525            string expected = null;
1526#if !(NETFX_CORE || PORTABLE)
1527            expected = @"{
1528  ""String"": ""string"",
1529  ""Int32"": 2147483647,
1530  ""UInt32"": 4294967295,
1531  ""Byte"": 255,
1532  ""SByte"": 127,
1533  ""Short"": 32767,
1534  ""UShort"": 65535,
1535  ""Long"": 9223372036854775807,
1536  ""ULong"": 9223372036854775807,
1537  ""Double"": 1.7976931348623157E+308,
1538  ""Float"": 3.40282347E+38,
1539  ""DBNull"": null,
1540  ""Bool"": true,
1541  ""Char"": ""\u0000""
1542}";
1543#else
1544      expected = @"{
1545  ""String"": ""string"",
1546  ""Int32"": 2147483647,
1547  ""UInt32"": 4294967295,
1548  ""Byte"": 255,
1549  ""SByte"": 127,
1550  ""Short"": 32767,
1551  ""UShort"": 65535,
1552  ""Long"": 9223372036854775807,
1553  ""ULong"": 9223372036854775807,
1554  ""Double"": 1.7976931348623157E+308,
1555  ""Float"": 3.40282347E+38,
1556  ""Bool"": true,
1557  ""Char"": ""\u0000""
1558}";
1559#endif
1560
1561            Assert.AreEqual(expected, json);
1562
1563            ConverableMembers c = JsonConvert.DeserializeObject<ConverableMembers>(json);
1564            Assert.AreEqual("string", c.String);
1565            Assert.AreEqual(double.MaxValue, c.Double);
1566#if !(NETFX_CORE || PORTABLE || PORTABLE40)
1567            Assert.AreEqual(DBNull.Value, c.DBNull);
1568#endif
1569        }
1570
1571        [Test]
1572        public void SerializeStack()
1573        {
1574            Stack<object> s = new Stack<object>();
1575            s.Push(1);
1576            s.Push(2);
1577            s.Push(3);
1578
1579            string json = JsonConvert.SerializeObject(s);
1580            Assert.AreEqual("[3,2,1]", json);
1581        }
1582
1583        [Test]
1584        public void FormattingOverride()
1585        {
1586            var obj = new { Formatting = "test" };
1587
1588            JsonSerializerSettings settings = new JsonSerializerSettings { Formatting = Formatting.Indented };
1589            string indented = JsonConvert.SerializeObject(obj, settings);
1590
1591            string none = JsonConvert.SerializeObject(obj, Formatting.None, settings);
1592            Assert.AreNotEqual(indented, none);
1593        }
1594
1595        [Test]
1596        public void DateTimeTimeZone()
1597        {
1598            var date = new DateTime(2001, 4, 4, 0, 0, 0, DateTimeKind.Utc);
1599
1600            string json = JsonConvert.SerializeObject(date);
1601            Assert.AreEqual(@"""2001-04-04T00:00:00Z""", json);
1602        }
1603
1604        [Test]
1605        public void GuidTest()
1606        {
1607            Guid guid = new Guid("BED7F4EA-1A96-11d2-8F08-00A0C9A6186D");
1608
1609            string json = JsonConvert.SerializeObject(new ClassWithGuid { GuidField = guid });
1610            Assert.AreEqual(@"{""GuidField"":""bed7f4ea-1a96-11d2-8f08-00a0c9a6186d""}", json);
1611
1612            ClassWithGuid c = JsonConvert.DeserializeObject<ClassWithGuid>(json);
1613            Assert.AreEqual(guid, c.GuidField);
1614        }
1615
1616        [Test]
1617        public void EnumTest()
1618        {
1619            string json = JsonConvert.SerializeObject(StringComparison.CurrentCultureIgnoreCase);
1620            Assert.AreEqual(@"1", json);
1621
1622            StringComparison s = JsonConvert.DeserializeObject<StringComparison>(json);
1623            Assert.AreEqual(StringComparison.CurrentCultureIgnoreCase, s);
1624        }
1625
1626        public class ClassWithTimeSpan
1627        {
1628            public TimeSpan TimeSpanField;
1629        }
1630
1631        [Test]
1632        public void TimeSpanTest()
1633        {
1634            TimeSpan ts = new TimeSpan(00, 23, 59, 1);
1635
1636            string json = JsonConvert.SerializeObject(new ClassWithTimeSpan { TimeSpanField = ts }, Formatting.Indented);
1637            Assert.AreEqual(@"{
1638  ""TimeSpanField"": ""23:59:01""
1639}", json);
1640
1641            ClassWithTimeSpan c = JsonConvert.DeserializeObject<ClassWithTimeSpan>(json);
1642            Assert.AreEqual(ts, c.TimeSpanField);
1643        }
1644
1645        [Test]
1646        public void JsonIgnoreAttributeOnClassTest()
1647        {
1648            string json = JsonConvert.SerializeObject(new JsonIgnoreAttributeOnClassTestClass());
1649
1650            Assert.AreEqual(@"{""TheField"":0,""Property"":21}", json);
1651
1652            JsonIgnoreAttributeOnClassTestClass c = JsonConvert.DeserializeObject<JsonIgnoreAttributeOnClassTestClass>(@"{""TheField"":99,""Property"":-1,""IgnoredField"":-1}");
1653
1654            Assert.AreEqual(0, c.IgnoredField);
1655            Assert.AreEqual(99, c.Field);
1656        }
1657
1658        [Test]
1659        public void ConstructorCaseSensitivity()
1660        {
1661            ConstructorCaseSensitivityClass c = new ConstructorCaseSensitivityClass("param1", "Param1", "Param2");
1662
1663            string json = JsonConvert.SerializeObject(c);
1664
1665            ConstructorCaseSensitivityClass deserialized = JsonConvert.DeserializeObject<ConstructorCaseSensitivityClass>(json);
1666
1667            Assert.AreEqual("param1", deserialized.param1);
1668            Assert.AreEqual("Param1", deserialized.Param1);
1669            Assert.AreEqual("Param2", deserialized.Param2);
1670        }
1671
1672        [Test]
1673        public void SerializerShouldUseClassConverter()
1674        {
1675            ConverterPrecedenceClass c1 = new ConverterPrecedenceClass("!Test!");
1676
1677            string json = JsonConvert.SerializeObject(c1);
1678            Assert.AreEqual(@"[""Class"",""!Test!""]", json);
1679
1680            ConverterPrecedenceClass c2 = JsonConvert.DeserializeObject<ConverterPrecedenceClass>(json);
1681
1682            Assert.AreEqual("!Test!", c2.TestValue);
1683        }
1684
1685        [Test]
1686        public void SerializerShouldUseClassConverterOverArgumentConverter()
1687        {
1688            ConverterPrecedenceClass c1 = new ConverterPrecedenceClass("!Test!");
1689
1690            string json = JsonConvert.SerializeObject(c1, new ArgumentConverterPrecedenceClassConverter());
1691            Assert.AreEqual(@"[""Class"",""!Test!""]", json);
1692
1693            ConverterPrecedenceClass c2 = JsonConvert.DeserializeObject<ConverterPrecedenceClass>(json, new ArgumentConverterPrecedenceClassConverter());
1694
1695            Assert.AreEqual("!Test!", c2.TestValue);
1696        }
1697
1698        [Test]
1699        public void SerializerShouldUseMemberConverter_IsoDate()
1700        {
1701            DateTime testDate = new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc);
1702            MemberConverterClass m1 = new MemberConverterClass { DefaultConverter = testDate, MemberConverter = testDate };
1703
1704            string json = JsonConvert.SerializeObject(m1);
1705            Assert.AreEqual(@"{""DefaultConverter"":""1970-01-01T00:00:00Z"",""MemberConverter"":""1970-01-01T00:00:00Z""}", json);
1706
1707            MemberConverterClass m2 = JsonConvert.DeserializeObject<MemberConverterClass>(json);
1708
1709            Assert.AreEqual(testDate, m2.DefaultConverter);
1710            Assert.AreEqual(testDate, m2.MemberConverter);
1711        }
1712
1713        [Test]
1714        public void SerializerShouldUseMemberConverter_MsDate()
1715        {
1716            DateTime testDate = new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc);
1717            MemberConverterClass m1 = new MemberConverterClass { DefaultConverter = testDate, MemberConverter = testDate };
1718
1719            string json = JsonConvert.SerializeObject(m1, new JsonSerializerSettings
1720            {
1721                DateFormatHandling = DateFormatHandling.MicrosoftDateFormat
1722            });
1723            Assert.AreEqual(@"{""DefaultConverter"":""\/Date(0)\/"",""MemberConverter"":""1970-01-01T00:00:00Z""}", json);
1724
1725            MemberConverterClass m2 = JsonConvert.DeserializeObject<MemberConverterClass>(json);
1726
1727            Assert.AreEqual(testDate, m2.DefaultConverter);
1728            Assert.AreEqual(testDate, m2.MemberConverter);
1729        }
1730
1731        [Test]
1732        public void SerializerShouldUseMemberConverter_MsDate_DateParseNone()
1733        {
1734            DateTime testDate = new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc);
1735            MemberConverterClass m1 = new MemberConverterClass { DefaultConverter = testDate, MemberConverter = testDate };
1736
1737            string json = JsonConvert.SerializeObject(m1, new JsonSerializerSettings
1738            {
1739                DateFormatHandling = DateFormatHandling.MicrosoftDateFormat,
1740            });
1741            Assert.AreEqual(@"{""DefaultConverter"":""\/Date(0)\/"",""MemberConverter"":""1970-01-01T00:00:00Z""}", json);
1742
1743            var m2 = JsonConvert.DeserializeObject<MemberConverterClass>(json, new JsonSerializerSettings
1744            {
1745                DateParseHandling = DateParseHandling.None
1746            });
1747
1748            Assert.AreEqual(new DateTime(1970, 1, 1), m2.DefaultConverter);
1749            Assert.AreEqual(new DateTime(1970, 1, 1), m2.MemberConverter);
1750        }
1751
1752        [Test]
1753        public void SerializerShouldUseMemberConverter_IsoDate_DateParseNone()
1754        {
1755            DateTime testDate = new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc);
1756            MemberConverterClass m1 = new MemberConverterClass { DefaultConverter = testDate, MemberConverter = testDate };
1757
1758            string json = JsonConvert.SerializeObject(m1, new JsonSerializerSettings
1759            {
1760                DateFormatHandling = DateFormatHandling.IsoDateFormat,
1761            });
1762            Assert.AreEqual(@"{""DefaultConverter"":""1970-01-01T00:00:00Z"",""MemberConverter"":""1970-01-01T00:00:00Z""}", json);
1763
1764            MemberConverterClass m2 = JsonConvert.DeserializeObject<MemberConverterClass>(json);
1765
1766            Assert.AreEqual(testDate, m2.DefaultConverter);
1767            Assert.AreEqual(testDate, m2.MemberConverter);
1768        }
1769
1770        [Test]
1771        public void SerializerShouldUseMemberConverterOverArgumentConverter()
1772        {
1773            DateTime testDate = new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc);
1774            MemberConverterClass m1 = new MemberConverterClass { DefaultConverter = testDate, MemberConverter = testDate };
1775
1776            string json = JsonConvert.SerializeObject(m1, new JavaScriptDateTimeConverter());
1777            Assert.AreEqual(@"{""DefaultConverter"":new Date(0),""MemberConverter"":""1970-01-01T00:00:00Z""}", json);
1778
1779            MemberConverterClass m2 = JsonConvert.DeserializeObject<MemberConverterClass>(json, new JavaScriptDateTimeConverter());
1780
1781            Assert.AreEqual(testDate, m2.DefaultConverter);
1782            Assert.AreEqual(testDate, m2.MemberConverter);
1783        }
1784
1785        [Test]
1786        public void ConverterAttributeExample()
1787        {
1788            DateTime date = Convert.ToDateTime("1970-01-01T00:00:00Z").ToUniversalTime();
1789
1790            MemberConverterClass c = new MemberConverterClass
1791            {
1792                DefaultConverter = date,
1793                MemberConverter = date
1794            };
1795
1796            string json = JsonConvert.SerializeObject(c, Formatting.Indented);
1797
1798            Console.WriteLine(json);
1799            //{
1800            //  "DefaultConverter": "\/Date(0)\/",
1801            //  "MemberConverter": "1970-01-01T00:00:00Z"
1802            //}
1803        }
1804
1805        [Test]
1806        public void SerializerShouldUseMemberConverterOverClassAndArgumentConverter()
1807        {
1808            ClassAndMemberConverterClass c1 = new ClassAndMemberConverterClass();
1809            c1.DefaultConverter = new ConverterPrecedenceClass("DefaultConverterValue");
1810            c1.MemberConverter = new ConverterPrecedenceClass("MemberConverterValue");
1811
1812            string json = JsonConvert.SerializeObject(c1, new ArgumentConverterPrecedenceClassConverter());
1813            Assert.AreEqual(@"{""DefaultConverter"":[""Class"",""DefaultConverterValue""],""MemberConverter"":[""Member"",""MemberConverterValue""]}", json);
1814
1815            ClassAndMemberConverterClass c2 = JsonConvert.DeserializeObject<ClassAndMemberConverterClass>(json, new ArgumentConverterPrecedenceClassConverter());
1816
1817            Assert.AreEqual("DefaultConverterValue", c2.DefaultConverter.TestValue);
1818            Assert.AreEqual("MemberConverterValue", c2.MemberConverter.TestValue);
1819        }
1820
1821        [Test]
1822        public void IncompatibleJsonAttributeShouldThrow()
1823        {
1824            ExceptionAssert.Throws<JsonSerializationException>(
1825                "Unexpected value when converting date. Expected DateTime or DateTimeOffset, got Newtonsoft.Json.Tests.TestObjects.IncompatibleJsonAttributeClass.",
1826                () =>
1827                {
1828                    IncompatibleJsonAttributeClass c = new IncompatibleJsonAttributeClass();
1829                    JsonConvert.SerializeObject(c);
1830                });
1831        }
1832
1833        [Test]
1834        public void GenericAbstractProperty()
1835        {
1836            string json = JsonConvert.SerializeObject(new GenericImpl());
1837            Assert.AreEqual(@"{""Id"":0}", json);
1838        }
1839
1840        [Test]
1841        public void DeserializeNullable()
1842        {
1843            string json;
1844
1845            json = JsonConvert.SerializeObject((int?)null);
1846            Assert.AreEqual("null", json);
1847
1848            json = JsonConvert.SerializeObject((int?)1);
1849            Assert.AreEqual("1", json);
1850        }
1851
1852        [Test]
1853        public void SerializeJsonRaw()
1854        {
1855            PersonRaw personRaw = new PersonRaw
1856            {
1857                FirstName = "FirstNameValue",
1858                RawContent = new JRaw("[1,2,3,4,5]"),
1859                LastName = "LastNameValue"
1860            };
1861
1862            string json;
1863
1864            json = JsonConvert.SerializeObject(personRaw);
1865            Assert.AreEqual(@"{""first_name"":""FirstNameValue"",""RawContent"":[1,2,3,4,5],""last_name"":""LastNameValue""}", json);
1866        }
1867
1868        [Test]
1869        public void DeserializeJsonRaw()
1870        {
1871            string json = @"{""first_name"":""FirstNameValue"",""RawContent"":[1,2,3,4,5],""last_name"":""LastNameValue""}";
1872
1873            PersonRaw personRaw = JsonConvert.DeserializeObject<PersonRaw>(json);
1874
1875            Assert.AreEqual("FirstNameValue", personRaw.FirstName);
1876            Assert.AreEqual("[1,2,3,4,5]", personRaw.RawContent.ToString());
1877            Assert.AreEqual("LastNameValue", personRaw.LastName);
1878        }
1879
1880
1881        [Test]
1882        public void DeserializeNullableMember()
1883        {
1884            UserNullable userNullablle = new UserNullable
1885            {
1886                Id = new Guid("AD6205E8-0DF4-465d-AEA6-8BA18E93A7E7"),
1887                FName = "FirstValue",
1888                LName = "LastValue",
1889                RoleId = 5,
1890                NullableRoleId = 6,
1891                NullRoleId = null,
1892                Active = true
1893            };
1894
1895            string json = JsonConvert.SerializeObject(userNullablle);
1896
1897            Assert.AreEqual(@"{""Id"":""ad6205e8-0df4-465d-aea6-8ba18e93a7e7"",""FName"":""FirstValue"",""LName"":""LastValue"",""RoleId"":5,""NullableRoleId"":6,""NullRoleId"":null,""Active"":true}", json);
1898
1899            UserNullable userNullablleDeserialized = JsonConvert.DeserializeObject<UserNullable>(json);
1900
1901            Assert.AreEqual(new Guid("AD6205E8-0DF4-465d-AEA6-8BA18E93A7E7"), userNullablleDeserialized.Id);
1902            Assert.AreEqual("FirstValue", userNullablleDeserialized.FName);
1903            Assert.AreEqual("LastValue", userNullablleDeserialized.LName);
1904            Assert.AreEqual(5, userNullablleDeserialized.RoleId);
1905            Assert.AreEqual(6, userNullablleDeserialized.NullableRoleId);
1906            Assert.AreEqual(null, userNullablleDeserialized.NullRoleId);
1907            Assert.AreEqual(true, userNullablleDeserialized.Active);
1908        }
1909
1910        [Test]
1911        public void DeserializeInt64ToNullableDouble()
1912        {
1913            string json = @"{""Height"":1}";
1914
1915            DoubleClass c = JsonConvert.DeserializeObject<DoubleClass>(json);
1916            Assert.AreEqual(1, c.Height);
1917        }
1918
1919        [Test]
1920        public void SerializeTypeProperty()
1921        {
1922            string boolRef = typeof(bool).AssemblyQualifiedName;
1923            TypeClass typeClass = new TypeClass { TypeProperty = typeof(bool) };
1924
1925            string json = JsonConvert.SerializeObject(typeClass);
1926            Assert.AreEqual(@"{""TypeProperty"":""" + boolRef + @"""}", json);
1927
1928            TypeClass typeClass2 = JsonConvert.DeserializeObject<TypeClass>(json);
1929            Assert.AreEqual(typeof(bool), typeClass2.TypeProperty);
1930
1931            string jsonSerializerTestRef = typeof(JsonSerializerTest).AssemblyQualifiedName;
1932            typeClass = new TypeClass { TypeProperty = typeof(JsonSerializerTest) };
1933
1934            json = JsonConvert.SerializeObject(typeClass);
1935            Assert.AreEqual(@"{""TypeProperty"":""" + jsonSerializerTestRef + @"""}", json);
1936
1937            typeClass2 = JsonConvert.DeserializeObject<TypeClass>(json);
1938            Assert.AreEqual(typeof(JsonSerializerTest), typeClass2.TypeProperty);
1939        }
1940
1941        [Test]
1942        public void RequiredMembersClass()
1943        {
1944            RequiredMembersClass c = new RequiredMembersClass()
1945            {
1946                BirthDate = new DateTime(2000, 12, 20, 10, 55, 55, DateTimeKind.Utc),
1947                FirstName = "Bob",
1948                LastName = "Smith",
1949                MiddleName = "Cosmo"
1950            };
1951
1952            string json = JsonConvert.SerializeObject(c, Formatting.Indented);
1953
1954            Assert.AreEqual(@"{
1955  ""FirstName"": ""Bob"",
1956  ""MiddleName"": ""Cosmo"",
1957  ""LastName"": ""Smith"",
1958  ""BirthDate"": ""2000-12-20T10:55:55Z""
1959}", json);
1960
1961            RequiredMembersClass c2 = JsonConvert.DeserializeObject<RequiredMembersClass>(json);
1962
1963            Assert.AreEqual("Bob", c2.FirstName);
1964            Assert.AreEqual(new DateTime(2000, 12, 20, 10, 55, 55, DateTimeKind.Utc), c2.BirthDate);
1965        }
1966
1967        [Test]
1968        public void DeserializeRequiredMembersClassWithNullValues()
1969        {
1970            string json = @"{
1971  ""FirstName"": ""I can't be null bro!"",
1972  ""MiddleName"": null,
1973  ""LastName"": null,
1974  ""BirthDate"": ""\/Date(977309755000)\/""
1975}";
1976
1977            RequiredMembersClass c = JsonConvert.DeserializeObject<RequiredMembersClass>(json);
1978
1979            Assert.AreEqual("I can't be null bro!", c.FirstName);
1980            Assert.AreEqual(null, c.MiddleName);
1981            Assert.AreEqual(null, c.LastName);
1982        }
1983
1984        [Test]
1985        public void DeserializeRequiredMembersClassNullRequiredValueProperty()
1986        {
1987            try
1988            {
1989                string json = @"{
1990  ""FirstName"": null,
1991  ""MiddleName"": null,
1992  ""LastName"": null,
1993  ""BirthDate"": ""\/Date(977309755000)\/""
1994}";
1995
1996                JsonConvert.DeserializeObject<RequiredMembersClass>(json);
1997                Assert.Fail();
1998            }
1999            catch (JsonSerializationException ex)
2000            {
2001                Assert.IsTrue(ex.Message.StartsWith("Required property 'FirstName' expects a value but got null. Path ''"));
2002            }
2003        }
2004
2005        [Test]
2006        public void SerializeRequiredMembersClassNullRequiredValueProperty()
2007        {
2008            ExceptionAssert.Throws<JsonSerializationException>(
2009                "Cannot write a null value for property 'FirstName'. Property requires a value. Path ''.",
2010                () =>
2011                {
2012                    RequiredMembersClass requiredMembersClass = new RequiredMembersClass
2013                    {
2014                        FirstName = null,
2015                        BirthDate = new DateTime(2000, 10, 10, 10, 10, 10, DateTimeKind.Utc),
2016                        LastName = null,
2017                        MiddleName = null
2018                    };
2019
2020                    string json = JsonConvert.SerializeObject(requiredMembersClass);
2021                    Console.WriteLine(json);
2022                });
2023        }
2024
2025        [Test]
2026        public void RequiredMembersClassMissingRequiredProperty()
2027        {
2028            try
2029            {
2030                string json = @"{
2031  ""FirstName"": ""Bob""
2032}";
2033
2034                JsonConvert.DeserializeObject<RequiredMembersClass>(json);
2035                Assert.Fail();
2036            }
2037            catch (JsonSerializationException ex)
2038            {
2039                Assert.IsTrue(ex.Message.StartsWith("Required property 'LastName' not found in JSON. Path ''"));
2040            }
2041        }
2042
2043        [Test]
2044        public void SerializeJaggedArray()
2045        {
2046            JaggedArray aa = new JaggedArray();
2047            aa.Before = "Before!";
2048            aa.After = "After!";
2049            aa.Coordinates = new[] { new[] { 1, 1 }, new[] { 1, 2 }, new[] { 2, 1 }, new[] { 2, 2 } };
2050
2051            string json = JsonConvert.SerializeObject(aa);
2052
2053            Assert.AreEqual(@"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2],[2,1],[2,2]],""After"":""After!""}", json);
2054        }
2055
2056        [Test]
2057        public void DeserializeJaggedArray()
2058        {
2059            string json = @"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2],[2,1],[2,2]],""After"":""After!""}";
2060
2061            JaggedArray aa = JsonConvert.DeserializeObject<JaggedArray>(json);
2062
2063            Assert.AreEqual("Before!", aa.Before);
2064            Assert.AreEqual("After!", aa.After);
2065            Assert.AreEqual(4, aa.Coordinates.Length);
2066            Assert.AreEqual(2, aa.Coordinates[0].Length);
2067            Assert.AreEqual(1, aa.Coordinates[0][0]);
2068            Assert.AreEqual(2, aa.Coordinates[1][1]);
2069
2070            string after = JsonConvert.SerializeObject(aa);
2071
2072            Assert.AreEqual(json, after);
2073        }
2074
2075        [Test]
2076        public void DeserializeGoogleGeoCode()
2077        {
2078            string json = @"{
2079  ""name"": ""1600 Amphitheatre Parkway, Mountain View, CA, USA"",
2080  ""Status"": {
2081    ""code"": 200,
2082    ""request"": ""geocode""
2083  },
2084  ""Placemark"": [
2085    {
2086      ""address"": ""1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA"",
2087      ""AddressDetails"": {
2088        ""Country"": {
2089          ""CountryNameCode"": ""US"",
2090          ""AdministrativeArea"": {
2091            ""AdministrativeAreaName"": ""CA"",
2092            ""SubAdministrativeArea"": {
2093              ""SubAdministrativeAreaName"": ""Santa Clara"",
2094              ""Locality"": {
2095                ""LocalityName"": ""Mountain View"",
2096                ""Thoroughfare"": {
2097                  ""ThoroughfareName"": ""1600 Amphitheatre Pkwy""
2098                },
2099                ""PostalCode"": {
2100                  ""PostalCodeNumber"": ""94043""
2101                }
2102              }
2103            }
2104          }
2105        },
2106        ""Accuracy"": 8
2107      },
2108      ""Point"": {
2109        ""coordinates"": [-122.083739, 37.423021, 0]
2110      }
2111    }
2112  ]
2113}";
2114
2115            GoogleMapGeocoderStructure jsonGoogleMapGeocoder = JsonConvert.DeserializeObject<GoogleMapGeocoderStructure>(json);
2116        }
2117
2118        [Test]
2119        public void DeserializeInterfaceProperty()
2120        {
2121            InterfacePropertyTestClass testClass = new InterfacePropertyTestClass();
2122            testClass.co = new Co();
2123            String strFromTest = JsonConvert.SerializeObject(testClass);
2124
2125            ExceptionAssert.Throws<JsonSerializationException>(
2126                @"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.",
2127                () => { InterfacePropertyTestClass testFromDe = (InterfacePropertyTestClass)JsonConvert.DeserializeObject(strFromTest, typeof(InterfacePropertyTestClass)); });
2128        }
2129
2130        private Person GetPerson()
2131        {
2132            Person person = new Person
2133            {
2134                Name = "Mike Manager",
2135                BirthDate = new DateTime(1983, 8, 3, 0, 0, 0, DateTimeKind.Utc),
2136                Department = "IT",
2137                LastModified = new DateTime(2009, 2, 15, 0, 0, 0, DateTimeKind.Utc)
2138            };
2139            return person;
2140        }
2141
2142        [Test]
2143        public void WriteJsonDates()
2144        {
2145            LogEntry entry = new LogEntry
2146            {
2147                LogDate = new DateTime(2009, 2, 15, 0, 0, 0, DateTimeKind.Utc),
2148                Details = "Application started."
2149            };
2150
2151            string defaultJson = JsonConvert.SerializeObject(entry);
2152            // {"Details":"Application started.","LogDate":"\/Date(1234656000000)\/"}
2153
2154            string isoJson = JsonConvert.SerializeObject(entry, new IsoDateTimeConverter());
2155            // {"Details":"Application started.","LogDate":"2009-02-15T00:00:00.0000000Z"}
2156
2157            string javascriptJson = JsonConvert.SerializeObject(entry, new JavaScriptDateTimeConverter());
2158            // {"Details":"Application started.","LogDate":new Date(1234656000000)}
2159
2160            Console.WriteLine(defaultJson);
2161            Console.WriteLine(isoJson);
2162            Console.WriteLine(javascriptJson);
2163        }
2164
2165        public void GenericListAndDictionaryInterfaceProperties()
2166        {
2167            GenericListAndDictionaryInterfaceProperties o = new GenericListAndDictionaryInterfaceProperties();
2168            o.IDictionaryProperty = new Dictionary<string, int>
2169            {
2170                { "one", 1 },
2171                { "two", 2 },
2172                { "three", 3 }
2173            };
2174            o.IListProperty = new List<int>
2175            {
2176                1, 2, 3
2177            };
2178            o.IEnumerableProperty = new List<int>
2179            {
2180                4, 5, 6
2181            };
2182
2183            string json = JsonConvert.SerializeObject(o, Formatting.Indented);
2184
2185            Assert.AreEqual(@"{
2186  ""IEnumerableProperty"": [
2187    4,
2188    5,
2189    6
2190  ],
2191  ""IListProperty"": [
2192    1,
2193    2,
2194    3
2195  ],
2196  ""IDictionaryProperty"": {
2197    ""one"": 1,
2198    ""two"": 2,
2199    ""three"": 3
2200  }
2201}", json);
2202
2203            GenericListAndDictionaryInterfaceProperties deserializedObject = JsonConvert.DeserializeObject<GenericListAndDictionaryInterfaceProperties>(json);
2204            Assert.IsNotNull(deserializedObject);
2205
2206            CollectionAssert.AreEqual(o.IListProperty.ToArray(), deserializedObject.IListProperty.ToArray());
2207            CollectionAssert.AreEqual(o.IEnumerableProperty.ToArray(), deserializedObject.IEnumerableProperty.ToArray());
2208            CollectionAssert.AreEqual(o.IDictionaryProperty.ToArray(), deserializedObject.IDictionaryProperty.ToArray());
2209        }
2210
2211        [Test]
2212        public void DeserializeBestMatchPropertyCase()
2213        {
2214            string json = @"{
2215  ""firstName"": ""firstName"",
2216  ""FirstName"": ""FirstName"",
2217  ""LastName"": ""LastName"",
2218  ""lastName"": ""lastName"",
2219}";
2220
2221            PropertyCase o = JsonConvert.DeserializeObject<PropertyCase>(json);
2222            Assert.IsNotNull(o);
2223
2224            Assert.AreEqual("firstName", o.firstName);
2225            Assert.AreEqual("FirstName", o.FirstName);
2226            Assert.AreEqual("LastName", o.LastName);
2227            Assert.AreEqual("lastName", o.lastName);
2228        }
2229
2230        public sealed class ConstructorAndDefaultValueAttributeTestClass
2231        {
2232            public ConstructorAndDefaultValueAttributeTestClass(string testProperty1)
2233            {
2234                TestProperty1 = testProperty1;
2235            }
2236
2237            public string TestProperty1 { get; set; }
2238
2239            [DefaultValue(21)]
2240            public int TestProperty2 { get; set; }
2241        }
2242
2243        [Test]
2244        public void PopulateDefaultValueWhenUsingConstructor()
2245        {
2246            string json = "{ 'testProperty1': 'value' }";
2247
2248            ConstructorAndDefaultValueAttributeTestClass c = JsonConvert.DeserializeObject<ConstructorAndDefaultValueAttributeTestClass>(json, new JsonSerializerSettings
2249            {
2250                DefaultValueHandling = DefaultValueHandling.Populate
2251            });
2252            Assert.AreEqual("value", c.TestProperty1);
2253            Assert.AreEqual(21, c.TestProperty2);
2254
2255            c = JsonConvert.DeserializeObject<ConstructorAndDefaultValueAttributeTestClass>(json, new JsonSerializerSettings
2256            {
2257                DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate
2258            });
2259            Assert.AreEqual("value", c.TestProperty1);
2260            Assert.AreEqual(21, c.TestProperty2);
2261        }
2262
2263        public sealed class ConstructorAndRequiredTestClass
2264        {
2265            public ConstructorAndRequiredTestClass(string testProperty1)
2266            {
2267                TestProperty1 = testProperty1;
2268            }
2269
2270            public string TestProperty1 { get; set; }
2271
2272            [JsonProperty(Required = Required.AllowNull)]
2273            public int TestProperty2 { get; set; }
2274        }
2275
2276        [Test]
2277        public void RequiredWhenUsingConstructor()
2278        {
2279            try
2280            {
2281                string json = "{ 'testProperty1': 'value' }";
2282                JsonConvert.DeserializeObject<ConstructorAndRequiredTestClass>(json);
2283
2284                Assert.Fail();
2285            }
2286            catch (JsonSerializationException ex)
2287            {
2288                Assert.IsTrue(ex.Message.StartsWith("Required property 'TestProperty2' not found in JSON. Path ''"));
2289            }
2290        }
2291
2292        [Test]
2293        public void DeserializePropertiesOnToNonDefaultConstructor()
2294        {
2295            SubKlass i = new SubKlass("my subprop");
2296            i.SuperProp = "overrided superprop";
2297
2298            string json = JsonConvert.SerializeObject(i);
2299            Assert.AreEqual(@"{""SubProp"":""my subprop"",""SuperProp"":""overrided superprop""}", json);
2300
2301            SubKlass ii = JsonConvert.DeserializeObject<SubKlass>(json);
2302
2303            string newJson = JsonConvert.SerializeObject(ii);
2304            Assert.AreEqual(@"{""SubProp"":""my subprop"",""SuperProp"":""overrided superprop""}", newJson);
2305        }
2306
2307        [Test]
2308        public void DeserializePropertiesOnToNonDefaultConstructorWithReferenceTracking()
2309        {
2310            SubKlass i = new SubKlass("my subprop");
2311            i.SuperProp = "overrided superprop";
2312
2313            string json = JsonConvert.SerializeObject(i, new JsonSerializerSettings
2314            {
2315                PreserveReferencesHandling = PreserveReferencesHandling.Objects
2316            });
2317
2318            Assert.AreEqual(@"{""$id"":""1"",""SubProp"":""my subprop"",""SuperProp"":""overrided superprop""}", json);
2319
2320            SubKlass ii = JsonConvert.DeserializeObject<SubKlass>(json, new JsonSerializerSettings
2321            {
2322                PreserveReferencesHandling = PreserveReferencesHandling.Objects
2323            });
2324
2325            string newJson = JsonConvert.SerializeObject(ii, new JsonSerializerSettings
2326            {
2327                PreserveReferencesHandling = PreserveReferencesHandling.Objects
2328            });
2329            Assert.AreEqual(@"{""$id"":""1"",""SubProp"":""my subprop"",""SuperProp"":""overrided superprop""}", newJson);
2330        }
2331
2332        [Test]
2333        public void SerializeJsonPropertyWithHandlingValues()
2334        {
2335            JsonPropertyWithHandlingValues o = new JsonPropertyWithHandlingValues();
2336            o.DefaultValueHandlingIgnoreProperty = "Default!";
2337            o.DefaultValueHandlingIncludeProperty = "Default!";
2338            o.DefaultValueHandlingPopulateProperty = "Default!";
2339            o.DefaultValueHandlingIgnoreAndPopulateProperty = "Default!";
2340
2341            string json = JsonConvert.SerializeObject(o, Formatting.Indented);
2342
2343            Assert.AreEqual(@"{
2344  ""DefaultValueHandlingIncludeProperty"": ""Default!"",
2345  ""DefaultValueHandlingPopulateProperty"": ""Default!"",
2346  ""NullValueHandlingIncludeProperty"": null,
2347  ""ReferenceLoopHandlingErrorProperty"": null,
2348  ""ReferenceLoopHandlingIgnoreProperty"": null,
2349  ""ReferenceLoopHandlingSerializeProperty"": null
2350}", json);
2351
2352            json = JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
2353
2354            Assert.AreEqual(@"{
2355  ""DefaultValueHandlingIncludeProperty"": ""Default!"",
2356  ""DefaultValueHandlingPopulateProperty"": ""Default!"",
2357  ""NullValueHandlingIncludeProperty"": null
2358}", json);
2359        }
2360
2361        [Test]
2362        public void DeserializeJsonPropertyWithHandlingValues()
2363        {
2364            string json = "{}";
2365
2366            JsonPropertyWithHandlingValues o = JsonConvert.DeserializeObject<JsonPropertyWithHandlingValues>(json);
2367            Assert.AreEqual("Default!", o.DefaultValueHandlingIgnoreAndPopulateProperty);
2368            Assert.AreEqual("Default!", o.DefaultValueHandlingPopulateProperty);
2369            Assert.AreEqual(null, o.DefaultValueHandlingIgnoreProperty);
2370            Assert.AreEqual(null, o.DefaultValueHandlingIncludeProperty);
2371        }
2372
2373        [Test]
2374        public void JsonPropertyWithHandlingValues_ReferenceLoopError()
2375        {
2376            string classRef = typeof(JsonPropertyWithHandlingValues).FullName;
2377
2378            ExceptionAssert.Throws<JsonSerializationException>(
2379                "Self referencing loop detected for property 'ReferenceLoopHandlingErrorProperty' with type '" + classRef + "'. Path ''.",
2380                () =>
2381                {
2382                    JsonPropertyWithHandlingValues o = new JsonPropertyWithHandlingValues();
2383                    o.ReferenceLoopHandlingErrorProperty = o;
2384
2385                    JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
2386                });
2387        }
2388
2389        [Test]
2390        public void PartialClassDeserialize()
2391        {
2392            string json = @"{
2393    ""request"": ""ux.settings.update"",
2394    ""sid"": ""14c561bd-32a8-457e-b4e5-4bba0832897f"",
2395    ""uid"": ""30c39065-0f31-de11-9442-001e3786a8ec"",
2396    ""fidOrder"": [
2397        ""id"",
2398        ""andytest_name"",
2399        ""andytest_age"",
2400        ""andytest_address"",
2401        ""andytest_phone"",
2402        ""date"",
2403        ""title"",
2404        ""titleId""
2405    ],
2406    ""entityName"": ""Andy Test"",
2407    ""setting"": ""entity.field.order""
2408}";
2409
2410            RequestOnly r = JsonConvert.DeserializeObject<RequestOnly>(json);
2411            Assert.AreEqual("ux.settings.update", r.Request);
2412
2413            NonRequest n = JsonConvert.DeserializeObject<NonRequest>(json);
2414            Assert.AreEqual(new Guid("14c561bd-32a8-457e-b4e5-4bba0832897f"), n.Sid);
2415            Assert.AreEqual(new Guid("30c39065-0f31-de11-9442-001e3786a8ec"), n.Uid);
2416            Assert.AreEqual(8, n.FidOrder.Count);
2417            Assert.AreEqual("id", n.FidOrder[0]);
2418            Assert.AreEqual("titleId", n.FidOrder[n.FidOrder.Count - 1]);
2419        }
2420
2421#if !(NET20 || NETFX_CORE || PORTABLE || PORTABLE40)
2422        [MetadataType(typeof(OptInClassMetadata))]
2423        public class OptInClass
2424        {
2425            [DataContract]
2426            public class OptInClassMetadata
2427            {
2428                [DataMember]
2429                public string Name { get; set; }
2430
2431                [DataMember]
2432                public int Age { get; set; }
2433
2434                public string NotIncluded { get; set; }
2435            }
2436
2437            public string Name { get; set; }
2438            public int Age { get; set; }
2439            public string NotIncluded { get; set; }
2440        }
2441
2442        [Test]
2443        public void OptInClassMetadataSerialization()
2444        {
2445            OptInClass optInClass = new OptInClass();
2446            optInClass.Age = 26;
2447            optInClass.Name = "James NK";
2448            optInClass.NotIncluded = "Poor me :(";
2449
2450            string json = JsonConvert.SerializeObject(optInClass, Formatting.Indented);
2451
2452            Assert.AreEqual(@"{
2453  ""Name"": ""James NK"",
2454  ""Age"": 26
2455}", json);
2456
2457            OptInClass newOptInClass = JsonConvert.DeserializeObject<OptInClass>(@"{
2458  ""Name"": ""James NK"",
2459  ""NotIncluded"": ""Ignore me!"",
2460  ""Age"": 26
2461}");
2462            Assert.AreEqual(26, newOptInClass.Age);
2463            Assert.AreEqual("James NK", newOptInClass.Name);
2464            Assert.AreEqual(null, newOptInClass.NotIncluded);
2465        }
2466#endif
2467
2468#if !NET20
2469        [DataContract]
2470        public class DataContractPrivateMembers
2471        {
2472            public DataContractPrivateMembers()
2473            {
2474            }
2475
2476            public DataContractPrivateMembers(string name, int age, int rank, string title)
2477            {
2478                _name = name;
2479                Age = age;
2480                Rank = rank;
2481                Title = title;
2482            }
2483
2484            [DataMember]
2485            private string _name;
2486
2487            [DataMember(Name = "_age")]
2488            private int Age { get; set; }
2489
2490            [JsonProperty]
2491            private int Rank { get; set; }
2492
2493            [JsonProperty(PropertyName = "JsonTitle")]
2494            [DataMember(Name = "DataTitle")]
2495            private string Title { get; set; }
2496
2497            public string NotIncluded { get; set; }
2498
2499            public override string ToString()
2500            {
2501                return "_name: " + _name + ", _age: " + Age + ", Rank: " + Rank + ", JsonTitle: " + Title;
2502            }
2503        }
2504
2505        [Test]
2506        public void SerializeDataContractPrivateMembers()
2507        {
2508            DataContractPrivateMembers c = new DataContractPrivateMembers("Jeff", 26, 10, "Dr");
2509            c.NotIncluded = "Hi";
2510            string json = JsonConvert.SerializeObject(c, Formatting.Indented);
2511
2512            Assert.AreEqual(@"{
2513  ""_name"": ""Jeff"",
2514  ""_age"": 26,
2515  ""Rank"": 10,
2516  ""JsonTitle"": ""Dr""
2517}", json);
2518
2519            DataContractPrivateMembers cc = JsonConvert.DeserializeObject<DataContractPrivateMembers>(json);
2520            Assert.AreEqual("_name: Jeff, _age: 26, Rank: 10, JsonTitle: Dr", cc.ToString());
2521        }
2522#endif
2523
2524        [Test]
2525        public void DeserializeDictionaryInterface()
2526        {
2527            string json = @"{
2528  ""Name"": ""Name!"",
2529  ""Dictionary"": {
2530    ""Item"": 11
2531  }
2532}";
2533
2534            DictionaryInterfaceClass c = JsonConvert.DeserializeObject<DictionaryInterfaceClass>(
2535                json,
2536                new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Replace });
2537
2538            Assert.AreEqual("Name!", c.Name);
2539            Assert.AreEqual(1, c.Dictionary.Count);
2540            Assert.AreEqual(11, c.Dictionary["Item"]);
2541        }
2542
2543        [Test]
2544        public void DeserializeDictionaryInterfaceWithExistingValues()
2545        {
2546            string json = @"{
2547  ""Random"": {
2548    ""blah"": 1
2549  },
2550  ""Name"": ""Name!"",
2551  ""Dictionary"": {
2552    ""Item"": 11,
2553    ""Item1"": 12
2554  },
2555  ""Collection"": [
2556    999
2557  ],
2558  ""Employee"": {
2559    ""Manager"": {
2560      ""Name"": ""ManagerName!""
2561    }
2562  }
2563}";
2564
2565            DictionaryInterfaceClass c = JsonConvert.DeserializeObject<DictionaryInterfaceClass>(json,
2566                new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Reuse });
2567
2568            Assert.AreEqual("Name!", c.Name);
2569            Assert.AreEqual(3, c.Dictionary.Count);
2570            Assert.AreEqual(11, c.Dictionary["Item"]);
2571            Assert.AreEqual(1, c.Dictionary["existing"]);
2572            Assert.AreEqual(4, c.Collection.Count);
2573            Assert.AreEqual(1, c.Collection.ElementAt(0));
2574            Assert.AreEqual(999, c.Collection.ElementAt(3));
2575            Assert.AreEqual("EmployeeName!", c.Employee.Name);
2576            Assert.AreEqual("ManagerName!", c.Employee.Manager.Name);
2577            Assert.IsNotNull(c.Random);
2578        }
2579
2580        [Test]
2581        public void TypedObjectDeserializationWithComments()
2582        {
2583            string json = @"/*comment1*/ { /*comment2*/
2584        ""Name"": /*comment3*/ ""Apple"" /*comment4*/, /*comment5*/
2585        ""ExpiryDate"": ""\/Date(1230422400000)\/"",
2586        ""Price"": 3.99,
2587        ""Sizes"": /*comment6*/ [ /*comment7*/
2588          ""Small"", /*comment8*/
2589          ""Medium"" /*comment9*/,
2590          /*comment10*/ ""Large""
2591        /*comment11*/ ] /*comment12*/
2592      } /*comment13*/";
2593
2594            Product deserializedProduct = (Product)JsonConvert.DeserializeObject(json, typeof(Product));
2595
2596            Assert.AreEqual("Apple", deserializedProduct.Name);
2597            Assert.AreEqual(new DateTime(2008, 12, 28, 0, 0, 0, DateTimeKind.Utc), deserializedProduct.ExpiryDate);
2598            Assert.AreEqual(3.99m, deserializedProduct.Price);
2599            Assert.AreEqual("Small", deserializedProduct.Sizes[0]);
2600            Assert.AreEqual("Medium", deserializedProduct.Sizes[1]);
2601            Assert.AreEqual("Large", deserializedProduct.Sizes[2]);
2602        }
2603
2604        [Test]
2605        public void NestedInsideOuterObject()
2606        {
2607            string json = @"{
2608  ""short"": {
2609    ""original"": ""http://www.contrast.ie/blog/online&#45;marketing&#45;2009/"",
2610    ""short"": ""m2sqc6"",
2611    ""shortened"": ""http://short.ie/m2sqc6"",
2612    ""error"": {
2613      ""code"": 0,
2614      ""msg"": ""No action taken""
2615    }
2616  }
2617}";
2618
2619            JObject o = JObject.Parse(json);
2620
2621            Shortie s = JsonConvert.DeserializeObject<Shortie>(o["short"].ToString());
2622            Assert.IsNotNull(s);
2623
2624            Assert.AreEqual(s.Original, "http://www.contrast.ie/blog/online&#45;marketing&#45;2009/");
2625            Assert.AreEqual(s.Short, "m2sqc6");
2626            Assert.AreEqual(s.Shortened, "http://short.ie/m2sqc6");
2627        }
2628
2629        [Test]
2630        public void UriSerialization()
2631        {
2632            Uri uri = new Uri("http://codeplex.com");
2633            string json = JsonConvert.SerializeObject(uri);
2634
2635            Assert.AreEqual("http://codeplex.com/", uri.ToString());
2636
2637            Uri newUri = JsonConvert.DeserializeObject<Uri>(json);
2638            Assert.AreEqual(uri, newUri);
2639        }
2640
2641        [Test]
2642        public void AnonymousPlusLinqToSql()
2643        {
2644            var value = new
2645            {
2646                bar = new JObject(new JProperty("baz", 13))
2647            };
2648
2649            string json = JsonConvert.SerializeObject(value);
2650
2651            Assert.AreEqual(@"{""bar"":{""baz"":13}}", json);
2652        }
2653
2654        [Test]
2655        public void SerializeEnumerableAsObject()
2656        {
2657            Content content = new Content
2658            {
2659                Text = "Blah, blah, blah",
2660                Children = new List<Content>
2661                {
2662                    new Content { Text = "First" },
2663                    new Content { Text = "Second" }
2664                }
2665            };
2666
2667            string json = JsonConvert.SerializeObject(content, Formatting.Indented);
2668
2669            Assert.AreEqual(@"{
2670  ""Children"": [
2671    {
2672      ""Children"": null,
2673      ""Text"": ""First""
2674    },
2675    {
2676      ""Children"": null,
2677      ""Text"": ""Second""
2678    }
2679  ],
2680  ""Text"": ""Blah, blah, blah""
2681}", json);
2682        }
2683
2684        [Test]
2685        public void DeserializeEnumerableAsObject()
2686        {
2687            string json = @"{
2688  ""Children"": [
2689    {
2690      ""Children"": null,
2691      ""Text"": ""First""
2692    },
2693    {
2694      ""Children"": null,
2695      ""Text"": ""Second""
2696    }
2697  ],
2698  ""Text"": ""Blah, blah, blah""
2699}";
2700
2701            Content content = JsonConvert.DeserializeObject<Content>(json);
2702
2703            Assert.AreEqual("Blah, blah, blah", content.Text);
2704            Assert.AreEqual(2, content.Children.Count);
2705            Assert.AreEqual("First", content.Children[0].Text);
2706            Assert.AreEqual("Second", content.Children[1].Text);
2707        }
2708
2709        [Test]
2710        public void RoleTransferTest()
2711        {
2712            string json = @"{""Operation"":""1"",""RoleName"":""Admin"",""Direction"":""0""}";
2713
2714            RoleTransfer r = JsonConvert.DeserializeObject<RoleTransfer>(json);
2715
2716            Assert.AreEqual(RoleTransferOperation.Second, r.Operation);
2717            Assert.AreEqual("Admin", r.RoleName);
2718            Assert.AreEqual(RoleTransferDirection.First, r.Direction);
2719        }
2720
2721        [Test]
2722        public void DeserializeGenericDictionary()
2723        {
2724            string json = @"{""key1"":""value1"",""key2"":""value2""}";
2725
2726            Dictionary<string, string> values = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
2727
2728            Console.WriteLine(values.Count);
2729            // 2
2730
2731            Console.WriteLine(values["key1"]);
2732            // value1
2733
2734            Assert.AreEqual(2, values.Count);
2735            Assert.AreEqual("value1", values["key1"]);
2736            Assert.AreEqual("value2", values["key2"]);
2737        }
2738
2739#if !NET20
2740        [Test]
2741        public void DeserializeEmptyStringToNullableDateTime()
2742        {
2743            string json = @"{""DateTimeField"":""""}";
2744
2745            NullableDateTimeTestClass c = JsonConvert.DeserializeObject<NullableDateTimeTestClass>(json);
2746            Assert.AreEqual(null, c.DateTimeField);
2747        }
2748#endif
2749
2750        [Test]
2751        public void FailWhenClassWithNoDefaultConstructorHasMultipleConstructorsWithArguments()
2752        {
2753            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)\/""}";
2754
2755            ExceptionAssert.Throws<JsonSerializationException>(
2756                @"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.",
2757                () => { JsonConvert.DeserializeObject<TestObjects.Event>(json); });
2758        }
2759
2760        [Test]
2761        public void DeserializeObjectSetOnlyProperty()
2762        {
2763            string json = @"{'SetOnlyProperty':[1,2,3,4,5]}";
2764
2765            SetOnlyPropertyClass2 setOnly = JsonConvert.DeserializeObject<SetOnlyPropertyClass2>(json);
2766            JArray a = (JArray)setOnly.GetValue();
2767            Assert.AreEqual(5, a.Count);
2768            Assert.AreEqual(1, (int)a[0]);
2769            Assert.AreEqual(5, (int)a[a.Count - 1]);
2770        }
2771
2772        [Test]
2773        public void DeserializeOptInClasses()
2774        {
2775            string json = @"{id: ""12"", name: ""test"", items: [{id: ""112"", name: ""testing""}]}";
2776
2777            ListTestClass l = JsonConvert.DeserializeObject<ListTestClass>(json);
2778        }
2779
2780        [Test]
2781        public void DeserializeNullableListWithNulls()
2782        {
2783            List<decimal?> l = JsonConvert.DeserializeObject<List<decimal?>>("[ 3.3, null, 1.1 ] ");
2784            Assert.AreEqual(3, l.Count);
2785
2786            Assert.AreEqual(3.3m, l[0]);
2787            Assert.AreEqual(null, l[1]);
2788            Assert.AreEqual(1.1m, l[2]);
2789        }
2790
2791        [Test]
2792        public void CannotDeserializeArrayIntoObject()
2793        {
2794            string json = @"[]";
2795
2796            ExceptionAssert.Throws<JsonSerializationException>(
2797                @"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.
2798To 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<T> 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.
2799Path '', line 1, position 1.",
2800                () => { JsonConvert.DeserializeObject<Person>(json); });
2801        }
2802
2803        [Test]
2804        public void CannotDeserializeArrayIntoDictionary()
2805        {
2806            string json = @"[]";
2807
2808            ExceptionAssert.Throws<JsonSerializationException>(
2809                @"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.
2810To 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<T> 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.
2811Path '', line 1, position 1.",
2812                () => { JsonConvert.DeserializeObject<Dictionary<string, string>>(json); });
2813        }
2814
2815#if !(NETFX_CORE || PORTABLE)
2816        [Test]
2817        public void CannotDeserializeArrayIntoSerializable()
2818        {
2819            string json = @"[]";
2820
2821            ExceptionAssert.Throws<JsonSerializationException>(
2822                @"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.
2823To 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<T> 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.
2824Path '', line 1, position 1.",
2825                () => { JsonConvert.DeserializeObject<Exception>(json); });
2826        }
2827#endif
2828
2829        [Test]
2830        public void CannotDeserializeArrayIntoDouble()
2831        {
2832            string json = @"[]";
2833
2834            ExceptionAssert.Throws<JsonSerializationException>(
2835                @"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.
2836To 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<T> 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.
2837Path '', line 1, position 1.",
2838                () => { JsonConvert.DeserializeObject<double>(json); });
2839        }
2840
2841#if !(NET35 || NET20 || PORTABLE40)
2842        [Test]
2843        public void CannotDeserializeArrayIntoDynamic()
2844        {
2845            string json = @"[]";
2846
2847            ExceptionAssert.Throws<JsonSerializationException>(
2848                @"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.
2849To 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<T> 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.
2850Path '', line 1, position 1.",
2851                () => { JsonConvert.DeserializeObject<DynamicDictionary>(json); });
2852        }
2853#endif
2854
2855        [Test]
2856        public void CannotDeserializeArrayIntoLinqToJson()
2857        {
2858            string json = @"[]";
2859
2860            ExceptionAssert.Throws<InvalidCastException>(
2861                @"Unable to cast object of type 'Newtonsoft.Json.Linq.JArray' to type 'Newtonsoft.Json.Linq.JObject'.",
2862                () => { JsonConvert.DeserializeObject<JObject>(json); });
2863        }
2864
2865        [Test]
2866        public void CannotDeserializeConstructorIntoObject()
2867        {
2868            string json = @"new Constructor(123)";
2869
2870            ExceptionAssert.Throws<JsonSerializationException>(
2871                @"Error converting value ""Constructor"" to type 'Newtonsoft.Json.Tests.TestObjects.Person'. Path '', line 1, position 16.",
2872                () => { JsonConvert.DeserializeObject<Person>(json); });
2873        }
2874
2875        [Test]
2876        public void CannotDeserializeConstructorIntoObjectNested()
2877        {
2878            string json = @"[new Constructor(123)]";
2879
2880            ExceptionAssert.Throws<JsonSerializationException>(
2881                @"Error converting value ""Constructor"" to type 'Newtonsoft.Json.Tests.TestObjects.Person'. Path '[0]', line 1, position 17.",
2882                () => { JsonConvert.DeserializeObject<List<Person>>(json); });
2883        }
2884
2885        [Test]
2886        public void CannotDeserializeObjectIntoArray()
2887        {
2888            string json = @"{}";
2889
2890            try
2891            {
2892                JsonConvert.DeserializeObject<List<Person>>(json);
2893                Assert.Fail();
2894            }
2895            catch (JsonSerializationException ex)
2896            {
2897                Assert.IsTrue(ex.Message.StartsWith(@"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.
2898To 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<T>) 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.
2899Path ''"));
2900            }
2901        }
2902
2903        [Test]
2904        public void CannotPopulateArrayIntoObject()
2905        {
2906            string json = @"[]";
2907
2908            ExceptionAssert.Throws<JsonSerializationException>(
2909                @"Cannot populate JSON array onto type 'Newtonsoft.Json.Tests.TestObjects.Person'. Path '', line 1, position 1.",
2910                () => { JsonConvert.PopulateObject(json, new Person()); });
2911        }
2912
2913        [Test]
2914        public void CannotPopulateObjectIntoArray()
2915        {
2916            string json = @"{}";
2917
2918            ExceptionAssert.Throws<JsonSerializationException>(
2919                @"Cannot populate JSON object onto type 'System.Collections.Generic.List`1[Newtonsoft.Json.Tests.TestObjects.Person]'. Path '', line 1, position 2.",
2920                () => { JsonConvert.PopulateObject(json, new List<Person>()); });
2921        }
2922
2923        [Test]
2924        public void DeserializeEmptyString()
2925        {
2926            string json = @"{""Name"":""""}";
2927
2928            Person p = JsonConvert.DeserializeObject<Person>(json);
2929            Assert.AreEqual("", p.Name);
2930        }
2931
2932        [Test]
2933        public void SerializePropertyGetError()
2934        {
2935            ExceptionAssert.Throws<JsonSerializationException>(
2936                @"Error getting value from 'ReadTimeout' on 'System.IO.MemoryStream'.",
2937                () =>
2938                {
2939                    JsonConvert.SerializeObject(new MemoryStream(), new JsonSerializerSettings
2940                    {
2941                        ContractResolver = new DefaultContractResolver
2942                        {
2943#if !(NETFX_CORE || PORTABLE || PORTABLE40)
2944                            IgnoreSerializableAttribute = true
2945#endif
2946                        }
2947                    });
2948                });
2949        }
2950
2951        [Test]
2952        public void DeserializePropertySetError()
2953        {
2954            ExceptionAssert.Throws<JsonSerializationException>(
2955                @"Error setting value to 'ReadTimeout' on 'System.IO.MemoryStream'.",
2956                () =>
2957                {
2958                    JsonConvert.DeserializeObject<MemoryStream>("{ReadTimeout:0}", new JsonSerializerSettings
2959                    {
2960                        ContractResolver = new DefaultContractResolver
2961                        {
2962#if !(NETFX_CORE || PORTABLE || PORTABLE40)
2963                            IgnoreSerializableAttribute = true
2964#endif
2965                        }
2966                    });
2967                });
2968        }
2969
2970        [Test]
2971        public void DeserializeEnsureTypeEmptyStringToIntError()
2972        {
2973            ExceptionAssert.Throws<JsonSerializationException>(
2974                @"Error converting value {null} to type 'System.Int32'. Path 'ReadTimeout', line 1, position 15.",
2975                () =>
2976                {
2977                    JsonConvert.DeserializeObject<MemoryStream>("{ReadTimeout:''}", new JsonSerializerSettings
2978                    {
2979                        ContractResolver = new DefaultContractResolver
2980                        {
2981#if !(NETFX_CORE || PORTABLE || PORTABLE40)
2982                            IgnoreSerializableAttribute = true
2983#endif
2984                        }
2985                    });
2986                });
2987        }
2988
2989        [Test]
2990        public void DeserializeEnsureTypeNullToIntError()
2991        {
2992            ExceptionAssert.Throws<JsonSerializationException>(
2993                @"Error converting value {null} to type 'System.Int32'. Path 'ReadTimeout', line 1, position 17.",
2994                () =>
2995                {
2996                    JsonConvert.DeserializeObject<MemoryStream>("{ReadTimeout:null}", new JsonSerializerSettings
2997                    {
2998                        ContractResolver = new DefaultContractResolver
2999                        {
3000#if !(NETFX_CORE || PORTABLE || PORTABLE40)
3001                            IgnoreSerializableAttribute = true
3002#endif
3003                        }
3004                    });
3005                });
3006        }
3007
3008        [Test]
3009        public void SerializeGenericListOfStrings()
3010        {
3011            List<String> strings = new List<String>();
3012
3013            strings.Add("str_1");
3014            strings.Add("str_2");
3015            strings.Add("str_3");
3016
3017            string json = JsonConvert.SerializeObject(strings);
3018            Assert.AreEqual(@"[""str_1"",""str_2"",""str_3""]", json);
3019        }
3020
3021        [Test]
3022        public void ConstructorReadonlyFieldsTest()
3023        {
3024            ConstructorReadonlyFields c1 = new ConstructorReadonlyFields("String!", int.MaxValue);
3025            string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
3026            Assert.AreEqual(@"{
3027  ""A"": ""String!"",
3028  ""B"": 2147483647
3029}", json);
3030
3031            ConstructorReadonlyFields c2 = JsonConvert.DeserializeObject<ConstructorReadonlyFields>(json);
3032            Assert.AreEqual("String!", c2.A);
3033            Assert.AreEqual(int.MaxValue, c2.B);
3034        }
3035
3036        [Test]
3037        public void SerializeStruct()
3038        {
3039            StructTest structTest = new StructTest
3040            {
3041                StringProperty = "StringProperty!",
3042                StringField = "StringField",
3043                IntProperty = 5,
3044                IntField = 10
3045            };
3046
3047            string json = JsonConvert.SerializeObject(structTest, Formatting.Indented);
3048            Console.WriteLine(json);
3049            Assert.AreEqual(@"{
3050  ""StringField"": ""StringField"",
3051  ""IntField"": 10,
3052  ""StringProperty"": ""StringProperty!"",
3053  ""IntProperty"": 5
3054}", json);
3055
3056            StructTest deserialized = JsonConvert.DeserializeObject<StructTest>(json);
3057            Assert.AreEqual(structTest.StringProperty, deserialized.StringProperty);
3058            Assert.AreEqual(structTest.StringField, deserialized.StringField);
3059            Assert.AreEqual(structTest.IntProperty, deserialized.IntProperty);
3060            Assert.AreEqual(structTest.IntField, deserialized.IntField);
3061        }
3062
3063        [Test]
3064        public void SerializeListWithJsonConverter()
3065        {
3066            Foo f = new Foo();
3067            f.Bars.Add(new Bar { Id = 0 });
3068            f.Bars.Add(new Bar { Id = 1 });
3069            f.Bars.Add(new Bar { Id = 2 });
3070
3071            string json = JsonConvert.SerializeObject(f, Formatting.Indented);
3072            Assert.AreEqual(@"{
3073  ""Bars"": [
3074    0,
3075    1,
3076    2
3077  ]
3078}", json);
3079
3080            Foo newFoo = JsonConvert.DeserializeObject<Foo>(json);
3081            Assert.AreEqual(3, newFoo.Bars.Count);
3082            Assert.AreEqual(0, newFoo.Bars[0].Id);
3083            Assert.AreEqual(1, newFoo.Bars[1].Id);
3084            Assert.AreEqual(2, newFoo.Bars[2].Id);
3085        }
3086
3087        [Test]
3088        public void SerializeGuidKeyedDictionary()
3089        {
3090            Dictionary<Guid, int> dictionary = new Dictionary<Guid, int>();
3091            dictionary.Add(new Guid("F60EAEE0-AE47-488E-B330-59527B742D77"), 1);
3092            dictionary.Add(new Guid("C2594C02-EBA1-426A-AA87-8DD8871350B0"), 2);
3093
3094            string json = JsonConvert.SerializeObject(dictionary, Formatting.Indented);
3095            Assert.AreEqual(@"{
3096  ""f60eaee0-ae47-488e-b330-59527b742d77"": 1,
3097  ""c2594c02-eba1-426a-aa87-8dd8871350b0"": 2
3098}", json);
3099        }
3100
3101        [Test]
3102        public void SerializePersonKeyedDictionary()
3103        {
3104            Dictionary<Person, int> dictionary = new Dictionary<Person, int>();
3105            dictionary.Add(new Person { Name = "p1" }, 1);
3106            dictionary.Add(new Person { Name = "p2" }, 2);
3107
3108            string json = JsonConvert.SerializeObject(dictionary, Formatting.Indented);
3109
3110            Assert.AreEqual(@"{
3111  ""Newtonsoft.Json.Tests.TestObjects.Person"": 1,
3112  ""Newtonsoft.Json.Tests.TestObjects.Person"": 2
3113}", json);
3114        }
3115
3116        [Test]
3117        public void DeserializePersonKeyedDictionary()
3118        {
3119            try
3120            {
3121                string json =
3122                    @"{
3123  ""Newtonsoft.Json.Tests.TestObjects.Person"": 1,
3124  ""Newtonsoft.Json.Tests.TestObjects.Person"": 2
3125}";
3126
3127                JsonConvert.DeserializeObject<Dictionary<Person, int>>(json);
3128                Assert.Fail();
3129            }
3130            catch (JsonSerializationException ex)
3131            {
3132                Assert.IsTrue(ex.Message.StartsWith("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'"));
3133            }
3134        }
3135
3136        [Test]
3137        public void SerializeFragment()
3138        {
3139            string googleSearchText = @"{
3140        ""responseData"": {
3141          ""results"": [
3142            {
3143              ""GsearchResultClass"": ""GwebSearch"",
3144              ""unescapedUrl"": ""http://en.wikipedia.org/wiki/Paris_Hilton"",
3145              ""url"": ""http://en.wikipedia.org/wiki/Paris_Hilton"",
3146              ""visibleUrl"": ""en.wikipedia.org"",
3147              ""cacheUrl"": ""http://www.google.com/search?q=cache:TwrPfhd22hYJ:en.wikipedia.org"",
3148              ""title"": ""<b>Paris Hilton</b> - Wikipedia, the free encyclopedia"",
3149              ""titleNoFormatting"": ""Paris Hilton - Wikipedia, the free encyclopedia"",
3150              ""content"": ""[1] In 2006, she released her debut album...""
3151            },
3152            {
3153              ""GsearchResultClass"": ""GwebSearch"",
3154              ""unescapedUrl"": ""http://www.imdb.com/name/nm0385296/"",
3155              ""url"": ""http://www.imdb.com/name/nm0385296/"",
3156              ""visibleUrl"": ""www.imdb.com"",
3157              ""cacheUrl"": ""http://www.google.com/search?q=cache:1i34KkqnsooJ:www.imdb.com"",
3158              ""title"": ""<b>Paris Hilton</b>"",
3159              ""titleNoFormatting"": ""Paris Hilton"",
3160              ""content"": ""Self: Zoolander. Socialite <b>Paris Hilton</b>...""
3161            }
3162          ],
3163          ""cursor"": {
3164            ""pages"": [
3165              {
3166                ""start"": ""0"",
3167                ""label"": 1
3168              },
3169              {
3170                ""start"": ""4"",
3171                ""label"": 2
3172              },
3173              {
3174                ""start"": ""8"",
3175                ""label"": 3
3176              },
3177              {
3178                ""start"": ""12"",
3179                ""label"": 4
3180              }
3181            ],
3182            ""estimatedResultCount"": ""59600000"",
3183            ""currentPageIndex"": 0,
3184            ""moreResultsUrl"": ""http://www.google.com/search?oe=utf8&ie=utf8...""
3185          }
3186        },
3187        ""responseDetails"": null,
3188        ""responseStatus"": 200
3189      }";
3190
3191            JObject googleSearch = JObject.Parse(googleSearchText);
3192
3193            // get JSON result objects into a list
3194            IList<JToken> results = googleSearch["responseData"]["results"].Children().ToList();
3195
3196            // serialize JSON results into .NET objects
3197            IList<SearchResult> searchResults = new List<SearchResult>();
3198            foreach (JToken result in results)
3199            {
3200                SearchResult searchResult = JsonConvert.DeserializeObject<SearchResult>(result.ToString());
3201                searchResults.Add(searchResult);
3202            }
3203
3204            // Title = <b>Paris Hilton</b> - Wikipedia, the free encyclopedia
3205            // Content = [1] In 2006, she released her debut album...
3206            // Url = http://en.wikipedia.org/wiki/Paris_Hilton
3207
3208            // Title = <b>Paris Hilton</b>
3209            // Content = Self: Zoolander. Socialite <b>Paris Hilton</b>...
3210            // Url = http://www.imdb.com/name/nm0385296/
3211
3212            Assert.AreEqual(2, searchResults.Count);
3213            Assert.AreEqual("<b>Paris Hilton</b> - Wikipedia, the free encyclopedia", searchResults[0].Title);
3214            Assert.AreEqual("<b>Paris Hilton</b>", searchResults[1].Title);
3215        }
3216
3217        [Test]
3218        public void DeserializeBaseReferenceWithDerivedValue()
3219        {
3220            PersonPropertyClass personPropertyClass = new PersonPropertyClass();
3221            WagePerson wagePerson = (WagePerson)personPropertyClass.Person;
3222
3223            wagePerson.BirthDate = new DateTime(2000, 11, 29, 23, 59, 59, DateTimeKind.Utc);
3224            wagePerson.Department = "McDees";
3225            wagePerson.HourlyWage = 12.50m;
3226            wagePerson.LastModified = new DateTime(2000, 11, 29, 23, 59, 59, DateTimeKind.Utc);
3227            wagePerson.Name = "Jim Bob";
3228
3229            string json = JsonConvert.SerializeObject(personPropertyClass, Formatting.Indented);
3230            Assert.AreEqual(
3231                @"{
3232  ""Person"": {
3233    ""HourlyWage"": 12.50,
3234    ""Name"": ""Jim Bob"",
3235    ""BirthDate"": ""2000-11-29T23:59:59Z"",
3236    ""LastModified"": ""2000-11-29T23:59:59Z""
3237  }
3238}",
3239                json);
3240
3241            PersonPropertyClass newPersonPropertyClass = JsonConvert.DeserializeObject<PersonPropertyClass>(json);
3242            Assert.AreEqual(wagePerson.HourlyWage, ((WagePerson)newPersonPropertyClass.Person).HourlyWage);
3243        }
3244
3245        public class ExistingValueClass
3246        {
3247            public Dictionary<string, string> Dictionary { get; set; }
3248            public List<string> List { get; set; }
3249
3250            public ExistingValueClass()
3251            {
3252                Dictionary = new Dictionary<string, string>
3253                {
3254                    { "existing", "yup" }
3255                };
3256                List = new List<string>
3257                {
3258                    "existing"
3259                };
3260            }
3261        }
3262
3263        [Test]
3264        public void DeserializePopulateDictionaryAndList()
3265        {
3266            ExistingValueClass d = JsonConvert.DeserializeObject<ExistingValueClass>(@"{'Dictionary':{appended:'appended',existing:'new'}}");
3267
3268            Assert.IsNotNull(d);
3269            Assert.IsNotNull(d.Dictionary);
3270            Assert.AreEqual(typeof(Dictionary<string, string>), d.Dictionary.GetType());
3271            Assert.AreEqual(typeof(List<string>), d.List.GetType());
3272            Assert.AreEqual(2, d.Dictionary.Count);
3273            Assert.AreEqual("new", d.Dictionary["existing"]);
3274            Assert.AreEqual("appended", d.Dictionary["appended"]);
3275            Assert.AreEqual(1, d.List.Count);
3276            Assert.AreEqual("existing", d.List[0]);
3277        }
3278
3279        public interface IKeyValueId
3280        {
3281            int Id { get; set; }
3282            string Key { get; set; }
3283            string Value { get; set; }
3284        }
3285
3286
3287        public class KeyValueId : IKeyValueId
3288        {
3289            public int Id { get; set; }
3290            public string Key { get; set; }
3291            public string Value { get; set; }
3292        }
3293
3294        public class ThisGenericTest<T> where T : IKeyValueId
3295        {
3296            private Dictionary<string, T> _dict1 = new Dictionary<string, T>();
3297
3298            public string MyProperty { get; set; }
3299
3300            public void Add(T item)
3301            {
3302                _dict1.Add(item.Key, item);
3303            }
3304
3305            public T this[string key]
3306            {
3307                get { return _dict1[key]; }
3308                set { _dict1[key] = value; }
3309            }
3310
3311            public T this[int id]
3312            {
3313                get { return _dict1.Values.FirstOrDefault(x => x.Id == id); }
3314                set
3315                {
3316                    var item = this[id];
3317
3318                    if (item == null)
3319                        Add(value);
3320                    else
3321                        _dict1[item.Key] = value;
3322                }
3323            }
3324
3325            public string ToJson()
3326            {
3327                return JsonConvert.SerializeObject(this, Formatting.Indented);
3328            }
3329
3330            public T[] TheItems
3331            {
3332                get { return _dict1.Values.ToArray<T>(); }
3333                set
3334                {
3335                    foreach (var item in value)
3336                        Add(item);
3337                }
3338            }
3339        }
3340
3341        [Test]
3342        public void IgnoreIndexedProperties()
3343        {
3344            ThisGenericTest<KeyValueId> g = new ThisGenericTest<KeyValueId>();
3345
3346            g.Add(new KeyValueId { Id = 1, Key = "key1", Value = "value1" });
3347            g.Add(new KeyValueId { Id = 2, Key = "key2", Value = "value2" });
3348
3349            g.MyProperty = "some value";
3350
3351            string json = g.ToJson();
3352
3353            Assert.AreEqual(@"{
3354  ""MyProperty"": ""some value"",
3355  ""TheItems"": [
3356    {
3357      ""Id"": 1,
3358      ""Key"": ""key1"",
3359      ""Value"": ""value1""
3360    },
3361    {
3362      ""Id"": 2,
3363      ""Key"": ""key2"",
3364      ""Value"": ""value2""
3365    }
3366  ]
3367}", json);
3368
3369            ThisGenericTest<KeyValueId> gen = JsonConvert.DeserializeObject<ThisGenericTest<KeyValueId>>(json);
3370            Assert.AreEqual("some value", gen.MyProperty);
3371        }
3372
3373        public class JRawValueTestObject
3374        {
3375            public JRaw Value { get; set; }
3376        }
3377
3378        [Test]
3379        public void JRawValue()
3380        {
3381            JRawValueTestObject deserialized = JsonConvert.DeserializeObject<JRawValueTestObject>("{value:3}");
3382            Assert.AreEqual("3", deserialized.Value.ToString());
3383
3384            deserialized = JsonConvert.DeserializeObject<JRawValueTestObject>("{value:'3'}");
3385            Assert.AreEqual(@"""3""", deserialized.Value.ToString());
3386        }
3387
3388        [Test]
3389        public void DeserializeDictionaryWithNoDefaultConstructor()
3390        {
3391            string json = "{key1:'value1',key2:'value2',key3:'value3'}";
3392
3393            var dic = JsonConvert.DeserializeObject<DictionaryWithNoDefaultConstructor>(json);
3394
3395            Assert.AreEqual(3, dic.Count);
3396            Assert.AreEqual("value1", dic["key1"]);
3397            Assert.AreEqual("value2", dic["key2"]);
3398            Assert.AreEqual("value3", dic["key3"]);
3399        }
3400
3401        [Test]
3402        public void DeserializeDictionaryWithNoDefaultConstructor_PreserveReferences()
3403        {
3404            string json = "{'$id':'1',key1:'value1',key2:'value2',key3:'value3'}";
3405
3406            ExceptionAssert.Throws<JsonSerializationException>("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.",
3407                () => JsonConvert.DeserializeObject<DictionaryWithNoDefaultConstructor>(json, new JsonSerializerSettings
3408                {
3409                    PreserveReferencesHandling = PreserveReferencesHandling.All,
3410                    MetadataPropertyHandling = MetadataPropertyHandling.Default
3411                }));
3412        }
3413
3414        public class DictionaryWithNoDefaultConstructor : Dictionary<string, string>
3415        {
3416            public DictionaryWithNoDefaultConstructor(IEnumerable<KeyValuePair<string, string>> initial)
3417            {
3418                foreach (KeyValuePair<string, string> pair in initial)
3419                {
3420                    Add(pair.Key, pair.Value);
3421                }
3422            }
3423        }
3424
3425        [JsonObject(MemberSerialization.OptIn)]
3426        public class A
3427        {
3428            [JsonProperty("A1")]
3429            private string _A1;
3430
3431            public string A1
3432            {
3433                get { return _A1; }
3434                set { _A1 = value; }
3435            }
3436
3437            [JsonProperty("A2")]
3438            private string A2 { get; set; }
3439        }
3440
3441        [JsonObject(MemberSerialization.OptIn)]
3442        public class B : A
3443        {
3444            public string B1 { get; set; }
3445
3446            [JsonProperty("B2")]
3447            private string _B2;
3448
3449            public string B2
3450            {
3451                get { return _B2; }
3452                set { _B2 = value; }
3453            }
3454
3455            [JsonProperty("B3")]
3456            private string B3 { get; set; }
3457        }
3458
3459        [Test]
3460        public void SerializeNonPublicBaseJsonProperties()
3461        {
3462            B value = new B();
3463            string json = JsonConvert.SerializeObject(value, Formatting.Indented);
3464
3465            Assert.AreEqual(@"{
3466  ""B2"": null,
3467  ""A1"": null,
3468  ""B3"": null,
3469  ""A2"": null
3470}", json);
3471        }
3472
3473        public class TestClass
3474        {
3475            public string Key { get; set; }
3476            public object Value { get; set; }
3477        }
3478
3479        [Test]
3480        public void DeserializeToObjectProperty()
3481        {
3482            var json = "{ Key: 'abc', Value: 123 }";
3483            var item = JsonConvert.DeserializeObject<TestClass>(json);
3484
3485            Assert.AreEqual(123L, item.Value);
3486        }
3487
3488        public abstract class Animal
3489        {
3490            public abstract string Name { get; }
3491        }
3492
3493        public class Human : Animal
3494        {
3495            public override string Name
3496            {
3497                get { return typeof(Human).Name; }
3498            }
3499
3500            public string Ethnicity { get; set; }
3501        }
3502
3503#if !NET20
3504        public class DataContractJsonSerializerTestClass
3505        {
3506            public TimeSpan TimeSpanProperty { get; set; }
3507            public Guid GuidProperty { get; set; }
3508            public Animal AnimalProperty { get; set; }
3509            public Exception ExceptionProperty { get; set; }
3510        }
3511
3512        [Test]
3513        public void DataContractJsonSerializerTest()
3514        {
3515            Exception ex = new Exception("Blah blah blah");
3516
3517            DataContractJsonSerializerTestClass c = new DataContractJsonSerializerTestClass();
3518            c.TimeSpanProperty = new TimeSpan(200, 20, 59, 30, 900);
3519            c.GuidProperty = new Guid("66143115-BE2A-4a59-AF0A-348E1EA15B1E");
3520            c.AnimalProperty = new Human() { Ethnicity = "European" };
3521            c.ExceptionProperty = ex;
3522
3523            MemoryStream ms = new MemoryStream();
3524            DataContractJsonSerializer serializer = new DataContractJsonSerializer(
3525                typeof(DataContractJsonSerializerTestClass),
3526                new Type[] { typeof(Human) });
3527            serializer.WriteObject(ms, c);
3528
3529            byte[] jsonBytes = ms.ToArray();
3530            string json = Encoding.UTF8.GetString(jsonBytes, 0, jsonBytes.Length);
3531
3532            //Console.WriteLine(JObject.Parse(json).ToString());
3533            //Console.WriteLine();
3534
3535            //Console.WriteLine(JsonConvert.SerializeObject(c, Formatting.Indented, new JsonSerializerSettings
3536            //  {
3537            //    //               TypeNameHandling = TypeNameHandling.Objects
3538            //  }));
3539        }
3540#endif
3541
3542        public class ModelStateDictionary<T> : IDictionary<string, T>
3543        {
3544            private readonly Dictionary<string, T> _innerDictionary = new Dictionary<string, T>(StringComparer.OrdinalIgnoreCase);
3545
3546            public ModelStateDictionary()
3547            {
3548            }
3549
3550            public ModelStateDictionary(ModelStateDictionary<T> dictionary)
3551            {
3552                if (dictionary == null)
3553                {
3554                    throw new ArgumentNullException("dictionary");
3555                }
3556
3557                foreach (var entry in dictionary)
3558                {
3559                    _innerDictionary.Add(entry.Key, entry.Value);
3560                }
3561            }
3562
3563            public int Count
3564            {
3565                get { return _innerDictionary.Count; }
3566            }
3567
3568            public bool IsReadOnly
3569            {
3570                get { return ((IDictionary<string, T>)_innerDictionary).IsReadOnly; }
3571            }
3572
3573            public ICollection<string> Keys
3574            {
3575                get { return _innerDictionary.Keys; }
3576            }
3577
3578            public T this[string key]
3579            {
3580                get
3581                {
3582                    T value;
3583                    _innerDictionary.TryGetValue(key, out value);
3584                    return value;
3585                }
3586                set { _innerDictionary[key] = value; }
3587            }
3588
3589            public ICollection<T> Values
3590            {
3591                get { return _innerDictionary.Values; }
3592            }
3593
3594            public void Add(KeyValuePair<string, T> item)
3595            {
3596                ((IDictionary<string, T>)_innerDictionary).Add(item);
3597            }
3598
3599            public void Add(string key, T value)
3600            {
3601                _innerDictionary.Add(key, value);
3602            }
3603
3604            public void Clear()
3605            {
3606                _innerDictionary.Clear();
3607            }
3608
3609            public bool Contains(KeyValuePair<string, T> item)
3610            {
3611                return ((IDictionary<string, T>)_innerDictionary).Contains(item);
3612            }
3613
3614            public bool ContainsKey(string key)
3615            {
3616                return _innerDictionary.ContainsKey(key);
3617            }
3618
3619            public void CopyTo(KeyValuePair<string, T>[] array, int arrayIndex)
3620            {
3621                ((IDictionary<string, T>)_innerDictionary).CopyTo(array, arrayIndex);
3622            }
3623
3624            public IEnumerator<KeyValuePair<string, T>> GetEnumerator()
3625            {
3626                return _innerDictionary.GetEnumerator();
3627            }
3628
3629            public void Merge(ModelStateDictionary<T> dictionary)
3630            {
3631                if (dictionary == null)
3632                {
3633                    return;
3634                }
3635
3636                foreach (var entry in dictionary)
3637                {
3638                    this[entry.Key] = entry.Value;
3639                }
3640            }
3641
3642            public bool Remove(KeyValuePair<string, T> item)
3643            {
3644                return ((IDictionary<string, T>)_innerDictionary).Remove(item);
3645            }
3646
3647            public bool Remove(string key)
3648            {
3649                return _innerDictionary.Remove(key);
3650            }
3651
3652            public bool TryGetValue(string key, out T value)
3653            {
3654                return _innerDictionary.TryGetValue(key, out value);
3655            }
3656
3657            IEnumerator IEnumerable.GetEnumerator()
3658            {
3659                return ((IEnumerable)_innerDictionary).GetEnumerator();
3660            }
3661        }
3662
3663        [Test]
3664        public void SerializeNonIDictionary()
3665        {
3666            ModelStateDictionary<string> modelStateDictionary = new ModelStateDictionary<string>();
3667            modelStateDictionary.Add("key", "value");
3668
3669            string json = JsonConvert.SerializeObject(modelStateDictionary);
3670
3671            Assert.AreEqual(@"{""key"":""value""}", json);
3672
3673            ModelStateDictionary<string> newModelStateDictionary = JsonConvert.DeserializeObject<ModelStateDictionary<string>>(json);
3674            Assert.AreEqual(1, newModelStateDictionary.Count);
3675            Assert.AreEqual("value", newModelStateDictionary["key"]);
3676        }
3677
3678#if !(NETFX_CORE || PORTABLE || PORTABLE40)
3679        public class ISerializableTestObject : ISerializable
3680        {
3681            internal string _stringValue;
3682            internal int _intValue;
3683            internal DateTimeOffset _dateTimeOffsetValue;
3684            internal Person _personValue;
3685            internal Person _nullPersonValue;
3686            internal int? _nullableInt;
3687            internal bool _booleanValue;
3688            internal byte _byteValue;
3689            internal char _charValue;
3690            internal DateTime _dateTimeValue;
3691            internal decimal _decimalValue;
3692            internal short _shortValue;
3693            internal long _longValue;
3694            internal sbyte _sbyteValue;
3695            internal float _floatValue;
3696            internal ushort _ushortValue;
3697            internal uint _uintValue;
3698            internal ulong _ulongValue;
3699
3700            public ISerializableTestObject(string stringValue, int intValue, DateTimeOffset dateTimeOffset, Person personValue)
3701            {
3702                _stringValue = stringValue;
3703                _intValue = intValue;
3704                _dateTimeOffsetValue = dateTimeOffset;
3705                _personValue = personValue;
3706                _dateTimeValue = new DateTime(0, DateTimeKind.Utc);
3707            }
3708
3709            protected ISerializableTestObject(SerializationInfo info, StreamingContext context)
3710            {
3711                _stringValue = info.GetString("stringValue");
3712                _intValue = info.GetInt32("intValue");
3713                _dateTimeOffsetValue = (DateTimeOffset)info.GetValue("dateTimeOffsetValue", typeof(DateTimeOffset));
3714                _personValue = (Person)info.GetValue("personValue", typeof(Person));
3715                _nullPersonValue = (Person)info.GetValue("nullPersonValue", typeof(Person));
3716                _nullableInt = (int?)info.GetValue("nullableInt", typeof(int?));
3717
3718                _booleanValue = info.GetBoolean("booleanValue");
3719                _byteValue = info.GetByte("byteValue");
3720                _charValue = info.GetChar("charValue");
3721                _dateTimeValue = info.GetDateTime("dateTimeValue");
3722                _decimalValue = info.GetDecimal("decimalValue");
3723                _shortValue = info.GetInt16("shortValue");
3724                _longValue = info.GetInt64("longValue");
3725                _sbyteValue = info.GetSByte("sbyteValue");
3726                _floatValue = info.GetSingle("floatValue");
3727                _ushortValue = info.GetUInt16("ushortValue");
3728                _uintValue = info.GetUInt32("uintValue");
3729                _ulongValue = info.GetUInt64("ulongValue");
3730            }
3731
3732            public void GetObjectData(SerializationInfo info, StreamingContext context)
3733            {
3734                info.AddValue("stringValue", _stringValue);
3735                info.AddValue("intValue", _intValue);
3736                info.AddValue("dateTimeOffsetValue", _dateTimeOffsetValue);
3737                info.AddValue("personValue", _personValue);
3738                info.AddValue("nullPersonValue", _nullPersonValue);
3739                info.AddValue("nullableInt", null);
3740
3741                info.AddValue("booleanValue", _booleanValue);
3742                info.AddValue("byteValue", _byteValue);
3743                info.AddValue("charValue", _charValue);
3744                info.AddValue("dateTimeValue", _dateTimeValue);
3745                info.AddValue("decimalValue", _decimalValue);
3746                info.AddValue("shortValue", _shortValue);
3747                info.AddValue("longValue", _longValue);
3748                info.AddValue("sbyteValue", _sbyteValue);
3749                info.AddValue("floatValue", _floatValue);
3750                info.AddValue("ushortValue", _ushortValue);
3751                info.AddValue("uintValue", _uintValue);
3752                info.AddValue("ulongValue", _ulongValue);
3753            }
3754        }
3755
3756#if DEBUG
3757        [Test]
3758        public void SerializeISerializableInPartialTrustWithIgnoreInterface()
3759        {
3760            try
3761            {
3762                JsonTypeReflector.SetFullyTrusted(false);
3763                ISerializableTestObject value = new ISerializableTestObject("string!", 0, default(DateTimeOffset), null);
3764
3765                string json = JsonConvert.SerializeObject(value, new JsonSerializerSettings
3766                {
3767                    ContractResolver = new DefaultContractResolver(false)
3768                    {
3769                        IgnoreSerializableInterface = true
3770                    }
3771                });
3772
3773                Assert.AreEqual("{}", json);
3774
3775                value = JsonConvert.DeserializeObject<ISerializableTestObject>("{booleanValue:true}", new JsonSerializerSettings
3776                {
3777                    ContractResolver = new DefaultContractResolver(false)
3778                    {
3779                        IgnoreSerializableInterface = true
3780                    }
3781                });
3782
3783                Assert.IsNotNull(value);
3784                Assert.AreEqual(false, value._booleanValue);
3785            }
3786            finally
3787            {
3788                JsonTypeReflector.SetFullyTrusted(true);
3789            }
3790        }
3791
3792        [Test]
3793        public void SerializeISerializableInPartialTrust()
3794        {
3795            try
3796            {
3797                ExceptionAssert.Throws<JsonSerializationException>(
3798                    @"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.
3799To 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.
3800Path 'booleanValue', line 1, position 14.",
3801                    () =>
3802                    {
3803                        JsonTypeReflector.SetFullyTrusted(false);
3804
3805                        JsonConvert.DeserializeObject<ISerializableTestObject>("{booleanValue:true}");
3806                    });
3807            }
3808            finally
3809            {
3810                JsonTypeReflector.SetFullyTrusted(true);
3811            }
3812        }
3813
3814        [Test]
3815        public void DeserializeISerializableInPartialTrust()
3816        {
3817            try
3818            {
3819                ExceptionAssert.Throws<JsonSerializationException>(
3820                    @"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.
3821To 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 ''.",
3822                    () =>
3823                    {
3824                        JsonTypeReflector.SetFullyTrusted(false);
3825                        ISerializableTestObject value = new ISerializableTestObject("string!", 0, default(DateTimeOffset), null);
3826
3827                        JsonConvert.SerializeObject(value);
3828                    });
3829            }
3830            finally
3831            {
3832                JsonTypeReflector.SetFullyTrusted(true);
3833            }
3834        }
3835#endif
3836
3837        [Test]
3838        public void SerializeISerializableTestObject_IsoDate()
3839        {
3840            Person person = new Person();
3841            person.BirthDate = new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc);
3842            person.LastModified = person.BirthDate;
3843            person.Department = "Department!";
3844            person.Name = "Name!";
3845
3846            DateTimeOffset dateTimeOffset = new DateTimeOffset(2000, 12, 20, 22, 59, 59, TimeSpan.FromHours(2));
3847            string dateTimeOffsetText;
3848#if !NET20
3849            dateTimeOffsetText = @"2000-12-20T22:59:59+02:00";
3850#else
3851            dateTimeOffsetText = @"12/20/2000 22:59:59 +02:00";
3852#endif
3853
3854            ISerializableTestObject o = new ISerializableTestObject("String!", int.MinValue, dateTimeOffset, person);
3855
3856            string json = JsonConvert.SerializeObject(o, Formatting.Indented);
3857            Assert.AreEqual(@"{
3858  ""stringValue"": ""String!"",
3859  ""intValue"": -2147483648,
3860  ""dateTimeOffsetValue"": """ + dateTimeOffsetText + @""",
3861  ""personValue"": {
3862    ""Name"": ""Name!"",
3863    ""BirthDate"": ""2000-01-01T01:01:01Z"",
3864    ""LastModified"": ""2000-01-01T01:01:01Z""
3865  },
3866  ""nullPersonValue"": null,
3867  ""nullableInt"": null,
3868  ""booleanValue"": false,
3869  ""byteValue"": 0,
3870  ""charValue"": ""\u0000"",
3871  ""dateTimeValue"": ""0001-01-01T00:00:00Z"",
3872  ""decimalValue"": 0.0,
3873  ""shortValue"": 0,
3874  ""longValue"": 0,
3875  ""sbyteValue"": 0,
3876  ""floatValue"": 0.0,
3877  ""ushortValue"": 0,
3878  ""uintValue"": 0,
3879  ""ulongValue"": 0
3880}", json);
3881
3882            ISerializableTestObject o2 = JsonConvert.DeserializeObject<ISerializableTestObject>(json);
3883            Assert.AreEqual("String!", o2._stringValue);
3884            Assert.AreEqual(int.MinValue, o2._intValue);
3885            Assert.AreEqual(dateTimeOffset, o2._dateTimeOffsetValue);
3886            Assert.AreEqual("Name!", o2._personValue.Name);
3887            Assert.AreEqual(null, o2._nullPersonValue);
3888            Assert.AreEqual(null, o2._nullableInt);
3889        }
3890
3891        [Test]
3892        public void SerializeISerializableTestObject_MsAjax()
3893        {
3894            Person person = new Person();
3895            person.BirthDate = new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc);
3896            person.LastModified = person.BirthDate;
3897            person.Department = "Department!";
3898            person.Name = "Name!";
3899
3900            DateTimeOffset dateTimeOffset = new DateTimeOffset(2000, 12, 20, 22, 59, 59, TimeSpan.FromHours(2));
3901            string dateTimeOffsetText;
3902#if !NET20
3903            dateTimeOffsetText = @"\/Date(977345999000+0200)\/";
3904#else
3905      dateTimeOffsetText = @"12/20/2000 22:59:59 +02:00";
3906#endif
3907
3908            ISerializableTestObject o = new ISerializableTestObject("String!", int.MinValue, dateTimeOffset, person);
3909
3910            string json = JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings
3911            {
3912                DateFormatHandling = DateFormatHandling.MicrosoftDateFormat
3913            });
3914            Assert.AreEqual(@"{
3915  ""stringValue"": ""String!"",
3916  ""intValue"": -2147483648,
3917  ""dateTimeOffsetValue"": """ + dateTimeOffsetText + @""",
3918  ""personValue"": {
3919    ""Name"": ""Name!"",
3920    ""BirthDate"": ""\/Date(946688461000)\/"",
3921    ""LastModified"": ""\/Date(946688461000)\/""
3922  },
3923  ""nullPersonValue"": null,
3924  ""nullableInt"": null,
3925  ""booleanValue"": false,
3926  ""byteValue"": 0,
3927  ""charValue"": ""\u0000"",
3928  ""dateTimeValue"": ""\/Date(-62135596800000)\/"",
3929  ""decimalValue"": 0.0,
3930  ""shortValue"": 0,
3931  ""longValue"": 0,
3932  ""sbyteValue"": 0,
3933  ""floatValue"": 0.0,
3934  ""ushortValue"": 0,
3935  ""uintValue"": 0,
3936  ""ulongValue"": 0
3937}", json);
3938
3939            ISerializableTestObject o2 = JsonConvert.DeserializeObject<ISerializableTestObject>(json);
3940            Assert.AreEqual("String!", o2._stringValue);
3941            Assert.AreEqual(int.MinValue, o2._intValue);
3942            Assert.AreEqual(dateTimeOffset, o2._dateTimeOffsetValue);
3943            Assert.AreEqual("Name!", o2._personValue.Name);
3944            Assert.AreEqual(null, o2._nullPersonValue);
3945            Assert.AreEqual(null, o2._nullableInt);
3946        }
3947#endif
3948
3949        public class KVPair<TKey, TValue>
3950        {
3951            public TKey Key { get; set; }
3952            public TValue Value { get; set; }
3953
3954            public KVPair(TKey k, TValue v)
3955            {
3956                Key = k;
3957                Value = v;
3958            }
3959        }
3960
3961        [Test]
3962        public void DeserializeUsingNonDefaultConstructorWithLeftOverValues()
3963        {
3964            List<KVPair<string, string>> kvPairs =
3965                JsonConvert.DeserializeObject<List<KVPair<string, string>>>(
3966                    "[{\"Key\":\"Two\",\"Value\":\"2\"},{\"Key\":\"One\",\"Value\":\"1\"}]");
3967
3968            Assert.AreEqual(2, kvPairs.Count);
3969            Assert.AreEqual("Two", kvPairs[0].Key);
3970            Assert.AreEqual("2", kvPairs[0].Value);
3971            Assert.AreEqual("One", kvPairs[1].Key);
3972            Assert.AreEqual("1", kvPairs[1].Value);
3973        }
3974
3975        [Test]
3976        public void SerializeClassWithInheritedProtectedMember()
3977        {
3978            AA myA = new AA(2);
3979            string json = JsonConvert.SerializeObject(myA, Formatting.Indented);
3980            Assert.AreEqual(@"{
3981  ""AA_field1"": 2,
3982  ""AA_property1"": 2,
3983  ""AA_property2"": 2,
3984  ""AA_property3"": 2,
3985  ""AA_property4"": 2
3986}", json);
3987
3988            BB myB = new BB(3, 4);
3989            json = JsonConvert.SerializeObject(myB, Formatting.Indented);
3990            Assert.AreEqual(@"{
3991  ""BB_field1"": 4,
3992  ""BB_field2"": 4,
3993  ""AA_field1"": 3,
3994  ""BB_property1"": 4,
3995  ""BB_property2"": 4,
3996  ""BB_property3"": 4,
3997  ""BB_property4"": 4,
3998  ""BB_property5"": 4,
3999  ""BB_property7"": 4,
4000  ""AA_property1"": 3,
4001  ""AA_property2"": 3,
4002  ""AA_property3"": 3,
4003  ""AA_property4"": 3
4004}", json);
4005        }
4006
4007#if !PORTABLE
4008        [Test]
4009        public void DeserializeClassWithInheritedProtectedMember()
4010        {
4011            AA myA = JsonConvert.DeserializeObject<AA>(
4012                @"{
4013  ""AA_field1"": 2,
4014  ""AA_field2"": 2,
4015  ""AA_property1"": 2,
4016  ""AA_property2"": 2,
4017  ""AA_property3"": 2,
4018  ""AA_property4"": 2,
4019  ""AA_property5"": 2,
4020  ""AA_property6"": 2
4021}");
4022
4023            Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetField("AA_field1", BindingFlags.Instance | BindingFlags.NonPublic), myA));
4024            Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetField("AA_field2", BindingFlags.Instance | BindingFlags.NonPublic), myA));
4025            Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property1", BindingFlags.Instance | BindingFlags.NonPublic), myA));
4026            Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property2", BindingFlags.Instance | BindingFlags.NonPublic), myA));
4027            Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property3", BindingFlags.Instance | BindingFlags.NonPublic), myA));
4028            Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property4", BindingFlags.Instance | BindingFlags.NonPublic), myA));
4029            Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property5", BindingFlags.Instance | BindingFlags.NonPublic), myA));
4030            Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property6", BindingFlags.Instance | BindingFlags.NonPublic), myA));
4031
4032            BB myB = JsonConvert.DeserializeObject<BB>(
4033                @"{
4034  ""BB_field1"": 4,
4035  ""BB_field2"": 4,
4036  ""AA_field1"": 3,
4037  ""AA_field2"": 3,
4038  ""AA_property1"": 2,
4039  ""AA_property2"": 2,
4040  ""AA_property3"": 2,
4041  ""AA_property4"": 2,
4042  ""AA_property5"": 2,
4043  ""AA_property6"": 2,
4044  ""BB_property1"": 3,
4045  ""BB_property2"": 3,
4046  ""BB_property3"": 3,
4047  ""BB_property4"": 3,
4048  ""BB_property5"": 3,
4049  ""BB_property6"": 3,
4050  ""BB_property7"": 3,
4051  ""BB_property8"": 3
4052}");
4053
4054            Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(AA).GetField("AA_field1", BindingFlags.Instance | BindingFlags.NonPublic), myB));
4055            Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetField("AA_field2", BindingFlags.Instance | BindingFlags.NonPublic), myB));
4056            Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property1", BindingFlags.Instance | BindingFlags.NonPublic), myB));
4057            Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property2", BindingFlags.Instance | BindingFlags.NonPublic), myB));
4058            Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property3", BindingFlags.Instance | BindingFlags.NonPublic), myB));
4059            Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property4", BindingFlags.Instance | BindingFlags.NonPublic), myB));
4060            Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property5", BindingFlags.Instance | BindingFlags.NonPublic), myB));
4061            Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property6", BindingFlags.Instance | BindingFlags.NonPublic), myB));
4062
4063            Assert.AreEqual(4, myB.BB_field1);
4064            Assert.AreEqual(4, myB.BB_field2);
4065            Assert.AreEqual(3, myB.BB_property1);
4066            Assert.AreEqual(3, myB.BB_property2);
4067            Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(BB).GetProperty("BB_property3", BindingFlags.Instance | BindingFlags.Public), myB));
4068            Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(BB).GetProperty("BB_property4", BindingFlags.Instance | BindingFlags.NonPublic), myB));
4069            Assert.AreEqual(0, myB.BB_property5);
4070            Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(BB).GetProperty("BB_property6", BindingFlags.Instance | BindingFlags.Public), myB));
4071            Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(BB).GetProperty("BB_property7", BindingFlags.Instance | BindingFlags.Public), myB));
4072            Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(BB).GetProperty("BB_property8", BindingFlags.Instance | BindingFlags.Public), myB));
4073        }
4074#endif
4075
4076        public class AA
4077        {
4078            [JsonProperty]
4079            protected int AA_field1;
4080
4081            protected int AA_field2;
4082
4083            [JsonProperty]
4084            protected int AA_property1 { get; set; }
4085
4086            [JsonProperty]
4087            protected int AA_property2 { get; private set; }
4088
4089            [JsonProperty]
4090            protected int AA_property3 { private get; set; }
4091
4092            [JsonProperty]
4093            private int AA_property4 { get; set; }
4094
4095            protected int AA_property5 { get; private set; }
4096            protected int AA_property6 { private get; set; }
4097
4098            public AA()
4099            {
4100            }
4101
4102            public AA(int f)
4103            {
4104                AA_field1 = f;
4105                AA_field2 = f;
4106                AA_property1 = f;
4107                AA_property2 = f;
4108                AA_property3 = f;
4109                AA_property4 = f;
4110                AA_property5 = f;
4111                AA_property6 = f;
4112            }
4113        }
4114
4115        public class BB : AA
4116        {
4117            [JsonProperty]
4118            public int BB_field1;
4119
4120            public int BB_field2;
4121
4122            [JsonProperty]
4123            public int BB_property1 { get; set; }
4124
4125            [JsonProperty]
4126            public int BB_property2 { get; private set; }
4127
4128            [JsonProperty]
4129            public int BB_property3 { private get; set; }
4130
4131            [JsonProperty]
4132            private int BB_property4 { get; set; }
4133
4134            public int BB_property5 { get; private set; }
4135            public int BB_property6 { private get; set; }
4136
4137            [JsonProperty]
4138            public int BB_property7 { protected get; set; }
4139
4140            public int BB_property8 { protected get; set; }
4141
4142            public BB()
4143            {
4144            }
4145
4146            public BB(int f, int g)
4147                : base(f)
4148            {
4149                BB_field1 = g;
4150                BB_field2 = g;
4151                BB_property1 = g;
4152                BB_property2 = g;
4153                BB_property3 = g;
4154                BB_property4 = g;
4155                BB_property5 = g;
4156                BB_property6 = g;
4157                BB_property7 = g;
4158                BB_property8 = g;
4159            }
4160        }
4161
4162#if !NET20
4163        public class XNodeTestObject
4164        {
4165            public XDocument Document { get; set; }
4166            public XElement Element { get; set; }
4167        }
4168#endif
4169
4170#if !NETFX_CORE
4171        public class XmlNodeTestObject
4172        {
4173            public XmlDocument Document { get; set; }
4174        }
4175#endif
4176
4177#if !(NET20 || PORTABLE40)
4178        [Test]
4179        public void SerializeDeserializeXNodeProperties()
4180        {
4181            XNodeTestObject testObject = new XNodeTestObject();
4182            testObject.Document = XDocument.Parse("<root>hehe, root</root>");
4183            testObject.Element = XElement.Parse(@"<fifth xmlns:json=""http://json.org"" json:Awesome=""true"">element</fifth>");
4184
4185            string json = JsonConvert.SerializeObject(testObject, Formatting.Indented);
4186            string expected = @"{
4187  ""Document"": {
4188    ""root"": ""hehe, root""
4189  },
4190  ""Element"": {
4191    ""fifth"": {
4192      ""@xmlns:json"": ""http://json.org"",
4193      ""@json:Awesome"": ""true"",
4194      ""#text"": ""element""
4195    }
4196  }
4197}";
4198            Assert.AreEqual(expected, json);
4199
4200            XNodeTestObject newTestObject = JsonConvert.DeserializeObject<XNodeTestObject>(json);
4201            Assert.AreEqual(testObject.Document.ToString(), newTestObject.Document.ToString());
4202            Assert.AreEqual(testObject.Element.ToString(), newTestObject.Element.ToString());
4203
4204            Assert.IsNull(newTestObject.Element.Parent);
4205        }
4206#endif
4207
4208#if !(NETFX_CORE || PORTABLE || PORTABLE40)
4209        [Test]
4210        public void SerializeDeserializeXmlNodeProperties()
4211        {
4212            XmlNodeTestObject testObject = new XmlNodeTestObject();
4213            XmlDocument document = new XmlDocument();
4214            document.LoadXml("<root>hehe, root</root>");
4215            testObject.Document = document;
4216
4217            string json = JsonConvert.SerializeObject(testObject, Formatting.Indented);
4218            string expected = @"{
4219  ""Document"": {
4220    ""root"": ""hehe, root""
4221  }
4222}";
4223            Assert.AreEqual(expected, json);
4224
4225            XmlNodeTestObject newTestObject = JsonConvert.DeserializeObject<XmlNodeTestObject>(json);
4226            Assert.AreEqual(testObject.Document.InnerXml, newTestObject.Document.InnerXml);
4227        }
4228#endif
4229
4230        [Test]
4231        public void FullClientMapSerialization()
4232        {
4233            ClientMap source = new ClientMap()
4234            {
4235                position = new Pos() { X = 100, Y = 200 },
4236                center = new PosDouble() { X = 251.6, Y = 361.3 }
4237            };
4238
4239            string json = JsonConvert.SerializeObject(source, new PosConverter(), new PosDoubleConverter());
4240            Assert.AreEqual("{\"position\":new Pos(100,200),\"center\":new PosD(251.6,361.3)}", json);
4241        }
4242
4243        public class ClientMap
4244        {
4245            public Pos position { get; set; }
4246            public PosDouble center { get; set; }
4247        }
4248
4249        public class Pos
4250        {
4251            public int X { get; set; }
4252            public int Y { get; set; }
4253        }
4254
4255        public class PosDouble
4256        {
4257            public double X { get; set; }
4258            public double Y { get; set; }
4259        }
4260
4261        public class PosConverter : JsonConverter
4262        {
4263            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
4264            {
4265                Pos p = (Pos)value;
4266
4267                if (p != null)
4268                    writer.WriteRawValue(String.Format("new Pos({0},{1})", p.X, p.Y));
4269                else
4270                    writer.WriteNull();
4271            }
4272
4273            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
4274            {
4275                throw new NotImplementedException();
4276            }
4277
4278            public override bool CanConvert(Type objectType)
4279            {
4280                return objectType.IsAssignableFrom(typeof(Pos));
4281            }
4282        }
4283
4284        public class PosDoubleConverter : JsonConverter
4285        {
4286            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
4287            {
4288                PosDouble p = (PosDouble)value;
4289
4290                if (p != null)
4291                    writer.WriteRawValue(String.Format(CultureInfo.InvariantCulture, "new PosD({0},{1})", p.X, p.Y));
4292                else
4293                    writer.WriteNull();
4294            }
4295
4296            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
4297            {
4298                throw new NotImplementedException();
4299            }
4300
4301            public override bool CanConvert(Type objectType)
4302            {
4303                return objectType.IsAssignableFrom(typeof(PosDouble));
4304            }
4305        }
4306
4307        [Test]
4308        public void SerializeRefAdditionalContent()
4309        {
4310            //Additional text found in JSON string after finishing deserializing object.
4311            //Test 1
4312            var reference = new Dictionary<string, object>();
4313            reference.Add("$ref", "Persons");
4314            reference.Add("$id", 1);
4315
4316            var child = new Dictionary<string, object>();
4317            child.Add("_id", 2);
4318            child.Add("Name", "Isabell");
4319            child.Add("Father", reference);
4320
4321            var json = JsonConvert.SerializeObject(child, Formatting.Indented);
4322
4323            ExceptionAssert.Throws<JsonSerializationException>(
4324                "Additional content found in JSON reference object. A JSON reference object should only have a $ref property. Path 'Father.$id', line 6, position 11.",
4325                () => { JsonConvert.DeserializeObject<Dictionary<string, object>>(json); });
4326        }
4327
4328        [Test]
4329        public void SerializeRefBadType()
4330        {
4331            ExceptionAssert.Throws<JsonSerializationException>(
4332                "JSON reference $ref property must have a string or null value. Path 'Father.$ref', line 5, position 14.",
4333                () =>
4334                {
4335                    //Additional text found in JSON string after finishing deserializing object.
4336                    //Test 1
4337                    var reference = new Dictionary<string, object>();
4338                    reference.Add("$ref", 1);
4339                    reference.Add("$id", 1);
4340
4341                    var child = new Dictionary<string, object>();
4342                    child.Add("_id", 2);
4343                    child.Add("Name", "Isabell");
4344                    child.Add("Father", reference);
4345
4346                    var json = JsonConvert.SerializeObject(child, Formatting.Indented);
4347                    JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
4348                });
4349        }
4350
4351        [Test]
4352        public void SerializeRefNull()
4353        {
4354            var reference = new Dictionary<string, object>();
4355            reference.Add("$ref", null);
4356            reference.Add("$id", null);
4357            reference.Add("blah", "blah!");
4358
4359            var child = new Dictionary<string, object>();
4360            child.Add("_id", 2);
4361            child.Add("Name", "Isabell");
4362            child.Add("Father", reference);
4363
4364            string json = JsonConvert.SerializeObject(child);
4365
4366            Console.WriteLine(json);
4367
4368            Dictionary<string, object> result = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
4369
4370            Assert.AreEqual(3, result.Count);
4371            Assert.AreEqual(1, ((JObject)result["Father"]).Count);
4372            Assert.AreEqual("blah!", (string)((JObject)result["Father"])["blah"]);
4373        }
4374
4375        public class ConstructorCompexIgnoredProperty
4376        {
4377            [JsonIgnore]
4378            public Product Ignored { get; set; }
4379
4380            public string First { get; set; }
4381            public int Second { get; set; }
4382
4383            public ConstructorCompexIgnoredProperty(string first, int second)
4384            {
4385                First = first;
4386                Second = second;
4387            }
4388        }
4389
4390        [Test]
4391        public void DeserializeIgnoredPropertyInConstructor()
4392        {
4393            string json = @"{""First"":""First"",""Second"":2,""Ignored"":{""Name"":""James""},""AdditionalContent"":{""LOL"":true}}";
4394
4395            ConstructorCompexIgnoredProperty cc = JsonConvert.DeserializeObject<ConstructorCompexIgnoredProperty>(json);
4396            Assert.AreEqual("First", cc.First);
4397            Assert.AreEqual(2, cc.Second);
4398            Assert.AreEqual(null, cc.Ignored);
4399        }
4400
4401        [Test]
4402        public void DeserializeFloatAsDecimal()
4403        {
4404            string json = @"{'value':9.9}";
4405
4406            var dic = JsonConvert.DeserializeObject<IDictionary<string, object>>(
4407                json, new JsonSerializerSettings
4408                {
4409                    FloatParseHandling = FloatParseHandling.Decimal
4410                });
4411
4412            Assert.AreEqual(typeof(decimal), dic["value"].GetType());
4413            Assert.AreEqual(9.9m, dic["value"]);
4414        }
4415
4416
4417
4418        public class DictionaryKey
4419        {
4420            public string Value { get; set; }
4421
4422            public override string ToString()
4423            {
4424                return Value;
4425            }
4426
4427            public static implicit operator DictionaryKey(string value)
4428            {
4429                return new DictionaryKey() { Value = value };
4430            }
4431        }
4432
4433        [Test]
4434        public void SerializeDeserializeDictionaryKey()
4435        {
4436            Dictionary<DictionaryKey, string> dictionary = new Dictionary<DictionaryKey, string>();
4437
4438            dictionary.Add(new DictionaryKey() { Value = "First!" }, "First");
4439            dictionary.Add(new DictionaryKey() { Value = "Second!" }, "Second");
4440
4441            string json = JsonConvert.SerializeObject(dictionary, Formatting.Indented);
4442
4443            Assert.AreEqual(@"{
4444  ""First!"": ""First"",
4445  ""Second!"": ""Second""
4446}", json);
4447
4448            Dictionary<DictionaryKey, string> newDictionary =
4449                JsonConvert.DeserializeObject<Dictionary<DictionaryKey, string>>(json);
4450
4451            Assert.AreEqual(2, newDictionary.Count);
4452        }
4453
4454        [Test]
4455        public void SerializeNullableArray()
4456        {
4457            string jsonText = JsonConvert.SerializeObject(new double?[] { 2.4, 4.3, null }, Formatting.Indented);
4458
4459            Assert.AreEqual(@"[
4460  2.4,
4461  4.3,
4462  null
4463]", jsonText);
4464        }
4465
4466        [Test]
4467        public void DeserializeNullableArray()
4468        {
4469            double?[] d = (double?[])JsonConvert.DeserializeObject(@"[
4470  2.4,
4471  4.3,
4472  null
4473]", typeof(double?[]));
4474
4475            Assert.AreEqual(3, d.Length);
4476            Assert.AreEqual(2.4, d[0]);
4477            Assert.AreEqual(4.3, d[1]);
4478            Assert.AreEqual(null, d[2]);
4479        }
4480
4481#if !NET20
4482        [Test]
4483        public void SerializeHashSet()
4484        {
4485            string jsonText = JsonConvert.SerializeObject(new HashSet<string>()
4486            {
4487                "One",
4488                "2",
4489                "III"
4490            }, Formatting.Indented);
4491
4492            Assert.AreEqual(@"[
4493  ""One"",
4494  ""2"",
4495  ""III""
4496]", jsonText);
4497
4498            HashSet<string> d = JsonConvert.DeserializeObject<HashSet<string>>(jsonText);
4499
4500            Assert.AreEqual(3, d.Count);
4501            Assert.IsTrue(d.Contains("One"));
4502            Assert.IsTrue(d.Contains("2"));
4503            Assert.IsTrue(d.Contains("III"));
4504        }
4505#endif
4506
4507        private class MyClass
4508        {
4509            public byte[] Prop1 { get; set; }
4510
4511            public MyClass()
4512            {
4513                Prop1 = new byte[0];
4514            }
4515        }
4516
4517        [Test]
4518        public void DeserializeByteArray()
4519        {
4520            JsonSerializer serializer1 = new JsonSerializer();
4521            serializer1.Converters.Add(new IsoDateTimeConverter());
4522            serializer1.NullValueHandling = NullValueHandling.Ignore;
4523
4524            string json = @"[{""Prop1"":""""},{""Prop1"":""""}]";
4525
4526            JsonTextReader reader = new JsonTextReader(new StringReader(json));
4527
4528            MyClass[] z = (MyClass[])serializer1.Deserialize(reader, typeof(MyClass[]));
4529            Assert.AreEqual(2, z.Length);
4530            Assert.AreEqual(0, z[0].Prop1.Length);
4531            Assert.AreEqual(0, z[1].Prop1.Length);
4532        }
4533
4534#if !NET20 && !NETFX_CORE
4535        public class StringDictionaryTestClass
4536        {
4537            public StringDictionary StringDictionaryProperty { get; set; }
4538        }
4539
4540        [Test]
4541        public void StringDictionaryTest()
4542        {
4543            string classRef = typeof(StringDictionary).FullName;
4544
4545            StringDictionaryTestClass s1 = new StringDictionaryTestClass()
4546            {
4547                StringDictionaryProperty = new StringDictionary()
4548                {
4549                    { "1", "One" },
4550                    { "2", "II" },
4551                    { "3", "3" }
4552                }
4553            };
4554
4555            string json = JsonConvert.SerializeObject(s1, Formatting.Indented);
4556
4557            ExceptionAssert.Throws<JsonSerializationException>(
4558                "Cannot create and populate list type " + classRef + ". Path 'StringDictionaryProperty', line 2, position 32.",
4559                () => { JsonConvert.DeserializeObject<StringDictionaryTestClass>(json); });
4560        }
4561#endif
4562
4563        [JsonObject(MemberSerialization.OptIn)]
4564        public struct StructWithAttribute
4565        {
4566            public string MyString { get; set; }
4567
4568            [JsonProperty]
4569            public int MyInt { get; set; }
4570        }
4571
4572        [Test]
4573        public void SerializeStructWithJsonObjectAttribute()
4574        {
4575            StructWithAttribute testStruct = new StructWithAttribute
4576            {
4577                MyInt = int.MaxValue
4578            };
4579
4580            string json = JsonConvert.SerializeObject(testStruct, Formatting.Indented);
4581
4582            Assert.AreEqual(@"{
4583  ""MyInt"": 2147483647
4584}", json);
4585
4586            StructWithAttribute newStruct = JsonConvert.DeserializeObject<StructWithAttribute>(json);
4587
4588            Assert.AreEqual(int.MaxValue, newStruct.MyInt);
4589        }
4590
4591        public class TimeZoneOffsetObject
4592        {
4593            public DateTimeOffset Offset { get; set; }
4594        }
4595
4596#if !NET20
4597        [Test]
4598        public void ReadWriteTimeZoneOffsetIso()
4599        {
4600            var serializeObject = JsonConvert.SerializeObject(new TimeZoneOffsetObject
4601            {
4602                Offset = new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(6))
4603            });
4604
4605            Assert.AreEqual("{\"Offset\":\"2000-01-01T00:00:00+06:00\"}", serializeObject);
4606
4607            JsonTextReader reader = new JsonTextReader(new StringReader(serializeObject));
4608            reader.DateParseHandling = DateParseHandling.None;
4609            
4610            JsonSerializer serializer = new JsonSerializer();
4611
4612            var deserializeObject = serializer.Deserialize<TimeZoneOffsetObject>(reader);
4613
4614            Assert.AreEqual(TimeSpan.FromHours(6), deserializeObject.Offset.Offset);
4615            Assert.AreEqual(new DateTime(2000, 1, 1), deserializeObject.Offset.Date);
4616        }
4617
4618        [Test]
4619        public void DeserializePropertyNullableDateTimeOffsetExactIso()
4620        {
4621            NullableDateTimeTestClass d = JsonConvert.DeserializeObject<NullableDateTimeTestClass>("{\"DateTimeOffsetField\":\"2000-01-01T00:00:00+06:00\"}");
4622            Assert.AreEqual(new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(6)), d.DateTimeOffsetField);
4623        }
4624
4625        [Test]
4626        public void ReadWriteTimeZoneOffsetMsAjax()
4627        {
4628            var serializeObject = JsonConvert.SerializeObject(new TimeZoneOffsetObject
4629            {
4630                Offset = new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(6))
4631            }, Formatting.None, new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.MicrosoftDateFormat });
4632
4633            Assert.AreEqual("{\"Offset\":\"\\/Date(946663200000+0600)\\/\"}", serializeObject);
4634
4635            JsonTextReader reader = new JsonTextReader(new StringReader(serializeObject));
4636
4637            JsonSerializer serializer = new JsonSerializer();
4638            serializer.DateParseHandling = DateParseHandling.None;
4639
4640            var deserializeObject = serializer.Deserialize<TimeZoneOffsetObject>(reader);
4641
4642            Assert.AreEqual(TimeSpan.FromHours(6), deserializeObject.Offset.Offset);
4643            Assert.AreEqual(new DateTime(2000, 1, 1), deserializeObject.Offset.Date);
4644        }
4645
4646        [Test]
4647        public void DeserializePropertyNullableDateTimeOffsetExactMsAjax()
4648        {
4649            NullableDateTimeTestClass d = JsonConvert.DeserializeObject<NullableDateTimeTestClass>("{\"DateTimeOffsetField\":\"\\/Date(946663200000+0600)\\/\"}");
4650            Assert.AreEqual(new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(6)), d.DateTimeOffsetField);
4651        }
4652#endif
4653
4654        public abstract class LogEvent
4655        {
4656            [JsonProperty("event")]
4657            public abstract string EventName { get; }
4658        }
4659
4660        public class DerivedEvent : LogEvent
4661        {
4662            public override string EventName
4663            {
4664                get { return "derived"; }
4665            }
4666        }
4667
4668        [Test]
4669        public void OverridenPropertyMembers()
4670        {
4671            string json = JsonConvert.SerializeObject(new DerivedEvent(), Formatting.Indented);
4672
4673            Assert.AreEqual(@"{
4674  ""event"": ""derived""
4675}", json);
4676        }
4677
4678#if !(NET35 || NET20 || PORTABLE40)
4679        [Test]
4680        public void SerializeExpandoObject()
4681        {
4682            dynamic expando = new ExpandoObject();
4683            expando.Int = 1;
4684            expando.Decimal = 99.9d;
4685            expando.Complex = new ExpandoObject();
4686            expando.Complex.String = "I am a string";
4687            expando.Complex.DateTime = new DateTime(2000, 12, 20, 18, 55, 0, DateTimeKind.Utc);
4688
4689            string json = JsonConvert.SerializeObject(expando, Formatting.Indented);
4690            Assert.AreEqual(@"{
4691  ""Int"": 1,
4692  ""Decimal"": 99.9,
4693  ""Complex"": {
4694    ""String"": ""I am a string"",
4695    ""DateTime"": ""2000-12-20T18:55:00Z""
4696  }
4697}", json);
4698
4699            IDictionary<string, object> newExpando = JsonConvert.DeserializeObject<ExpandoObject>(json);
4700
4701            CustomAssert.IsInstanceOfType(typeof(long), newExpando["Int"]);
4702            Assert.AreEqual((long)expando.Int, newExpando["Int"]);
4703
4704            CustomAssert.IsInstanceOfType(typeof(double), newExpando["Decimal"]);
4705            Assert.AreEqual(expando.Decimal, newExpando["Decimal"]);
4706
4707            CustomAssert.IsInstanceOfType(typeof(ExpandoObject), newExpando["Complex"]);
4708            IDictionary<string, object> o = (ExpandoObject)newExpando["Complex"];
4709
4710            CustomAssert.IsInstanceOfType(typeof(string), o["String"]);
4711            Assert.AreEqual(expando.Complex.String, o["String"]);
4712
4713            CustomAssert.IsInstanceOfType(typeof(DateTime), o["DateTime"]);
4714            Assert.AreEqual(expando.Complex.DateTime, o["DateTime"]);
4715        }
4716#endif
4717
4718        [Test]
4719        public void DeserializeDecimalExact()
4720        {
4721            decimal d = JsonConvert.DeserializeObject<decimal>("123456789876543.21");
4722            Assert.AreEqual(123456789876543.21m, d);
4723        }
4724
4725        [Test]
4726        public void DeserializeNullableDecimalExact()
4727        {
4728            decimal? d = JsonConvert.DeserializeObject<decimal?>("123456789876543.21");
4729            Assert.AreEqual(123456789876543.21m, d);
4730        }
4731
4732        [Test]
4733        public void DeserializeDecimalPropertyExact()
4734        {
4735            string json = "{Amount:123456789876543.21}";
4736            JsonTextReader reader = new JsonTextReader(new StringReader(json));
4737            reader.FloatParseHandling = FloatParseHandling.Decimal;
4738
4739            JsonSerializer serializer = new JsonSerializer();
4740
4741            Invoice i = serializer.Deserialize<Invoice>(reader);
4742            Assert.AreEqual(123456789876543.21m, i.Amount);
4743        }
4744
4745        [Test]
4746        public void DeserializeDecimalArrayExact()
4747        {
4748            string json = "[123456789876543.21]";
4749            IList<decimal> a = JsonConvert.DeserializeObject<IList<decimal>>(json);
4750            Assert.AreEqual(123456789876543.21m, a[0]);
4751        }
4752
4753        [Test]
4754        public void DeserializeDecimalDictionaryExact()
4755        {
4756            string json = "{'Value':123456789876543.21}";
4757            JsonTextReader reader = new JsonTextReader(new StringReader(json));
4758            reader.FloatParseHandling = FloatParseHandling.Decimal;
4759
4760            JsonSerializer serializer = new JsonSerializer();
4761
4762            IDictionary<string, decimal> d = serializer.Deserialize<IDictionary<string, decimal>>(reader);
4763            Assert.AreEqual(123456789876543.21m, d["Value"]);
4764        }
4765
4766        public struct Vector
4767        {
4768            public float X;
4769            public float Y;
4770            public float Z;
4771
4772            public override string ToString()
4773            {
4774                return string.Format("({0},{1},{2})", X, Y, Z);
4775            }
4776        }
4777
4778        public class VectorParent
4779        {
4780            public Vector Position;
4781        }
4782
4783        [Test]
4784        public void DeserializeStructProperty()
4785        {
4786            VectorParent obj = new VectorParent();
4787            obj.Position = new Vector { X = 1, Y = 2, Z = 3 };
4788
4789            string str = JsonConvert.SerializeObject(obj);
4790
4791            obj = JsonConvert.DeserializeObject<VectorParent>(str);
4792
4793            Assert.AreEqual(1, obj.Position.X);
4794            Assert.AreEqual(2, obj.Position.Y);
4795            Assert.AreEqual(3, obj.Position.Z);
4796        }
4797
4798        [JsonObject(MemberSerialization.OptIn)]
4799        public class Derived : Base
4800        {
4801            [JsonProperty]
4802            public string IDoWork { get; private set; }
4803
4804            private Derived()
4805            {
4806            }
4807
4808            internal Derived(string dontWork, string doWork)
4809                : base(dontWork)
4810            {
4811                IDoWork = doWork;
4812            }
4813        }
4814
4815        [JsonObject(MemberSerialization.OptIn)]
4816        public class Base
4817        {
4818            [JsonProperty]
4819            public string IDontWork { get; private set; }
4820
4821            protected Base()
4822            {
4823            }
4824
4825            internal Base(string dontWork)
4826            {
4827                IDontWork = dontWork;
4828            }
4829        }
4830
4831        [Test]
4832        public void PrivateSetterOnBaseClassProperty()
4833        {
4834            var derived = new Derived("meh", "woo");
4835
4836            var settings = new JsonSerializerSettings
4837            {
4838                TypeNameHandling = TypeNameHandling.Objects,
4839                ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
4840            };
4841
4842            string json = JsonConvert.SerializeObject(derived, Formatting.Indented, settings);
4843
4844            var meh = JsonConvert.DeserializeObject<Base>(json, settings);
4845
4846            Assert.AreEqual(((Derived)meh).IDoWork, "woo");
4847            Assert.AreEqual(meh.IDontWork, "meh");
4848        }
4849
4850#if !(NET20 || NETFX_CORE)
4851        [DataContract]
4852        public struct StructISerializable : ISerializable
4853        {
4854            private string _name;
4855
4856            public StructISerializable(SerializationInfo info, StreamingContext context)
4857            {
4858                _name = info.GetString("Name");
4859            }
4860
4861            [DataMember]
4862            public string Name
4863            {
4864                get { return _name; }
4865                set { _name = value; }
4866            }
4867
4868            public void GetObjectData(SerializationInfo info, StreamingContext context)
4869            {
4870                info.AddValue("Name", _name);
4871            }
4872        }
4873
4874        [DataContract]
4875        public class NullableStructPropertyClass
4876        {
4877            private StructISerializable _foo1;
4878            private StructISerializable? _foo2;
4879
4880            [DataMember]
4881            public StructISerializable Foo1
4882            {
4883                get { return _foo1; }
4884                set { _foo1 = value; }
4885            }
4886
4887            [DataMember]
4888            public StructISerializable? Foo2
4889            {
4890                get { return _foo2; }
4891                set { _foo2 = value; }
4892            }
4893        }
4894
4895        [Test]
4896        public void DeserializeNullableStruct()
4897        {
4898            NullableStructPropertyClass nullableStructPropertyClass = new NullableStructPropertyClass();
4899            nullableStructPropertyClass.Foo1 = new StructISerializable() { Name = "foo 1" };
4900            nullableStructPropertyClass.Foo2 = new StructISerializable() { Name = "foo 2" };
4901
4902            NullableStructPropertyClass barWithNull = new NullableStructPropertyClass();
4903            barWithNull.Foo1 = new StructISerializable() { Name = "foo 1" };
4904            barWithNull.Foo2 = null;
4905
4906            //throws error on deserialization because bar1.Foo2 is of type Foo?
4907            string s = JsonConvert.SerializeObject(nullableStructPropertyClass);
4908            NullableStructPropertyClass deserialized = deserialize(s);
4909            Assert.AreEqual(deserialized.Foo1.Name, "foo 1");
4910            Assert.AreEqual(deserialized.Foo2.Value.Name, "foo 2");
4911
4912            //no error Foo2 is null
4913            s = JsonConvert.SerializeObject(barWithNull);
4914            deserialized = deserialize(s);
4915            Assert.AreEqual(deserialized.Foo1.Name, "foo 1");
4916            Assert.AreEqual(deserialized.Foo2, null);
4917        }
4918
4919
4920        private static NullableStructPropertyClass deserialize(string serStr)
4921        {
4922            return JsonConvert.DeserializeObject<NullableStructPropertyClass>(
4923                serStr,
4924                new JsonSerializerSettings
4925                {
4926                    NullValueHandling = NullValueHandling.Ignore,
4927                    MissingMemberHandling = MissingMemberHandling.Ignore
4928                });
4929        }
4930#endif
4931
4932        public class Response
4933        {
4934            public string Name { get; set; }
4935            public JToken Data { get; set; }
4936        }
4937
4938        [Test]
4939        public void DeserializeJToken()
4940        {
4941            Response response = new Response
4942            {
4943                Name = "Success",
4944                Data = new JObject(new JProperty("First", "Value1"), new JProperty("Second", "Value2"))
4945            };
4946
4947            string json = JsonConvert.SerializeObject(response, Formatting.Indented);
4948
4949            Response deserializedResponse = JsonConvert.DeserializeObject<Response>(json);
4950
4951            Assert.AreEqual("Success", deserializedResponse.Name);
4952            Assert.IsTrue(deserializedResponse.Data.DeepEquals(response.Data));
4953        }
4954
4955        [Test]
4956        public void DeserializeMinValueDecimal()
4957        {
4958            var data = new DecimalTest(decimal.MinValue);
4959            var json = JsonConvert.SerializeObject(data);
4960            var obj = JsonConvert.DeserializeObject<DecimalTest>(json, new JsonSerializerSettings { MetadataPropertyHandling = MetadataPropertyHandling.Default });
4961
4962            Assert.AreEqual(decimal.MinValue, obj.Value);
4963        }
4964
4965        [Test]
4966        public void NonPublicConstructorWithJsonConstructorTest()
4967        {
4968            NonPublicConstructorWithJsonConstructor c = JsonConvert.DeserializeObject<NonPublicConstructorWithJsonConstructor>("{}");
4969            Assert.AreEqual("NonPublic", c.Constructor);
4970        }
4971
4972        [Test]
4973        public void PublicConstructorOverridenByJsonConstructorTest()
4974        {
4975            PublicConstructorOverridenByJsonConstructor c = JsonConvert.DeserializeObject<PublicConstructorOverridenByJsonConstructor>("{Value:'value!'}");
4976            Assert.AreEqual("Public Paramatized", c.Constructor);
4977            Assert.AreEqual("value!", c.Value);
4978        }
4979
4980        [Test]
4981        public void MultipleParamatrizedConstructorsJsonConstructorTest()
4982        {
4983            MultipleParamatrizedConstructorsJsonConstructor c = JsonConvert.DeserializeObject<MultipleParamatrizedConstructorsJsonConstructor>("{Value:'value!', Age:1}");
4984            Assert.AreEqual("Public Paramatized 2", c.Constructor);
4985            Assert.AreEqual("value!", c.Value);
4986            Assert.AreEqual(1, c.Age);
4987        }
4988
4989        [Test]
4990        public void DeserializeEnumerable()
4991        {
4992            EnumerableClass c = new EnumerableClass
4993            {
4994                Enumerable = new List<string> { "One", "Two", "Three" }
4995            };
4996
4997            string json = JsonConvert.SerializeObject(c, Formatting.Indented);
4998
4999            Assert.AreEqual(@"{
5000  ""Enumerable"": [
5001    ""One"",
5002    ""Two"",
5003    ""Three""
5004  ]
5005}", json);
5006
5007            EnumerableClass c2 = JsonConvert.DeserializeObject<EnumerableClass>(json);
5008
5009            Assert.AreEqual("One", c2.Enumerable.ElementAt(0));
5010            Assert.AreEqual("Two", c2.Enumerable.ElementAt(1));
5011            Assert.AreEqual("Three", c2.Enumerable.ElementAt(2));
5012        }
5013
5014        [Test]
5015        public void SerializeAttributesOnBase()
5016        {
5017            ComplexItem i = new ComplexItem();
5018
5019            string json = JsonConvert.SerializeObject(i, Formatting.Indented);
5020
5021            Assert.AreEqual(@"{
5022  ""Name"": null
5023}", json);
5024        }
5025
5026        [Test]
5027        public void DeserializeStringEnglish()
5028        {
5029            string json = @"{
5030  'Name': 'James Hughes',
5031  'Age': '40',
5032  'Height': '44.4',
5033  'Price': '4'
5034}";
5035
5036            DeserializeStringConvert p = JsonConvert.DeserializeObject<DeserializeStringConvert>(json);
5037            Assert.AreEqual(40, p.Age);
5038            Assert.AreEqual(44.4, p.Height);
5039            Assert.AreEqual(4m, p.Price);
5040        }
5041
5042        [Test]
5043        public void DeserializeNullDateTimeValueTest()
5044        {
5045            ExceptionAssert.Throws<JsonSerializationException>(
5046                "Error converting value {null} to type 'System.DateTime'. Path '', line 1, position 4.",
5047                () => { JsonConvert.DeserializeObject("null", typeof(DateTime)); });
5048        }
5049
5050        [Test]
5051        public void DeserializeNullNullableDateTimeValueTest()
5052        {
5053            object dateTime = JsonConvert.DeserializeObject("null", typeof(DateTime?));
5054
5055            Assert.IsNull(dateTime);
5056        }
5057
5058        [Test]
5059        public void MultiIndexSuperTest()
5060        {
5061            MultiIndexSuper e = new MultiIndexSuper();
5062
5063            string json = JsonConvert.SerializeObject(e, Formatting.Indented);
5064
5065            Assert.AreEqual(@"{}", json);
5066        }
5067
5068        public class MultiIndexSuper : MultiIndexBase
5069        {
5070        }
5071
5072        public abstract class MultiIndexBase
5073        {
5074            protected internal object this[string propertyName]
5075            {
5076                get { return null; }
5077                set { }
5078            }
5079
5080            protected internal object this[object property]
5081            {
5082                get { return null; }
5083                set { }
5084            }
5085        }
5086
5087        public class CommentTestClass
5088        {
5089            public bool Indexed { get; set; }
5090            public int StartYear { get; set; }
5091            public IList<decimal> Values { get; set; }
5092        }
5093
5094        [Test]
5095        public void CommentTestClassTest()
5096        {
5097            string json = @"{""indexed"":true, ""startYear"":1939, ""values"":
5098                            [  3000,  /* 1940-1949 */
5099                               3000,   3600,   3600,   3600,   3600,   4200,   4200,   4200,   4200,   4800,  /* 1950-1959 */
5100                               4800,   4800,   4800,   4800,   4800,   4800,   6600,   6600,   7800,   7800,  /* 1960-1969 */
5101                               7800,   7800,   9000,  10800,  13200,  14100,  15300,  16500,  17700,  22900,  /* 1970-1979 */
5102                              25900,  29700,  32400,  35700,  37800,  39600,  42000,  43800,  45000,  48000,  /* 1980-1989 */
5103                              51300,  53400,  55500,  57600,  60600,  61200,  62700,  65400,  68400,  72600,  /* 1990-1999 */
5104                              76200,  80400,  84900,  87000,  87900,  90000,  94200,  97500, 102000, 106800,  /* 2000-2009 */
5105                             106800, 106800]  /* 2010-2011 */
5106                                }";
5107
5108            CommentTestClass commentTestClass = JsonConvert.DeserializeObject<CommentTestClass>(json);
5109
5110            Assert.AreEqual(true, commentTestClass.Indexed);
5111            Assert.AreEqual(1939, commentTestClass.StartYear);
5112            Assert.AreEqual(63, commentTestClass.Values.Count);
5113        }
5114
5115        private class DTOWithParameterisedConstructor
5116        {
5117            public DTOWithParameterisedConstructor(string A)
5118            {
5119                this.A = A;
5120                B = 2;
5121            }
5122
5123            public string A { get; set; }
5124            public int? B { get; set; }
5125        }
5126
5127        private class DTOWithoutParameterisedConstructor
5128        {
5129            public DTOWithoutParameterisedConstructor()
5130            {
5131                B = 2;
5132            }
5133
5134            public string A { get; set; }
5135            public int? B { get; set; }
5136        }
5137
5138        [Test]
5139        public void PopulationBehaviourForOmittedPropertiesIsTheSameForParameterisedConstructorAsForDefaultConstructor()
5140        {
5141            string json = @"{A:""Test""}";
5142
5143            var withoutParameterisedConstructor = JsonConvert.DeserializeObject<DTOWithoutParameterisedConstructor>(json);
5144            var withParameterisedConstructor = JsonConvert.DeserializeObject<DTOWithParameterisedConstructor>(json);
5145            Assert.AreEqual(withoutParameterisedConstructor.B, withParameterisedConstructor.B);
5146        }
5147
5148        public class EnumerableArrayPropertyClass
5149        {
5150            public IEnumerable<int> Numbers
5151            {
5152                get
5153                {
5154                    return new[] { 1, 2, 3 }; //fails
5155                    //return new List<int>(new[] { 1, 2, 3 }); //works
5156                }
5157            }
5158        }
5159
5160        [Test]
5161        public void SkipPopulatingArrayPropertyClass()
5162        {
5163            string json = JsonConvert.SerializeObject(new EnumerableArrayPropertyClass());
5164            JsonConvert.DeserializeObject<EnumerableArrayPropertyClass>(json);
5165        }
5166
5167#if !(NET20)
5168        [DataContract]
5169        public class BaseDataContract
5170        {
5171            [DataMember(Name = "virtualMember")]
5172            public virtual string VirtualMember { get; set; }
5173
5174            [DataMember(Name = "nonVirtualMember")]
5175            public string NonVirtualMember { get; set; }
5176        }
5177
5178        public class ChildDataContract : BaseDataContract
5179        {
5180            public override string VirtualMember { get; set; }
5181            public string NewMember { get; set; }
5182        }
5183
5184        [Test]
5185        public void ChildDataContractTest()
5186        {
5187            ChildDataContract cc = new ChildDataContract
5188            {
5189                VirtualMember = "VirtualMember!",
5190                NonVirtualMember = "NonVirtualMember!"
5191            };
5192
5193            string result = JsonConvert.SerializeObject(cc, Formatting.Indented);
5194            //      Assert.AreEqual(@"{
5195            //  ""VirtualMember"": ""VirtualMember!"",
5196            //  ""NewMember"": null,
5197            //  ""nonVirtualMember"": ""NonVirtualMember!""
5198            //}", result);
5199
5200            Console.WriteLine(result);
5201        }
5202
5203        [Test]
5204        public void ChildDataContractTestWithDataContractSerializer()
5205        {
5206            ChildDataContract cc = new ChildDataContract
5207            {
5208                VirtualMember = "VirtualMember!",
5209                NonVirtualMember = "NonVirtualMember!"
5210            };
5211
5212            DataContractSerializer serializer = new DataContractSerializer(typeof(ChildDataContract));
5213
5214            MemoryStream ms = new MemoryStream();
5215            serializer.WriteObject(ms, cc);
5216
5217            string xml = Encoding.UTF8.GetString(ms.ToArray(), 0, Convert.ToInt32(ms.Length));
5218
5219            Console.WriteLine(xml);
5220        }
5221#endif
5222
5223        [JsonObject(MemberSerialization = MemberSerialization.OptIn)]
5224        public class BaseObject
5225        {
5226            [JsonProperty(PropertyName = "virtualMember")]
5227            public virtual string VirtualMember { get; set; }
5228
5229            [JsonProperty(PropertyName = "nonVirtualMember")]
5230            public string NonVirtualMember { get; set; }
5231        }
5232
5233        public class ChildObject : BaseObject
5234        {
5235            public override string VirtualMember { get; set; }
5236            public string NewMember { get; set; }
5237        }
5238
5239        public class ChildWithDifferentOverrideObject : BaseObject
5240        {
5241            [JsonProperty(PropertyName = "differentVirtualMember")]
5242            public override string VirtualMember { get; set; }
5243        }
5244
5245        [Test]
5246        public void ChildObjectTest()
5247        {
5248            ChildObject cc = new ChildObject
5249            {
5250                VirtualMember = "VirtualMember!",
5251                NonVirtualMember = "NonVirtualMember!"
5252            };
5253
5254            string result = JsonConvert.SerializeObject(cc);
5255            Assert.AreEqual(@"{""virtualMember"":""VirtualMember!"",""nonVirtualMember"":""NonVirtualMember!""}", result);
5256        }
5257
5258        [Test]
5259        public void ChildWithDifferentOverrideObjectTest()
5260        {
5261            ChildWithDifferentOverrideObject cc = new ChildWithDifferentOverrideObject
5262            {
5263                VirtualMember = "VirtualMember!",
5264                NonVirtualMember = "NonVirtualMember!"
5265            };
5266
5267            string result = JsonConvert.SerializeObject(cc);
5268            Console.WriteLine(result);
5269            Assert.AreEqual(@"{""differentVirtualMember"":""VirtualMember!"",""nonVirtualMember"":""NonVirtualMember!""}", result);
5270        }
5271
5272        [JsonObject(MemberSerialization = MemberSerialization.OptIn)]
5273        public interface IInterfaceObject
5274        {
5275            [JsonProperty(PropertyName = "virtualMember")]
5276            [JsonConverter(typeof(IsoDateTimeConverter))]
5277            DateTime InterfaceMember { get; set; }
5278        }
5279
5280        public class ImplementInterfaceObject : IInterfaceObject
5281        {
5282            public DateTime InterfaceMember { get; set; }
5283            public string NewMember { get; set; }
5284
5285            [JsonProperty(PropertyName = "newMemberWithProperty")]
5286            public string NewMemberWithProperty { get; set; }
5287        }
5288
5289        [Test]
5290        public void ImplementInterfaceObjectTest()
5291        {
5292            ImplementInterfaceObject cc = new ImplementInterfaceObject
5293            {
5294                InterfaceMember = new DateTime(2010, 12, 31, 0, 0, 0, DateTimeKind.Utc),
5295                NewMember = "NewMember!"
5296            };
5297
5298            string result = JsonConvert.SerializeObject(cc, Formatting.Indented);
5299
5300            Assert.AreEqual(@"{
5301  ""virtualMember"": ""2010-12-31T00:00:00Z"",
5302  ""newMemberWithProperty"": null
5303}", result);
5304        }
5305
5306        public class NonDefaultConstructorWithReadOnlyCollectionProperty
5307        {
5308            public string Title { get; set; }
5309            public IList<string> Categories { get; private set; }
5310
5311            public NonDefaultConstructorWithReadOnlyCollectionProperty(string title)
5312            {
5313                Title = title;
5314                Categories = new List<string>();
5315            }
5316        }
5317
5318        [Test]
5319        public void NonDefaultConstructorWithReadOnlyCollectionPropertyTest()
5320        {
5321            NonDefaultConstructorWithReadOnlyCollectionProperty c1 = new NonDefaultConstructorWithReadOnlyCollectionProperty("blah");
5322            c1.Categories.Add("one");
5323            c1.Categories.Add("two");
5324
5325            string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
5326            Assert.AreEqual(@"{
5327  ""Title"": ""blah"",
5328  ""Categories"": [
5329    ""one"",
5330    ""two""
5331  ]
5332}", json);
5333
5334            NonDefaultConstructorWithReadOnlyCollectionProperty c2 = JsonConvert.DeserializeObject<NonDefaultConstructorWithReadOnlyCollectionProperty>(json);
5335            Assert.AreEqual(c1.Title, c2.Title);
5336            Assert.AreEqual(c1.Categories.Count, c2.Categories.Count);
5337            Assert.AreEqual("one", c2.Categories[0]);
5338            Assert.AreEqual("two", c2.Categories[1]);
5339        }
5340
5341        public class NonDefaultConstructorWithReadOnlyDictionaryProperty
5342        {
5343            public string Title { get; set; }
5344            public IDictionary<string, int> Categories { get; private set; }
5345
5346            public NonDefaultConstructorWithReadOnlyDictionaryProperty(string title)
5347            {
5348                Title = title;
5349                Categories = new Dictionary<string, int>();
5350            }
5351        }
5352
5353        [Test]
5354        public void NonDefaultConstructorWithReadOnlyDictionaryPropertyTest()
5355        {
5356            NonDefaultConstructorWithReadOnlyDictionaryProperty c1 = new NonDefaultConstructorWithReadOnlyDictionaryProperty("blah");
5357            c1.Categories.Add("one", 1);
5358            c1.Categories.Add("two", 2);
5359
5360            string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
5361            Assert.AreEqual(@"{
5362  ""Title"": ""blah"",
5363  ""Categories"": {
5364    ""one"": 1,
5365    ""two"": 2
5366  }
5367}", json);
5368
5369            NonDefaultConstructorWithReadOnlyDictionaryProperty c2 = JsonConvert.DeserializeObject<NonDefaultConstructorWithReadOnlyDictionaryProperty>(json);
5370            Assert.AreEqual(c1.Title, c2.Title);
5371            Assert.AreEqual(c1.Categories.Count, c2.Categories.Count);
5372            Assert.AreEqual(1, c2.Categories["one"]);
5373            Assert.AreEqual(2, c2.Categories["two"]);
5374        }
5375
5376        [JsonObject(MemberSerialization.OptIn)]
5377        public class ClassAttributeBase
5378        {
5379            [JsonProperty]
5380            public string BaseClassValue { get; set; }
5381        }
5382
5383        public class ClassAttributeDerived : ClassAttributeBase
5384        {
5385            [JsonProperty]
5386            public string DerivedClassValue { get; set; }
5387
5388            public string NonSerialized { get; set; }
5389        }
5390
5391        public class CollectionClassAttributeDerived : ClassAttributeBase, ICollection<object>
5392        {
5393            [JsonProperty]
5394            public string CollectionDerivedClassValue { get; set; }
5395
5396            public void Add(object item)
5397            {
5398                throw new NotImplementedException();
5399            }
5400
5401            public void Clear()
5402            {
5403                throw new NotImplementedException();
5404            }
5405
5406            public bool Contains(object item)
5407            {
5408                throw new NotImplementedException();
5409            }
5410
5411            public void CopyTo(object[] array, int arrayIndex)
5412            {
5413                throw new NotImplementedException();
5414            }
5415
5416            public int Count
5417            {
5418                get { throw new NotImplementedException(); }
5419            }
5420
5421            public bool IsReadOnly
5422            {
5423                get { throw new NotImplementedException(); }
5424            }
5425
5426            public bool Remove(object item)
5427            {
5428                throw new NotImplementedException();
5429            }
5430
5431            public IEnumerator<object> GetEnumerator()
5432            {
5433                throw new NotImplementedException();
5434            }
5435
5436            IEnumerator IEnumerable.GetEnumerator()
5437            {
5438                throw new NotImplementedException();
5439            }
5440        }
5441
5442        [Test]
5443        public void ClassAttributesInheritance()
5444        {
5445            string json = JsonConvert.SerializeObject(new ClassAttributeDerived
5446            {
5447                BaseClassValue = "BaseClassValue!",
5448                DerivedClassValue = "DerivedClassValue!",
5449                NonSerialized = "NonSerialized!"
5450            }, Formatting.Indented);
5451
5452            Assert.AreEqual(@"{
5453  ""DerivedClassValue"": ""DerivedClassValue!"",
5454  ""BaseClassValue"": ""BaseClassValue!""
5455}", json);
5456
5457            json = JsonConvert.SerializeObject(new CollectionClassAttributeDerived
5458            {
5459                BaseClassValue = "BaseClassValue!",
5460                CollectionDerivedClassValue = "CollectionDerivedClassValue!"
5461            }, Formatting.Indented);
5462
5463            Assert.AreEqual(@"{
5464  ""CollectionDerivedClassValue"": ""CollectionDerivedClassValue!"",
5465  ""BaseClassValue"": ""BaseClassValue!""
5466}", json);
5467        }
5468
5469        public class PrivateMembersClassWithAttributes
5470        {
5471            public PrivateMembersClassWithAttributes(string privateString, string internalString, string readonlyString)
5472            {
5473                _privateString = privateString;
5474                _readonlyString = readonlyString;
5475                _internalString = internalString;
5476            }
5477
5478            public PrivateMembersClassWithAttributes()
5479            {
5480                _readonlyString = "default!";
5481            }
5482
5483            [JsonProperty]
5484            private string _privateString;
5485
5486            [JsonProperty]
5487            private readonly string _readonlyString;
5488
5489            [JsonProperty]
5490            internal string _internalString;
5491
5492            public string UseValue()
5493            {
5494                return _readonlyString;
5495            }
5496        }
5497
5498        [Test]
5499        public void PrivateMembersClassWithAttributesTest()
5500        {
5501            PrivateMembersClassWithAttributes c1 = new PrivateMembersClassWithAttributes("privateString!", "internalString!", "readonlyString!");
5502
5503            string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
5504            Assert.AreEqual(@"{
5505  ""_privateString"": ""privateString!"",
5506  ""_readonlyString"": ""readonlyString!"",
5507  ""_internalString"": ""internalString!""
5508}", json);
5509
5510            PrivateMembersClassWithAttributes c2 = JsonConvert.DeserializeObject<PrivateMembersClassWithAttributes>(json);
5511            Assert.AreEqual("readonlyString!", c2.UseValue());
5512        }
5513
5514        public partial class BusRun
5515        {
5516            public IEnumerable<Nullable<DateTime>> Departures { get; set; }
5517            public Boolean WheelchairAccessible { get; set; }
5518        }
5519
5520        [Test]
5521        public void DeserializeGenericEnumerableProperty()
5522        {
5523            BusRun r = JsonConvert.DeserializeObject<BusRun>("{\"Departures\":[\"\\/Date(1309874148734-0400)\\/\",\"\\/Date(1309874148739-0400)\\/\",null],\"WheelchairAccessible\":true}");
5524
5525            Assert.AreEqual(typeof(List<DateTime?>), r.Departures.GetType());
5526            Assert.AreEqual(3, r.Departures.Count());
5527            Assert.IsNotNull(r.Departures.ElementAt(0));
5528            Assert.IsNotNull(r.Departures.ElementAt(1));
5529            Assert.IsNull(r.Departures.ElementAt(2));
5530        }
5531
5532#if !(NET20)
5533        [DataContract]
5534        public class BaseType
5535        {
5536            [DataMember]
5537            public string zebra;
5538        }
5539
5540        [DataContract]
5541        public class DerivedType : BaseType
5542        {
5543            [DataMember(Order = 0)]
5544            public string bird;
5545
5546            [DataMember(Order = 1)]
5547            public string parrot;
5548
5549            [DataMember]
5550            public string dog;
5551
5552            [DataMember(Order = 3)]
5553            public string antelope;
5554
5555            [DataMember]
5556            public string cat;
5557
5558            [JsonProperty(Order = 1)]
5559            public string albatross;
5560
5561            [JsonProperty(Order = -2)]
5562            public string dinosaur;
5563        }
5564
5565        [Test]
5566        public void JsonPropertyDataMemberOrder()
5567        {
5568            DerivedType d = new DerivedType();
5569            string json = JsonConvert.SerializeObject(d, Formatting.Indented);
5570
5571            Assert.AreEqual(@"{
5572  ""dinosaur"": null,
5573  ""dog"": null,
5574  ""cat"": null,
5575  ""zebra"": null,
5576  ""bird"": null,
5577  ""parrot"": null,
5578  ""albatross"": null,
5579  ""antelope"": null
5580}", json);
5581        }
5582#endif
5583
5584        public class ClassWithException
5585        {
5586            public IList<Exception> Exceptions { get; set; }
5587
5588            public ClassWithException()
5589            {
5590                Exceptions = new List<Exception>();
5591            }
5592        }
5593
5594#if !(NETFX_CORE || PORTABLE || PORTABLE40)
5595        [Test]
5596        public void SerializeException1()
5597        {
5598            ClassWithException classWithException = new ClassWithException();
5599            try
5600            {
5601                throw new Exception("Test Exception");
5602            }
5603            catch (Exception ex)
5604            {
5605                classWithException.Exceptions.Add(ex);
5606            }
5607            string sex = JsonConvert.SerializeObject(classWithException);
5608            ClassWithException dex = JsonConvert.DeserializeObject<ClassWithException>(sex);
5609            Assert.AreEqual(dex.Exceptions[0].ToString(), dex.Exceptions[0].ToString());
5610
5611            sex = JsonConvert.SerializeObject(classWithException, Formatting.Indented);
5612
5613            dex = JsonConvert.DeserializeObject<ClassWithException>(sex); // this fails!
5614            Assert.AreEqual(dex.Exceptions[0].ToString(), dex.Exceptions[0].ToString());
5615        }
5616#endif
5617
5618        [Test]
5619        public void UriGuidTimeSpanTestClassEmptyTest()
5620        {
5621            UriGuidTimeSpanTestClass c1 = new UriGuidTimeSpanTestClass();
5622            string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
5623
5624            Assert.AreEqual(@"{
5625  ""Guid"": ""00000000-0000-0000-0000-000000000000"",
5626  ""NullableGuid"": null,
5627  ""TimeSpan"": ""00:00:00"",
5628  ""NullableTimeSpan"": null,
5629  ""Uri"": null
5630}", json);
5631
5632            UriGuidTimeSpanTestClass c2 = JsonConvert.DeserializeObject<UriGuidTimeSpanTestClass>(json);
5633            Assert.AreEqual(c1.Guid, c2.Guid);
5634            Assert.AreEqual(c1.NullableGuid, c2.NullableGuid);
5635            Assert.AreEqual(c1.TimeSpan, c2.TimeSpan);
5636            Assert.AreEqual(c1.NullableTimeSpan, c2.NullableTimeSpan);
5637            Assert.AreEqual(c1.Uri, c2.Uri);
5638        }
5639
5640        [Test]
5641        public void UriGuidTimeSpanTestClassValuesTest()
5642        {
5643            UriGuidTimeSpanTestClass c1 = new UriGuidTimeSpanTestClass
5644            {
5645                Guid = new Guid("1924129C-F7E0-40F3-9607-9939C531395A"),
5646                NullableGuid = new Guid("9E9F3ADF-E017-4F72-91E0-617EBE85967D"),
5647                TimeSpan = TimeSpan.FromDays(1),
5648                NullableTimeSpan = TimeSpan.FromHours(1),
5649                Uri = new Uri("http://testuri.com")
5650            };
5651            string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
5652
5653            Assert.AreEqual(@"{
5654  ""Guid"": ""1924129c-f7e0-40f3-9607-9939c531395a"",
5655  ""NullableGuid"": ""9e9f3adf-e017-4f72-91e0-617ebe85967d"",
5656  ""TimeSpan"": ""1.00:00:00"",
5657  ""NullableTimeSpan"": ""01:00:00"",
5658  ""Uri"": ""http://testuri.com""
5659}", json);
5660
5661            UriGuidTimeSpanTestClass c2 = JsonConvert.DeserializeObject<UriGuidTimeSpanTestClass>(json);
5662            Assert.AreEqual(c1.Guid, c2.Guid);
5663            Assert.AreEqual(c1.NullableGuid, c2.NullableGuid);
5664            Assert.AreEqual(c1.TimeSpan, c2.TimeSpan);
5665            Assert.AreEqual(c1.NullableTimeSpan, c2.NullableTimeSpan);
5666            Assert.AreEqual(c1.Uri, c2.Uri);
5667        }
5668
5669        [Test]
5670        public void UsingJsonTextWriter()
5671        {
5672            // The property of the object has to be a number for the cast exception to occure
5673            object o = new { p = 1 };
5674
5675            var json = JObject.FromObject(o);
5676
5677            using (var sw = new StringWriter())
5678            using (var jw = new JsonTextWriter(sw))
5679            {
5680                jw.WriteToken(json.CreateReader());
5681                jw.Flush();
5682
5683                string result = sw.ToString();
5684                Assert.AreEqual(@"{""p"":1}", result);
5685            }
5686        }
5687
5688        [Test]
5689        public void SerializeUriWithQuotes()
5690        {
5691            string input = "http://test.com/%22foo+bar%22";
5692            Uri uri = new Uri(input);
5693            string json = JsonConvert.SerializeObject(uri);
5694            Uri output = JsonConvert.DeserializeObject<Uri>(json);
5695
5696            Assert.AreEqual(uri, output);
5697        }
5698
5699        [Test]
5700        public void SerializeUriWithSlashes()
5701        {
5702            string input = @"http://tes/?a=b\\c&d=e\";
5703            Uri uri = new Uri(input);
5704            string json = JsonConvert.SerializeObject(uri);
5705            Uri output = JsonConvert.DeserializeObject<Uri>(json);
5706
5707            Assert.AreEqual(uri, output);
5708        }
5709
5710        [Test]
5711        public void DeserializeByteArrayWithTypeNameHandling()
5712        {
5713            TestObject test = new TestObject("Test", new byte[] { 72, 63, 62, 71, 92, 55 });
5714
5715            JsonSerializer serializer = new JsonSerializer();
5716            serializer.TypeNameHandling = TypeNameHandling.All;
5717
5718            byte[] objectBytes;
5719            using (MemoryStream bsonStream = new MemoryStream())
5720            using (JsonWriter bsonWriter = new JsonTextWriter(new StreamWriter(bsonStream)))
5721            {
5722                serializer.Serialize(bsonWriter, test);
5723                bsonWriter.Flush();
5724
5725                objectBytes = bsonStream.ToArray();
5726            }
5727
5728            using (MemoryStream bsonStream = new MemoryStream(objectBytes))
5729            using (JsonReader bsonReader = new JsonTextReader(new StreamReader(bsonStream)))
5730            {
5731                // Get exception here
5732                TestObject newObject = (TestObject)serializer.Deserialize(bsonReader);
5733
5734                Assert.AreEqual("Test", newObject.Name);
5735                CollectionAssert.AreEquivalent(new byte[] { 72, 63, 62, 71, 92, 55 }, newObject.Data);
5736            }
5737        }
5738
5739#if !(NET20 || NETFX_CORE)
5740        [Test]
5741        public void DeserializeDecimalsWithCulture()
5742        {
5743            CultureInfo initialCulture = Thread.CurrentThread.CurrentCulture;
5744
5745            try
5746            {
5747                CultureInfo testCulture = CultureInfo.CreateSpecificCulture("nb-NO");
5748
5749                Thread.CurrentThread.CurrentCulture = testCulture;
5750                Thread.CurrentThread.CurrentUICulture = testCulture;
5751
5752                string json = @"{ 'Quantity': '1.5', 'OptionalQuantity': '2.2' }";
5753
5754                DecimalTestClass c = JsonConvert.DeserializeObject<DecimalTestClass>(json);
5755
5756                Assert.AreEqual(1.5m, c.Quantity);
5757                Assert.AreEqual(2.2d, c.OptionalQuantity);
5758            }
5759            finally
5760            {
5761                Thread.CurrentThread.CurrentCulture = initialCulture;
5762                Thread.CurrentThread.CurrentUICulture = initialCulture;
5763            }
5764        }
5765#endif
5766
5767        [Test]
5768        public void ReadForTypeHackFixDecimal()
5769        {
5770            IList<decimal> d1 = new List<decimal> { 1.1m };
5771
5772            string json = JsonConvert.SerializeObject(d1);
5773
5774            IList<decimal> d2 = JsonConvert.DeserializeObject<IList<decimal>>(json);
5775
5776            Assert.AreEqual(d1.Count, d2.Count);
5777            Assert.AreEqual(d1[0], d2[0]);
5778        }
5779
5780        [Test]
5781        public void ReadForTypeHackFixDateTimeOffset()
5782        {
5783            IList<DateTimeOffset?> d1 = new List<DateTimeOffset?> { null };
5784
5785            string json = JsonConvert.SerializeObject(d1);
5786
5787            IList<DateTimeOffset?> d2 = JsonConvert.DeserializeObject<IList<DateTimeOffset?>>(json);
5788
5789            Assert.AreEqual(d1.Count, d2.Count);
5790            Assert.AreEqual(d1[0], d2[0]);
5791        }
5792
5793        [Test]
5794        public void ReadForTypeHackFixByteArray()
5795        {
5796            IList<byte[]> d1 = new List<byte[]> { null };
5797
5798            string json = JsonConvert.SerializeObject(d1);
5799
5800            IList<byte[]> d2 = JsonConvert.DeserializeObject<IList<byte[]>>(json);
5801
5802            Assert.AreEqual(d1.Count, d2.Count);
5803            Assert.AreEqual(d1[0], d2[0]);
5804        }
5805
5806        [Test]
5807        public void SerializeInheritanceHierarchyWithDuplicateProperty()
5808        {
5809            Bb b = new Bb();
5810            b.no = true;
5811            Aa a = b;
5812            a.no = int.MaxValue;
5813
5814            string json = JsonConvert.SerializeObject(b);
5815
5816            Assert.AreEqual(@"{""no"":true}", json);
5817
5818            Bb b2 = JsonConvert.DeserializeObject<Bb>(json);
5819
5820            Assert.AreEqual(true, b2.no);
5821        }
5822
5823        [Test]
5824        public void DeserializeNullInt()
5825        {
5826            string json = @"[
5827  1,
5828  2,
5829  3,
5830  null
5831]";
5832
5833            ExceptionAssert.Throws<JsonSerializationException>(
5834                "Error converting value {null} to type 'System.Int32'. Path '[3]', line 5, position 7.",
5835                () => { List<int> numbers = JsonConvert.DeserializeObject<List<int>>(json); });
5836        }
5837
5838#if !(PORTABLE || NETFX_CORE)
5839        public class ConvertableIntTestClass
5840        {
5841            public ConvertibleInt Integer { get; set; }
5842            public ConvertibleInt? NullableInteger1 { get; set; }
5843            public ConvertibleInt? NullableInteger2 { get; set; }
5844        }
5845
5846        [Test]
5847        public void SerializeIConvertible()
5848        {
5849            ConvertableIntTestClass c = new ConvertableIntTestClass
5850            {
5851                Integer = new ConvertibleInt(1),
5852                NullableInteger1 = new ConvertibleInt(2),
5853                NullableInteger2 = null
5854            };
5855
5856            string json = JsonConvert.SerializeObject(c, Formatting.Indented);
5857
5858            Assert.AreEqual(@"{
5859  ""Integer"": 1,
5860  ""NullableInteger1"": 2,
5861  ""NullableInteger2"": null
5862}", json);
5863        }
5864
5865        [Test]
5866        public void DeserializeIConvertible()
5867        {
5868            string json = @"{
5869  ""Integer"": 1,
5870  ""NullableInteger1"": 2,
5871  ""NullableInteger2"": null
5872}";
5873