PageRenderTime 266ms CodeModel.GetById 6ms app.highlight 212ms RepoModel.GetById 1ms app.codeStats 2ms

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

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