PageRenderTime 345ms CodeModel.GetById 7ms app.highlight 275ms RepoModel.GetById 1ms app.codeStats 3ms

/modules/JSON/Source/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs

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