All files
[pithos-ms-client] / trunk / Libraries / Json40r2 / Source / Src / Newtonsoft.Json.Tests / Serialization / JsonSerializerTest.cs
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
26 using System;
27 using System.Collections.Generic;
28 #if !SILVERLIGHT && !PocketPC && !NET20
29 using System.ComponentModel.DataAnnotations;
30 using System.Configuration;
31 using System.Runtime.CompilerServices;
32 using System.Threading;
33 using System.Web.Script.Serialization;
34 #endif
35 using System.Text;
36 using NUnit.Framework;
37 using Newtonsoft.Json;
38 using System.IO;
39 using System.Collections;
40 using System.Xml;
41 using System.Xml.Serialization;
42 using System.Collections.ObjectModel;
43 using Newtonsoft.Json.Linq;
44 using System.Linq;
45 using Newtonsoft.Json.Converters;
46 #if !PocketPC && !NET20 && !WINDOWS_PHONE
47 using System.Runtime.Serialization.Json;
48 #endif
49 using Newtonsoft.Json.Tests.TestObjects;
50 using System.Runtime.Serialization;
51 using System.Globalization;
52 using Newtonsoft.Json.Utilities;
53 using System.Reflection;
54 #if !NET20 && !SILVERLIGHT
55 using System.Xml.Linq;
56 using System.Text.RegularExpressions;
57 using System.Collections.Specialized;
58 using System.Linq.Expressions;
59 #endif
60 #if !(NET35 || NET20 || WINDOWS_PHONE)
61 using System.Dynamic;
62 using System.ComponentModel;
63 #endif
64
65 namespace Newtonsoft.Json.Tests.Serialization
66 {
67   public class JsonSerializerTest : TestFixtureBase
68   {
69     [Test]
70     public void PersonTypedObjectDeserialization()
71     {
72       Store store = new Store();
73
74       string jsonText = JsonConvert.SerializeObject(store);
75
76       Store deserializedStore = (Store)JsonConvert.DeserializeObject(jsonText, typeof(Store));
77
78       Assert.AreEqual(store.Establised, deserializedStore.Establised);
79       Assert.AreEqual(store.product.Count, deserializedStore.product.Count);
80
81       Console.WriteLine(jsonText);
82     }
83
84     [Test]
85     public void TypedObjectDeserialization()
86     {
87       Product product = new Product();
88
89       product.Name = "Apple";
90       product.ExpiryDate = new DateTime(2008, 12, 28);
91       product.Price = 3.99M;
92       product.Sizes = new string[] { "Small", "Medium", "Large" };
93
94       string output = JsonConvert.SerializeObject(product);
95       //{
96       //  "Name": "Apple",
97       //  "ExpiryDate": "\/Date(1230375600000+1300)\/",
98       //  "Price": 3.99,
99       //  "Sizes": [
100       //    "Small",
101       //    "Medium",
102       //    "Large"
103       //  ]
104       //}
105
106       Product deserializedProduct = (Product)JsonConvert.DeserializeObject(output, typeof(Product));
107
108       Assert.AreEqual("Apple", deserializedProduct.Name);
109       Assert.AreEqual(new DateTime(2008, 12, 28), deserializedProduct.ExpiryDate);
110       Assert.AreEqual(3.99, deserializedProduct.Price);
111       Assert.AreEqual("Small", deserializedProduct.Sizes[0]);
112       Assert.AreEqual("Medium", deserializedProduct.Sizes[1]);
113       Assert.AreEqual("Large", deserializedProduct.Sizes[2]);
114     }
115
116     //[Test]
117     //public void Advanced()
118     //{
119     //  Product product = new Product();
120     //  product.ExpiryDate = new DateTime(2008, 12, 28);
121
122     //  JsonSerializer serializer = new JsonSerializer();
123     //  serializer.Converters.Add(new JavaScriptDateTimeConverter());
124     //  serializer.NullValueHandling = NullValueHandling.Ignore;
125
126     //  using (StreamWriter sw = new StreamWriter(@"c:\json.txt"))
127     //  using (JsonWriter writer = new JsonTextWriter(sw))
128     //  {
129     //    serializer.Serialize(writer, product);
130     //    // {"ExpiryDate":new Date(1230375600000),"Price":0}
131     //  }
132     //}
133
134     [Test]
135     public void JsonConvertSerializer()
136     {
137       string value = @"{""Name"":""Orange"", ""Price"":3.99, ""ExpiryDate"":""01/24/2010 12:00:00""}";
138
139       Product p = JsonConvert.DeserializeObject(value, typeof(Product)) as Product;
140
141       Assert.AreEqual("Orange", p.Name);
142       Assert.AreEqual(new DateTime(2010, 1, 24, 12, 0, 0), p.ExpiryDate);
143       Assert.AreEqual(3.99, p.Price);
144     }
145
146     [Test]
147     public void DeserializeJavaScriptDate()
148     {
149       DateTime dateValue = new DateTime(2010, 3, 30);
150       Dictionary<string, object> testDictionary = new Dictionary<string, object>();
151       testDictionary["date"] = dateValue;
152
153       string jsonText = JsonConvert.SerializeObject(testDictionary);
154
155 #if !PocketPC && !NET20 && !WINDOWS_PHONE
156       MemoryStream ms = new MemoryStream();
157       DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Dictionary<string, object>));
158       serializer.WriteObject(ms, testDictionary);
159
160       byte[] data = ms.ToArray();
161       string output = Encoding.UTF8.GetString(data, 0, data.Length);
162 #endif
163
164       Dictionary<string, object> deserializedDictionary = (Dictionary<string, object>)JsonConvert.DeserializeObject(jsonText, typeof(Dictionary<string, object>));
165       DateTime deserializedDate = (DateTime)deserializedDictionary["date"];
166
167       Assert.AreEqual(dateValue, deserializedDate);
168
169       Console.WriteLine("DeserializeJavaScriptDate");
170       Console.WriteLine(jsonText);
171       Console.WriteLine();
172       Console.WriteLine(jsonText);
173     }
174
175     [Test]
176     public void TestMethodExecutorObject()
177     {
178       MethodExecutorObject executorObject = new MethodExecutorObject();
179       executorObject.serverClassName = "BanSubs";
180       executorObject.serverMethodParams = new object[] { "21321546", "101", "1236", "D:\\1.txt" };
181       executorObject.clientGetResultFunction = "ClientBanSubsCB";
182
183       string output = JsonConvert.SerializeObject(executorObject);
184
185       MethodExecutorObject executorObject2 = JsonConvert.DeserializeObject(output, typeof(MethodExecutorObject)) as MethodExecutorObject;
186
187       Assert.AreNotSame(executorObject, executorObject2);
188       Assert.AreEqual(executorObject2.serverClassName, "BanSubs");
189       Assert.AreEqual(executorObject2.serverMethodParams.Length, 4);
190       Assert.Contains("101", executorObject2.serverMethodParams);
191       Assert.AreEqual(executorObject2.clientGetResultFunction, "ClientBanSubsCB");
192     }
193
194 #if !SILVERLIGHT
195     [Test]
196     public void HashtableDeserialization()
197     {
198       string value = @"{""Name"":""Orange"", ""Price"":3.99, ""ExpiryDate"":""01/24/2010 12:00:00""}";
199
200       Hashtable p = JsonConvert.DeserializeObject(value, typeof(Hashtable)) as Hashtable;
201
202       Assert.AreEqual("Orange", p["Name"].ToString());
203     }
204
205     [Test]
206     public void TypedHashtableDeserialization()
207     {
208       string value = @"{""Name"":""Orange"", ""Hash"":{""ExpiryDate"":""01/24/2010 12:00:00"",""UntypedArray"":[""01/24/2010 12:00:00""]}}";
209
210       TypedSubHashtable p = JsonConvert.DeserializeObject(value, typeof(TypedSubHashtable)) as TypedSubHashtable;
211
212       Assert.AreEqual("01/24/2010 12:00:00", p.Hash["ExpiryDate"].ToString());
213       Assert.AreEqual(@"[
214   ""01/24/2010 12:00:00""
215 ]", p.Hash["UntypedArray"].ToString());
216     }
217 #endif
218
219     [Test]
220     public void SerializeDeserializeGetOnlyProperty()
221     {
222       string value = JsonConvert.SerializeObject(new GetOnlyPropertyClass());
223
224       GetOnlyPropertyClass c = JsonConvert.DeserializeObject<GetOnlyPropertyClass>(value);
225
226       Assert.AreEqual(c.Field, "Field");
227       Assert.AreEqual(c.GetOnlyProperty, "GetOnlyProperty");
228     }
229
230     [Test]
231     public void SerializeDeserializeSetOnlyProperty()
232     {
233       string value = JsonConvert.SerializeObject(new SetOnlyPropertyClass());
234
235       SetOnlyPropertyClass c = JsonConvert.DeserializeObject<SetOnlyPropertyClass>(value);
236
237       Assert.AreEqual(c.Field, "Field");
238     }
239
240     [Test]
241     public void JsonIgnoreAttributeTest()
242     {
243       string json = JsonConvert.SerializeObject(new JsonIgnoreAttributeTestClass());
244
245       Assert.AreEqual(@"{""Field"":0,""Property"":21}", json);
246
247       JsonIgnoreAttributeTestClass c = JsonConvert.DeserializeObject<JsonIgnoreAttributeTestClass>(@"{""Field"":99,""Property"":-1,""IgnoredField"":-1,""IgnoredObject"":[1,2,3,4,5]}");
248
249       Assert.AreEqual(0, c.IgnoredField);
250       Assert.AreEqual(99, c.Field);
251     }
252
253     [Test]
254     public void GoogleSearchAPI()
255     {
256       string json = @"{
257     results:
258         [
259             {
260                 GsearchResultClass:""GwebSearch"",
261                 unescapedUrl : ""http://www.google.com/"",
262                 url : ""http://www.google.com/"",
263                 visibleUrl : ""www.google.com"",
264                 cacheUrl : 
265 ""http://www.google.com/search?q=cache:zhool8dxBV4J:www.google.com"",
266                 title : ""Google"",
267                 titleNoFormatting : ""Google"",
268                 content : ""Enables users to search the Web, Usenet, and 
269 images. Features include PageRank,   caching and translation of 
270 results, and an option to find similar pages.""
271             },
272             {
273                 GsearchResultClass:""GwebSearch"",
274                 unescapedUrl : ""http://news.google.com/"",
275                 url : ""http://news.google.com/"",
276                 visibleUrl : ""news.google.com"",
277                 cacheUrl : 
278 ""http://www.google.com/search?q=cache:Va_XShOz_twJ:news.google.com"",
279                 title : ""Google News"",
280                 titleNoFormatting : ""Google News"",
281                 content : ""Aggregated headlines and a search engine of many of the world's news sources.""
282             },
283             
284             {
285                 GsearchResultClass:""GwebSearch"",
286                 unescapedUrl : ""http://groups.google.com/"",
287                 url : ""http://groups.google.com/"",
288                 visibleUrl : ""groups.google.com"",
289                 cacheUrl : 
290 ""http://www.google.com/search?q=cache:x2uPD3hfkn0J:groups.google.com"",
291                 title : ""Google Groups"",
292                 titleNoFormatting : ""Google Groups"",
293                 content : ""Enables users to search and browse the Usenet 
294 archives which consist of over 700   million messages, and post new 
295 comments.""
296             },
297             
298             {
299                 GsearchResultClass:""GwebSearch"",
300                 unescapedUrl : ""http://maps.google.com/"",
301                 url : ""http://maps.google.com/"",
302                 visibleUrl : ""maps.google.com"",
303                 cacheUrl : 
304 ""http://www.google.com/search?q=cache:dkf5u2twBXIJ:maps.google.com"",
305                 title : ""Google Maps"",
306                 titleNoFormatting : ""Google Maps"",
307                 content : ""Provides directions, interactive maps, and 
308 satellite/aerial imagery of the United   States. Can also search by 
309 keyword such as type of business.""
310             }
311         ],
312         
313     adResults:
314         [
315             {
316                 GsearchResultClass:""GwebSearch.ad"",
317                 title : ""Gartner Symposium/ITxpo"",
318                 content1 : ""Meet brilliant Gartner IT analysts"",
319                 content2 : ""20-23 May 2007- Barcelona, Spain"",
320                 url : 
321 ""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="", 
322
323                 impressionUrl : 
324 ""http://www.google.com/uds/css/ad-indicator-on.gif?ai=BVualExYGRo3hD5ianAPJvejjD8-s6ye7kdTwArbI4gTAlrECEAEYASDXtMMFOAFQubWAjvr_____AWDXw_4EiAEBmAEAyAEBgAIB"", 
325
326                 unescapedUrl : 
327 ""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="", 
328
329                 visibleUrl : ""www.gartner.com""
330             }
331         ]
332 }
333 ";
334       object o = JsonConvert.DeserializeObject(json);
335       string s = string.Empty;
336       s += s;
337     }
338
339     [Test]
340     public void TorrentDeserializeTest()
341     {
342       string jsonText = @"{
343 """":"""",
344 ""label"": [
345        [""SomeName"",6]
346 ],
347 ""torrents"": [
348        [""192D99A5C943555CB7F00A852821CF6D6DB3008A"",201,""filename.avi"",178311826,1000,178311826,72815250,408,1603,7,121430,""NameOfLabelPrevioslyDefined"",3,6,0,8,128954,-1,0],
349 ],
350 ""torrentc"": ""1816000723""
351 }";
352
353       JObject o = (JObject)JsonConvert.DeserializeObject(jsonText);
354       Assert.AreEqual(4, o.Children().Count());
355
356       JToken torrentsArray = (JToken)o["torrents"];
357       JToken nestedTorrentsArray = (JToken)torrentsArray[0];
358       Assert.AreEqual(nestedTorrentsArray.Children().Count(), 19);
359     }
360
361     [Test]
362     public void JsonPropertyClassSerialize()
363     {
364       JsonPropertyClass test = new JsonPropertyClass();
365       test.Pie = "Delicious";
366       test.SweetCakesCount = int.MaxValue;
367
368       string jsonText = JsonConvert.SerializeObject(test);
369
370       Assert.AreEqual(@"{""pie"":""Delicious"",""pie1"":""PieChart!"",""sweet_cakes_count"":2147483647}", jsonText);
371
372       JsonPropertyClass test2 = JsonConvert.DeserializeObject<JsonPropertyClass>(jsonText);
373
374       Assert.AreEqual(test.Pie, test2.Pie);
375       Assert.AreEqual(test.SweetCakesCount, test2.SweetCakesCount);
376     }
377
378     [Test]
379     [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"A member with the name 'pie' already exists on 'Newtonsoft.Json.Tests.TestObjects.BadJsonPropertyClass'. Use the JsonPropertyAttribute to specify another name.")]
380     public void BadJsonPropertyClassSerialize()
381     {
382       JsonConvert.SerializeObject(new BadJsonPropertyClass());
383     }
384
385     [Test]
386     public void InheritedListSerialize()
387     {
388       Article a1 = new Article("a1");
389       Article a2 = new Article("a2");
390
391       ArticleCollection articles1 = new ArticleCollection();
392       articles1.Add(a1);
393       articles1.Add(a2);
394
395       string jsonText = JsonConvert.SerializeObject(articles1);
396
397       ArticleCollection articles2 = JsonConvert.DeserializeObject<ArticleCollection>(jsonText);
398
399       Assert.AreEqual(articles1.Count, articles2.Count);
400       Assert.AreEqual(articles1[0].Name, articles2[0].Name);
401     }
402
403     [Test]
404     public void ReadOnlyCollectionSerialize()
405     {
406       ReadOnlyCollection<int> r1 = new ReadOnlyCollection<int>(new int[] { 0, 1, 2, 3, 4 });
407
408       string jsonText = JsonConvert.SerializeObject(r1);
409
410       ReadOnlyCollection<int> r2 = JsonConvert.DeserializeObject<ReadOnlyCollection<int>>(jsonText);
411
412       CollectionAssert.AreEqual(r1, r2);
413     }
414
415 #if !PocketPC && !NET20 && !WINDOWS_PHONE
416     [Test]
417     public void Unicode()
418     {
419       string json = @"[""PRE\u003cPOST""]";
420
421       DataContractJsonSerializer s = new DataContractJsonSerializer(typeof(List<string>));
422       List<string> dataContractResult = (List<string>)s.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(json)));
423
424       List<string> jsonNetResult = JsonConvert.DeserializeObject<List<string>>(json);
425
426       Assert.AreEqual(1, jsonNetResult.Count);
427       Assert.AreEqual(dataContractResult[0], jsonNetResult[0]);
428     }
429
430     [Test]
431     public void BackslashEqivilence()
432     {
433       string json = @"[""vvv\/vvv\tvvv\""vvv\bvvv\nvvv\rvvv\\vvv\fvvv""]";
434
435 #if !SILVERLIGHT
436       JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
437       List<string> javaScriptSerializerResult = javaScriptSerializer.Deserialize<List<string>>(json);
438 #endif
439
440       DataContractJsonSerializer s = new DataContractJsonSerializer(typeof(List<string>));
441       List<string> dataContractResult = (List<string>)s.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(json)));
442
443       List<string> jsonNetResult = JsonConvert.DeserializeObject<List<string>>(json);
444
445       Assert.AreEqual(1, jsonNetResult.Count);
446       Assert.AreEqual(dataContractResult[0], jsonNetResult[0]);
447 #if !SILVERLIGHT
448       Assert.AreEqual(javaScriptSerializerResult[0], jsonNetResult[0]);
449 #endif
450     }
451
452     [Test]
453     [ExpectedException(typeof(JsonReaderException), ExpectedMessage = @"Bad JSON escape sequence: \j. Line 1, position 7.")]
454     public void InvalidBackslash()
455     {
456       string json = @"[""vvv\jvvv""]";
457
458       JsonConvert.DeserializeObject<List<string>>(json);
459     }
460
461     [Test]
462     public void DateTimeTest()
463     {
464       List<DateTime> testDates = new List<DateTime> {
465         new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Local),
466         new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Unspecified),
467         new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Utc),
468         new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Local),
469         new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Unspecified),
470         new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc),
471       };
472       string result;
473
474
475       MemoryStream ms = new MemoryStream();
476       DataContractJsonSerializer s = new DataContractJsonSerializer(typeof(List<DateTime>));
477       s.WriteObject(ms, testDates);
478       ms.Seek(0, SeekOrigin.Begin);
479       StreamReader sr = new StreamReader(ms);
480
481       string expected = sr.ReadToEnd();
482
483       result = JsonConvert.SerializeObject(testDates);
484       Assert.AreEqual(expected, result);
485     }
486
487     [Test]
488     public void DateTimeOffset()
489     {
490       List<DateTimeOffset> testDates = new List<DateTimeOffset> {
491         new DateTimeOffset(new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Utc)),
492         new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero),
493         new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(13)),
494         new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.FromHours(-3.5)),
495       };
496
497       string result = JsonConvert.SerializeObject(testDates);
498       Assert.AreEqual(@"[""\/Date(-59011455539000+0000)\/"",""\/Date(946688461000+0000)\/"",""\/Date(946641661000+1300)\/"",""\/Date(946701061000-0330)\/""]", result);
499     }
500 #endif
501
502     [Test]
503     public void NonStringKeyDictionary()
504     {
505       Dictionary<int, int> values = new Dictionary<int, int>();
506       values.Add(-5, 6);
507       values.Add(int.MinValue, int.MaxValue);
508
509       string json = JsonConvert.SerializeObject(values);
510
511       Assert.AreEqual(@"{""-5"":6,""-2147483648"":2147483647}", json);
512
513       Dictionary<int, int> newValues = JsonConvert.DeserializeObject<Dictionary<int, int>>(json);
514
515       CollectionAssert.AreEqual(values, newValues);
516     }
517
518     [Test]
519     public void AnonymousObjectSerialization()
520     {
521       var anonymous =
522         new
523         {
524           StringValue = "I am a string",
525           IntValue = int.MaxValue,
526           NestedAnonymous = new { NestedValue = byte.MaxValue },
527           NestedArray = new[] { 1, 2 },
528           Product = new Product() { Name = "TestProduct" }
529         };
530
531       string json = JsonConvert.SerializeObject(anonymous);
532       Assert.AreEqual(@"{""StringValue"":""I am a string"",""IntValue"":2147483647,""NestedAnonymous"":{""NestedValue"":255},""NestedArray"":[1,2],""Product"":{""Name"":""TestProduct"",""ExpiryDate"":""\/Date(946684800000)\/"",""Price"":0.0,""Sizes"":null}}", json);
533
534       anonymous = JsonConvert.DeserializeAnonymousType(json, anonymous);
535       Assert.AreEqual("I am a string", anonymous.StringValue);
536       Assert.AreEqual(int.MaxValue, anonymous.IntValue);
537       Assert.AreEqual(255, anonymous.NestedAnonymous.NestedValue);
538       Assert.AreEqual(2, anonymous.NestedArray.Length);
539       Assert.AreEqual(1, anonymous.NestedArray[0]);
540       Assert.AreEqual(2, anonymous.NestedArray[1]);
541       Assert.AreEqual("TestProduct", anonymous.Product.Name);
542     }
543
544     [Test]
545     public void CustomCollectionSerialization()
546     {
547       ProductCollection collection = new ProductCollection()
548       {
549         new Product() { Name = "Test1" },
550         new Product() { Name = "Test2" },
551         new Product() { Name = "Test3" }
552       };
553
554       JsonSerializer jsonSerializer = new JsonSerializer();
555       jsonSerializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
556
557       StringWriter sw = new StringWriter();
558
559       jsonSerializer.Serialize(sw, collection);
560
561       Assert.AreEqual(@"[{""Name"":""Test1"",""ExpiryDate"":""\/Date(946684800000)\/"",""Price"":0.0,""Sizes"":null},{""Name"":""Test2"",""ExpiryDate"":""\/Date(946684800000)\/"",""Price"":0.0,""Sizes"":null},{""Name"":""Test3"",""ExpiryDate"":""\/Date(946684800000)\/"",""Price"":0.0,""Sizes"":null}]",
562         sw.GetStringBuilder().ToString());
563
564       ProductCollection collectionNew = (ProductCollection)jsonSerializer.Deserialize(new JsonTextReader(new StringReader(sw.GetStringBuilder().ToString())), typeof(ProductCollection));
565
566       CollectionAssert.AreEqual(collection, collectionNew);
567     }
568
569     [Test]
570     public void SerializeObject()
571     {
572       string json = JsonConvert.SerializeObject(new object());
573       Assert.AreEqual("{}", json);
574     }
575
576     [Test]
577     public void SerializeNull()
578     {
579       string json = JsonConvert.SerializeObject(null);
580       Assert.AreEqual("null", json);
581     }
582
583     [Test]
584     public void CanDeserializeIntArrayWhenNotFirstPropertyInJson()
585     {
586       string json = "{foo:'hello',bar:[1,2,3]}";
587       ClassWithArray wibble = JsonConvert.DeserializeObject<ClassWithArray>(json);
588       Assert.AreEqual("hello", wibble.Foo);
589
590       Assert.AreEqual(4, wibble.Bar.Count);
591       Assert.AreEqual(int.MaxValue, wibble.Bar[0]);
592       Assert.AreEqual(1, wibble.Bar[1]);
593       Assert.AreEqual(2, wibble.Bar[2]);
594       Assert.AreEqual(3, wibble.Bar[3]);
595     }
596
597     [Test]
598     public void CanDeserializeIntArray_WhenArrayIsFirstPropertyInJson()
599     {
600       string json = "{bar:[1,2,3], foo:'hello'}";
601       ClassWithArray wibble = JsonConvert.DeserializeObject<ClassWithArray>(json);
602       Assert.AreEqual("hello", wibble.Foo);
603
604       Assert.AreEqual(4, wibble.Bar.Count);
605       Assert.AreEqual(int.MaxValue, wibble.Bar[0]);
606       Assert.AreEqual(1, wibble.Bar[1]);
607       Assert.AreEqual(2, wibble.Bar[2]);
608       Assert.AreEqual(3, wibble.Bar[3]);
609     }
610
611     [Test]
612     public void ObjectCreationHandlingReplace()
613     {
614       string json = "{bar:[1,2,3], foo:'hello'}";
615
616       JsonSerializer s = new JsonSerializer();
617       s.ObjectCreationHandling = ObjectCreationHandling.Replace;
618
619       ClassWithArray wibble = (ClassWithArray)s.Deserialize(new StringReader(json), typeof(ClassWithArray));
620
621       Assert.AreEqual("hello", wibble.Foo);
622
623       Assert.AreEqual(1, wibble.Bar.Count);
624     }
625
626     [Test]
627     public void CanDeserializeSerializedJson()
628     {
629       ClassWithArray wibble = new ClassWithArray();
630       wibble.Foo = "hello";
631       wibble.Bar.Add(1);
632       wibble.Bar.Add(2);
633       wibble.Bar.Add(3);
634       string json = JsonConvert.SerializeObject(wibble);
635
636       ClassWithArray wibbleOut = JsonConvert.DeserializeObject<ClassWithArray>(json);
637       Assert.AreEqual("hello", wibbleOut.Foo);
638
639       Assert.AreEqual(5, wibbleOut.Bar.Count);
640       Assert.AreEqual(int.MaxValue, wibbleOut.Bar[0]);
641       Assert.AreEqual(int.MaxValue, wibbleOut.Bar[1]);
642       Assert.AreEqual(1, wibbleOut.Bar[2]);
643       Assert.AreEqual(2, wibbleOut.Bar[3]);
644       Assert.AreEqual(3, wibbleOut.Bar[4]);
645     }
646
647     [Test]
648     public void SerializeConverableObjects()
649     {
650       string json = JsonConvert.SerializeObject(new ConverableMembers());
651
652       Assert.AreEqual(@"{""String"":""string"",""Int32"":2147483647,""UInt32"":4294967295,""Byte"":255,""SByte"":127,""Short"":32767,""UShort"":65535,""Long"":9223372036854775807,""ULong"":9223372036854775807,""Double"":1.7976931348623157E+308,""Float"":3.40282347E+38,""DBNull"":null,""Bool"":true,""Char"":""\u0000""}", json);
653
654       ConverableMembers c = JsonConvert.DeserializeObject<ConverableMembers>(json);
655       Assert.AreEqual("string", c.String);
656       Assert.AreEqual(double.MaxValue, c.Double);
657       Assert.AreEqual(DBNull.Value, c.DBNull);
658     }
659
660     [Test]
661     public void SerializeStack()
662     {
663       Stack<object> s = new Stack<object>();
664       s.Push(1);
665       s.Push(2);
666       s.Push(3);
667
668       string json = JsonConvert.SerializeObject(s);
669       Assert.AreEqual("[3,2,1]", json);
670     }
671
672     [Test]
673     public void GuidTest()
674     {
675       Guid guid = new Guid("BED7F4EA-1A96-11d2-8F08-00A0C9A6186D");
676
677       string json = JsonConvert.SerializeObject(new ClassWithGuid { GuidField = guid });
678       Assert.AreEqual(@"{""GuidField"":""bed7f4ea-1a96-11d2-8f08-00a0c9a6186d""}", json);
679
680       ClassWithGuid c = JsonConvert.DeserializeObject<ClassWithGuid>(json);
681       Assert.AreEqual(guid, c.GuidField);
682     }
683
684     [Test]
685     public void EnumTest()
686     {
687       string json = JsonConvert.SerializeObject(StringComparison.CurrentCultureIgnoreCase);
688       Assert.AreEqual(@"1", json);
689
690       StringComparison s = JsonConvert.DeserializeObject<StringComparison>(json);
691       Assert.AreEqual(StringComparison.CurrentCultureIgnoreCase, s);
692     }
693
694     public class ClassWithTimeSpan
695     {
696       public TimeSpan TimeSpanField;
697     }
698
699     [Test]
700     public void TimeSpanTest()
701     {
702       TimeSpan ts = new TimeSpan(00, 23, 59, 1);
703
704       string json = JsonConvert.SerializeObject(new ClassWithTimeSpan { TimeSpanField = ts }, Formatting.Indented);
705       Assert.AreEqual(@"{
706   ""TimeSpanField"": ""23:59:01""
707 }", json);
708
709       ClassWithTimeSpan c = JsonConvert.DeserializeObject<ClassWithTimeSpan>(json);
710       Assert.AreEqual(ts, c.TimeSpanField);
711     }
712
713     [Test]
714     public void JsonIgnoreAttributeOnClassTest()
715     {
716       string json = JsonConvert.SerializeObject(new JsonIgnoreAttributeOnClassTestClass());
717
718       Assert.AreEqual(@"{""TheField"":0,""Property"":21}", json);
719
720       JsonIgnoreAttributeOnClassTestClass c = JsonConvert.DeserializeObject<JsonIgnoreAttributeOnClassTestClass>(@"{""TheField"":99,""Property"":-1,""IgnoredField"":-1}");
721
722       Assert.AreEqual(0, c.IgnoredField);
723       Assert.AreEqual(99, c.Field);
724     }
725
726 #if !SILVERLIGHT
727     [Test]
728     public void SerializeArrayAsArrayList()
729     {
730       string jsonText = @"[3, ""somestring"",[1,2,3],{}]";
731       ArrayList o = JsonConvert.DeserializeObject<ArrayList>(jsonText);
732
733       Assert.AreEqual(4, o.Count);
734       Assert.AreEqual(3, ((JArray)o[2]).Count);
735       Assert.AreEqual(0, ((JObject)o[3]).Count);
736     }
737 #endif
738
739     [Test]
740     public void SerializeMemberGenericList()
741     {
742       Name name = new Name("The Idiot in Next To Me");
743
744       PhoneNumber p1 = new PhoneNumber("555-1212");
745       PhoneNumber p2 = new PhoneNumber("444-1212");
746
747       name.pNumbers.Add(p1);
748       name.pNumbers.Add(p2);
749
750       string json = JsonConvert.SerializeObject(name, Formatting.Indented);
751
752       Assert.AreEqual(@"{
753   ""personsName"": ""The Idiot in Next To Me"",
754   ""pNumbers"": [
755     {
756       ""phoneNumber"": ""555-1212""
757     },
758     {
759       ""phoneNumber"": ""444-1212""
760     }
761   ]
762 }", json);
763
764       Name newName = JsonConvert.DeserializeObject<Name>(json);
765
766       Assert.AreEqual("The Idiot in Next To Me", newName.personsName);
767
768       // not passed in as part of the constructor but assigned to pNumbers property
769       Assert.AreEqual(2, newName.pNumbers.Count);
770       Assert.AreEqual("555-1212", newName.pNumbers[0].phoneNumber);
771       Assert.AreEqual("444-1212", newName.pNumbers[1].phoneNumber);
772     }
773
774     [Test]
775     public void ConstructorCaseSensitivity()
776     {
777       ConstructorCaseSensitivityClass c = new ConstructorCaseSensitivityClass("param1", "Param1", "Param2");
778
779       string json = JsonConvert.SerializeObject(c);
780
781       ConstructorCaseSensitivityClass deserialized = JsonConvert.DeserializeObject<ConstructorCaseSensitivityClass>(json);
782
783       Assert.AreEqual("param1", deserialized.param1);
784       Assert.AreEqual("Param1", deserialized.Param1);
785       Assert.AreEqual("Param2", deserialized.Param2);
786     }
787
788     [Test]
789     public void SerializerShouldUseClassConverter()
790     {
791       ConverterPrecedenceClass c1 = new ConverterPrecedenceClass("!Test!");
792
793       string json = JsonConvert.SerializeObject(c1);
794       Assert.AreEqual(@"[""Class"",""!Test!""]", json);
795
796       ConverterPrecedenceClass c2 = JsonConvert.DeserializeObject<ConverterPrecedenceClass>(json);
797
798       Assert.AreEqual("!Test!", c2.TestValue);
799     }
800
801     [Test]
802     public void SerializerShouldUseClassConverterOverArgumentConverter()
803     {
804       ConverterPrecedenceClass c1 = new ConverterPrecedenceClass("!Test!");
805
806       string json = JsonConvert.SerializeObject(c1, new ArgumentConverterPrecedenceClassConverter());
807       Assert.AreEqual(@"[""Class"",""!Test!""]", json);
808
809       ConverterPrecedenceClass c2 = JsonConvert.DeserializeObject<ConverterPrecedenceClass>(json, new ArgumentConverterPrecedenceClassConverter());
810
811       Assert.AreEqual("!Test!", c2.TestValue);
812     }
813
814     [Test]
815     public void SerializerShouldUseMemberConverter()
816     {
817       DateTime testDate = new DateTime(JsonConvert.InitialJavaScriptDateTicks, DateTimeKind.Utc);
818       MemberConverterClass m1 = new MemberConverterClass { DefaultConverter = testDate, MemberConverter = testDate };
819
820       string json = JsonConvert.SerializeObject(m1);
821       Assert.AreEqual(@"{""DefaultConverter"":""\/Date(0)\/"",""MemberConverter"":""1970-01-01T00:00:00Z""}", json);
822
823       MemberConverterClass m2 = JsonConvert.DeserializeObject<MemberConverterClass>(json);
824
825       Assert.AreEqual(testDate, m2.DefaultConverter);
826       Assert.AreEqual(testDate, m2.MemberConverter);
827     }
828
829     [Test]
830     public void SerializerShouldUseMemberConverterOverArgumentConverter()
831     {
832       DateTime testDate = new DateTime(JsonConvert.InitialJavaScriptDateTicks, DateTimeKind.Utc);
833       MemberConverterClass m1 = new MemberConverterClass { DefaultConverter = testDate, MemberConverter = testDate };
834
835       string json = JsonConvert.SerializeObject(m1, new JavaScriptDateTimeConverter());
836       Assert.AreEqual(@"{""DefaultConverter"":new Date(0),""MemberConverter"":""1970-01-01T00:00:00Z""}", json);
837
838       MemberConverterClass m2 = JsonConvert.DeserializeObject<MemberConverterClass>(json, new JavaScriptDateTimeConverter());
839
840       Assert.AreEqual(testDate, m2.DefaultConverter);
841       Assert.AreEqual(testDate, m2.MemberConverter);
842     }
843
844     [Test]
845     public void ConverterAttributeExample()
846     {
847       DateTime date = Convert.ToDateTime("1970-01-01T00:00:00Z").ToUniversalTime();
848
849       MemberConverterClass c = new MemberConverterClass
850         {
851           DefaultConverter = date,
852           MemberConverter = date
853         };
854
855       string json = JsonConvert.SerializeObject(c, Formatting.Indented);
856
857       Console.WriteLine(json);
858       //{
859       //  "DefaultConverter": "\/Date(0)\/",
860       //  "MemberConverter": "1970-01-01T00:00:00Z"
861       //}
862     }
863
864     [Test]
865     public void SerializerShouldUseMemberConverterOverClassAndArgumentConverter()
866     {
867       ClassAndMemberConverterClass c1 = new ClassAndMemberConverterClass();
868       c1.DefaultConverter = new ConverterPrecedenceClass("DefaultConverterValue");
869       c1.MemberConverter = new ConverterPrecedenceClass("MemberConverterValue");
870
871       string json = JsonConvert.SerializeObject(c1, new ArgumentConverterPrecedenceClassConverter());
872       Assert.AreEqual(@"{""DefaultConverter"":[""Class"",""DefaultConverterValue""],""MemberConverter"":[""Member"",""MemberConverterValue""]}", json);
873
874       ClassAndMemberConverterClass c2 = JsonConvert.DeserializeObject<ClassAndMemberConverterClass>(json, new ArgumentConverterPrecedenceClassConverter());
875
876       Assert.AreEqual("DefaultConverterValue", c2.DefaultConverter.TestValue);
877       Assert.AreEqual("MemberConverterValue", c2.MemberConverter.TestValue);
878     }
879
880     [Test]
881     [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "JsonConverter IsoDateTimeConverter on Newtonsoft.Json.Tests.TestObjects.IncompatibleJsonAttributeClass is not compatible with member type IncompatibleJsonAttributeClass.")]
882     public void IncompatibleJsonAttributeShouldThrow()
883     {
884       IncompatibleJsonAttributeClass c = new IncompatibleJsonAttributeClass();
885       JsonConvert.SerializeObject(c);
886     }
887
888     [Test]
889     public void GenericAbstractProperty()
890     {
891       string json = JsonConvert.SerializeObject(new GenericImpl());
892       Assert.AreEqual(@"{""Id"":0}", json);
893     }
894
895     [Test]
896     public void DeserializeNullable()
897     {
898       string json;
899
900       json = JsonConvert.SerializeObject((int?)null);
901       Assert.AreEqual("null", json);
902
903       json = JsonConvert.SerializeObject((int?)1);
904       Assert.AreEqual("1", json);
905     }
906
907     [Test]
908     public void SerializeJsonRaw()
909     {
910       PersonRaw personRaw = new PersonRaw
911       {
912         FirstName = "FirstNameValue",
913         RawContent = new JRaw("[1,2,3,4,5]"),
914         LastName = "LastNameValue"
915       };
916
917       string json;
918
919       json = JsonConvert.SerializeObject(personRaw);
920       Assert.AreEqual(@"{""first_name"":""FirstNameValue"",""RawContent"":[1,2,3,4,5],""last_name"":""LastNameValue""}", json);
921     }
922
923     [Test]
924     public void DeserializeJsonRaw()
925     {
926       string json = @"{""first_name"":""FirstNameValue"",""RawContent"":[1,2,3,4,5],""last_name"":""LastNameValue""}";
927
928       PersonRaw personRaw = JsonConvert.DeserializeObject<PersonRaw>(json);
929
930       Assert.AreEqual("FirstNameValue", personRaw.FirstName);
931       Assert.AreEqual("[1,2,3,4,5]", personRaw.RawContent.ToString());
932       Assert.AreEqual("LastNameValue", personRaw.LastName);
933     }
934
935
936     [Test]
937     public void DeserializeNullableMember()
938     {
939       UserNullable userNullablle = new UserNullable
940                                     {
941                                       Id = new Guid("AD6205E8-0DF4-465d-AEA6-8BA18E93A7E7"),
942                                       FName = "FirstValue",
943                                       LName = "LastValue",
944                                       RoleId = 5,
945                                       NullableRoleId = 6,
946                                       NullRoleId = null,
947                                       Active = true
948                                     };
949
950       string json = JsonConvert.SerializeObject(userNullablle);
951
952       Assert.AreEqual(@"{""Id"":""ad6205e8-0df4-465d-aea6-8ba18e93a7e7"",""FName"":""FirstValue"",""LName"":""LastValue"",""RoleId"":5,""NullableRoleId"":6,""NullRoleId"":null,""Active"":true}", json);
953
954       UserNullable userNullablleDeserialized = JsonConvert.DeserializeObject<UserNullable>(json);
955
956       Assert.AreEqual(new Guid("AD6205E8-0DF4-465d-AEA6-8BA18E93A7E7"), userNullablleDeserialized.Id);
957       Assert.AreEqual("FirstValue", userNullablleDeserialized.FName);
958       Assert.AreEqual("LastValue", userNullablleDeserialized.LName);
959       Assert.AreEqual(5, userNullablleDeserialized.RoleId);
960       Assert.AreEqual(6, userNullablleDeserialized.NullableRoleId);
961       Assert.AreEqual(null, userNullablleDeserialized.NullRoleId);
962       Assert.AreEqual(true, userNullablleDeserialized.Active);
963     }
964
965     [Test]
966     public void DeserializeInt64ToNullableDouble()
967     {
968       string json = @"{""Height"":1}";
969
970       DoubleClass c = JsonConvert.DeserializeObject<DoubleClass>(json);
971       Assert.AreEqual(1, c.Height);
972     }
973
974     [Test]
975     public void SerializeTypeProperty()
976     {
977       string boolRef = typeof(bool).AssemblyQualifiedName;
978       TypeClass typeClass = new TypeClass { TypeProperty = typeof(bool) };
979
980       string json = JsonConvert.SerializeObject(typeClass);
981       Assert.AreEqual(@"{""TypeProperty"":""" + boolRef + @"""}", json);
982
983       TypeClass typeClass2 = JsonConvert.DeserializeObject<TypeClass>(json);
984       Assert.AreEqual(typeof(bool), typeClass2.TypeProperty);
985
986       string jsonSerializerTestRef = typeof(JsonSerializerTest).AssemblyQualifiedName;
987       typeClass = new TypeClass { TypeProperty = typeof(JsonSerializerTest) };
988
989       json = JsonConvert.SerializeObject(typeClass);
990       Assert.AreEqual(@"{""TypeProperty"":""" + jsonSerializerTestRef + @"""}", json);
991
992       typeClass2 = JsonConvert.DeserializeObject<TypeClass>(json);
993       Assert.AreEqual(typeof(JsonSerializerTest), typeClass2.TypeProperty);
994     }
995
996     [Test]
997     public void RequiredMembersClass()
998     {
999       RequiredMembersClass c = new RequiredMembersClass()
1000       {
1001         BirthDate = new DateTime(2000, 12, 20, 10, 55, 55, DateTimeKind.Utc),
1002         FirstName = "Bob",
1003         LastName = "Smith",
1004         MiddleName = "Cosmo"
1005       };
1006
1007       string json = JsonConvert.SerializeObject(c, Formatting.Indented);
1008
1009       Assert.AreEqual(@"{
1010   ""FirstName"": ""Bob"",
1011   ""MiddleName"": ""Cosmo"",
1012   ""LastName"": ""Smith"",
1013   ""BirthDate"": ""\/Date(977309755000)\/""
1014 }", json);
1015
1016       RequiredMembersClass c2 = JsonConvert.DeserializeObject<RequiredMembersClass>(json);
1017
1018       Assert.AreEqual("Bob", c2.FirstName);
1019       Assert.AreEqual(new DateTime(2000, 12, 20, 10, 55, 55, DateTimeKind.Utc), c2.BirthDate);
1020     }
1021
1022     [Test]
1023     public void DeserializeRequiredMembersClassWithNullValues()
1024     {
1025       string json = @"{
1026   ""FirstName"": ""I can't be null bro!"",
1027   ""MiddleName"": null,
1028   ""LastName"": null,
1029   ""BirthDate"": ""\/Date(977309755000)\/""
1030 }";
1031
1032       RequiredMembersClass c = JsonConvert.DeserializeObject<RequiredMembersClass>(json);
1033
1034       Assert.AreEqual("I can't be null bro!", c.FirstName);
1035       Assert.AreEqual(null, c.MiddleName);
1036       Assert.AreEqual(null, c.LastName);
1037     }
1038
1039     [Test]
1040     [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "Required property 'FirstName' expects a value but got null.")]
1041     public void DeserializeRequiredMembersClassNullRequiredValueProperty()
1042     {
1043       string json = @"{
1044   ""FirstName"": null,
1045   ""MiddleName"": null,
1046   ""LastName"": null,
1047   ""BirthDate"": ""\/Date(977309755000)\/""
1048 }";
1049
1050       JsonConvert.DeserializeObject<RequiredMembersClass>(json);
1051     }
1052
1053     [Test]
1054     [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "Cannot write a null value for property 'FirstName'. Property requires a value.")]
1055     public void SerializeRequiredMembersClassNullRequiredValueProperty()
1056     {
1057       RequiredMembersClass requiredMembersClass = new RequiredMembersClass
1058         {
1059           FirstName = null,
1060           BirthDate = new DateTime(2000, 10, 10, 10, 10, 10, DateTimeKind.Utc),
1061           LastName = null,
1062           MiddleName = null
1063         };
1064
1065       string json = JsonConvert.SerializeObject(requiredMembersClass);
1066       Console.WriteLine(json);
1067     }
1068
1069     [Test]
1070     [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "Required property 'LastName' not found in JSON.")]
1071     public void RequiredMembersClassMissingRequiredProperty()
1072     {
1073       string json = @"{
1074   ""FirstName"": ""Bob""
1075 }";
1076
1077       JsonConvert.DeserializeObject<RequiredMembersClass>(json);
1078     }
1079
1080     [Test]
1081     public void SerializeJaggedArray()
1082     {
1083       JaggedArray aa = new JaggedArray();
1084       aa.Before = "Before!";
1085       aa.After = "After!";
1086       aa.Coordinates = new[] { new[] { 1, 1 }, new[] { 1, 2 }, new[] { 2, 1 }, new[] { 2, 2 } };
1087
1088       string json = JsonConvert.SerializeObject(aa);
1089
1090       Assert.AreEqual(@"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2],[2,1],[2,2]],""After"":""After!""}", json);
1091     }
1092
1093     [Test]
1094     public void DeserializeJaggedArray()
1095     {
1096       string json = @"{""Before"":""Before!"",""Coordinates"":[[1,1],[1,2],[2,1],[2,2]],""After"":""After!""}";
1097
1098       JaggedArray aa = JsonConvert.DeserializeObject<JaggedArray>(json);
1099
1100       Assert.AreEqual("Before!", aa.Before);
1101       Assert.AreEqual("After!", aa.After);
1102       Assert.AreEqual(4, aa.Coordinates.Length);
1103       Assert.AreEqual(2, aa.Coordinates[0].Length);
1104       Assert.AreEqual(1, aa.Coordinates[0][0]);
1105       Assert.AreEqual(2, aa.Coordinates[1][1]);
1106
1107       string after = JsonConvert.SerializeObject(aa);
1108
1109       Assert.AreEqual(json, after);
1110     }
1111
1112     [Test]
1113     public void DeserializeGoogleGeoCode()
1114     {
1115       string json = @"{
1116   ""name"": ""1600 Amphitheatre Parkway, Mountain View, CA, USA"",
1117   ""Status"": {
1118     ""code"": 200,
1119     ""request"": ""geocode""
1120   },
1121   ""Placemark"": [
1122     {
1123       ""address"": ""1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA"",
1124       ""AddressDetails"": {
1125         ""Country"": {
1126           ""CountryNameCode"": ""US"",
1127           ""AdministrativeArea"": {
1128             ""AdministrativeAreaName"": ""CA"",
1129             ""SubAdministrativeArea"": {
1130               ""SubAdministrativeAreaName"": ""Santa Clara"",
1131               ""Locality"": {
1132                 ""LocalityName"": ""Mountain View"",
1133                 ""Thoroughfare"": {
1134                   ""ThoroughfareName"": ""1600 Amphitheatre Pkwy""
1135                 },
1136                 ""PostalCode"": {
1137                   ""PostalCodeNumber"": ""94043""
1138                 }
1139               }
1140             }
1141           }
1142         },
1143         ""Accuracy"": 8
1144       },
1145       ""Point"": {
1146         ""coordinates"": [-122.083739, 37.423021, 0]
1147       }
1148     }
1149   ]
1150 }";
1151
1152       GoogleMapGeocoderStructure jsonGoogleMapGeocoder = JsonConvert.DeserializeObject<GoogleMapGeocoderStructure>(json);
1153     }
1154
1155     [Test]
1156     [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"Could not create an instance of type Newtonsoft.Json.Tests.TestObjects.ICo. Type is an interface or abstract class and cannot be instantated.")]
1157     public void DeserializeInterfaceProperty()
1158     {
1159       InterfacePropertyTestClass testClass = new InterfacePropertyTestClass();
1160       testClass.co = new Co();
1161       String strFromTest = JsonConvert.SerializeObject(testClass);
1162       InterfacePropertyTestClass testFromDe = (InterfacePropertyTestClass)JsonConvert.DeserializeObject(strFromTest, typeof(InterfacePropertyTestClass));
1163     }
1164
1165     private Person GetPerson()
1166     {
1167       Person person = new Person
1168                         {
1169                           Name = "Mike Manager",
1170                           BirthDate = new DateTime(1983, 8, 3, 0, 0, 0, DateTimeKind.Utc),
1171                           Department = "IT",
1172                           LastModified = new DateTime(2009, 2, 15, 0, 0, 0, DateTimeKind.Utc)
1173                         };
1174       return person;
1175     }
1176
1177     //[Test]
1178     public void WriteJsonToFile()
1179     {
1180       //Person person = GetPerson();
1181
1182       //string json = JsonConvert.SerializeObject(person, Formatting.Indented);
1183
1184       //File.WriteAllText(@"c:\person.json", json);
1185
1186       Person person = GetPerson();
1187
1188       using (FileStream fs = System.IO.File.Open(@"c:\person.json", FileMode.CreateNew))
1189       using (StreamWriter sw = new StreamWriter(fs))
1190       using (JsonWriter jw = new JsonTextWriter(sw))
1191       {
1192         jw.Formatting = Formatting.Indented;
1193
1194         JsonSerializer serializer = new JsonSerializer();
1195         serializer.Serialize(jw, person);
1196       }
1197     }
1198
1199     [Test]
1200     public void WriteJsonDates()
1201     {
1202       LogEntry entry = new LogEntry
1203                          {
1204                            LogDate = new DateTime(2009, 2, 15, 0, 0, 0, DateTimeKind.Utc),
1205                            Details = "Application started."
1206                          };
1207
1208       string defaultJson = JsonConvert.SerializeObject(entry);
1209       // {"Details":"Application started.","LogDate":"\/Date(1234656000000)\/"}
1210
1211       string isoJson = JsonConvert.SerializeObject(entry, new IsoDateTimeConverter());
1212       // {"Details":"Application started.","LogDate":"2009-02-15T00:00:00.0000000Z"}
1213
1214       string javascriptJson = JsonConvert.SerializeObject(entry, new JavaScriptDateTimeConverter());
1215       // {"Details":"Application started.","LogDate":new Date(1234656000000)}
1216
1217       Console.WriteLine(defaultJson);
1218       Console.WriteLine(isoJson);
1219       Console.WriteLine(javascriptJson);
1220     }
1221
1222     public void GenericListAndDictionaryInterfaceProperties()
1223     {
1224       GenericListAndDictionaryInterfaceProperties o = new GenericListAndDictionaryInterfaceProperties();
1225       o.IDictionaryProperty = new Dictionary<string, int>
1226                                 {
1227                                   {"one", 1},
1228                                   {"two", 2},
1229                                   {"three", 3}
1230                                 };
1231       o.IListProperty = new List<int>
1232                           {
1233                             1, 2, 3
1234                           };
1235       o.IEnumerableProperty = new List<int>
1236                                 {
1237                                   4, 5, 6
1238                                 };
1239
1240       string json = JsonConvert.SerializeObject(o, Formatting.Indented);
1241
1242       Assert.AreEqual(@"{
1243   ""IEnumerableProperty"": [
1244     4,
1245     5,
1246     6
1247   ],
1248   ""IListProperty"": [
1249     1,
1250     2,
1251     3
1252   ],
1253   ""IDictionaryProperty"": {
1254     ""one"": 1,
1255     ""two"": 2,
1256     ""three"": 3
1257   }
1258 }", json);
1259
1260       GenericListAndDictionaryInterfaceProperties deserializedObject = JsonConvert.DeserializeObject<GenericListAndDictionaryInterfaceProperties>(json);
1261       Assert.IsNotNull(deserializedObject);
1262
1263       CollectionAssert.AreEqual(o.IListProperty.ToArray(), deserializedObject.IListProperty.ToArray());
1264       CollectionAssert.AreEqual(o.IEnumerableProperty.ToArray(), deserializedObject.IEnumerableProperty.ToArray());
1265       CollectionAssert.AreEqual(o.IDictionaryProperty.ToArray(), deserializedObject.IDictionaryProperty.ToArray());
1266     }
1267
1268     [Test]
1269     public void DeserializeBestMatchPropertyCase()
1270     {
1271       string json = @"{
1272   ""firstName"": ""firstName"",
1273   ""FirstName"": ""FirstName"",
1274   ""LastName"": ""LastName"",
1275   ""lastName"": ""lastName"",
1276 }";
1277
1278       PropertyCase o = JsonConvert.DeserializeObject<PropertyCase>(json);
1279       Assert.IsNotNull(o);
1280
1281       Assert.AreEqual("firstName", o.firstName);
1282       Assert.AreEqual("FirstName", o.FirstName);
1283       Assert.AreEqual("LastName", o.LastName);
1284       Assert.AreEqual("lastName", o.lastName);
1285     }
1286
1287     [Test]
1288     public void DeserializePropertiesOnToNonDefaultConstructor()
1289     {
1290       SubKlass i = new SubKlass("my subprop");
1291       i.SuperProp = "overrided superprop";
1292
1293       string json = JsonConvert.SerializeObject(i);
1294       Assert.AreEqual(@"{""SubProp"":""my subprop"",""SuperProp"":""overrided superprop""}", json);
1295
1296       SubKlass ii = JsonConvert.DeserializeObject<SubKlass>(json);
1297
1298       string newJson = JsonConvert.SerializeObject(ii);
1299       Assert.AreEqual(@"{""SubProp"":""my subprop"",""SuperProp"":""overrided superprop""}", newJson);
1300     }
1301
1302     [Test]
1303     public void JsonPropertyWithHandlingValues()
1304     {
1305       JsonPropertyWithHandlingValues o = new JsonPropertyWithHandlingValues();
1306       o.DefaultValueHandlingIgnoreProperty = "Default!";
1307       o.DefaultValueHandlingIncludeProperty = "Default!";
1308
1309       string json = JsonConvert.SerializeObject(o, Formatting.Indented);
1310
1311       Assert.AreEqual(@"{
1312   ""DefaultValueHandlingIncludeProperty"": ""Default!"",
1313   ""NullValueHandlingIncludeProperty"": null,
1314   ""ReferenceLoopHandlingErrorProperty"": null,
1315   ""ReferenceLoopHandlingIgnoreProperty"": null,
1316   ""ReferenceLoopHandlingSerializeProperty"": null
1317 }", json);
1318
1319       json = JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
1320
1321       Assert.AreEqual(@"{
1322   ""DefaultValueHandlingIncludeProperty"": ""Default!"",
1323   ""NullValueHandlingIncludeProperty"": null
1324 }", json);
1325     }
1326
1327     [Test]
1328     [ExpectedException(typeof(JsonSerializationException))]
1329     public void JsonPropertyWithHandlingValues_ReferenceLoopError()
1330     {
1331       JsonPropertyWithHandlingValues o = new JsonPropertyWithHandlingValues();
1332       o.ReferenceLoopHandlingErrorProperty = o;
1333
1334       JsonConvert.SerializeObject(o, Formatting.Indented, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
1335     }
1336
1337     [Test]
1338     public void PartialClassDeserialize()
1339     {
1340       string json = @"{
1341     ""request"": ""ux.settings.update"",
1342     ""sid"": ""14c561bd-32a8-457e-b4e5-4bba0832897f"",
1343     ""uid"": ""30c39065-0f31-de11-9442-001e3786a8ec"",
1344     ""fidOrder"": [
1345         ""id"",
1346         ""andytest_name"",
1347         ""andytest_age"",
1348         ""andytest_address"",
1349         ""andytest_phone"",
1350         ""date"",
1351         ""title"",
1352         ""titleId""
1353     ],
1354     ""entityName"": ""Andy Test"",
1355     ""setting"": ""entity.field.order""
1356 }";
1357
1358       RequestOnly r = JsonConvert.DeserializeObject<RequestOnly>(json);
1359       Assert.AreEqual("ux.settings.update", r.Request);
1360
1361       NonRequest n = JsonConvert.DeserializeObject<NonRequest>(json);
1362       Assert.AreEqual(new Guid("14c561bd-32a8-457e-b4e5-4bba0832897f"), n.Sid);
1363       Assert.AreEqual(new Guid("30c39065-0f31-de11-9442-001e3786a8ec"), n.Uid);
1364       Assert.AreEqual(8, n.FidOrder.Count);
1365       Assert.AreEqual("id", n.FidOrder[0]);
1366       Assert.AreEqual("titleId", n.FidOrder[n.FidOrder.Count - 1]);
1367     }
1368
1369 #if !SILVERLIGHT && !PocketPC && !NET20
1370     [MetadataType(typeof(OptInClassMetadata))]
1371     public class OptInClass
1372     {
1373       [DataContract]
1374       public class OptInClassMetadata
1375       {
1376         [DataMember]
1377         public string Name { get; set; }
1378         [DataMember]
1379         public int Age { get; set; }
1380         public string NotIncluded { get; set; }
1381       }
1382
1383       public string Name { get; set; }
1384       public int Age { get; set; }
1385       public string NotIncluded { get; set; }
1386     }
1387
1388     [Test]
1389     public void OptInClassMetadataSerialization()
1390     {
1391       OptInClass optInClass = new OptInClass();
1392       optInClass.Age = 26;
1393       optInClass.Name = "James NK";
1394       optInClass.NotIncluded = "Poor me :(";
1395
1396       string json = JsonConvert.SerializeObject(optInClass, Formatting.Indented);
1397
1398       Assert.AreEqual(@"{
1399   ""Name"": ""James NK"",
1400   ""Age"": 26
1401 }", json);
1402
1403       OptInClass newOptInClass = JsonConvert.DeserializeObject<OptInClass>(@"{
1404   ""Name"": ""James NK"",
1405   ""NotIncluded"": ""Ignore me!"",
1406   ""Age"": 26
1407 }");
1408       Assert.AreEqual(26, newOptInClass.Age);
1409       Assert.AreEqual("James NK", newOptInClass.Name);
1410       Assert.AreEqual(null, newOptInClass.NotIncluded);
1411     }
1412 #endif
1413
1414 #if !PocketPC && !NET20
1415     [DataContract]
1416     public class DataContractPrivateMembers
1417     {
1418       public DataContractPrivateMembers()
1419       {
1420       }
1421
1422       public DataContractPrivateMembers(string name, int age, int rank, string title)
1423       {
1424         _name = name;
1425         Age = age;
1426         Rank = rank;
1427         Title = title;
1428       }
1429
1430       [DataMember]
1431       private string _name;
1432       [DataMember(Name = "_age")]
1433       private int Age { get; set; }
1434       [JsonProperty]
1435       private int Rank { get; set; }
1436       [JsonProperty(PropertyName = "JsonTitle")]
1437       [DataMember(Name = "DataTitle")]
1438       private string Title { get; set; }
1439
1440       public string NotIncluded { get; set; }
1441
1442       public override string ToString()
1443       {
1444         return "_name: " + _name + ", _age: " + Age + ", Rank: " + Rank + ", JsonTitle: " + Title;
1445       }
1446     }
1447
1448     [Test]
1449     public void SerializeDataContractPrivateMembers()
1450     {
1451       DataContractPrivateMembers c = new DataContractPrivateMembers("Jeff", 26, 10, "Dr");
1452       c.NotIncluded = "Hi";
1453       string json = JsonConvert.SerializeObject(c, Formatting.Indented);
1454
1455       Assert.AreEqual(@"{
1456   ""_name"": ""Jeff"",
1457   ""_age"": 26,
1458   ""Rank"": 10,
1459   ""JsonTitle"": ""Dr""
1460 }", json);
1461
1462       DataContractPrivateMembers cc = JsonConvert.DeserializeObject<DataContractPrivateMembers>(json);
1463       Assert.AreEqual("_name: Jeff, _age: 26, Rank: 10, JsonTitle: Dr", cc.ToString());
1464     }
1465 #endif
1466
1467     [Test]
1468     public void DeserializeDictionaryInterface()
1469     {
1470       string json = @"{
1471   ""Name"": ""Name!"",
1472   ""Dictionary"": {
1473     ""Item"": 11
1474   }
1475 }";
1476
1477       DictionaryInterfaceClass c = JsonConvert.DeserializeObject<DictionaryInterfaceClass>(json,
1478         new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Replace });
1479       Assert.AreEqual("Name!", c.Name);
1480       Assert.AreEqual(1, c.Dictionary.Count);
1481       Assert.AreEqual(11, c.Dictionary["Item"]);
1482     }
1483
1484     [Test]
1485     public void DeserializeDictionaryInterfaceWithExistingValues()
1486     {
1487       string json = @"{
1488   ""Random"": {
1489     ""blah"": 1
1490   },
1491   ""Name"": ""Name!"",
1492   ""Dictionary"": {
1493     ""Item"": 11,
1494     ""Item1"": 12
1495   },
1496   ""Collection"": [
1497     999
1498   ],
1499   ""Employee"": {
1500     ""Manager"": {
1501       ""Name"": ""ManagerName!""
1502     }
1503   }
1504 }";
1505
1506       DictionaryInterfaceClass c = JsonConvert.DeserializeObject<DictionaryInterfaceClass>(json,
1507         new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Reuse });
1508
1509       Assert.AreEqual("Name!", c.Name);
1510       Assert.AreEqual(3, c.Dictionary.Count);
1511       Assert.AreEqual(11, c.Dictionary["Item"]);
1512       Assert.AreEqual(1, c.Dictionary["existing"]);
1513       Assert.AreEqual(4, c.Collection.Count);
1514       Assert.AreEqual(1, c.Collection.ElementAt(0));
1515       Assert.AreEqual(999, c.Collection.ElementAt(3));
1516       Assert.AreEqual("EmployeeName!", c.Employee.Name);
1517       Assert.AreEqual("ManagerName!", c.Employee.Manager.Name);
1518       Assert.IsNotNull(c.Random);
1519     }
1520
1521     [Test]
1522     public void TypedObjectDeserializationWithComments()
1523     {
1524       string json = @"/*comment*/ { /*comment*/
1525         ""Name"": /*comment*/ ""Apple"" /*comment*/, /*comment*/
1526         ""ExpiryDate"": ""\/Date(1230422400000)\/"",
1527         ""Price"": 3.99,
1528         ""Sizes"": /*comment*/ [ /*comment*/
1529           ""Small"", /*comment*/
1530           ""Medium"" /*comment*/,
1531           /*comment*/ ""Large""
1532         /*comment*/ ] /*comment*/
1533       } /*comment*/";
1534
1535       Product deserializedProduct = (Product)JsonConvert.DeserializeObject(json, typeof(Product));
1536
1537       Assert.AreEqual("Apple", deserializedProduct.Name);
1538       Assert.AreEqual(new DateTime(2008, 12, 28, 0, 0, 0, DateTimeKind.Utc), deserializedProduct.ExpiryDate);
1539       Assert.AreEqual(3.99, deserializedProduct.Price);
1540       Assert.AreEqual("Small", deserializedProduct.Sizes[0]);
1541       Assert.AreEqual("Medium", deserializedProduct.Sizes[1]);
1542       Assert.AreEqual("Large", deserializedProduct.Sizes[2]);
1543     }
1544
1545     [Test]
1546     public void NestedInsideOuterObject()
1547     {
1548       string json = @"{
1549   ""short"": {
1550     ""original"": ""http://www.contrast.ie/blog/online&#45;marketing&#45;2009/"",
1551     ""short"": ""m2sqc6"",
1552     ""shortened"": ""http://short.ie/m2sqc6"",
1553     ""error"": {
1554       ""code"": 0,
1555       ""msg"": ""No action taken""
1556     }
1557   }
1558 }";
1559
1560       JObject o = JObject.Parse(json);
1561
1562       Shortie s = JsonConvert.DeserializeObject<Shortie>(o["short"].ToString());
1563       Assert.IsNotNull(s);
1564
1565       Assert.AreEqual(s.Original, "http://www.contrast.ie/blog/online&#45;marketing&#45;2009/");
1566       Assert.AreEqual(s.Short, "m2sqc6");
1567       Assert.AreEqual(s.Shortened, "http://short.ie/m2sqc6");
1568     }
1569
1570     [Test]
1571     public void UriSerialization()
1572     {
1573       Uri uri = new Uri("http://codeplex.com");
1574       string json = JsonConvert.SerializeObject(uri);
1575
1576       Assert.AreEqual("http://codeplex.com/", uri.ToString());
1577
1578       Uri newUri = JsonConvert.DeserializeObject<Uri>(json);
1579       Assert.AreEqual(uri, newUri);
1580     }
1581
1582     [Test]
1583     public void AnonymousPlusLinqToSql()
1584     {
1585       var value = new
1586         {
1587           bar = new JObject(new JProperty("baz", 13))
1588         };
1589
1590       string json = JsonConvert.SerializeObject(value);
1591
1592       Assert.AreEqual(@"{""bar"":{""baz"":13}}", json);
1593     }
1594
1595     [Test]
1596     public void SerializeEnumerableAsObject()
1597     {
1598       Content content = new Content
1599         {
1600           Text = "Blah, blah, blah",
1601           Children = new List<Content>
1602             {
1603               new Content { Text = "First" },
1604               new Content { Text = "Second" }
1605             }
1606         };
1607
1608       string json = JsonConvert.SerializeObject(content, Formatting.Indented);
1609
1610       Assert.AreEqual(@"{
1611   ""Children"": [
1612     {
1613       ""Children"": null,
1614       ""Text"": ""First""
1615     },
1616     {
1617       ""Children"": null,
1618       ""Text"": ""Second""
1619     }
1620   ],
1621   ""Text"": ""Blah, blah, blah""
1622 }", json);
1623     }
1624
1625     [Test]
1626     public void DeserializeEnumerableAsObject()
1627     {
1628       string json = @"{
1629   ""Children"": [
1630     {
1631       ""Children"": null,
1632       ""Text"": ""First""
1633     },
1634     {
1635       ""Children"": null,
1636       ""Text"": ""Second""
1637     }
1638   ],
1639   ""Text"": ""Blah, blah, blah""
1640 }";
1641
1642       Content content = JsonConvert.DeserializeObject<Content>(json);
1643
1644       Assert.AreEqual("Blah, blah, blah", content.Text);
1645       Assert.AreEqual(2, content.Children.Count);
1646       Assert.AreEqual("First", content.Children[0].Text);
1647       Assert.AreEqual("Second", content.Children[1].Text);
1648     }
1649
1650     [Test]
1651     public void RoleTransferTest()
1652     {
1653       string json = @"{""Operation"":""1"",""RoleName"":""Admin"",""Direction"":""0""}";
1654
1655       RoleTransfer r = JsonConvert.DeserializeObject<RoleTransfer>(json);
1656
1657       Assert.AreEqual(RoleTransferOperation.Second, r.Operation);
1658       Assert.AreEqual("Admin", r.RoleName);
1659       Assert.AreEqual(RoleTransferDirection.First, r.Direction);
1660     }
1661
1662     [Test]
1663     public void PrimitiveValuesInObjectArray()
1664     {
1665       string json = @"{""action"":""Router"",""method"":""Navigate"",""data"":[""dashboard"",null],""type"":""rpc"",""tid"":2}";
1666
1667       ObjectArrayPropertyTest o = JsonConvert.DeserializeObject<ObjectArrayPropertyTest>(json);
1668
1669       Assert.AreEqual("Router", o.Action);
1670       Assert.AreEqual("Navigate", o.Method);
1671       Assert.AreEqual(2, o.Data.Length);
1672       Assert.AreEqual("dashboard", o.Data[0]);
1673       Assert.AreEqual(null, o.Data[1]);
1674     }
1675
1676     [Test]
1677     public void ComplexValuesInObjectArray()
1678     {
1679       string json = @"{""action"":""Router"",""method"":""Navigate"",""data"":[""dashboard"",[""id"", 1, ""teststring"", ""test""],{""one"":1}],""type"":""rpc"",""tid"":2}";
1680
1681       ObjectArrayPropertyTest o = JsonConvert.DeserializeObject<ObjectArrayPropertyTest>(json);
1682
1683       Assert.AreEqual("Router", o.Action);
1684       Assert.AreEqual("Navigate", o.Method);
1685       Assert.AreEqual(3, o.Data.Length);
1686       Assert.AreEqual("dashboard", o.Data[0]);
1687       Assert.IsInstanceOfType(typeof(JArray), o.Data[1]);
1688       Assert.AreEqual(4, ((JArray)o.Data[1]).Count);
1689       Assert.IsInstanceOfType(typeof(JObject), o.Data[2]);
1690       Assert.AreEqual(1, ((JObject)o.Data[2]).Count);
1691       Assert.AreEqual(1, (int)((JObject)o.Data[2])["one"]);
1692     }
1693
1694     [Test]
1695     public void DeserializeGenericDictionary()
1696     {
1697       string json = @"{""key1"":""value1"",""key2"":""value2""}";
1698
1699       Dictionary<string, string> values = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
1700
1701       Console.WriteLine(values.Count);
1702       // 2
1703
1704       Console.WriteLine(values["key1"]);
1705       // value1
1706
1707       Assert.AreEqual(2, values.Count);
1708       Assert.AreEqual("value1", values["key1"]);
1709       Assert.AreEqual("value2", values["key2"]);
1710     }
1711
1712     [Test]
1713     public void SerializeGenericList()
1714     {
1715       Product p1 = new Product
1716         {
1717           Name = "Product 1",
1718           Price = 99.95m,
1719           ExpiryDate = new DateTime(2000, 12, 29, 0, 0, 0, DateTimeKind.Utc),
1720         };
1721       Product p2 = new Product
1722       {
1723         Name = "Product 2",
1724         Price = 12.50m,
1725         ExpiryDate = new DateTime(2009, 7, 31, 0, 0, 0, DateTimeKind.Utc),
1726       };
1727
1728       List<Product> products = new List<Product>();
1729       products.Add(p1);
1730       products.Add(p2);
1731
1732       string json = JsonConvert.SerializeObject(products, Formatting.Indented);
1733       //[
1734       //  {
1735       //    "Name": "Product 1",
1736       //    "ExpiryDate": "\/Date(978048000000)\/",
1737       //    "Price": 99.95,
1738       //    "Sizes": null
1739       //  },
1740       //  {
1741       //    "Name": "Product 2",
1742       //    "ExpiryDate": "\/Date(1248998400000)\/",
1743       //    "Price": 12.50,
1744       //    "Sizes": null
1745       //  }
1746       //]
1747
1748       Assert.AreEqual(@"[
1749   {
1750     ""Name"": ""Product 1"",
1751     ""ExpiryDate"": ""\/Date(978048000000)\/"",
1752     ""Price"": 99.95,
1753     ""Sizes"": null
1754   },
1755   {
1756     ""Name"": ""Product 2"",
1757     ""ExpiryDate"": ""\/Date(1248998400000)\/"",
1758     ""Price"": 12.50,
1759     ""Sizes"": null
1760   }
1761 ]", json);
1762     }
1763
1764     [Test]
1765     public void DeserializeGenericList()
1766     {
1767       string json = @"[
1768         {
1769           ""Name"": ""Product 1"",
1770           ""ExpiryDate"": ""\/Date(978048000000)\/"",
1771           ""Price"": 99.95,
1772           ""Sizes"": null
1773         },
1774         {
1775           ""Name"": ""Product 2"",
1776           ""ExpiryDate"": ""\/Date(1248998400000)\/"",
1777           ""Price"": 12.50,
1778           ""Sizes"": null
1779         }
1780       ]";
1781
1782       List<Product> products = JsonConvert.DeserializeObject<List<Product>>(json);
1783
1784       Console.WriteLine(products.Count);
1785       // 2
1786
1787       Product p1 = products[0];
1788
1789       Console.WriteLine(p1.Name);
1790       // Product 1
1791
1792       Assert.AreEqual(2, products.Count);
1793       Assert.AreEqual("Product 1", products[0].Name);
1794     }
1795
1796 #if !PocketPC && !NET20
1797     [Test]
1798     public void DeserializeEmptyStringToNullableDateTime()
1799     {
1800       string json = @"{""DateTimeField"":""""}";
1801
1802       NullableDateTimeTestClass c = JsonConvert.DeserializeObject<NullableDateTimeTestClass>(json);
1803       Assert.AreEqual(null, c.DateTimeField);
1804     }
1805 #endif
1806
1807     [Test]
1808     [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"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.")]
1809     public void FailWhenClassWithNoDefaultConstructorHasMultipleConstructorsWithArguments()
1810     {
1811       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)\/""}";
1812
1813       Event e = JsonConvert.DeserializeObject<Event>(json);
1814     }
1815
1816     [Test]
1817     public void DeserializeObjectSetOnlyProperty()
1818     {
1819       string json = @"{'SetOnlyProperty':[1,2,3,4,5]}";
1820
1821       SetOnlyPropertyClass2 setOnly = JsonConvert.DeserializeObject<SetOnlyPropertyClass2>(json);
1822       JArray a = (JArray)setOnly.GetValue();
1823       Assert.AreEqual(5, a.Count);
1824       Assert.AreEqual(1, (int)a[0]);
1825       Assert.AreEqual(5, (int)a[a.Count - 1]);
1826     }
1827
1828     [Test]
1829     public void DeserializeOptInClasses()
1830     {
1831       string json = @"{id: ""12"", name: ""test"", items: [{id: ""112"", name: ""testing""}]}";
1832
1833       ListTestClass l = JsonConvert.DeserializeObject<ListTestClass>(json);
1834     }
1835
1836     [Test]
1837     public void DeserializeNullableListWithNulls()
1838     {
1839       List<decimal?> l = JsonConvert.DeserializeObject<List<decimal?>>("[ 3.3, null, 1.1 ] ");
1840       Assert.AreEqual(3, l.Count);
1841
1842       Assert.AreEqual(3.3m, l[0]);
1843       Assert.AreEqual(null, l[1]);
1844       Assert.AreEqual(1.1m, l[2]);
1845     }
1846
1847     [Test]
1848     [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"Cannot deserialize JSON array into type 'Newtonsoft.Json.Tests.TestObjects.Person'.")]
1849     public void CannotDeserializeArrayIntoObject()
1850     {
1851       string json = @"[]";
1852
1853       JsonConvert.DeserializeObject<Person>(json);
1854     }
1855
1856     [Test]
1857     [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"Cannot deserialize JSON object into type 'System.Collections.Generic.List`1[Newtonsoft.Json.Tests.TestObjects.Person]'.")]
1858     public void CannotDeserializeObjectIntoArray()
1859     {
1860       string json = @"{}";
1861
1862       JsonConvert.DeserializeObject<List<Person>>(json);
1863     }
1864
1865     [Test]
1866     [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"Cannot populate JSON array onto type 'Newtonsoft.Json.Tests.TestObjects.Person'.")]
1867     public void CannotPopulateArrayIntoObject()
1868     {
1869       string json = @"[]";
1870
1871       JsonConvert.PopulateObject(json, new Person());
1872     }
1873
1874     [Test]
1875     [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"Cannot populate JSON object onto type 'System.Collections.Generic.List`1[Newtonsoft.Json.Tests.TestObjects.Person]'.")]
1876     public void CannotPopulateObjectIntoArray()
1877     {
1878       string json = @"{}";
1879
1880       JsonConvert.PopulateObject(json, new List<Person>());
1881     }
1882
1883     [Test]
1884     public void DeserializeEmptyString()
1885     {
1886       string json = @"{""Name"":""""}";
1887
1888       Person p = JsonConvert.DeserializeObject<Person>(json);
1889       Assert.AreEqual("", p.Name);
1890     }
1891
1892     [Test]
1893     [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"Error getting value from 'ReadTimeout' on 'System.IO.MemoryStream'.")]
1894     public void SerializePropertyGetError()
1895     {
1896       JsonConvert.SerializeObject(new MemoryStream());
1897     }
1898
1899     [Test]
1900     [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"Error setting value to 'ReadTimeout' on 'System.IO.MemoryStream'.")]
1901     public void DeserializePropertySetError()
1902     {
1903       JsonConvert.DeserializeObject<MemoryStream>("{ReadTimeout:0}");
1904     }
1905
1906     [Test]
1907     [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"Error converting value """" to type 'System.Int32'.")]
1908     public void DeserializeEnsureTypeEmptyStringToIntError()
1909     {
1910       JsonConvert.DeserializeObject<MemoryStream>("{ReadTimeout:''}");
1911     }
1912
1913     [Test]
1914     [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"Error converting value {null} to type 'System.Int32'.")]
1915     public void DeserializeEnsureTypeNullToIntError()
1916     {
1917       JsonConvert.DeserializeObject<MemoryStream>("{ReadTimeout:null}");
1918     }
1919
1920     [Test]
1921     public void SerializeGenericListOfStrings()
1922     {
1923       List<String> strings = new List<String>();
1924
1925       strings.Add("str_1");
1926       strings.Add("str_2");
1927       strings.Add("str_3");
1928
1929       string json = JsonConvert.SerializeObject(strings);
1930       Assert.AreEqual(@"[""str_1"",""str_2"",""str_3""]", json);
1931     }
1932
1933     [Test]
1934     public void ConstructorReadonlyFieldsTest()
1935     {
1936       ConstructorReadonlyFields c1 = new ConstructorReadonlyFields("String!", int.MaxValue);
1937       string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
1938       Assert.AreEqual(@"{
1939   ""A"": ""String!"",
1940   ""B"": 2147483647
1941 }", json);
1942
1943       ConstructorReadonlyFields c2 = JsonConvert.DeserializeObject<ConstructorReadonlyFields>(json);
1944       Assert.AreEqual("String!", c2.A);
1945       Assert.AreEqual(int.MaxValue, c2.B);
1946     }
1947
1948     [Test]
1949     public void SerializeStruct()
1950     {
1951       StructTest structTest = new StructTest
1952                                 {
1953                                   StringProperty = "StringProperty!",
1954                                   StringField = "StringField",
1955                                   IntProperty = 5,
1956                                   IntField = 10
1957                                 };
1958
1959       string json = JsonConvert.SerializeObject(structTest, Formatting.Indented);
1960       Console.WriteLine(json);
1961       Assert.AreEqual(@"{
1962   ""StringField"": ""StringField"",
1963   ""IntField"": 10,
1964   ""StringProperty"": ""StringProperty!"",
1965   ""IntProperty"": 5
1966 }", json);
1967
1968       StructTest deserialized = JsonConvert.DeserializeObject<StructTest>(json);
1969       Assert.AreEqual(structTest.StringProperty, deserialized.StringProperty);
1970       Assert.AreEqual(structTest.StringField, deserialized.StringField);
1971       Assert.AreEqual(structTest.IntProperty, deserialized.IntProperty);
1972       Assert.AreEqual(structTest.IntField, deserialized.IntField);
1973     }
1974
1975     [Test]
1976     public void SerializeListWithJsonConverter()
1977     {
1978       Foo f = new Foo();
1979       f.Bars.Add(new Bar { Id = 0 });
1980       f.Bars.Add(new Bar { Id = 1 });
1981       f.Bars.Add(new Bar { Id = 2 });
1982
1983       string json = JsonConvert.SerializeObject(f, Formatting.Indented);
1984       Assert.AreEqual(@"{
1985   ""Bars"": [
1986     0,
1987     1,
1988     2
1989   ]
1990 }", json);
1991
1992       Foo newFoo = JsonConvert.DeserializeObject<Foo>(json);
1993       Assert.AreEqual(3, newFoo.Bars.Count);
1994       Assert.AreEqual(0, newFoo.Bars[0].Id);
1995       Assert.AreEqual(1, newFoo.Bars[1].Id);
1996       Assert.AreEqual(2, newFoo.Bars[2].Id);
1997     }
1998
1999     [Test]
2000     public void SerializeGuidKeyedDictionary()
2001     {
2002       Dictionary<Guid, int> dictionary = new Dictionary<Guid, int>();
2003       dictionary.Add(new Guid("F60EAEE0-AE47-488E-B330-59527B742D77"), 1);
2004       dictionary.Add(new Guid("C2594C02-EBA1-426A-AA87-8DD8871350B0"), 2);
2005
2006       string json = JsonConvert.SerializeObject(dictionary, Formatting.Indented);
2007       Assert.AreEqual(@"{
2008   ""f60eaee0-ae47-488e-b330-59527b742d77"": 1,
2009   ""c2594c02-eba1-426a-aa87-8dd8871350b0"": 2
2010 }", json);
2011     }
2012
2013     [Test]
2014     public void SerializePersonKeyedDictionary()
2015     {
2016       Dictionary<Person, int> dictionary = new Dictionary<Person, int>();
2017       dictionary.Add(new Person { Name = "p1" }, 1);
2018       dictionary.Add(new Person { Name = "p2" }, 2);
2019
2020       string json = JsonConvert.SerializeObject(dictionary, Formatting.Indented);
2021
2022       Assert.AreEqual(@"{
2023   ""Newtonsoft.Json.Tests.TestObjects.Person"": 1,
2024   ""Newtonsoft.Json.Tests.TestObjects.Person"": 2
2025 }", json);
2026     }
2027
2028     [Test]
2029     [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "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.")]
2030     public void DeserializePersonKeyedDictionary()
2031     {
2032       string json =
2033         @"{
2034   ""Newtonsoft.Json.Tests.TestObjects.Person"": 1,
2035   ""Newtonsoft.Json.Tests.TestObjects.Person"": 2
2036 }";
2037
2038       JsonConvert.DeserializeObject<Dictionary<Person, int>>(json);
2039     }
2040
2041     [Test]
2042     public void SerializeFragment()
2043     {
2044       string googleSearchText = @"{
2045         ""responseData"": {
2046           ""results"": [
2047             {
2048               ""GsearchResultClass"": ""GwebSearch"",
2049               ""unescapedUrl"": ""http://en.wikipedia.org/wiki/Paris_Hilton"",
2050               ""url"": ""http://en.wikipedia.org/wiki/Paris_Hilton"",
2051               ""visibleUrl"": ""en.wikipedia.org"",
2052               ""cacheUrl"": ""http://www.google.com/search?q=cache:TwrPfhd22hYJ:en.wikipedia.org"",
2053               ""title"": ""<b>Paris Hilton</b> - Wikipedia, the free encyclopedia"",
2054               ""titleNoFormatting"": ""Paris Hilton - Wikipedia, the free encyclopedia"",
2055               ""content"": ""[1] In 2006, she released her debut album...""
2056             },
2057             {
2058               ""GsearchResultClass"": ""GwebSearch"",
2059               ""unescapedUrl"": ""http://www.imdb.com/name/nm0385296/"",
2060               ""url"": ""http://www.imdb.com/name/nm0385296/"",
2061               ""visibleUrl"": ""www.imdb.com"",
2062               ""cacheUrl"": ""http://www.google.com/search?q=cache:1i34KkqnsooJ:www.imdb.com"",
2063               ""title"": ""<b>Paris Hilton</b>"",
2064               ""titleNoFormatting"": ""Paris Hilton"",
2065               ""content"": ""Self: Zoolander. Socialite <b>Paris Hilton</b>...""
2066             }
2067           ],
2068           ""cursor"": {
2069             ""pages"": [
2070               {
2071                 ""start"": ""0"",
2072                 ""label"": 1
2073               },
2074               {
2075                 ""start"": ""4"",
2076                 ""label"": 2
2077               },
2078               {
2079                 ""start"": ""8"",
2080                 ""label"": 3
2081               },
2082               {
2083                 ""start"": ""12"",
2084                 ""label"": 4
2085               }
2086             ],
2087             ""estimatedResultCount"": ""59600000"",
2088             ""currentPageIndex"": 0,
2089             ""moreResultsUrl"": ""http://www.google.com/search?oe=utf8&ie=utf8...""
2090           }
2091         },
2092         ""responseDetails"": null,
2093         ""responseStatus"": 200
2094       }";
2095
2096       JObject googleSearch = JObject.Parse(googleSearchText);
2097
2098       // get JSON result objects into a list
2099       IList<JToken> results = googleSearch["responseData"]["results"].Children().ToList();
2100
2101       // serialize JSON results into .NET objects
2102       IList<SearchResult> searchResults = new List<SearchResult>();
2103       foreach (JToken result in results)
2104       {
2105         SearchResult searchResult = JsonConvert.DeserializeObject<SearchResult>(result.ToString());
2106         searchResults.Add(searchResult);
2107       }
2108
2109       // Title = <b>Paris Hilton</b> - Wikipedia, the free encyclopedia
2110       // Content = [1] In 2006, she released her debut album...
2111       // Url = http://en.wikipedia.org/wiki/Paris_Hilton
2112
2113       // Title = <b>Paris Hilton</b>
2114       // Content = Self: Zoolander. Socialite <b>Paris Hilton</b>...
2115       // Url = http://www.imdb.com/name/nm0385296/
2116
2117       Assert.AreEqual(2, searchResults.Count);
2118       Assert.AreEqual("<b>Paris Hilton</b> - Wikipedia, the free encyclopedia", searchResults[0].Title);
2119       Assert.AreEqual("<b>Paris Hilton</b>", searchResults[1].Title);
2120     }
2121
2122     [Test]
2123     public void DeserializeBaseReferenceWithDerivedValue()
2124     {
2125       PersonPropertyClass personPropertyClass = new PersonPropertyClass();
2126       WagePerson wagePerson = (WagePerson)personPropertyClass.Person;
2127
2128       wagePerson.BirthDate = new DateTime(2000, 11, 29, 23, 59, 59, DateTimeKind.Utc);
2129       wagePerson.Department = "McDees";
2130       wagePerson.HourlyWage = 12.50m;
2131       wagePerson.LastModified = new DateTime(2000, 11, 29, 23, 59, 59, DateTimeKind.Utc);
2132       wagePerson.Name = "Jim Bob";
2133
2134       string json = JsonConvert.SerializeObject(personPropertyClass, Formatting.Indented);
2135       Assert.AreEqual(
2136         @"{
2137   ""Person"": {
2138     ""HourlyWage"": 12.50,
2139     ""Name"": ""Jim Bob"",
2140     ""BirthDate"": ""\/Date(975542399000)\/"",
2141     ""LastModified"": ""\/Date(975542399000)\/""
2142   }
2143 }",
2144         json);
2145
2146       PersonPropertyClass newPersonPropertyClass = JsonConvert.DeserializeObject<PersonPropertyClass>(json);
2147       Assert.AreEqual(wagePerson.HourlyWage, ((WagePerson)newPersonPropertyClass.Person).HourlyWage);
2148     }
2149
2150     public class ExistingValueClass
2151     {
2152       public Dictionary<string, string> Dictionary { get; set; }
2153       public List<string> List { get; set; }
2154
2155       public ExistingValueClass()
2156       {
2157         Dictionary = new Dictionary<string, string>
2158                        {
2159                          {"existing", "yup"}
2160                        };
2161         List = new List<string>
2162                  {
2163                    "existing"
2164                  };
2165       }
2166     }
2167
2168     [Test]
2169     public void DeserializePopulateDictionaryAndList()
2170     {
2171       ExistingValueClass d = JsonConvert.DeserializeObject<ExistingValueClass>(@"{'Dictionary':{appended:'appended',existing:'new'}}");
2172
2173       Assert.IsNotNull(d);
2174       Assert.IsNotNull(d.Dictionary);
2175       Assert.AreEqual(typeof(Dictionary<string, string>), d.Dictionary.GetType());
2176       Assert.AreEqual(typeof(List<string>), d.List.GetType());
2177       Assert.AreEqual(2, d.Dictionary.Count);
2178       Assert.AreEqual("new", d.Dictionary["existing"]);
2179       Assert.AreEqual("appended", d.Dictionary["appended"]);
2180       Assert.AreEqual(1, d.List.Count);
2181       Assert.AreEqual("existing", d.List[0]);
2182     }
2183
2184     public interface IKeyValueId
2185     {
2186       int Id { get; set; }
2187       string Key { get; set; }
2188       string Value { get; set; }
2189     }
2190
2191
2192     public class KeyValueId : IKeyValueId
2193     {
2194       public int Id { get; set; }
2195       public string Key { get; set; }
2196       public string Value { get; set; }
2197     }
2198
2199     public class ThisGenericTest<T> where T : IKeyValueId
2200     {
2201       private Dictionary<string, T> _dict1 = new Dictionary<string, T>();
2202
2203       public string MyProperty { get; set; }
2204
2205       public void Add(T item)
2206       {
2207         this._dict1.Add(item.Key, item);
2208       }
2209
2210       public T this[string key]
2211       {
2212         get { return this._dict1[key]; }
2213         set { this._dict1[key] = value; }
2214       }
2215
2216       public T this[int id]
2217       {
2218         get { return this._dict1.Values.FirstOrDefault(x => x.Id == id); }
2219         set
2220         {
2221           var item = this[id];
2222
2223           if (item == null)
2224             this.Add(value);
2225           else
2226             this._dict1[item.Key] = value;
2227         }
2228       }
2229
2230       public string ToJson()
2231       {
2232         return JsonConvert.SerializeObject(this, Formatting.Indented);
2233       }
2234
2235       public T[] TheItems
2236       {
2237         get { return this._dict1.Values.ToArray<T>(); }
2238         set
2239         {
2240           foreach (var item in value)
2241             this.Add(item);
2242         }
2243       }
2244     }
2245
2246     [Test]
2247     public void IgnoreIndexedProperties()
2248     {
2249       ThisGenericTest<KeyValueId> g = new ThisGenericTest<KeyValueId>();
2250
2251       g.Add(new KeyValueId { Id = 1, Key = "key1", Value = "value1" });
2252       g.Add(new KeyValueId { Id = 2, Key = "key2", Value = "value2" });
2253
2254       g.MyProperty = "some value";
2255
2256       string json = g.ToJson();
2257
2258       Assert.AreEqual(@"{
2259   ""MyProperty"": ""some value"",
2260   ""TheItems"": [
2261     {
2262       ""Id"": 1,
2263       ""Key"": ""key1"",
2264       ""Value"": ""value1""
2265     },
2266     {
2267       ""Id"": 2,
2268       ""Key"": ""key2"",
2269       ""Value"": ""value2""
2270     }
2271   ]
2272 }", json);
2273
2274       ThisGenericTest<KeyValueId> gen = JsonConvert.DeserializeObject<ThisGenericTest<KeyValueId>>(json);
2275       Assert.AreEqual("some value", gen.MyProperty);
2276     }
2277
2278     public class JRawValueTestObject
2279     {
2280       public JRaw Value { get; set; }
2281     }
2282
2283     [Test]
2284     public void JRawValue()
2285     {
2286       JRawValueTestObject deserialized = JsonConvert.DeserializeObject<JRawValueTestObject>("{value:3}");
2287       Assert.AreEqual("3", deserialized.Value.ToString());
2288
2289       deserialized = JsonConvert.DeserializeObject<JRawValueTestObject>("{value:'3'}");
2290       Assert.AreEqual(@"""3""", deserialized.Value.ToString());
2291     }
2292
2293     [Test]
2294     [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "Unable to find a default constructor to use for type Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+DictionaryWithNoDefaultConstructor.")]
2295     public void DeserializeDictionaryWithNoDefaultConstructor()
2296     {
2297       string json = "{key1:'value',key2:'value',key3:'value'}";
2298       JsonConvert.DeserializeObject<DictionaryWithNoDefaultConstructor>(json);
2299     }
2300
2301     public class DictionaryWithNoDefaultConstructor : Dictionary<string, string>
2302     {
2303       public DictionaryWithNoDefaultConstructor(IEnumerable<KeyValuePair<string, string>> initial)
2304       {
2305         foreach (KeyValuePair<string, string> pair in initial)
2306         {
2307           Add(pair.Key, pair.Value);
2308         }
2309       }
2310     }
2311
2312     [JsonObject(MemberSerialization.OptIn)]
2313     public class A
2314     {
2315       [JsonProperty("A1")]
2316       private string _A1;
2317       public string A1 { get { return _A1; } set { _A1 = value; } }
2318
2319       [JsonProperty("A2")]
2320       private string A2 { get; set; }
2321     }
2322
2323     [JsonObject(MemberSerialization.OptIn)]
2324     public class B : A
2325     {
2326       public string B1 { get; set; }
2327
2328       [JsonProperty("B2")]
2329       string _B2;
2330       public string B2 { get { return _B2; } set { _B2 = value; } }
2331
2332       [JsonProperty("B3")]
2333       private string B3 { get; set; }
2334     }
2335
2336     [Test]
2337     public void SerializeNonPublicBaseJsonProperties()
2338     {
2339       B value = new B();
2340       string json = JsonConvert.SerializeObject(value, Formatting.Indented);
2341
2342       Assert.AreEqual(@"{
2343   ""B2"": null,
2344   ""A1"": null,
2345   ""B3"": null,
2346   ""A2"": null
2347 }", json);
2348     }
2349
2350     public class TestClass
2351     {
2352       public string Key { get; set; }
2353       public object Value { get; set; }
2354     }
2355
2356     [Test]
2357     public void DeserializeToObjectProperty()
2358     {
2359       var json = "{ Key: 'abc', Value: 123 }";
2360       var item = JsonConvert.DeserializeObject<TestClass>(json);
2361
2362       Assert.AreEqual(123, item.Value);
2363     }
2364
2365     public abstract class Animal
2366     {
2367       public abstract string Name { get; }
2368     }
2369
2370     public class Human : Animal
2371     {
2372       public override string Name
2373       {
2374         get { return typeof(Human).Name; }
2375       }
2376
2377       public string Ethnicity { get; set; }
2378     }
2379
2380 #if !NET20 && !PocketPC && !WINDOWS_PHONE
2381     public class DataContractJsonSerializerTestClass
2382     {
2383       public TimeSpan TimeSpanProperty { get; set; }
2384       public Guid GuidProperty { get; set; }
2385       public Animal AnimalProperty { get; set; }
2386       public Exception ExceptionProperty { get; set; }
2387     }
2388
2389     [Test]
2390     public void DataContractJsonSerializerTest()
2391     {
2392       Exception ex = new Exception("Blah blah blah");
2393
2394       DataContractJsonSerializerTestClass c = new DataContractJsonSerializerTestClass();
2395       c.TimeSpanProperty = new TimeSpan(200, 20, 59, 30, 900);
2396       c.GuidProperty = new Guid("66143115-BE2A-4a59-AF0A-348E1EA15B1E");
2397       c.AnimalProperty = new Human() { Ethnicity = "European" };
2398       c.ExceptionProperty = ex;
2399
2400       MemoryStream ms = new MemoryStream();
2401       DataContractJsonSerializer serializer = new DataContractJsonSerializer(
2402         typeof(DataContractJsonSerializerTestClass),
2403         new Type[] { typeof(Human) });
2404       serializer.WriteObject(ms, c);
2405
2406       byte[] jsonBytes = ms.ToArray();
2407       string json = Encoding.UTF8.GetString(jsonBytes, 0, jsonBytes.Length);
2408
2409       Console.WriteLine(JObject.Parse(json).ToString());
2410       Console.WriteLine();
2411
2412       Console.WriteLine(JsonConvert.SerializeObject(c, Formatting.Indented, new JsonSerializerSettings
2413                                                                           {
2414                                                                             //               TypeNameHandling = TypeNameHandling.Objects
2415                                                                           }));
2416     }
2417 #endif
2418
2419     public class ModelStateDictionary<T> : IDictionary<string, T>
2420     {
2421
2422       private readonly Dictionary<string, T> _innerDictionary = new Dictionary<string, T>(StringComparer.OrdinalIgnoreCase);
2423
2424       public ModelStateDictionary()
2425       {
2426       }
2427
2428       public ModelStateDictionary(ModelStateDictionary<T> dictionary)
2429       {
2430         if (dictionary == null)
2431         {
2432           throw new ArgumentNullException("dictionary");
2433         }
2434
2435         foreach (var entry in dictionary)
2436         {
2437           _innerDictionary.Add(entry.Key, entry.Value);
2438         }
2439       }
2440
2441       public int Count
2442       {
2443         get
2444         {
2445           return _innerDictionary.Count;
2446         }
2447       }
2448
2449       public bool IsReadOnly
2450       {
2451         get
2452         {
2453           return ((IDictionary<string, T>)_innerDictionary).IsReadOnly;
2454         }
2455       }
2456
2457       public ICollection<string> Keys
2458       {
2459         get
2460         {
2461           return _innerDictionary.Keys;
2462         }
2463       }
2464
2465       public T this[string key]
2466       {
2467         get
2468         {
2469           T value;
2470           _innerDictionary.TryGetValue(key, out value);
2471           return value;
2472         }
2473         set
2474         {
2475           _innerDictionary[key] = value;
2476         }
2477       }
2478
2479       public ICollection<T> Values
2480       {
2481         get
2482         {
2483           return _innerDictionary.Values;
2484         }
2485       }
2486
2487       public void Add(KeyValuePair<string, T> item)
2488       {
2489         ((IDictionary<string, T>)_innerDictionary).Add(item);
2490       }
2491
2492       public void Add(string key, T value)
2493       {
2494         _innerDictionary.Add(key, value);
2495       }
2496
2497       public void Clear()
2498       {
2499         _innerDictionary.Clear();
2500       }
2501
2502       public bool Contains(KeyValuePair<string, T> item)
2503       {
2504         return ((IDictionary<string, T>)_innerDictionary).Contains(item);
2505       }
2506
2507       public bool ContainsKey(string key)
2508       {
2509         return _innerDictionary.ContainsKey(key);
2510       }
2511
2512       public void CopyTo(KeyValuePair<string, T>[] array, int arrayIndex)
2513       {
2514         ((IDictionary<string, T>)_innerDictionary).CopyTo(array, arrayIndex);
2515       }
2516
2517       public IEnumerator<KeyValuePair<string, T>> GetEnumerator()
2518       {
2519         return _innerDictionary.GetEnumerator();
2520       }
2521
2522       public void Merge(ModelStateDictionary<T> dictionary)
2523       {
2524         if (dictionary == null)
2525         {
2526           return;
2527         }
2528
2529         foreach (var entry in dictionary)
2530         {
2531           this[entry.Key] = entry.Value;
2532         }
2533       }
2534
2535       public bool Remove(KeyValuePair<string, T> item)
2536       {
2537         return ((IDictionary<string, T>)_innerDictionary).Remove(item);
2538       }
2539
2540       public bool Remove(string key)
2541       {
2542         return _innerDictionary.Remove(key);
2543       }
2544
2545       public bool TryGetValue(string key, out T value)
2546       {
2547         return _innerDictionary.TryGetValue(key, out value);
2548       }
2549
2550       IEnumerator IEnumerable.GetEnumerator()
2551       {
2552         return ((IEnumerable)_innerDictionary).GetEnumerator();
2553       }
2554     }
2555
2556     [Test]
2557     public void SerializeNonIDictionary()
2558     {
2559       ModelStateDictionary<string> modelStateDictionary = new ModelStateDictionary<string>();
2560       modelStateDictionary.Add("key", "value");
2561
2562       string json = JsonConvert.SerializeObject(modelStateDictionary);
2563
2564       Assert.AreEqual(@"{""key"":""value""}", json);
2565
2566       ModelStateDictionary<string> newModelStateDictionary = JsonConvert.DeserializeObject<ModelStateDictionary<string>>(json);
2567       Assert.AreEqual(1, newModelStateDictionary.Count);
2568       Assert.AreEqual("value", newModelStateDictionary["key"]);
2569     }
2570
2571 #if !SILVERLIGHT && !PocketPC
2572     public class ISerializableTestObject : ISerializable
2573     {
2574       internal string _stringValue;
2575       internal int _intValue;
2576       internal DateTimeOffset _dateTimeOffsetValue;
2577       internal Person _personValue;
2578       internal Person _nullPersonValue;
2579       internal int? _nullableInt;
2580       internal bool _booleanValue;
2581       internal byte _byteValue;
2582       internal char _charValue;
2583       internal DateTime _dateTimeValue;
2584       internal decimal _decimalValue;
2585       internal short _shortValue;
2586       internal long _longValue;
2587       internal sbyte _sbyteValue;
2588       internal float _floatValue;
2589       internal ushort _ushortValue;
2590       internal uint _uintValue;
2591       internal ulong _ulongValue;
2592
2593       public ISerializableTestObject(string stringValue, int intValue, DateTimeOffset dateTimeOffset, Person personValue)
2594       {
2595         _stringValue = stringValue;
2596         _intValue = intValue;
2597         _dateTimeOffsetValue = dateTimeOffset;
2598         _personValue = personValue;
2599         _dateTimeValue = new DateTime(0, DateTimeKind.Utc);
2600       }
2601
2602       protected ISerializableTestObject(SerializationInfo info, StreamingContext context)
2603       {
2604         _stringValue = info.GetString("stringValue");
2605         _intValue = info.GetInt32("intValue");
2606         _dateTimeOffsetValue = (DateTimeOffset)info.GetValue("dateTimeOffsetValue", typeof(DateTimeOffset));
2607         _personValue = (Person)info.GetValue("personValue", typeof(Person));
2608         _nullPersonValue = (Person)info.GetValue("nullPersonValue", typeof(Person));
2609         _nullableInt = (int?)info.GetValue("nullableInt", typeof(int?));
2610
2611         _booleanValue = info.GetBoolean("booleanValue");
2612         _byteValue = info.GetByte("byteValue");
2613         _charValue = info.GetChar("charValue");
2614         _dateTimeValue = info.GetDateTime("dateTimeValue");
2615         _decimalValue = info.GetDecimal("decimalValue");
2616         _shortValue = info.GetInt16("shortValue");
2617         _longValue = info.GetInt64("longValue");
2618         _sbyteValue = info.GetSByte("sbyteValue");
2619         _floatValue = info.GetSingle("floatValue");
2620         _ushortValue = info.GetUInt16("ushortValue");
2621         _uintValue = info.GetUInt32("uintValue");
2622         _ulongValue = info.GetUInt64("ulongValue");
2623       }
2624
2625       public void GetObjectData(SerializationInfo info, StreamingContext context)
2626       {
2627         info.AddValue("stringValue", _stringValue);
2628         info.AddValue("intValue", _intValue);
2629         info.AddValue("dateTimeOffsetValue", _dateTimeOffsetValue);
2630         info.AddValue("personValue", _personValue);
2631         info.AddValue("nullPersonValue", _nullPersonValue);
2632         info.AddValue("nullableInt", null);
2633
2634         info.AddValue("booleanValue", _booleanValue);
2635         info.AddValue("byteValue", _byteValue);
2636         info.AddValue("charValue", _charValue);
2637         info.AddValue("dateTimeValue", _dateTimeValue);
2638         info.AddValue("decimalValue", _decimalValue);
2639         info.AddValue("shortValue", _shortValue);
2640         info.AddValue("longValue", _longValue);
2641         info.AddValue("sbyteValue", _sbyteValue);
2642         info.AddValue("floatValue", _floatValue);
2643         info.AddValue("ushortValue", _ushortValue);
2644         info.AddValue("uintValue", _uintValue);
2645         info.AddValue("ulongValue", _ulongValue);
2646       }
2647     }
2648
2649     [Test]
2650     public void SerializeISerializableTestObject()
2651     {
2652       Person person = new Person();
2653       person.BirthDate = new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc);
2654       person.LastModified = person.BirthDate;
2655       person.Department = "Department!";
2656       person.Name = "Name!";
2657
2658       DateTimeOffset dateTimeOffset = new DateTimeOffset(2000, 12, 20, 22, 59, 59, TimeSpan.FromHours(2));
2659       string dateTimeOffsetText;
2660 #if !NET20
2661       dateTimeOffsetText = @"\/Date(977345999000+0200)\/";
2662 #else
2663       dateTimeOffsetText = @"12/20/2000 22:59:59 +02:00";
2664 #endif
2665
2666       ISerializableTestObject o = new ISerializableTestObject("String!", int.MinValue, dateTimeOffset, person);
2667
2668       string json = JsonConvert.SerializeObject(o, Formatting.Indented);
2669       Assert.AreEqual(@"{
2670   ""stringValue"": ""String!"",
2671   ""intValue"": -2147483648,
2672   ""dateTimeOffsetValue"": """ + dateTimeOffsetText + @""",
2673   ""personValue"": {
2674     ""Name"": ""Name!"",
2675     ""BirthDate"": ""\/Date(946688461000)\/"",
2676     ""LastModified"": ""\/Date(946688461000)\/""
2677   },
2678   ""nullPersonValue"": null,
2679   ""nullableInt"": null,
2680   ""booleanValue"": false,
2681   ""byteValue"": 0,
2682   ""charValue"": ""\u0000"",
2683   ""dateTimeValue"": ""\/Date(-62135596800000)\/"",
2684   ""decimalValue"": 0.0,
2685   ""shortValue"": 0,
2686   ""longValue"": 0,
2687   ""sbyteValue"": 0,
2688   ""floatValue"": 0.0,
2689   ""ushortValue"": 0,
2690   ""uintValue"": 0,
2691   ""ulongValue"": 0
2692 }", json);
2693
2694       ISerializableTestObject o2 = JsonConvert.DeserializeObject<ISerializableTestObject>(json);
2695       Assert.AreEqual("String!", o2._stringValue);
2696       Assert.AreEqual(int.MinValue, o2._intValue);
2697       Assert.AreEqual(dateTimeOffset, o2._dateTimeOffsetValue);
2698       Assert.AreEqual("Name!", o2._personValue.Name);
2699       Assert.AreEqual(null, o2._nullPersonValue);
2700       Assert.AreEqual(null, o2._nullableInt);
2701     }
2702 #endif
2703
2704     public class KVPair<TKey, TValue>
2705     {
2706       public TKey Key { get; set; }
2707       public TValue Value { get; set; }
2708
2709       public KVPair(TKey k, TValue v)
2710       {
2711         Key = k;
2712         Value = v;
2713       }
2714     }
2715
2716     [Test]
2717     public void DeserializeUsingNonDefaultConstructorWithLeftOverValues()
2718     {
2719       List<KVPair<string, string>> kvPairs =
2720         JsonConvert.DeserializeObject<List<KVPair<string, string>>>(
2721           "[{\"Key\":\"Two\",\"Value\":\"2\"},{\"Key\":\"One\",\"Value\":\"1\"}]");
2722
2723       Assert.AreEqual(2, kvPairs.Count);
2724       Assert.AreEqual("Two", kvPairs[0].Key);
2725       Assert.AreEqual("2", kvPairs[0].Value);
2726       Assert.AreEqual("One", kvPairs[1].Key);
2727       Assert.AreEqual("1", kvPairs[1].Value);
2728     }
2729
2730     [Test]
2731     public void SerializeClassWithInheritedProtectedMember()
2732     {
2733       AA myA = new AA(2);
2734       string json = JsonConvert.SerializeObject(myA, Formatting.Indented);
2735       Assert.AreEqual(@"{
2736   ""AA_field1"": 2,
2737   ""AA_property1"": 2,
2738   ""AA_property2"": 2,
2739   ""AA_property3"": 2,
2740   ""AA_property4"": 2
2741 }", json);
2742
2743       BB myB = new BB(3, 4);
2744       json = JsonConvert.SerializeObject(myB, Formatting.Indented);
2745       Assert.AreEqual(@"{
2746   ""BB_field1"": 4,
2747   ""BB_field2"": 4,
2748   ""AA_field1"": 3,
2749   ""BB_property1"": 4,
2750   ""BB_property2"": 4,
2751   ""BB_property3"": 4,
2752   ""BB_property4"": 4,
2753   ""BB_property5"": 4,
2754   ""BB_property7"": 4,
2755   ""AA_property1"": 3,
2756   ""AA_property2"": 3,
2757   ""AA_property3"": 3,
2758   ""AA_property4"": 3
2759 }", json);
2760     }
2761
2762     [Test]
2763     public void DeserializeClassWithInheritedProtectedMember()
2764     {
2765       AA myA = JsonConvert.DeserializeObject<AA>(
2766           @"{
2767   ""AA_field1"": 2,
2768   ""AA_field2"": 2,
2769   ""AA_property1"": 2,
2770   ""AA_property2"": 2,
2771   ""AA_property3"": 2,
2772   ""AA_property4"": 2,
2773   ""AA_property5"": 2,
2774   ""AA_property6"": 2
2775 }");
2776
2777       Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetField("AA_field1", BindingFlags.Instance | BindingFlags.NonPublic), myA));
2778       Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetField("AA_field2", BindingFlags.Instance | BindingFlags.NonPublic), myA));
2779       Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property1", BindingFlags.Instance | BindingFlags.NonPublic), myA));
2780       Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property2", BindingFlags.Instance | BindingFlags.NonPublic), myA));
2781       Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property3", BindingFlags.Instance | BindingFlags.NonPublic), myA));
2782       Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property4", BindingFlags.Instance | BindingFlags.NonPublic), myA));
2783       Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property5", BindingFlags.Instance | BindingFlags.NonPublic), myA));
2784       Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property6", BindingFlags.Instance | BindingFlags.NonPublic), myA));
2785
2786       BB myB = JsonConvert.DeserializeObject<BB>(
2787           @"{
2788   ""BB_field1"": 4,
2789   ""BB_field2"": 4,
2790   ""AA_field1"": 3,
2791   ""AA_field2"": 3,
2792   ""AA_property1"": 2,
2793   ""AA_property2"": 2,
2794   ""AA_property3"": 2,
2795   ""AA_property4"": 2,
2796   ""AA_property5"": 2,
2797   ""AA_property6"": 2,
2798   ""BB_property1"": 3,
2799   ""BB_property2"": 3,
2800   ""BB_property3"": 3,
2801   ""BB_property4"": 3,
2802   ""BB_property5"": 3,
2803   ""BB_property6"": 3,
2804   ""BB_property7"": 3,
2805   ""BB_property8"": 3
2806 }");
2807
2808       Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(AA).GetField("AA_field1", BindingFlags.Instance | BindingFlags.NonPublic), myB));
2809       Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetField("AA_field2", BindingFlags.Instance | BindingFlags.NonPublic), myB));
2810       Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property1", BindingFlags.Instance | BindingFlags.NonPublic), myB));
2811       Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property2", BindingFlags.Instance | BindingFlags.NonPublic), myB));
2812       Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property3", BindingFlags.Instance | BindingFlags.NonPublic), myB));
2813       Assert.AreEqual(2, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property4", BindingFlags.Instance | BindingFlags.NonPublic), myB));
2814       Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property5", BindingFlags.Instance | BindingFlags.NonPublic), myB));
2815       Assert.AreEqual(0, ReflectionUtils.GetMemberValue(typeof(AA).GetProperty("AA_property6", BindingFlags.Instance | BindingFlags.NonPublic), myB));
2816
2817       Assert.AreEqual(4, myB.BB_field1);
2818       Assert.AreEqual(4, myB.BB_field2);
2819       Assert.AreEqual(3, myB.BB_property1);
2820       Assert.AreEqual(3, myB.BB_property2);
2821       Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(BB).GetProperty("BB_property3", BindingFlags.Instance | BindingFlags.Public), myB));
2822       Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(BB).GetProperty("BB_property4", BindingFlags.Instance | BindingFlags.NonPublic), myB));
2823       Assert.AreEqual(0, myB.BB_property5);
2824       Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(BB).GetProperty("BB_property6", BindingFlags.Instance | BindingFlags.Public), myB));
2825       Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(BB).GetProperty("BB_property7", BindingFlags.Instance | BindingFlags.Public), myB));
2826       Assert.AreEqual(3, ReflectionUtils.GetMemberValue(typeof(BB).GetProperty("BB_property8", BindingFlags.Instance | BindingFlags.Public), myB));
2827     }
2828
2829     public class AA
2830     {
2831       [JsonProperty]
2832       protected int AA_field1;
2833       protected int AA_field2;
2834       [JsonProperty]
2835       protected int AA_property1 { get; set; }
2836       [JsonProperty]
2837       protected int AA_property2 { get; private set; }
2838       [JsonProperty]
2839       protected int AA_property3 { private get; set; }
2840       [JsonProperty]
2841       private int AA_property4 { get; set; }
2842       protected int AA_property5 { get; private set; }
2843       protected int AA_property6 { private get; set; }
2844
2845       public AA()
2846       {
2847       }
2848
2849       public AA(int f)
2850       {
2851         AA_field1 = f;
2852         AA_field2 = f;
2853         AA_property1 = f;
2854         AA_property2 = f;
2855         AA_property3 = f;
2856         AA_property4 = f;
2857         AA_property5 = f;
2858         AA_property6 = f;
2859       }
2860     }
2861
2862     public class BB : AA
2863     {
2864       [JsonProperty]
2865       public int BB_field1;
2866       public int BB_field2;
2867       [JsonProperty]
2868       public int BB_property1 { get; set; }
2869       [JsonProperty]
2870       public int BB_property2 { get; private set; }
2871       [JsonProperty]
2872       public int BB_property3 { private get; set; }
2873       [JsonProperty]
2874       private int BB_property4 { get; set; }
2875       public int BB_property5 { get; private set; }
2876       public int BB_property6 { private get; set; }
2877       [JsonProperty]
2878       public int BB_property7 { protected get; set; }
2879       public int BB_property8 { protected get; set; }
2880
2881       public BB()
2882       {
2883       }
2884
2885       public BB(int f, int g)
2886         : base(f)
2887       {
2888         BB_field1 = g;
2889         BB_field2 = g;
2890         BB_property1 = g;
2891         BB_property2 = g;
2892         BB_property3 = g;
2893         BB_property4 = g;
2894         BB_property5 = g;
2895         BB_property6 = g;
2896         BB_property7 = g;
2897         BB_property8 = g;
2898       }
2899     }
2900
2901 #if !NET20 && !SILVERLIGHT
2902     public class XNodeTestObject
2903     {
2904       public XDocument Document { get; set; }
2905       public XElement Element { get; set; }
2906     }
2907 #endif
2908
2909 #if !SILVERLIGHT
2910     public class XmlNodeTestObject
2911     {
2912       public XmlDocument Document { get; set; }
2913     }
2914 #endif
2915
2916 #if !NET20 && !SILVERLIGHT
2917     [Test]
2918     public void SerializeDeserializeXNodeProperties()
2919     {
2920       XNodeTestObject testObject = new XNodeTestObject();
2921       testObject.Document = XDocument.Parse("<root>hehe, root</root>");
2922       testObject.Element = XElement.Parse(@"<fifth xmlns:json=""http://json.org"" json:Awesome=""true"">element</fifth>");
2923
2924       string json = JsonConvert.SerializeObject(testObject, Formatting.Indented);
2925       string expected = @"{
2926   ""Document"": {
2927     ""root"": ""hehe, root""
2928   },
2929   ""Element"": {
2930     ""fifth"": {
2931       ""@xmlns:json"": ""http://json.org"",
2932       ""@json:Awesome"": ""true"",
2933       ""#text"": ""element""
2934     }
2935   }
2936 }";
2937       Assert.AreEqual(expected, json);
2938
2939       XNodeTestObject newTestObject = JsonConvert.DeserializeObject<XNodeTestObject>(json);
2940       Assert.AreEqual(testObject.Document.ToString(), newTestObject.Document.ToString());
2941       Assert.AreEqual(testObject.Element.ToString(), newTestObject.Element.ToString());
2942
2943       Assert.IsNull(newTestObject.Element.Parent);
2944     }
2945 #endif
2946
2947 #if !SILVERLIGHT
2948     [Test]
2949     public void SerializeDeserializeXmlNodeProperties()
2950     {
2951       XmlNodeTestObject testObject = new XmlNodeTestObject();
2952       XmlDocument document = new XmlDocument();
2953       document.LoadXml("<root>hehe, root</root>");
2954       testObject.Document = document;
2955
2956       string json = JsonConvert.SerializeObject(testObject, Formatting.Indented);
2957       string expected = @"{
2958   ""Document"": {
2959     ""root"": ""hehe, root""
2960   }
2961 }";
2962       Assert.AreEqual(expected, json);
2963
2964       XmlNodeTestObject newTestObject = JsonConvert.DeserializeObject<XmlNodeTestObject>(json);
2965       Assert.AreEqual(testObject.Document.InnerXml, newTestObject.Document.InnerXml);
2966     }
2967 #endif
2968
2969     [Test]
2970     public void FullClientMapSerialization()
2971     {
2972       ClientMap source = new ClientMap()
2973       {
2974         position = new Pos() { X = 100, Y = 200 },
2975         center = new PosDouble() { X = 251.6, Y = 361.3 }
2976       };
2977
2978       string json = JsonConvert.SerializeObject(source, new PosConverter(), new PosDoubleConverter());
2979       Assert.AreEqual("{\"position\":new Pos(100,200),\"center\":new PosD(251.6,361.3)}", json);
2980     }
2981
2982     public class ClientMap
2983     {
2984       public Pos position { get; set; }
2985       public PosDouble center { get; set; }
2986     }
2987
2988     public class Pos
2989     {
2990       public int X { get; set; }
2991       public int Y { get; set; }
2992     }
2993
2994     public class PosDouble
2995     {
2996       public double X { get; set; }
2997       public double Y { get; set; }
2998     }
2999
3000     public class PosConverter : JsonConverter
3001     {
3002       public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
3003       {
3004         Pos p = (Pos)value;
3005
3006         if (p != null)
3007           writer.WriteRawValue(String.Format("new Pos({0},{1})", p.X, p.Y));
3008         else
3009           writer.WriteNull();
3010       }
3011
3012       public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
3013       {
3014         throw new NotImplementedException();
3015       }
3016
3017       public override bool CanConvert(Type objectType)
3018       {
3019         return objectType.IsAssignableFrom(typeof(Pos));
3020       }
3021     }
3022
3023     public class PosDoubleConverter : JsonConverter
3024     {
3025       public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
3026       {
3027         PosDouble p = (PosDouble)value;
3028
3029         if (p != null)
3030           writer.WriteRawValue(String.Format(CultureInfo.InvariantCulture, "new PosD({0},{1})", p.X, p.Y));
3031         else
3032           writer.WriteNull();
3033       }
3034
3035       public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
3036       {
3037         throw new NotImplementedException();
3038       }
3039
3040       public override bool CanConvert(Type objectType)
3041       {
3042         return objectType.IsAssignableFrom(typeof(PosDouble));
3043       }
3044     }
3045
3046     [Test]
3047     public void TestEscapeDictionaryStrings()
3048     {
3049       const string s = @"host\user";
3050       string serialized = JsonConvert.SerializeObject(s);
3051       Assert.AreEqual(@"""host\\user""", serialized);
3052
3053       Dictionary<int, object> d1 = new Dictionary<int, object>();
3054       d1.Add(5, s);
3055       Assert.AreEqual(@"{""5"":""host\\user""}", JsonConvert.SerializeObject(d1));
3056
3057       Dictionary<string, object> d2 = new Dictionary<string, object>();
3058       d2.Add(s, 5);
3059       Assert.AreEqual(@"{""host\\user"":5}", JsonConvert.SerializeObject(d2));
3060     }
3061
3062     public class GenericListTestClass
3063     {
3064       public List<string> GenericList { get; set; }
3065
3066       public GenericListTestClass()
3067       {
3068         GenericList = new List<string>();
3069       }
3070     }
3071
3072     [Test]
3073     public void DeserializeExistingGenericList()
3074     {
3075       GenericListTestClass c = new GenericListTestClass();
3076       c.GenericList.Add("1");
3077       c.GenericList.Add("2");
3078
3079       string json = JsonConvert.SerializeObject(c, Formatting.Indented);
3080
3081       GenericListTestClass newValue = JsonConvert.DeserializeObject<GenericListTestClass>(json);
3082       Assert.AreEqual(2, newValue.GenericList.Count);
3083       Assert.AreEqual(typeof(List<string>), newValue.GenericList.GetType());
3084     }
3085
3086     [Test]
3087     public void DeserializeSimpleKeyValuePair()
3088     {
3089       List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>();
3090       list.Add(new KeyValuePair<string, string>("key1", "value1"));
3091       list.Add(new KeyValuePair<string, string>("key2", "value2"));
3092
3093       string json = JsonConvert.SerializeObject(list);
3094
3095       Assert.AreEqual(@"[{""Key"":""key1"",""Value"":""value1""},{""Key"":""key2"",""Value"":""value2""}]", json);
3096
3097       List<KeyValuePair<string, string>> result = JsonConvert.DeserializeObject<List<KeyValuePair<string, string>>>(json);
3098       Assert.AreEqual(2, result.Count);
3099       Assert.AreEqual("key1", result[0].Key);
3100       Assert.AreEqual("value1", result[0].Value);
3101       Assert.AreEqual("key2", result[1].Key);
3102       Assert.AreEqual("value2", result[1].Value);
3103     }
3104
3105     [Test]
3106     public void DeserializeComplexKeyValuePair()
3107     {
3108       DateTime dateTime = new DateTime(2000, 12, 1, 23, 1, 1, DateTimeKind.Utc);
3109
3110       List<KeyValuePair<string, WagePerson>> list = new List<KeyValuePair<string, WagePerson>>();
3111       list.Add(new KeyValuePair<string, WagePerson>("key1", new WagePerson
3112                                                               {
3113                                                                 BirthDate = dateTime,
3114                                                                 Department = "Department1",
3115                                                                 LastModified = dateTime,
3116                                                                 HourlyWage = 1
3117                                                               }));
3118       list.Add(new KeyValuePair<string, WagePerson>("key2", new WagePerson
3119       {
3120         BirthDate = dateTime,
3121         Department = "Department2",
3122         LastModified = dateTime,
3123         HourlyWage = 2
3124       }));
3125
3126       string json = JsonConvert.SerializeObject(list, Formatting.Indented);
3127
3128       Assert.AreEqual(@"[
3129   {
3130     ""Key"": ""key1"",
3131     ""Value"": {
3132       ""HourlyWage"": 1.0,
3133       ""Name"": null,
3134       ""BirthDate"": ""\/Date(975711661000)\/"",
3135       ""LastModified"": ""\/Date(975711661000)\/""
3136     }
3137   },
3138   {
3139     ""Key"": ""key2"",
3140     ""Value"": {
3141       ""HourlyWage"": 2.0,
3142       ""Name"": null,
3143       ""BirthDate"": ""\/Date(975711661000)\/"",
3144       ""LastModified"": ""\/Date(975711661000)\/""
3145     }
3146   }
3147 ]", json);
3148
3149       List<KeyValuePair<string, WagePerson>> result = JsonConvert.DeserializeObject<List<KeyValuePair<string, WagePerson>>>(json);
3150       Assert.AreEqual(2, result.Count);
3151       Assert.AreEqual("key1", result[0].Key);
3152       Assert.AreEqual(1, result[0].Value.HourlyWage);
3153       Assert.AreEqual("key2", result[1].Key);
3154       Assert.AreEqual(2, result[1].Value.HourlyWage);
3155     }
3156
3157     public class StringListAppenderConverter : JsonConverter
3158     {
3159       public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
3160       {
3161         writer.WriteValue(value);
3162       }
3163
3164       public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
3165       {
3166         List<string> existingStrings = (List<string>)existingValue;
3167         List<string> newStrings = new List<string>(existingStrings);
3168
3169         reader.Read();
3170
3171         while (reader.TokenType != JsonToken.EndArray)
3172         {
3173           string s = (string)reader.Value;
3174           newStrings.Add(s);
3175
3176           reader.Read();
3177         }
3178
3179         return newStrings;
3180       }
3181
3182       public override bool CanConvert(Type objectType)
3183       {
3184         return (objectType == typeof(List<string>));
3185       }
3186     }
3187
3188     [Test]
3189     public void StringListAppenderConverterTest()
3190     {
3191       Movie p = new Movie();
3192       p.ReleaseCountries = new List<string> { "Existing" };
3193
3194       JsonConvert.PopulateObject("{'ReleaseCountries':['Appended']}", p, new JsonSerializerSettings
3195         {
3196           Converters = new List<JsonConverter> { new StringListAppenderConverter() }
3197         });
3198
3199       Assert.AreEqual(2, p.ReleaseCountries.Count);
3200       Assert.AreEqual("Existing", p.ReleaseCountries[0]);
3201       Assert.AreEqual("Appended", p.ReleaseCountries[1]);
3202     }
3203
3204     public class StringAppenderConverter : JsonConverter
3205     {
3206       public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
3207       {
3208         writer.WriteValue(value);
3209       }
3210
3211       public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
3212       {
3213         string existingString = (string)existingValue;
3214         string newString = existingString + (string)reader.Value;
3215
3216         return newString;
3217       }
3218
3219       public override bool CanConvert(Type objectType)
3220       {
3221         return (objectType == typeof(string));
3222       }
3223     }
3224
3225     [Test]
3226     public void StringAppenderConverterTest()
3227     {
3228       Movie p = new Movie();
3229       p.Name = "Existing,";
3230
3231       JsonConvert.PopulateObject("{'Name':'Appended'}", p, new JsonSerializerSettings
3232       {
3233         Converters = new List<JsonConverter> { new StringAppenderConverter() }
3234       });
3235
3236       Assert.AreEqual(p.Name, "Existing,Appended");
3237     }
3238
3239     [Test]
3240     [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "Additional content found in JSON reference object. A JSON reference object should only have a $ref property.")]
3241     public void SerializeRefAdditionalContent()
3242     {
3243       //Additional text found in JSON string after finishing deserializing object.
3244       //Test 1
3245       var reference = new Dictionary<string, object>();
3246       reference.Add("$ref", "Persons");
3247       reference.Add("$id", 1);
3248
3249       var child = new Dictionary<string, object>();
3250       child.Add("_id", 2);
3251       child.Add("Name", "Isabell");
3252       child.Add("Father", reference);
3253
3254       var json = JsonConvert.SerializeObject(child);
3255       JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
3256     }
3257
3258     [Test]
3259     [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "JSON reference $ref property must have a string value.")]
3260     public void SerializeRefBadType()
3261     {
3262       //Additional text found in JSON string after finishing deserializing object.
3263       //Test 1
3264       var reference = new Dictionary<string, object>();
3265       reference.Add("$ref", 1);
3266       reference.Add("$id", 1);
3267
3268       var child = new Dictionary<string, object>();
3269       child.Add("_id", 2);
3270       child.Add("Name", "Isabell");
3271       child.Add("Father", reference);
3272
3273       var json = JsonConvert.SerializeObject(child);
3274       JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
3275     }
3276
3277     public class ConstructorCompexIgnoredProperty
3278     {
3279       [JsonIgnore]
3280       public Product Ignored { get; set; }
3281       public string First { get; set; }
3282       public int Second { get; set; }
3283
3284       public ConstructorCompexIgnoredProperty(string first, int second)
3285       {
3286         First = first;
3287         Second = second;
3288       }
3289     }
3290
3291     [Test]
3292     public void DeserializeIgnoredPropertyInConstructor()
3293     {
3294       string json = @"{""First"":""First"",""Second"":2,""Ignored"":{""Name"":""James""},""AdditionalContent"":{""LOL"":true}}";
3295
3296       ConstructorCompexIgnoredProperty cc = JsonConvert.DeserializeObject<ConstructorCompexIgnoredProperty>(json);
3297       Assert.AreEqual("First", cc.First);
3298       Assert.AreEqual(2, cc.Second);
3299       Assert.AreEqual(null, cc.Ignored);
3300     }
3301
3302     public class ShouldSerializeTestClass
3303     {
3304       internal bool _shouldSerializeName;
3305
3306       public string Name { get; set; }
3307       public int Age { get; set; }
3308
3309       public void ShouldSerializeAge()
3310       {
3311         // dummy. should never be used because it doesn't return bool
3312       }
3313
3314       public bool ShouldSerializeName()
3315       {
3316         return _shouldSerializeName;
3317       }
3318     }
3319
3320     [Test]
3321     public void ShouldSerializeTest()
3322     {
3323       ShouldSerializeTestClass c = new ShouldSerializeTestClass();
3324       c.Name = "James";
3325       c.Age = 27;
3326
3327       string json = JsonConvert.SerializeObject(c, Formatting.Indented);
3328
3329       Assert.AreEqual(@"{
3330   ""Age"": 27
3331 }", json);
3332
3333       c._shouldSerializeName = true;
3334       json = JsonConvert.SerializeObject(c, Formatting.Indented);
3335
3336       Assert.AreEqual(@"{
3337   ""Name"": ""James"",
3338   ""Age"": 27
3339 }", json);
3340
3341       ShouldSerializeTestClass deserialized = JsonConvert.DeserializeObject<ShouldSerializeTestClass>(json);
3342       Assert.AreEqual("James", deserialized.Name);
3343       Assert.AreEqual(27, deserialized.Age);
3344     }
3345
3346     public class Employee
3347     {
3348       public string Name { get; set; }
3349       public Employee Manager { get; set; }
3350
3351       public bool ShouldSerializeManager()
3352       {
3353         return (Manager != this);
3354       }
3355     }
3356
3357     [Test]
3358     public void ShouldSerializeExample()
3359     {
3360       Employee joe = new Employee();
3361       joe.Name = "Joe Employee";
3362       Employee mike = new Employee();
3363       mike.Name = "Mike Manager";
3364
3365       joe.Manager = mike;
3366       mike.Manager = mike;
3367
3368       string json = JsonConvert.SerializeObject(new[] { joe, mike }, Formatting.Indented);
3369       // [
3370       //   {
3371       //     "Name": "Joe Employee",
3372       //     "Manager": {
3373       //       "Name": "Mike Manager"
3374       //     }
3375       //   },
3376       //   {
3377       //     "Name": "Mike Manager"
3378       //   }
3379       // ]
3380
3381       Console.WriteLine(json);
3382     }
3383
3384     public class SpecifiedTestClass
3385     {
3386       private bool _nameSpecified;
3387
3388       public string Name { get; set; }
3389       public int Age { get; set; }
3390       public int Weight { get; set; }
3391       public int Height { get; set; }
3392
3393       // dummy. should never be used because it isn't of type bool
3394       [JsonIgnore]
3395       public long AgeSpecified { get; set; }
3396
3397       [JsonIgnore]
3398       public bool NameSpecified
3399       {
3400         get { return _nameSpecified; }
3401         set { _nameSpecified = value; }
3402       }
3403
3404       [JsonIgnore]
3405       public bool WeightSpecified;
3406
3407       [JsonIgnore]
3408       [System.Xml.Serialization.XmlIgnoreAttribute]
3409       public bool HeightSpecified;
3410     }
3411
3412     [Test]
3413     public void SpecifiedTest()
3414     {
3415       SpecifiedTestClass c = new SpecifiedTestClass();
3416       c.Name = "James";
3417       c.Age = 27;
3418       c.NameSpecified = false;
3419
3420       string json = JsonConvert.SerializeObject(c, Formatting.Indented);
3421
3422       Assert.AreEqual(@"{
3423   ""Age"": 27
3424 }", json);
3425
3426       SpecifiedTestClass deserialized = JsonConvert.DeserializeObject<SpecifiedTestClass>(json);
3427       Assert.IsNull(deserialized.Name);
3428       Assert.IsFalse(deserialized.NameSpecified);
3429       Assert.IsFalse(deserialized.WeightSpecified);
3430       Assert.IsFalse(deserialized.HeightSpecified);
3431       Assert.AreEqual(27, deserialized.Age);
3432
3433       c.NameSpecified = true;
3434       c.WeightSpecified = true;
3435       c.HeightSpecified = true;
3436       json = JsonConvert.SerializeObject(c, Formatting.Indented);
3437
3438       Assert.AreEqual(@"{
3439   ""Name"": ""James"",
3440   ""Age"": 27,
3441   ""Weight"": 0,
3442   ""Height"": 0
3443 }", json);
3444
3445       deserialized = JsonConvert.DeserializeObject<SpecifiedTestClass>(json);
3446       Assert.AreEqual("James", deserialized.Name);
3447       Assert.IsTrue(deserialized.NameSpecified);
3448       Assert.IsTrue(deserialized.WeightSpecified);
3449       Assert.IsTrue(deserialized.HeightSpecified);
3450       Assert.AreEqual(27, deserialized.Age);
3451     }
3452
3453     //    [Test]
3454     //    public void XmlSerializerSpecifiedTrueTest()
3455     //    {
3456     //      XmlSerializer s = new XmlSerializer(typeof(OptionalOrder));
3457
3458     //      StringWriter sw = new StringWriter();
3459     //      s.Serialize(sw, new OptionalOrder() { FirstOrder = "First", FirstOrderSpecified = true });
3460
3461     //      Console.WriteLine(sw.ToString());
3462
3463     //      string xml = @"<?xml version=""1.0"" encoding=""utf-16""?>
3464     //<OptionalOrder xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
3465     //  <FirstOrder>First</FirstOrder>
3466     //</OptionalOrder>";
3467
3468     //      OptionalOrder o = (OptionalOrder)s.Deserialize(new StringReader(xml));
3469     //      Console.WriteLine(o.FirstOrder);
3470     //      Console.WriteLine(o.FirstOrderSpecified);
3471     //    }
3472
3473     //    [Test]
3474     //    public void XmlSerializerSpecifiedFalseTest()
3475     //    {
3476     //      XmlSerializer s = new XmlSerializer(typeof(OptionalOrder));
3477
3478     //      StringWriter sw = new StringWriter();
3479     //      s.Serialize(sw, new OptionalOrder() { FirstOrder = "First", FirstOrderSpecified = false });
3480
3481     //      Console.WriteLine(sw.ToString());
3482
3483     //      //      string xml = @"<?xml version=""1.0"" encoding=""utf-16""?>
3484     //      //<OptionalOrder xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
3485     //      //  <FirstOrder>First</FirstOrder>
3486     //      //</OptionalOrder>";
3487
3488     //      //      OptionalOrder o = (OptionalOrder)s.Deserialize(new StringReader(xml));
3489     //      //      Console.WriteLine(o.FirstOrder);
3490     //      //      Console.WriteLine(o.FirstOrderSpecified);
3491     //    }
3492
3493     public class OptionalOrder
3494     {
3495       // This field shouldn't be serialized 
3496       // if it is uninitialized.
3497       public string FirstOrder;
3498       // Use the XmlIgnoreAttribute to ignore the 
3499       // special field named "FirstOrderSpecified".
3500       [System.Xml.Serialization.XmlIgnoreAttribute]
3501       public bool FirstOrderSpecified;
3502     }
3503
3504     public class FamilyDetails
3505     {
3506       public string Name { get; set; }
3507       public int NumberOfChildren { get; set; }
3508
3509       [JsonIgnore]
3510       public bool NumberOfChildrenSpecified { get; set; }
3511     }
3512
3513     [Test]
3514     public void SpecifiedExample()
3515     {
3516       FamilyDetails joe = new FamilyDetails();
3517       joe.Name = "Joe Family Details";
3518       joe.NumberOfChildren = 4;
3519       joe.NumberOfChildrenSpecified = true;
3520
3521       FamilyDetails martha = new FamilyDetails();
3522       martha.Name = "Martha Family Details";
3523       martha.NumberOfChildren = 3;
3524       martha.NumberOfChildrenSpecified = false;
3525
3526       string json = JsonConvert.SerializeObject(new[] { joe, martha }, Formatting.Indented);
3527       //[
3528       //  {
3529       //    "Name": "Joe Family Details",
3530       //    "NumberOfChildren": 4
3531       //  },
3532       //  {
3533       //    "Name": "Martha Family Details"
3534       //  }
3535       //]
3536       Console.WriteLine(json);
3537
3538       string mikeString = "{\"Name\": \"Mike Person\"}";
3539       FamilyDetails mike = JsonConvert.DeserializeObject<FamilyDetails>(mikeString);
3540
3541       Console.WriteLine("mikeString specifies number of children: {0}", mike.NumberOfChildrenSpecified);
3542
3543       string mikeFullDisclosureString = "{\"Name\": \"Mike Person\", \"NumberOfChildren\": \"0\"}";
3544       mike = JsonConvert.DeserializeObject<FamilyDetails>(mikeFullDisclosureString);
3545
3546       Console.WriteLine("mikeString specifies number of children: {0}", mike.NumberOfChildrenSpecified);
3547     }
3548
3549     public class DictionaryKey
3550     {
3551       public string Value { get; set; }
3552
3553       public override string ToString()
3554       {
3555         return Value;
3556       }
3557
3558       public static implicit operator DictionaryKey(string value)
3559       {
3560         return new DictionaryKey() { Value = value };
3561       }
3562     }
3563
3564     [Test]
3565     public void SerializeDeserializeDictionaryKey()
3566     {
3567       Dictionary<DictionaryKey, string> dictionary = new Dictionary<DictionaryKey, string>();
3568
3569       dictionary.Add(new DictionaryKey() { Value = "First!" }, "First");
3570       dictionary.Add(new DictionaryKey() { Value = "Second!" }, "Second");
3571
3572       string json = JsonConvert.SerializeObject(dictionary, Formatting.Indented);
3573
3574       Assert.AreEqual(@"{
3575   ""First!"": ""First"",
3576   ""Second!"": ""Second""
3577 }", json);
3578
3579       Dictionary<DictionaryKey, string> newDictionary =
3580         JsonConvert.DeserializeObject<Dictionary<DictionaryKey, string>>(json);
3581
3582       Assert.AreEqual(2, newDictionary.Count);
3583     }
3584
3585     [Test]
3586     public void SerializeNullableArray()
3587     {
3588       string jsonText = JsonConvert.SerializeObject(new double?[] { 2.4, 4.3, null }, Formatting.Indented);
3589
3590       Assert.AreEqual(@"[
3591   2.4,
3592   4.3,
3593   null
3594 ]", jsonText);
3595
3596       double?[] d = (double?[])JsonConvert.DeserializeObject(jsonText, typeof(double?[]));
3597
3598       Assert.AreEqual(3, d.Length);
3599       Assert.AreEqual(2.4, d[0]);
3600       Assert.AreEqual(4.3, d[1]);
3601       Assert.AreEqual(null, d[2]);
3602     }
3603
3604 #if !SILVERLIGHT && !NET20 && !PocketPC
3605     [Test]
3606     public void SerializeHashSet()
3607     {
3608       string jsonText = JsonConvert.SerializeObject(new HashSet<string>()
3609                                                       {
3610                                                         "One",
3611                                                         "2",
3612                                                         "III"
3613                                                       }, Formatting.Indented);
3614
3615       Assert.AreEqual(@"[
3616   ""One"",
3617   ""2"",
3618   ""III""
3619 ]", jsonText);
3620
3621       HashSet<string> d = JsonConvert.DeserializeObject<HashSet<string>>(jsonText);
3622
3623       Assert.AreEqual(3, d.Count);
3624       Assert.IsTrue(d.Contains("One"));
3625       Assert.IsTrue(d.Contains("2"));
3626       Assert.IsTrue(d.Contains("III"));
3627     }
3628 #endif
3629
3630     private class MyClass
3631     {
3632       public byte[] Prop1 { get; set; }
3633
3634       public MyClass()
3635       {
3636         Prop1 = new byte[0];
3637       }
3638     }
3639
3640     [Test]
3641     public void DeserializeByteArray()
3642     {
3643       JsonSerializer serializer1 = new JsonSerializer();
3644       serializer1.Converters.Add(new IsoDateTimeConverter());
3645       serializer1.NullValueHandling = NullValueHandling.Ignore;
3646
3647       string json = @"[{""Prop1"":""""},{""Prop1"":""""}]";
3648
3649       JsonTextReader reader = new JsonTextReader(new StringReader(json));
3650
3651       MyClass[] z = (MyClass[])serializer1.Deserialize(reader, typeof(MyClass[]));
3652       Assert.AreEqual(2, z.Length);
3653       Assert.AreEqual(0, z[0].Prop1.Length);
3654       Assert.AreEqual(0, z[1].Prop1.Length);
3655     }
3656
3657 #if !NET20 && !PocketPC && !SILVERLIGHT
3658     public class StringDictionaryTestClass
3659     {
3660       public StringDictionary StringDictionaryProperty { get; set; }
3661     }
3662
3663     [Test]
3664     [ExpectedException(typeof(Exception), ExpectedMessage = "Cannot create and populate list type System.Collections.Specialized.StringDictionary.")]
3665     public void StringDictionaryTest()
3666     {
3667       StringDictionaryTestClass s1 = new StringDictionaryTestClass()
3668         {
3669           StringDictionaryProperty = new StringDictionary()
3670             {
3671               {"1", "One"},
3672               {"2", "II"},
3673               {"3", "3"}              
3674             }
3675         };
3676
3677       string json = JsonConvert.SerializeObject(s1, Formatting.Indented);
3678
3679       JsonConvert.DeserializeObject<StringDictionaryTestClass>(json);
3680     }
3681 #endif
3682
3683     [JsonObject(MemberSerialization.OptIn)]
3684     public struct StructWithAttribute
3685     {
3686       public string MyString { get; set; }
3687       [JsonProperty]
3688       public int MyInt { get; set; }
3689     }
3690
3691     [Test]
3692     public void SerializeStructWithJsonObjectAttribute()
3693     {
3694       StructWithAttribute testStruct = new StructWithAttribute
3695         {
3696           MyInt = int.MaxValue
3697         };
3698
3699       string json = JsonConvert.SerializeObject(testStruct, Formatting.Indented);
3700
3701       Assert.AreEqual(@"{
3702   ""MyInt"": 2147483647
3703 }", json);
3704
3705       StructWithAttribute newStruct = JsonConvert.DeserializeObject<StructWithAttribute>(json);
3706
3707       Assert.AreEqual(int.MaxValue, newStruct.MyInt);
3708     }
3709
3710     public class TimeZoneOffsetObject
3711     {
3712       public DateTimeOffset Offset { get; set; }
3713     }
3714
3715 #if !NET20
3716     [Test]
3717     public void ReadWriteTimeZoneOffset()
3718     {
3719       var serializeObject = JsonConvert.SerializeObject(new TimeZoneOffsetObject
3720       {
3721         Offset = new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(6))
3722       });
3723
3724       Assert.AreEqual("{\"Offset\":\"\\/Date(946663200000+0600)\\/\"}", serializeObject);
3725       var deserializeObject = JsonConvert.DeserializeObject<TimeZoneOffsetObject>(serializeObject);
3726       Assert.AreEqual(TimeSpan.FromHours(6), deserializeObject.Offset.Offset);
3727       Assert.AreEqual(new DateTime(2000, 1, 1), deserializeObject.Offset.Date);
3728     }
3729
3730     [Test]
3731     public void DeserializePropertyNullableDateTimeOffsetExact()
3732     {
3733       NullableDateTimeTestClass d = JsonConvert.DeserializeObject<NullableDateTimeTestClass>("{\"DateTimeOffsetField\":\"\\/Date(946663200000+0600)\\/\"}");
3734       Assert.AreEqual(new DateTimeOffset(new DateTime(2000, 1, 1), TimeSpan.FromHours(6)), d.DateTimeOffsetField);
3735     }
3736 #endif
3737
3738     public abstract class LogEvent
3739     {
3740       [JsonProperty("event")]
3741       public abstract string EventName { get; }
3742     }
3743
3744     public class DerivedEvent : LogEvent
3745     {
3746       public override string EventName { get { return "derived"; } }
3747     }
3748
3749     [Test]
3750     public void OverridenPropertyMembers()
3751     {
3752       string json = JsonConvert.SerializeObject(new DerivedEvent(), Formatting.Indented);
3753
3754       Assert.AreEqual(@"{
3755   ""event"": ""derived""
3756 }", json);
3757     }
3758
3759 #if !(NET35 || NET20 || WINDOWS_PHONE)
3760     [Test]
3761     public void SerializeExpandoObject()
3762     {
3763       dynamic expando = new ExpandoObject();
3764       expando.Int = 1;
3765       expando.Decimal = 99.9d;
3766       expando.Complex = new ExpandoObject();
3767       expando.Complex.String = "I am a string";
3768       expando.Complex.DateTime = new DateTime(2000, 12, 20, 18, 55, 0, DateTimeKind.Utc);
3769
3770       string json = JsonConvert.SerializeObject(expando, Formatting.Indented);
3771       Assert.AreEqual(@"{
3772   ""Int"": 1,
3773   ""Decimal"": 99.9,
3774   ""Complex"": {
3775     ""String"": ""I am a string"",
3776     ""DateTime"": ""\/Date(977338500000)\/""
3777   }
3778 }", json);
3779
3780       IDictionary<string, object> newExpando = JsonConvert.DeserializeObject<ExpandoObject>(json);
3781
3782       Assert.IsInstanceOfType(typeof(long), newExpando["Int"]);
3783       Assert.AreEqual(expando.Int, newExpando["Int"]);
3784
3785       Assert.IsInstanceOfType(typeof(double), newExpando["Decimal"]);
3786       Assert.AreEqual(expando.Decimal, newExpando["Decimal"]);
3787
3788       Assert.IsInstanceOfType(typeof(ExpandoObject), newExpando["Complex"]);
3789       IDictionary<string, object> o = (ExpandoObject)newExpando["Complex"];
3790
3791       Assert.IsInstanceOfType(typeof(string), o["String"]);
3792       Assert.AreEqual(expando.Complex.String, o["String"]);
3793
3794       Assert.IsInstanceOfType(typeof(DateTime), o["DateTime"]);
3795       Assert.AreEqual(expando.Complex.DateTime, o["DateTime"]);
3796     }
3797 #endif
3798
3799     [Test]
3800     public void DeserializeDecimalExact()
3801     {
3802       decimal d = JsonConvert.DeserializeObject<decimal>("123456789876543.21");
3803       Assert.AreEqual(123456789876543.21m, d);
3804     }
3805
3806     [Test]
3807     public void DeserializeNullableDecimalExact()
3808     {
3809       decimal? d = JsonConvert.DeserializeObject<decimal?>("123456789876543.21");
3810       Assert.AreEqual(123456789876543.21m, d);
3811     }
3812
3813     [Test]
3814     public void DeserializeDecimalPropertyExact()
3815     {
3816       string json = "{Amount:123456789876543.21}";
3817       Invoice i = JsonConvert.DeserializeObject<Invoice>(json);
3818       Assert.AreEqual(123456789876543.21m, i.Amount);
3819     }
3820
3821     [Test]
3822     public void DeserializeDecimalArrayExact()
3823     {
3824       string json = "[123456789876543.21]";
3825       IList<decimal> a = JsonConvert.DeserializeObject<IList<decimal>>(json);
3826       Assert.AreEqual(123456789876543.21m, a[0]);
3827     }
3828
3829     [Test]
3830     public void DeserializeDecimalDictionaryExact()
3831     {
3832       string json = "{'Value':123456789876543.21}";
3833       IDictionary<string, decimal> d = JsonConvert.DeserializeObject<IDictionary<string, decimal>>(json);
3834       Assert.AreEqual(123456789876543.21m, d["Value"]);
3835     }
3836
3837     public struct Vector
3838     {
3839       public float X;
3840       public float Y;
3841       public float Z;
3842
3843       public override string ToString()
3844       {
3845         return string.Format("({0},{1},{2})", X, Y, Z);
3846       }
3847     }
3848
3849     public class VectorParent
3850     {
3851       public Vector Position;
3852     }
3853
3854     [Test]
3855     public void DeserializeStructProperty()
3856     {
3857       VectorParent obj = new VectorParent();
3858       obj.Position = new Vector { X = 1, Y = 2, Z = 3 };
3859
3860       string str = JsonConvert.SerializeObject(obj);
3861
3862       obj = JsonConvert.DeserializeObject<VectorParent>(str);
3863
3864       Assert.AreEqual(1, obj.Position.X);
3865       Assert.AreEqual(2, obj.Position.Y);
3866       Assert.AreEqual(3, obj.Position.Z);
3867     }
3868
3869     [JsonObject(MemberSerialization.OptIn)]
3870     public class Derived : Base
3871     {
3872       [JsonProperty]
3873       public string IDoWork { get; private set; }
3874
3875       private Derived() { }
3876
3877       internal Derived(string dontWork, string doWork)
3878         : base(dontWork)
3879       {
3880         IDoWork = doWork;
3881       }
3882     }
3883
3884     [JsonObject(MemberSerialization.OptIn)]
3885     public class Base
3886     {
3887       [JsonProperty]
3888       public string IDontWork { get; private set; }
3889
3890       protected Base() { }
3891
3892       internal Base(string dontWork)
3893       {
3894         IDontWork = dontWork;
3895       }
3896     }
3897
3898     [Test]
3899     public void PrivateSetterOnBaseClassProperty()
3900     {
3901       var derived = new Derived("meh", "woo");
3902
3903       var settings = new JsonSerializerSettings
3904       {
3905         TypeNameHandling = TypeNameHandling.Objects,
3906         ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor
3907       };
3908
3909       string json = JsonConvert.SerializeObject(derived, Formatting.Indented, settings);
3910
3911       var meh = JsonConvert.DeserializeObject<Base>(json, settings);
3912
3913       Assert.AreEqual(((Derived)meh).IDoWork, "woo");
3914       Assert.AreEqual(meh.IDontWork, "meh");
3915     }
3916
3917 #if !(SILVERLIGHT || PocketPC || NET20)
3918     [DataContract]
3919     public struct StructISerializable : ISerializable
3920     {
3921       private string _name;
3922
3923       public StructISerializable(SerializationInfo info, StreamingContext context)
3924       {
3925         _name = info.GetString("Name");
3926       }
3927
3928       [DataMember]
3929       public string Name
3930       {
3931         get { return _name; }
3932         set { _name = value; }
3933       }
3934
3935       public void GetObjectData(SerializationInfo info, StreamingContext context)
3936       {
3937         info.AddValue("Name", _name);
3938       }
3939     }
3940
3941     [DataContract]
3942     public class NullableStructPropertyClass
3943     {
3944       private StructISerializable _foo1;
3945       private StructISerializable? _foo2;
3946
3947       [DataMember]
3948       public StructISerializable Foo1
3949       {
3950         get { return _foo1; }
3951         set { _foo1 = value; }
3952       }
3953
3954       [DataMember]
3955       public StructISerializable? Foo2
3956       {
3957         get { return _foo2; }
3958         set { _foo2 = value; }
3959       }
3960     }
3961
3962     [Test]
3963     public void DeserializeNullableStruct()
3964     {
3965       NullableStructPropertyClass nullableStructPropertyClass = new NullableStructPropertyClass();
3966       nullableStructPropertyClass.Foo1 = new StructISerializable() { Name = "foo 1" };
3967       nullableStructPropertyClass.Foo2 = new StructISerializable() { Name = "foo 2" };
3968
3969       NullableStructPropertyClass barWithNull = new NullableStructPropertyClass();
3970       barWithNull.Foo1 = new StructISerializable() { Name = "foo 1" };
3971       barWithNull.Foo2 = null;
3972
3973       //throws error on deserialization because bar1.Foo2 is of type Foo?
3974       string s = JsonConvert.SerializeObject(nullableStructPropertyClass);
3975       NullableStructPropertyClass deserialized = deserialize(s);
3976       Assert.AreEqual(deserialized.Foo1.Name, "foo 1");
3977       Assert.AreEqual(deserialized.Foo2.Value.Name, "foo 2");
3978
3979       //no error Foo2 is null
3980       s = JsonConvert.SerializeObject(barWithNull);
3981       deserialized = deserialize(s);
3982       Assert.AreEqual(deserialized.Foo1.Name, "foo 1");
3983       Assert.AreEqual(deserialized.Foo2, null);
3984     }
3985
3986
3987     static NullableStructPropertyClass deserialize(string serStr)
3988     {
3989       return JsonConvert.DeserializeObject<NullableStructPropertyClass>(
3990         serStr,
3991         new JsonSerializerSettings
3992         {
3993           NullValueHandling = NullValueHandling.Ignore,
3994           MissingMemberHandling = MissingMemberHandling.Ignore
3995         });
3996     }
3997 #endif
3998
3999     public class Response
4000     {
4001       public string Name { get; set; }
4002       public JToken Data { get; set; }
4003     }
4004
4005     [Test]
4006     public void DeserializeJToken()
4007     {
4008       Response response = new Response
4009         {
4010           Name = "Success",
4011           Data = new JObject(new JProperty("First", "Value1"), new JProperty("Second", "Value2"))
4012         };
4013
4014       string json = JsonConvert.SerializeObject(response, Formatting.Indented);
4015
4016       Response deserializedResponse = JsonConvert.DeserializeObject<Response>(json);
4017
4018       Assert.AreEqual("Success", deserializedResponse.Name);
4019       Assert.IsTrue(deserializedResponse.Data.DeepEquals(response.Data));
4020     }
4021
4022     public abstract class Test<T>
4023     {
4024       public abstract T Value { get; set; }
4025     }
4026
4027     [JsonObject(MemberSerialization.OptIn)]
4028     public class DecimalTest : Test<decimal>
4029     {
4030       protected DecimalTest() { }
4031       public DecimalTest(decimal val)
4032       {
4033         Value = val;
4034       }
4035
4036       [JsonProperty]
4037       public override decimal Value { get; set; }
4038     }
4039
4040     [Test]
4041     public void OnError()
4042     {
4043       var data = new DecimalTest(decimal.MinValue);
4044       var json = JsonConvert.SerializeObject(data);
4045       var obj = JsonConvert.DeserializeObject<DecimalTest>(json);
4046
4047       Assert.AreEqual(decimal.MinValue, obj.Value);
4048     }
4049
4050     public class NonPublicConstructorWithJsonConstructor
4051     {
4052       public string Value { get; private set; }
4053       public string Constructor { get; private set; }
4054
4055       [JsonConstructor]
4056       private NonPublicConstructorWithJsonConstructor()
4057       {
4058         Constructor = "NonPublic";
4059       }
4060
4061       public NonPublicConstructorWithJsonConstructor(string value)
4062       {
4063         Value = value;
4064         Constructor = "Public Paramatized";
4065       }
4066     }
4067
4068     [Test]
4069     public void NonPublicConstructorWithJsonConstructorTest()
4070     {
4071       NonPublicConstructorWithJsonConstructor c = JsonConvert.DeserializeObject<NonPublicConstructorWithJsonConstructor>("{}");
4072       Assert.AreEqual("NonPublic", c.Constructor);
4073     }
4074
4075     public class PublicConstructorOverridenByJsonConstructor
4076     {
4077       public string Value { get; private set; }
4078       public string Constructor { get; private set; }
4079
4080       public PublicConstructorOverridenByJsonConstructor()
4081       {
4082         Constructor = "NonPublic";
4083       }
4084
4085       [JsonConstructor]
4086       public PublicConstructorOverridenByJsonConstructor(string value)
4087       {
4088         Value = value;
4089         Constructor = "Public Paramatized";
4090       }
4091     }
4092
4093     [Test]
4094     public void PublicConstructorOverridenByJsonConstructorTest()
4095     {
4096       PublicConstructorOverridenByJsonConstructor c = JsonConvert.DeserializeObject<PublicConstructorOverridenByJsonConstructor>("{Value:'value!'}");
4097       Assert.AreEqual("Public Paramatized", c.Constructor);
4098       Assert.AreEqual("value!", c.Value);
4099     }
4100
4101     public class MultipleParamatrizedConstructorsJsonConstructor
4102     {
4103       public string Value { get; private set; }
4104       public int Age { get; private set; }
4105       public string Constructor { get; private set; }
4106
4107       public MultipleParamatrizedConstructorsJsonConstructor(string value)
4108       {
4109         Value = value;
4110         Constructor = "Public Paramatized 1";
4111       }
4112
4113       [JsonConstructor]
4114       public MultipleParamatrizedConstructorsJsonConstructor(string value, int age)
4115       {
4116         Value = value;
4117         Age = age;
4118         Constructor = "Public Paramatized 2";
4119       }
4120     }
4121
4122     [Test]
4123     public void MultipleParamatrizedConstructorsJsonConstructorTest()
4124     {
4125       MultipleParamatrizedConstructorsJsonConstructor c = JsonConvert.DeserializeObject<MultipleParamatrizedConstructorsJsonConstructor>("{Value:'value!', Age:1}");
4126       Assert.AreEqual("Public Paramatized 2", c.Constructor);
4127       Assert.AreEqual("value!", c.Value);
4128       Assert.AreEqual(1, c.Age);
4129     }
4130
4131     public class EnumerableClass
4132     {
4133       public IEnumerable<string> Enumerable { get; set; }
4134     }
4135
4136     [Test]
4137     public void DeserializeEnumerable()
4138     {
4139       EnumerableClass c = new EnumerableClass
4140         {
4141           Enumerable = new List<string> { "One", "Two", "Three" }
4142         };
4143
4144       string json = JsonConvert.SerializeObject(c, Formatting.Indented);
4145
4146       Assert.AreEqual(@"{
4147   ""Enumerable"": [
4148     ""One"",
4149     ""Two"",
4150     ""Three""
4151   ]
4152 }", json);
4153
4154       EnumerableClass c2 = JsonConvert.DeserializeObject<EnumerableClass>(json);
4155
4156       Assert.AreEqual("One", c2.Enumerable.ElementAt(0));
4157       Assert.AreEqual("Two", c2.Enumerable.ElementAt(1));
4158       Assert.AreEqual("Three", c2.Enumerable.ElementAt(2));
4159     }
4160
4161     [JsonObject(MemberSerialization.OptIn)]
4162     public class ItemBase
4163     {
4164       [JsonProperty]
4165       public string Name { get; set; }
4166     }
4167
4168     public class ComplexItem : ItemBase
4169     {
4170       public Stream Source { get; set; }
4171     }
4172
4173     [Test]
4174     public void SerializeAttributesOnBase()
4175     {
4176       ComplexItem i = new ComplexItem();
4177
4178       string json = JsonConvert.SerializeObject(i, Formatting.Indented);
4179
4180       Assert.AreEqual(@"{
4181   ""Name"": null
4182 }", json);
4183     }
4184
4185     public class DeserializeStringConvert
4186     {
4187       public string Name { get; set; }
4188       public int Age { get; set; }
4189       public double Height { get; set; }
4190       public decimal Price { get; set; }
4191     }
4192
4193     [Test]
4194     public void DeserializeStringEnglish()
4195     {
4196       string json = @"{
4197   'Name': 'James Hughes',
4198   'Age': '40',
4199   'Height': '44.4',
4200   'Price': '4'
4201 }";
4202
4203       DeserializeStringConvert p = JsonConvert.DeserializeObject<DeserializeStringConvert>(json);
4204       Assert.AreEqual(40, p.Age);
4205       Assert.AreEqual(44.4, p.Height);
4206       Assert.AreEqual(4d, p.Price);
4207     }
4208
4209     [Test]
4210     [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "Error converting value {null} to type 'System.DateTime'.")]
4211     public void DeserializeNullDateTimeValueTest()
4212     {
4213       JsonConvert.DeserializeObject("null", typeof(DateTime));
4214     }
4215
4216     [Test]
4217     public void DeserializeNullNullableDateTimeValueTest()
4218     {
4219       object dateTime = JsonConvert.DeserializeObject("null", typeof(DateTime?));
4220
4221       Assert.IsNull(dateTime);
4222     }
4223
4224     [Test]
4225     public void MultiIndexSuperTest()
4226     {
4227       MultiIndexSuper e = new MultiIndexSuper();
4228
4229       string json = JsonConvert.SerializeObject(e, Formatting.Indented);
4230
4231       Assert.AreEqual(@"{}", json);
4232     }
4233
4234     public class MultiIndexSuper : MultiIndexBase
4235     {
4236       
4237     }
4238
4239     public abstract class MultiIndexBase
4240     {
4241       protected internal object this[string propertyName]
4242       {
4243         get { return null; }
4244         set { }
4245       }
4246       protected internal object this[object property]
4247       {
4248         get { return null; }
4249         set { }
4250       }
4251     }
4252
4253     public class CommentTestClass
4254     {
4255       public bool Indexed { get; set; }
4256       public int StartYear { get; set; }
4257       public IList<decimal> Values { get; set; }
4258     }
4259
4260     [Test]
4261     public void CommentTestClassTest()
4262     {
4263       string json = @"{""indexed"":true, ""startYear"":1939, ""values"":
4264                             [  3000,  /* 1940-1949 */
4265                                3000,   3600,   3600,   3600,   3600,   4200,   4200,   4200,   4200,   4800,  /* 1950-1959 */
4266                                4800,   4800,   4800,   4800,   4800,   4800,   6600,   6600,   7800,   7800,  /* 1960-1969 */
4267                                7800,   7800,   9000,  10800,  13200,  14100,  15300,  16500,  17700,  22900,  /* 1970-1979 */
4268                               25900,  29700,  32400,  35700,  37800,  39600,  42000,  43800,  45000,  48000,  /* 1980-1989 */
4269                               51300,  53400,  55500,  57600,  60600,  61200,  62700,  65400,  68400,  72600,  /* 1990-1999 */
4270                               76200,  80400,  84900,  87000,  87900,  90000,  94200,  97500, 102000, 106800,  /* 2000-2009 */
4271                              106800, 106800]  /* 2010-2011 */
4272                                 }";
4273
4274       CommentTestClass commentTestClass = JsonConvert.DeserializeObject<CommentTestClass>(json);
4275
4276       Assert.AreEqual(true, commentTestClass.Indexed);
4277       Assert.AreEqual(1939, commentTestClass.StartYear);
4278       Assert.AreEqual(63, commentTestClass.Values.Count);
4279     }
4280
4281     class DTOWithParameterisedConstructor
4282     {
4283       public DTOWithParameterisedConstructor(string A)
4284       {
4285         this.A = A;
4286         B = 2;
4287       }
4288
4289       public string A { get; set; }
4290       public int? B { get; set; }
4291     }
4292
4293     class DTOWithoutParameterisedConstructor
4294     {
4295       public DTOWithoutParameterisedConstructor()
4296       {
4297         B = 2;
4298       }
4299
4300       public string A { get; set; }
4301       public int? B { get; set; }
4302     }
4303
4304     [Test]
4305     public void PopulationBehaviourForOmittedPropertiesIsTheSameForParameterisedConstructorAsForDefaultConstructor()
4306     {
4307       string json = @"{A:""Test""}";
4308
4309       var withoutParameterisedConstructor = JsonConvert.DeserializeObject<DTOWithoutParameterisedConstructor>(json);
4310       var withParameterisedConstructor = JsonConvert.DeserializeObject<DTOWithParameterisedConstructor>(json);
4311       Assert.AreEqual(withoutParameterisedConstructor.B, withParameterisedConstructor.B);
4312     }
4313   }
4314 }