Json.NET
Code Coverage Statistics for Source File

Newtonsoft.Json.Tests\Serialization\PreserveReferencesHandlingTests.cs

Symbol Coverage: 94.90% (186 of 196)

Branch Coverage: 81.08% (30 of 37)

Cyclomatic Complexity Avg: 1.03 Max:2

Code Lines: 520


L V Source
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
using System.Linq;
29
using System.Text;
30
using Newtonsoft.Json.Linq;
31
using Newtonsoft.Json.Tests.TestObjects;
32
using NUnit.Framework;
33

  
34
namespace Newtonsoft.Json.Tests.Serialization
35
{
36
  public class PreserveReferencesHandlingTests : TestFixtureBase
37
  {
38
    [Test]
39
    public void SerializeDictionarysWithPreserveObjectReferences()
40
    {
41
 1
      CircularDictionary circularDictionary = new CircularDictionary();
42
 1
      circularDictionary.Add("other", new CircularDictionary { { "blah", null } });
43
 1
      circularDictionary.Add("self", circularDictionary);
44

  
45
 1
      string json = JsonConvert.SerializeObject(circularDictionary, Formatting.Indented,
46
 1
        new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.All });
47

  
48
 1
      Assert.AreEqual(@"{
49
 1
  ""$id"": ""1"",
50
 1
  ""other"": {
51
 1
    ""$id"": ""2"",
52
 1
    ""blah"": null
53
 1
  },
54
 1
  ""self"": {
55
 1
    ""$ref"": ""1""
56
 1
  }
57
 1
}", json);
58
 1
    }
59

  
60
    [Test]
61
    public void DeserializeDictionarysWithPreserveObjectReferences()
62
    {
63
 1
      string json = @"{
64
 1
  ""$id"": ""1"",
65
 1
  ""other"": {
66
 1
    ""$id"": ""2"",
67
 1
    ""blah"": null
68
 1
  },
69
 1
  ""self"": {
70
 1
    ""$ref"": ""1""
71
 1
  }
72
 1
}";
73

  
74
 1
      CircularDictionary circularDictionary = JsonConvert.DeserializeObject<CircularDictionary>(json,
75
 1
        new JsonSerializerSettings
76
 1
        {
77
 1
          PreserveReferencesHandling = PreserveReferencesHandling.All
78
 1
        });
79

  
80
 1
      Assert.AreEqual(2, circularDictionary.Count);
81
 1
      Assert.AreEqual(1, circularDictionary["other"].Count);
82
 1
      Assert.AreEqual(circularDictionary, circularDictionary["self"]);
83
 1
    }
84

  
85
    public class CircularList : List<CircularList>
86
    {
87
    }
88

  
89
    [Test]
90
    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "Self referencing loop")]
91
    public void SerializeCircularListsError()
92
    {
93
 1
      CircularList circularList = new CircularList();
94
 1
      circularList.Add(null);
95
 1
      circularList.Add(new CircularList { null });
96
 1
      circularList.Add(new CircularList { new CircularList { circularList } });
97

  
98
 1
      JsonConvert.SerializeObject(circularList, Formatting.Indented);
99
 0
    }
100

  
101
    [Test]
102
    public void SerializeCircularListsIgnore()
103
    {
104
 1
      CircularList circularList = new CircularList();
105
 1
      circularList.Add(null);
106
 1
      circularList.Add(new CircularList { null });
107
 1
      circularList.Add(new CircularList { new CircularList { circularList } });
108

  
109
 1
      string json = JsonConvert.SerializeObject(circularList,
110
 1
                                                Formatting.Indented,
111
 1
                                                new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
112

  
113
 1
      Assert.AreEqual(@"[
114
 1
  null,
115
 1
  [
116
 1
    null
117
 1
  ],
118
 1
  [
119
 1
    []
120
 1
  ]
121
 1
]", json);
122
 1
    }
123

  
124
    [Test]
125
    public void SerializeListsWithPreserveObjectReferences()
126
    {
127
 1
      CircularList circularList = new CircularList();
128
 1
      circularList.Add(null);
129
 1
      circularList.Add(new CircularList { null });
130
 1
      circularList.Add(new CircularList { new CircularList { circularList } });
131

  
132
 1
      string json = JsonConvert.SerializeObject(circularList, Formatting.Indented,
133
 1
        new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.All });
134

  
135
 1
      WriteEscapedJson(json);
136
 1
      Assert.AreEqual(@"{
137
 1
  ""$id"": ""1"",
138
 1
  ""$values"": [
139
 1
    null,
140
 1
    {
141
 1
      ""$id"": ""2"",
142
 1
      ""$values"": [
143
 1
        null
144
 1
      ]
145
 1
    },
146
 1
    {
147
 1
      ""$id"": ""3"",
148
 1
      ""$values"": [
149
 1
        {
150
 1
          ""$id"": ""4"",
151
 1
          ""$values"": [
152
 1
            {
153
 1
              ""$ref"": ""1""
154
 1
            }
155
 1
          ]
156
 1
        }
157
 1
      ]
158
 1
    }
159
 1
  ]
160
 1
}", json);
161
 1
    }
162

  
163
    [Test]
164
    public void DeserializeListsWithPreserveObjectReferences()
165
    {
166
 1
      string json = @"{
167
 1
  ""$id"": ""1"",
168
 1
  ""$values"": [
169
 1
    null,
170
 1
    {
171
 1
      ""$id"": ""2"",
172
 1
      ""$values"": [
173
 1
        null
174
 1
      ]
175
 1
    },
176
 1
    {
177
 1
      ""$id"": ""3"",
178
 1
      ""$values"": [
179
 1
        {
180
 1
          ""$id"": ""4"",
181
 1
          ""$values"": [
182
 1
            {
183
 1
              ""$ref"": ""1""
184
 1
            }
185
 1
          ]
186
 1
        }
187
 1
      ]
188
 1
    }
189
 1
  ]
190
 1
}";
191

  
192
 1
      CircularList circularList = JsonConvert.DeserializeObject<CircularList>(json,
193
 1
        new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.All });
194

  
195
 1
      Assert.AreEqual(3, circularList.Count);
196
 1
      Assert.AreEqual(null, circularList[0]);
197
 1
      Assert.AreEqual(1, circularList[1].Count);
198
 1
      Assert.AreEqual(1, circularList[2].Count);
199
 1
      Assert.AreEqual(1, circularList[2][0].Count);
200
 1
      Assert.IsTrue(ReferenceEquals(circularList, circularList[2][0][0]));
201
 1
    }
202

  
203
    [Test]
204
    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"Cannot preserve reference to array or readonly list: System.String[][]")]
205
    public void DeserializeArraysWithPreserveObjectReferences()
206
    {
207
 1
      string json = @"{
208
 1
  ""$id"": ""1"",
209
 1
  ""$values"": [
210
 1
    null,
211
 1
    {
212
 1
      ""$id"": ""2"",
213
 1
      ""$values"": [
214
 1
        null
215
 1
      ]
216
 1
    },
217
 1
    {
218
 1
      ""$id"": ""3"",
219
 1
      ""$values"": [
220
 1
        {
221
 1
          ""$id"": ""4"",
222
 1
          ""$values"": [
223
 1
            {
224
 1
              ""$ref"": ""1""
225
 1
            }
226
 1
          ]
227
 1
        }
228
 1
      ]
229
 1
    }
230
 1
  ]
231
 1
}";
232

  
233
 1
      JsonConvert.DeserializeObject<string[][]>(json,
234
 1
        new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.All });
235
 0
    }
236

  
237
    public class CircularDictionary : Dictionary<string, CircularDictionary>
238
    {
239
    }
240

  
241
    [Test]
242
    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "Self referencing loop")]
243
    public void SerializeCircularDictionarysError()
244
    {
245
 1
      CircularDictionary circularDictionary = new CircularDictionary();
246
 1
      circularDictionary.Add("other", new CircularDictionary { { "blah", null } });
247
 1
      circularDictionary.Add("self", circularDictionary);
248

  
249
 1
      JsonConvert.SerializeObject(circularDictionary, Formatting.Indented);
250
 0
    }
251

  
252
    [Test]
253
    public void SerializeCircularDictionarysIgnore()
254
    {
255
 1
      CircularDictionary circularDictionary = new CircularDictionary();
256
 1
      circularDictionary.Add("other", new CircularDictionary { { "blah", null } });
257
 1
      circularDictionary.Add("self", circularDictionary);
258

  
259
 1
      string json = JsonConvert.SerializeObject(circularDictionary, Formatting.Indented,
260
 1
        new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
261

  
262
 1
      Assert.AreEqual(@"{
263
 1
  ""other"": {
264
 1
    ""blah"": null
265
 1
  }
266
 1
}", json);
267
 1
    }
268

  
269
    [Test]
270
    [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"Unexpected end when deserializing object.")]
271
    public void UnexpectedEnd()
272
    {
273
 1
      string json = @"{
274
 1
  ""$id"":";
275

  
276
 1
      JsonConvert.DeserializeObject<string[][]>(json,
277
 1
        new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.All });
278
 0
    }
279

  
280
    public class CircularReferenceClassConverter : JsonConverter
281
    {
282
      public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
283
      {
284
 3
        CircularReferenceClass circularReferenceClass = (CircularReferenceClass)value;
285

  
286
 3
        string reference = serializer.ReferenceResolver.GetReference(circularReferenceClass);
287

  
288
 3
        JObject me = new JObject();
289
 3
        me["$id"] = new JValue(reference);
290
 3
        me["$type"] = new JValue(value.GetType().Name);
291
 3
        me["Name"] = new JValue(circularReferenceClass.Name);
292

  
293
 3
        JObject o = JObject.FromObject(circularReferenceClass.Child, serializer);
294
 3
        me["Child"] = o;
295

  
296
 3
        me.WriteTo(writer);
297
 3
      }
298

  
299
      public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
300
      {
301
 4
        JObject o = JObject.Load(reader);
302
 4
        string id = (string)o["$id"];
303
 4
        if (id != null)
304
        {
305
 3
          CircularReferenceClass circularReferenceClass = new CircularReferenceClass();
306
 3
          serializer.Populate(o.CreateReader(), circularReferenceClass);
307
 3
          return circularReferenceClass;
308
        }
309
        else
310
        {
311
 1
          string reference = (string)o["$ref"];
312
 1
          return serializer.ReferenceResolver.ResolveReference(reference);
313
        }
314
 4
      }
315

  
316
      public override bool CanConvert(Type objectType)
317
      {
318
 11
        return (objectType == typeof(CircularReferenceClass));
319
 11
      }
320
    }
321

  
322
    [Test]
323
    public void SerializeCircularReferencesWithConverter()
324
    {
325
 1
      CircularReferenceClass c1 = new CircularReferenceClass { Name = "c1" };
326
 1
      CircularReferenceClass c2 = new CircularReferenceClass { Name = "c2" };
327
 1
      CircularReferenceClass c3 = new CircularReferenceClass { Name = "c3" };
328

  
329
 1
      c1.Child = c2;
330
 1
      c2.Child = c3;
331
 1
      c3.Child = c1;
332

  
333
 1
      string json = JsonConvert.SerializeObject(c1, Formatting.Indented, new JsonSerializerSettings
334
 1
      {
335
 1
        PreserveReferencesHandling = PreserveReferencesHandling.Objects,
336
 1
        Converters = new List<JsonConverter> { new CircularReferenceClassConverter() }
337
 1
      });
338

  
339
 1
      Assert.AreEqual(@"{
340
 1
  ""$id"": ""1"",
341
 1
  ""$type"": ""CircularReferenceClass"",
342
 1
  ""Name"": ""c1"",
343
 1
  ""Child"": {
344
 1
    ""$id"": ""2"",
345
 1
    ""$type"": ""CircularReferenceClass"",
346
 1
    ""Name"": ""c2"",
347
 1
    ""Child"": {
348
 1
      ""$id"": ""3"",
349
 1
      ""$type"": ""CircularReferenceClass"",
350
 1
      ""Name"": ""c3"",
351
 1
      ""Child"": {
352
 1
        ""$ref"": ""1""
353
 1
      }
354
 1
    }
355
 1
  }
356
 1
}", json);
357
 1
    }
358

  
359
    [Test]
360
    public void DeserializeCircularReferencesWithConverter()
361
    {
362
 1
      string json = @"{
363
 1
  ""$id"": ""1"",
364
 1
  ""$type"": ""CircularReferenceClass"",
365
 1
  ""Name"": ""c1"",
366
 1
  ""Child"": {
367
 1
    ""$id"": ""2"",
368
 1
    ""$type"": ""CircularReferenceClass"",
369
 1
    ""Name"": ""c2"",
370
 1
    ""Child"": {
371
 1
      ""$id"": ""3"",
372
 1
      ""$type"": ""CircularReferenceClass"",
373
 1
      ""Name"": ""c3"",
374
 1
      ""Child"": {
375
 1
        ""$ref"": ""1""
376
 1
      }
377
 1
    }
378
 1
  }
379
 1
}";
380

  
381
 1
      CircularReferenceClass c1 = JsonConvert.DeserializeObject<CircularReferenceClass>(json, new JsonSerializerSettings
382
 1
      {
383
 1
        PreserveReferencesHandling = PreserveReferencesHandling.Objects,
384
 1
        Converters = new List<JsonConverter> { new CircularReferenceClassConverter() }
385
 1
      });
386

  
387
 1
      Assert.AreEqual("c1", c1.Name);
388
 1
      Assert.AreEqual("c2", c1.Child.Name);
389
 1
      Assert.AreEqual("c3", c1.Child.Child.Name);
390
 1
      Assert.AreEqual("c1", c1.Child.Child.Child.Name);
391
 1
    }
392

  
393
    [Test]
394
    public void SerializeEmployeeReference()
395
    {
396
 1
      EmployeeReference mikeManager = new EmployeeReference
397
 1
      {
398
 1
        Name = "Mike Manager"
399
 1
      };
400
 1
      EmployeeReference joeUser = new EmployeeReference
401
 1
      {
402
 1
        Name = "Joe User",
403
 1
        Manager = mikeManager
404
 1
      };
405

  
406
 1
      List<EmployeeReference> employees = new List<EmployeeReference>
407
 1
        {
408
 1
          mikeManager,
409
 1
          joeUser
410
 1
        };
411

  
412
 1
      string json = JsonConvert.SerializeObject(employees, Formatting.Indented);
413
 1
      Assert.AreEqual(@"[
414
 1
  {
415
 1
    ""$id"": ""1"",
416
 1
    ""Name"": ""Mike Manager"",
417
 1
    ""Manager"": null
418
 1
  },
419
 1
  {
420
 1
    ""$id"": ""2"",
421
 1
    ""Name"": ""Joe User"",
422
 1
    ""Manager"": {
423
 1
      ""$ref"": ""1""
424
 1
    }
425
 1
  }
426
 1
]", json);
427
 1
    }
428

  
429
    [Test]
430
    public void DeserializeEmployeeReference()
431
    {
432
 1
      string json = @"[
433
 1
  {
434
 1
    ""$id"": ""1"",
435
 1
    ""Name"": ""Mike Manager"",
436
 1
    ""Manager"": null
437
 1
  },
438
 1
  {
439
 1
    ""$id"": ""2"",
440
 1
    ""Name"": ""Joe User"",
441
 1
    ""Manager"": {
442
 1
      ""$ref"": ""1""
443
 1
    }
444
 1
  }
445
 1
]";
446

  
447
 1
      List<EmployeeReference> employees = JsonConvert.DeserializeObject<List<EmployeeReference>>(json);
448

  
449
 1
      Assert.AreEqual(2, employees.Count);
450
 1
      Assert.AreEqual("Mike Manager", employees[0].Name);
451
 1
      Assert.AreEqual("Joe User", employees[1].Name);
452
 1
      Assert.AreEqual(employees[0], employees[1].Manager);
453
 1
    }
454

  
455
    [Test]
456
    public void SerializeCircularReference()
457
    {
458
 1
      CircularReferenceClass c1 = new CircularReferenceClass { Name = "c1" };
459
 1
      CircularReferenceClass c2 = new CircularReferenceClass { Name = "c2" };
460
 1
      CircularReferenceClass c3 = new CircularReferenceClass { Name = "c3" };
461

  
462
 1
      c1.Child = c2;
463
 1
      c2.Child = c3;
464
 1
      c3.Child = c1;
465

  
466
 1
      string json = JsonConvert.SerializeObject(c1, Formatting.Indented, new JsonSerializerSettings
467
 1
      {
468
 1
        PreserveReferencesHandling = PreserveReferencesHandling.Objects
469
 1
      });
470

  
471
 1
      Assert.AreEqual(@"{
472
 1
  ""$id"": ""1"",
473
 1
  ""Name"": ""c1"",
474
 1
  ""Child"": {
475
 1
    ""$id"": ""2"",
476
 1
    ""Name"": ""c2"",
477
 1
    ""Child"": {
478
 1
      ""$id"": ""3"",
479
 1
      ""Name"": ""c3"",
480
 1
      ""Child"": {
481
 1
        ""$ref"": ""1""
482
 1
      }
483
 1
    }
484
 1
  }
485
 1
}", json);
486
 1
    }
487

  
488
    [Test]
489
    public void DeserializeCircularReference()
490
    {
491
 1
      string json = @"{
492
 1
  ""$id"": ""1"",
493
 1
  ""Name"": ""c1"",
494
 1
  ""Child"": {
495
 1
    ""$id"": ""2"",
496
 1
    ""Name"": ""c2"",
497
 1
    ""Child"": {
498
 1
      ""$id"": ""3"",
499
 1
      ""Name"": ""c3"",
500
 1
      ""Child"": {
501
 1
        ""$ref"": ""1""
502
 1
      }
503
 1
    }
504
 1
  }
505
 1
}";
506

  
507
 1
      CircularReferenceClass c1 =
508
 1
        JsonConvert.DeserializeObject<CircularReferenceClass>(json, new JsonSerializerSettings
509
 1
        {
510
 1
          PreserveReferencesHandling = PreserveReferencesHandling.Objects
511
 1
        });
512

  
513
 1
      Assert.AreEqual("c1", c1.Name);
514
 1
      Assert.AreEqual("c2", c1.Child.Name);
515
 1
      Assert.AreEqual("c3", c1.Child.Child.Name);
516
 1
      Assert.AreEqual("c1", c1.Child.Child.Child.Name);
517
 1
    }
518

  
519
    [Test]
520
    public void SerializeReferenceInList()
521
    {
522
 1
      EmployeeReference e1 = new EmployeeReference { Name = "e1" };
523
 1
      EmployeeReference e2 = new EmployeeReference { Name = "e2" };
524

  
525
 1
      List<EmployeeReference> employees = new List<EmployeeReference> { e1, e2, e1, e2 };
526

  
527
 1
      string json = JsonConvert.SerializeObject(employees, Formatting.Indented);
528

  
529
 1
      Assert.AreEqual(@"[
530
 1
  {
531
 1
    ""$id"": ""1"",
532
 1
    ""Name"": ""e1"",
533
 1
    ""Manager"": null
534
 1
  },
535
 1
  {
536
 1
    ""$id"": ""2"",
537
 1
    ""Name"": ""e2"",
538
 1
    ""Manager"": null
539
 1
  },
540
 1
  {
541
 1
    ""$ref"": ""1""
542
 1
  },
543
 1
  {
544
 1
    ""$ref"": ""2""
545
 1
  }
546
 1
]", json);
547
 1
    }
548

  
549
    [Test]
550
    public void DeserializeReferenceInList()
551
    {
552
 1
      string json = @"[
553
 1
  {
554
 1
    ""$id"": ""1"",
555
 1
    ""Name"": ""e1"",
556
 1
    ""Manager"": null
557
 1
  },
558
 1
  {
559
 1
    ""$id"": ""2"",
560
 1
    ""Name"": ""e2"",
561
 1
    ""Manager"": null
562
 1
  },
563
 1
  {
564
 1
    ""$ref"": ""1""
565
 1
  },
566
 1
  {
567
 1
    ""$ref"": ""2""
568
 1
  }
569
 1
]";
570

  
571
 1
      List<EmployeeReference> employees = JsonConvert.DeserializeObject<List<EmployeeReference>>(json);
572
 1
      Assert.AreEqual(4, employees.Count);
573

  
574
 1
      Assert.AreEqual("e1", employees[0].Name);
575
 1
      Assert.AreEqual("e2", employees[1].Name);
576
 1
      Assert.AreEqual("e1", employees[2].Name);
577
 1
      Assert.AreEqual("e2", employees[3].Name);
578

  
579
 1
      Assert.AreEqual(employees[0], employees[2]);
580
 1
      Assert.AreEqual(employees[1], employees[3]);
581
 1
    }
582

  
583
    [Test]
584
    public void SerializeReferenceInDictionary()
585
    {
586
 1
      EmployeeReference e1 = new EmployeeReference { Name = "e1" };
587
 1
      EmployeeReference e2 = new EmployeeReference { Name = "e2" };
588

  
589
 1
      Dictionary<string, EmployeeReference> employees = new Dictionary<string, EmployeeReference>
590
 1
        {
591
 1
          {"One", e1},
592
 1
          {"Two", e2},
593
 1
          {"Three", e1},
594
 1
          {"Four", e2}
595
 1
        };
596

  
597
 1
      string json = JsonConvert.SerializeObject(employees, Formatting.Indented);
598

  
599
 1
      Assert.AreEqual(@"{
600
 1
  ""One"": {
601
 1
    ""$id"": ""1"",
602
 1
    ""Name"": ""e1"",
603
 1
    ""Manager"": null
604
 1
  },
605
 1
  ""Two"": {
606
 1
    ""$id"": ""2"",
607
 1
    ""Name"": ""e2"",
608
 1
    ""Manager"": null
609
 1
  },
610
 1
  ""Three"": {
611
 1
    ""$ref"": ""1""
612
 1
  },
613
 1
  ""Four"": {
614
 1
    ""$ref"": ""2""
615
 1
  }
616
 1
}", json);
617
 1
    }
618

  
619
    [Test]
620
    public void DeserializeReferenceInDictionary()
621
    {
622
 1
      string json = @"{
623
 1
  ""One"": {
624
 1
    ""$id"": ""1"",
625
 1
    ""Name"": ""e1"",
626
 1
    ""Manager"": null
627
 1
  },
628
 1
  ""Two"": {
629
 1
    ""$id"": ""2"",
630
 1
    ""Name"": ""e2"",
631
 1
    ""Manager"": null
632
 1
  },
633
 1
  ""Three"": {
634
 1
    ""$ref"": ""1""
635
 1
  },
636
 1
  ""Four"": {
637
 1
    ""$ref"": ""2""
638
 1
  }
639
 1
}";
640

  
641
 1
      Dictionary<string, EmployeeReference> employees = JsonConvert.DeserializeObject<Dictionary<string, EmployeeReference>>(json);
642
 1
      Assert.AreEqual(4, employees.Count);
643

  
644
 1
      EmployeeReference e1 = employees["One"];
645
 1
      EmployeeReference e2 = employees["Two"];
646

  
647
 1
      Assert.AreEqual("e1", e1.Name);
648
 1
      Assert.AreEqual("e2", e2.Name);
649

  
650
 1
      Assert.AreEqual(e1, employees["Three"]);
651
 1
      Assert.AreEqual(e2, employees["Four"]);
652
 1
    }
653

  
654
    [Test]
655
    public void ExampleWithout()
656
    {
657
 1
      Person p = new Person
658
 1
        {
659
 1
          BirthDate = new DateTime(1980, 12, 23, 0, 0, 0, DateTimeKind.Utc),
660
 1
          LastModified = new DateTime(2009, 2, 20, 12, 59, 21, DateTimeKind.Utc),
661
 1
          Department = "IT",
662
 1
          Name = "James"
663
 1
        };
664

  
665
 1
      List<Person> people = new List<Person>();
666
 1
      people.Add(p);
667
 1
      people.Add(p);
668

  
669
 1
      string json = JsonConvert.SerializeObject(people, Formatting.Indented);
670
      //[
671
      //  {
672
      //    "Name": "James",
673
      //    "BirthDate": "\/Date(346377600000)\/",
674
      //    "LastModified": "\/Date(1235134761000)\/"
675
      //  },
676
      //  {
677
      //    "Name": "James",
678
      //    "BirthDate": "\/Date(346377600000)\/",
679
      //    "LastModified": "\/Date(1235134761000)\/"
680
      //  }
681
      //]
682
 1
    }
683

  
684
    [Test]
685
    public void ExampleWith()
686
    {
687
 1
      Person p = new Person
688
 1
      {
689
 1
        BirthDate = new DateTime(1980, 12, 23, 0, 0, 0, DateTimeKind.Utc),
690
 1
        LastModified = new DateTime(2009, 2, 20, 12, 59, 21, DateTimeKind.Utc),
691
 1
        Department = "IT",
692
 1
        Name = "James"
693
 1
      };
694

  
695
 1
      List<Person> people = new List<Person>();
696
 1
      people.Add(p);
697
 1
      people.Add(p);
698

  
699
 1
      string json = JsonConvert.SerializeObject(people, Formatting.Indented,
700
 1
        new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects });
701
      //[
702
      //  {
703
      //    "$id": "1",
704
      //    "Name": "James",
705
      //    "BirthDate": "\/Date(346377600000)\/",
706
      //    "LastModified": "\/Date(1235134761000)\/"
707
      //  },
708
      //  {
709
      //    "$ref": "1"
710
      //  }
711
      //]
712

  
713
 1
      List<Person> deserializedPeople = JsonConvert.DeserializeObject<List<Person>>(json,
714
 1
        new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects });
715

  
716
 1
      Console.WriteLine(deserializedPeople.Count);
717
      // 2
718

  
719
 1
      Person p1 = deserializedPeople[0];
720
 1
      Person p2 = deserializedPeople[1];
721

  
722
 1
      Console.WriteLine(p1.Name);
723
      // James
724
 1
      Console.WriteLine(p2.Name);
725
      // James
726

  
727
 1
      bool equal = Object.ReferenceEquals(p1, p2);
728
      // true
729
 1
    }
730

  
731
    [JsonObject(MemberSerialization = MemberSerialization.OptIn)]
732
    public class User
733
    {
734
      #region properties
735

  
736
      [JsonProperty(Required = Required.Always, PropertyName = "SecretType")]
737
      private string secretType;
738

  
739
      [JsonProperty(Required = Required.Always)]
740
      public string Login { get; set; }
741

  
742
      public Type SecretType
743
      {
744
 0
        get { return Type.GetType(secretType); }
745
 2
        set { secretType = value.AssemblyQualifiedName; }
746
      }
747

  
748
      [JsonProperty]
749
      public User Friend { get; set; }
750

  
751
      #endregion
752

  
753
      #region constructors
754

  
755
 4
      public User()
756
      {
757

  
758
 4
      }
759

  
760
 2
      public User(string login, Type secretType)
761
 2
        : this()
762
      {
763
 2
        this.Login = login;
764
 2
        this.SecretType = secretType;
765
 2
      }
766

  
767
      #endregion
768

  
769
      #region methods
770

  
771
      public override int GetHashCode()
772
      {
773
 0
        return SecretType.GetHashCode();
774
 0
      }
775

  
776
      public override string ToString()
777
      {
778
 0
        return string.Format("SecretType: {0}, Login: {1}", secretType, Login);
779
 0
      }
780

  
781
      #endregion
782
    }
783

  
784
    [Test]
785
    public void DeserializeTypeWithDubiousGetHashcode()
786
    {
787
 1
      User user1 = new User("Peter", typeof(Version));
788
 1
      User user2 = new User("Michael", typeof(Version));
789

  
790
 1
      user1.Friend = user2;
791

  
792
 1
      JsonSerializerSettings serializerSettings = new JsonSerializerSettings
793
 1
      {
794
 1
        TypeNameHandling = TypeNameHandling.All,
795
 1
        ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
796
 1
        ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor,
797
 1
        PreserveReferencesHandling = PreserveReferencesHandling.Objects
798
 1
      };
799

  
800
 1
      string json = JsonConvert.SerializeObject(user1, Formatting.Indented, serializerSettings);
801

  
802
 1
      User deserializedUser = JsonConvert.DeserializeObject<User>(json, serializerSettings);
803
 1
      Assert.IsNotNull(deserializedUser);
804
 1
    }
805
  }
806
}