PageRenderTime 10ms CodeModel.GetById 3ms app.highlight 35ms RepoModel.GetById 1ms app.codeStats 1ms

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

https://bitbucket.org/Ecarestia/newtonsoft.json
C# | 2420 lines | 2371 code | 18 blank | 31 comment | 3 complexity | 3e2923cf9a3c4a227ed7b21a1a9caebf MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1#region License
   2// Copyright (c) 2007 James Newton-King
   3//
   4// Permission is hereby granted, free of charge, to any person
   5// obtaining a copy of this software and associated documentation
   6// files (the "Software"), to deal in the Software without
   7// restriction, including without limitation the rights to use,
   8// copy, modify, merge, publish, distribute, sublicense, and/or sell
   9// copies of the Software, and to permit persons to whom the
  10// Software is furnished to do so, subject to the following
  11// conditions:
  12//
  13// The above copyright notice and this permission notice shall be
  14// included in all copies or substantial portions of the Software.
  15//
  16// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  18// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  20// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  21// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  23// OTHER DEALINGS IN THE SOFTWARE.
  24#endregion
  25
  26#if NET20
  27using Newtonsoft.Json.Utilities.LinqBridge;
  28#else
  29using System.Linq;
  30#endif
  31#if !(PORTABLE || PORTABLE40)
  32using System.Collections.ObjectModel;
  33#if !(NET35 || NET20)
  34using System.Dynamic;
  35#endif
  36using System.Text;
  37using Newtonsoft.Json.Tests.Linq;
  38using System;
  39using System.Collections;
  40using System.Collections.Generic;
  41using System.Globalization;
  42using System.Runtime.Serialization.Formatters;
  43using Newtonsoft.Json.Linq;
  44using Newtonsoft.Json.Serialization;
  45using Newtonsoft.Json.Tests.TestObjects;
  46using Newtonsoft.Json.Tests.TestObjects.Organization;
  47#if DNXCORE50
  48using Xunit;
  49using Test = Xunit.FactAttribute;
  50using Assert = Newtonsoft.Json.Tests.XUnitAssert;
  51#else
  52using NUnit.Framework;
  53#endif
  54using Newtonsoft.Json.Utilities;
  55using System.Net;
  56using System.Runtime.Serialization;
  57using System.IO;
  58
  59namespace Newtonsoft.Json.Tests.Serialization
  60{
  61    [TestFixture]
  62    public class TypeNameHandlingTests : TestFixtureBase
  63    {
  64#if !(NET20 || NET35)
  65        [Test]
  66        public void SerializeValueTupleWithTypeName()
  67        {
  68            string tupleRef = ReflectionUtils.GetTypeName(typeof(ValueTuple<int, int, string>), TypeNameAssemblyFormatHandling.Simple, null);
  69
  70            ValueTuple<int, int, string> t = ValueTuple.Create(1, 2, "string");
  71
  72            string json = JsonConvert.SerializeObject(t, Formatting.Indented, new JsonSerializerSettings
  73            {
  74                TypeNameHandling = TypeNameHandling.All
  75            });
  76
  77            StringAssert.AreEqual(@"{
  78  ""$type"": """ + tupleRef + @""",
  79  ""Item1"": 1,
  80  ""Item2"": 2,
  81  ""Item3"": ""string""
  82}", json);
  83
  84            ValueTuple<int, int, string> t2 = (ValueTuple<int, int, string>)JsonConvert.DeserializeObject(json, new JsonSerializerSettings
  85            {
  86                TypeNameHandling = TypeNameHandling.All
  87            });
  88
  89            Assert.AreEqual(1, t2.Item1);
  90            Assert.AreEqual(2, t2.Item2);
  91            Assert.AreEqual("string", t2.Item3);
  92        }
  93#endif
  94
  95#if !(NET20 || NET35 || NET40)
  96        public class KnownAutoTypes
  97        {
  98            public ICollection<string> Collection { get; set; }
  99            public IList<string> List { get; set; }
 100            public IDictionary<string, string> Dictionary { get; set; }
 101            public ISet<string> Set { get; set; }
 102            public IReadOnlyCollection<string> ReadOnlyCollection { get; set; }
 103            public IReadOnlyList<string> ReadOnlyList { get; set; }
 104            public IReadOnlyDictionary<string, string> ReadOnlyDictionary { get; set; }
 105        }
 106
 107        [Test]
 108        public void KnownAutoTypesTest()
 109        {
 110            KnownAutoTypes c = new KnownAutoTypes
 111            {
 112                Collection = new List<string> { "Collection value!" },
 113                List = new List<string> { "List value!" },
 114                Dictionary = new Dictionary<string, string>
 115                {
 116                    { "Dictionary key!", "Dictionary value!" }
 117                },
 118                ReadOnlyCollection = new ReadOnlyCollection<string>(new[] { "Read Only Collection value!" }),
 119                ReadOnlyList = new ReadOnlyCollection<string>(new[] { "Read Only List value!" }),
 120                Set = new HashSet<string> { "Set value!" },
 121                ReadOnlyDictionary = new ReadOnlyDictionary<string, string>(new Dictionary<string, string>
 122                {
 123                    { "Read Only Dictionary key!", "Read Only Dictionary value!" }
 124                })
 125            };
 126
 127            string json = JsonConvert.SerializeObject(c, Formatting.Indented, new JsonSerializerSettings
 128            {
 129                TypeNameHandling = TypeNameHandling.Auto
 130            });
 131
 132            StringAssert.AreEqual(@"{
 133  ""Collection"": [
 134    ""Collection value!""
 135  ],
 136  ""List"": [
 137    ""List value!""
 138  ],
 139  ""Dictionary"": {
 140    ""Dictionary key!"": ""Dictionary value!""
 141  },
 142  ""Set"": [
 143    ""Set value!""
 144  ],
 145  ""ReadOnlyCollection"": [
 146    ""Read Only Collection value!""
 147  ],
 148  ""ReadOnlyList"": [
 149    ""Read Only List value!""
 150  ],
 151  ""ReadOnlyDictionary"": {
 152    ""Read Only Dictionary key!"": ""Read Only Dictionary value!""
 153  }
 154}", json);
 155        }
 156#endif
 157
 158        [Test]
 159        public void DictionaryAuto()
 160        {
 161            Dictionary<string, object> dic = new Dictionary<string, object>
 162            {
 163                { "movie", new Movie { Name = "Die Hard" } }
 164            };
 165
 166            string json = JsonConvert.SerializeObject(dic, Formatting.Indented, new JsonSerializerSettings
 167            {
 168                TypeNameHandling = TypeNameHandling.Auto
 169            });
 170
 171            StringAssert.AreEqual(@"{
 172  ""movie"": {
 173    ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Movie, Newtonsoft.Json.Tests"",
 174    ""Name"": ""Die Hard"",
 175    ""Description"": null,
 176    ""Classification"": null,
 177    ""Studio"": null,
 178    ""ReleaseDate"": null,
 179    ""ReleaseCountries"": null
 180  }
 181}", json);
 182        }
 183
 184        [Test]
 185        public void KeyValuePairAuto()
 186        {
 187            IList<KeyValuePair<string, object>> dic = new List<KeyValuePair<string, object>>
 188            {
 189                new KeyValuePair<string, object>("movie", new Movie { Name = "Die Hard" })
 190            };
 191
 192            string json = JsonConvert.SerializeObject(dic, Formatting.Indented, new JsonSerializerSettings
 193            {
 194                TypeNameHandling = TypeNameHandling.Auto
 195            });
 196
 197            StringAssert.AreEqual(@"[
 198  {
 199    ""Key"": ""movie"",
 200    ""Value"": {
 201      ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Movie, Newtonsoft.Json.Tests"",
 202      ""Name"": ""Die Hard"",
 203      ""Description"": null,
 204      ""Classification"": null,
 205      ""Studio"": null,
 206      ""ReleaseDate"": null,
 207      ""ReleaseCountries"": null
 208    }
 209  }
 210]", json);
 211        }
 212
 213        [Test]
 214        public void NestedValueObjects()
 215        {
 216            StringBuilder sb = new StringBuilder();
 217            for (int i = 0; i < 3; i++)
 218            {
 219                sb.Append(@"{""$value"":");
 220            }
 221
 222            ExceptionAssert.Throws<JsonSerializationException>(() =>
 223            {
 224                var reader = new JsonTextReader(new StringReader(sb.ToString()));
 225                var ser = new JsonSerializer();
 226                ser.MetadataPropertyHandling = MetadataPropertyHandling.Default;
 227                ser.Deserialize<sbyte>(reader);
 228            }, "Unexpected token when deserializing primitive value: StartObject. Path '$value', line 1, position 11.");
 229        }
 230
 231        [Test]
 232        public void SerializeRootTypeNameIfDerivedWithAuto()
 233        {
 234            var serializer = new JsonSerializer()
 235            {
 236                TypeNameHandling = TypeNameHandling.Auto
 237            };
 238            var sw = new StringWriter();
 239            serializer.Serialize(new JsonTextWriter(sw) { Formatting = Formatting.Indented }, new WagePerson(), typeof(Person));
 240            var result = sw.ToString();
 241
 242            StringAssert.AreEqual(@"{
 243  ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Organization.WagePerson, Newtonsoft.Json.Tests"",
 244  ""HourlyWage"": 0.0,
 245  ""Name"": null,
 246  ""BirthDate"": ""0001-01-01T00:00:00"",
 247  ""LastModified"": ""0001-01-01T00:00:00""
 248}", result);
 249
 250            Assert.IsTrue(result.Contains("WagePerson"));
 251            using (var rd = new JsonTextReader(new StringReader(result)))
 252            {
 253                var person = serializer.Deserialize<Person>(rd);
 254
 255                CustomAssert.IsInstanceOfType(typeof(WagePerson), person);
 256            }
 257        }
 258
 259        [Test]
 260        public void SerializeRootTypeNameAutoWithJsonConvert()
 261        {
 262            string json = JsonConvert.SerializeObject(new WagePerson(), typeof(object), Formatting.Indented, new JsonSerializerSettings
 263            {
 264                TypeNameHandling = TypeNameHandling.Auto
 265            });
 266
 267            StringAssert.AreEqual(@"{
 268  ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Organization.WagePerson, Newtonsoft.Json.Tests"",
 269  ""HourlyWage"": 0.0,
 270  ""Name"": null,
 271  ""BirthDate"": ""0001-01-01T00:00:00"",
 272  ""LastModified"": ""0001-01-01T00:00:00""
 273}", json);
 274        }
 275
 276        [Test]
 277        public void SerializeRootTypeNameAutoWithJsonConvert_Generic()
 278        {
 279            string json = JsonConvert.SerializeObject(new WagePerson(), typeof(object), Formatting.Indented, new JsonSerializerSettings
 280            {
 281                TypeNameHandling = TypeNameHandling.Auto
 282            });
 283
 284            StringAssert.AreEqual(@"{
 285  ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Organization.WagePerson, Newtonsoft.Json.Tests"",
 286  ""HourlyWage"": 0.0,
 287  ""Name"": null,
 288  ""BirthDate"": ""0001-01-01T00:00:00"",
 289  ""LastModified"": ""0001-01-01T00:00:00""
 290}", json);
 291        }
 292
 293        [Test]
 294        public void SerializeRootTypeNameAutoWithJsonConvert_Generic2()
 295        {
 296            string json = JsonConvert.SerializeObject(new WagePerson(), typeof(object), new JsonSerializerSettings
 297            {
 298                TypeNameHandling = TypeNameHandling.Auto
 299            });
 300
 301            StringAssert.AreEqual(@"{""$type"":""Newtonsoft.Json.Tests.TestObjects.Organization.WagePerson, Newtonsoft.Json.Tests"",""HourlyWage"":0.0,""Name"":null,""BirthDate"":""0001-01-01T00:00:00"",""LastModified"":""0001-01-01T00:00:00""}", json);
 302        }
 303
 304        public class Wrapper
 305        {
 306            public IList<EmployeeReference> Array { get; set; }
 307            public IDictionary<string, EmployeeReference> Dictionary { get; set; }
 308        }
 309
 310        [Test]
 311        public void SerializeWrapper()
 312        {
 313            Wrapper wrapper = new Wrapper();
 314            wrapper.Array = new List<EmployeeReference>
 315            {
 316                new EmployeeReference()
 317            };
 318            wrapper.Dictionary = new Dictionary<string, EmployeeReference>
 319            {
 320                { "First", new EmployeeReference() }
 321            };
 322
 323            string json = JsonConvert.SerializeObject(wrapper, Formatting.Indented, new JsonSerializerSettings
 324            {
 325                TypeNameHandling = TypeNameHandling.Auto
 326            });
 327
 328            StringAssert.AreEqual(@"{
 329  ""Array"": [
 330    {
 331      ""$id"": ""1"",
 332      ""Name"": null,
 333      ""Manager"": null
 334    }
 335  ],
 336  ""Dictionary"": {
 337    ""First"": {
 338      ""$id"": ""2"",
 339      ""Name"": null,
 340      ""Manager"": null
 341    }
 342  }
 343}", json);
 344
 345            Wrapper w2 = JsonConvert.DeserializeObject<Wrapper>(json);
 346            CustomAssert.IsInstanceOfType(typeof(List<EmployeeReference>), w2.Array);
 347            CustomAssert.IsInstanceOfType(typeof(Dictionary<string, EmployeeReference>), w2.Dictionary);
 348        }
 349
 350        [Test]
 351        public void WriteTypeNameForObjects()
 352        {
 353            string employeeRef = ReflectionUtils.GetTypeName(typeof(EmployeeReference), TypeNameAssemblyFormatHandling.Simple, null);
 354
 355            EmployeeReference employee = new EmployeeReference();
 356
 357            string json = JsonConvert.SerializeObject(employee, Formatting.Indented, new JsonSerializerSettings
 358            {
 359                TypeNameHandling = TypeNameHandling.Objects
 360            });
 361
 362            StringAssert.AreEqual(@"{
 363  ""$id"": ""1"",
 364  ""$type"": """ + employeeRef + @""",
 365  ""Name"": null,
 366  ""Manager"": null
 367}", json);
 368        }
 369
 370        [Test]
 371        public void DeserializeTypeName()
 372        {
 373            string employeeRef = ReflectionUtils.GetTypeName(typeof(EmployeeReference), TypeNameAssemblyFormatHandling.Simple, null);
 374
 375            string json = @"{
 376  ""$id"": ""1"",
 377  ""$type"": """ + employeeRef + @""",
 378  ""Name"": ""Name!"",
 379  ""Manager"": null
 380}";
 381
 382            object employee = JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings
 383            {
 384                TypeNameHandling = TypeNameHandling.Objects
 385            });
 386
 387            CustomAssert.IsInstanceOfType(typeof(EmployeeReference), employee);
 388            Assert.AreEqual("Name!", ((EmployeeReference)employee).Name);
 389        }
 390
 391#if !(PORTABLE || DNXCORE50)
 392        [Test]
 393        public void DeserializeTypeNameFromGacAssembly()
 394        {
 395            string cookieRef = ReflectionUtils.GetTypeName(typeof(Cookie), TypeNameAssemblyFormatHandling.Simple, null);
 396
 397            string json = @"{
 398  ""$id"": ""1"",
 399  ""$type"": """ + cookieRef + @"""
 400}";
 401
 402            object cookie = JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings
 403            {
 404                TypeNameHandling = TypeNameHandling.Objects
 405            });
 406
 407            CustomAssert.IsInstanceOfType(typeof(Cookie), cookie);
 408        }
 409#endif
 410
 411        [Test]
 412        public void SerializeGenericObjectListWithTypeName()
 413        {
 414            string employeeRef = typeof(EmployeeReference).AssemblyQualifiedName;
 415            string personRef = typeof(Person).AssemblyQualifiedName;
 416
 417            List<object> values = new List<object>
 418            {
 419                new EmployeeReference
 420                {
 421                    Name = "Bob",
 422                    Manager = new EmployeeReference { Name = "Frank" }
 423                },
 424                new Person
 425                {
 426                    Department = "Department",
 427                    BirthDate = new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc),
 428                    LastModified = new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc)
 429                },
 430                "String!",
 431                int.MinValue
 432            };
 433
 434            string json = JsonConvert.SerializeObject(values, Formatting.Indented, new JsonSerializerSettings
 435            {
 436                TypeNameHandling = TypeNameHandling.Objects,
 437#pragma warning disable 618
 438                TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
 439#pragma warning restore 618
 440            });
 441
 442            StringAssert.AreEqual(@"[
 443  {
 444    ""$id"": ""1"",
 445    ""$type"": """ + employeeRef + @""",
 446    ""Name"": ""Bob"",
 447    ""Manager"": {
 448      ""$id"": ""2"",
 449      ""$type"": """ + employeeRef + @""",
 450      ""Name"": ""Frank"",
 451      ""Manager"": null
 452    }
 453  },
 454  {
 455    ""$type"": """ + personRef + @""",
 456    ""Name"": null,
 457    ""BirthDate"": ""2000-12-30T00:00:00Z"",
 458    ""LastModified"": ""2000-12-30T00:00:00Z""
 459  },
 460  ""String!"",
 461  -2147483648
 462]", json);
 463        }
 464
 465        [Test]
 466        public void DeserializeGenericObjectListWithTypeName()
 467        {
 468            string employeeRef = typeof(EmployeeReference).AssemblyQualifiedName;
 469            string personRef = typeof(Person).AssemblyQualifiedName;
 470
 471            string json = @"[
 472  {
 473    ""$id"": ""1"",
 474    ""$type"": """ + employeeRef + @""",
 475    ""Name"": ""Bob"",
 476    ""Manager"": {
 477      ""$id"": ""2"",
 478      ""$type"": """ + employeeRef + @""",
 479      ""Name"": ""Frank"",
 480      ""Manager"": null
 481    }
 482  },
 483  {
 484    ""$type"": """ + personRef + @""",
 485    ""Name"": null,
 486    ""BirthDate"": ""\/Date(978134400000)\/"",
 487    ""LastModified"": ""\/Date(978134400000)\/""
 488  },
 489  ""String!"",
 490  -2147483648
 491]";
 492
 493            List<object> values = (List<object>)JsonConvert.DeserializeObject(json, typeof(List<object>), new JsonSerializerSettings
 494            {
 495                TypeNameHandling = TypeNameHandling.Objects,
 496#pragma warning disable 618
 497                TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
 498#pragma warning restore 618
 499            });
 500
 501            Assert.AreEqual(4, values.Count);
 502
 503            EmployeeReference e = (EmployeeReference)values[0];
 504            Person p = (Person)values[1];
 505
 506            Assert.AreEqual("Bob", e.Name);
 507            Assert.AreEqual("Frank", e.Manager.Name);
 508
 509            Assert.AreEqual(null, p.Name);
 510            Assert.AreEqual(new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc), p.BirthDate);
 511            Assert.AreEqual(new DateTime(2000, 12, 30, 0, 0, 0, DateTimeKind.Utc), p.LastModified);
 512
 513            Assert.AreEqual("String!", values[2]);
 514            Assert.AreEqual((long)int.MinValue, values[3]);
 515        }
 516
 517        [Test]
 518        public void DeserializeWithBadTypeName()
 519        {
 520            string employeeRef = typeof(EmployeeReference).AssemblyQualifiedName;
 521            string personRef = typeof(Person).AssemblyQualifiedName;
 522
 523            string json = @"{
 524  ""$id"": ""1"",
 525  ""$type"": """ + employeeRef + @""",
 526  ""Name"": ""Name!"",
 527  ""Manager"": null
 528}";
 529
 530            try
 531            {
 532                JsonConvert.DeserializeObject(json, typeof(Person), new JsonSerializerSettings
 533                {
 534                    TypeNameHandling = TypeNameHandling.Objects,
 535#pragma warning disable 618
 536                    TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
 537#pragma warning restore 618
 538                });
 539            }
 540            catch (JsonSerializationException ex)
 541            {
 542                Assert.IsTrue(ex.Message.StartsWith(@"Type specified in JSON '" + employeeRef + @"' is not compatible with '" + personRef + @"'."));
 543            }
 544        }
 545
 546        [Test]
 547        public void DeserializeTypeNameWithNoTypeNameHandling()
 548        {
 549            string employeeRef = typeof(EmployeeReference).AssemblyQualifiedName;
 550
 551            string json = @"{
 552  ""$id"": ""1"",
 553  ""$type"": """ + employeeRef + @""",
 554  ""Name"": ""Name!"",
 555  ""Manager"": null
 556}";
 557
 558            JObject o = (JObject)JsonConvert.DeserializeObject(json);
 559
 560            StringAssert.AreEqual(@"{
 561  ""Name"": ""Name!"",
 562  ""Manager"": null
 563}", o.ToString());
 564        }
 565
 566        [Test]
 567        public void DeserializeTypeNameOnly()
 568        {
 569            string json = @"{
 570  ""$id"": ""1"",
 571  ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Employee"",
 572  ""Name"": ""Name!"",
 573  ""Manager"": null
 574}";
 575
 576            ExceptionAssert.Throws<JsonSerializationException>(() =>
 577            {
 578                JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings
 579                {
 580                    TypeNameHandling = TypeNameHandling.Objects
 581                });
 582            }, "Type specified in JSON 'Newtonsoft.Json.Tests.TestObjects.Employee' was not resolved. Path '$type', line 3, position 55.");
 583        }
 584
 585        public interface ICorrelatedMessage
 586        {
 587            string CorrelationId { get; set; }
 588        }
 589
 590        public class SendHttpRequest : ICorrelatedMessage
 591        {
 592            public SendHttpRequest()
 593            {
 594                RequestEncoding = "UTF-8";
 595                Method = "GET";
 596            }
 597
 598            public string Method { get; set; }
 599            public Dictionary<string, string> Headers { get; set; }
 600            public string Url { get; set; }
 601            public Dictionary<string, string> RequestData;
 602            public string RequestBodyText { get; set; }
 603            public string User { get; set; }
 604            public string Passwd { get; set; }
 605            public string RequestEncoding { get; set; }
 606            public string CorrelationId { get; set; }
 607        }
 608
 609        [Test]
 610        public void DeserializeGenericTypeName()
 611        {
 612            string typeName = typeof(SendHttpRequest).AssemblyQualifiedName;
 613
 614            string json = @"{
 615""$type"": """ + typeName + @""",
 616""RequestData"": {
 617""$type"": ""System.Collections.Generic.Dictionary`2[[System.String, mscorlib,Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"",
 618""Id"": ""siedemnaście"",
 619""X"": ""323""
 620},
 621""Method"": ""GET"",
 622""Url"": ""http://www.onet.pl"",
 623""RequestEncoding"": ""UTF-8"",
 624""CorrelationId"": ""xyz""
 625}";
 626
 627            ICorrelatedMessage message = JsonConvert.DeserializeObject<ICorrelatedMessage>(json, new JsonSerializerSettings
 628            {
 629                TypeNameHandling = TypeNameHandling.Objects,
 630#pragma warning disable 618
 631                TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
 632#pragma warning restore 618
 633            });
 634
 635            CustomAssert.IsInstanceOfType(typeof(SendHttpRequest), message);
 636
 637            SendHttpRequest request = (SendHttpRequest)message;
 638            Assert.AreEqual("xyz", request.CorrelationId);
 639            Assert.AreEqual(2, request.RequestData.Count);
 640            Assert.AreEqual("siedemnaście", request.RequestData["Id"]);
 641        }
 642
 643        [Test]
 644        public void SerializeObjectWithMultipleGenericLists()
 645        {
 646            string containerTypeName = typeof(Container).AssemblyQualifiedName;
 647            string productListTypeName = typeof(List<Product>).AssemblyQualifiedName;
 648
 649            Container container = new Container
 650            {
 651                In = new List<Product>(),
 652                Out = new List<Product>()
 653            };
 654
 655            string json = JsonConvert.SerializeObject(container, Formatting.Indented,
 656                new JsonSerializerSettings
 657                {
 658                    NullValueHandling = NullValueHandling.Ignore,
 659                    TypeNameHandling = TypeNameHandling.All,
 660#pragma warning disable 618
 661                    TypeNameAssemblyFormat = FormatterAssemblyStyle.Full
 662#pragma warning restore 618
 663                });
 664
 665            StringAssert.AreEqual(@"{
 666  ""$type"": """ + containerTypeName + @""",
 667  ""In"": {
 668    ""$type"": """ + productListTypeName + @""",
 669    ""$values"": []
 670  },
 671  ""Out"": {
 672    ""$type"": """ + productListTypeName + @""",
 673    ""$values"": []
 674  }
 675}", json);
 676        }
 677
 678        public class TypeNameProperty
 679        {
 680            public string Name { get; set; }
 681
 682            [JsonProperty(TypeNameHandling = TypeNameHandling.All)]
 683            public object Value { get; set; }
 684        }
 685
 686        [Test]
 687        public void WriteObjectTypeNameForProperty()
 688        {
 689            string typeNamePropertyRef = ReflectionUtils.GetTypeName(typeof(TypeNameProperty), TypeNameAssemblyFormatHandling.Simple, null);
 690
 691            TypeNameProperty typeNameProperty = new TypeNameProperty
 692            {
 693                Name = "Name!",
 694                Value = new TypeNameProperty
 695                {
 696                    Name = "Nested!"
 697                }
 698            };
 699
 700            string json = JsonConvert.SerializeObject(typeNameProperty, Formatting.Indented);
 701
 702            StringAssert.AreEqual(@"{
 703  ""Name"": ""Name!"",
 704  ""Value"": {
 705    ""$type"": """ + typeNamePropertyRef + @""",
 706    ""Name"": ""Nested!"",
 707    ""Value"": null
 708  }
 709}", json);
 710
 711            TypeNameProperty deserialized = JsonConvert.DeserializeObject<TypeNameProperty>(json);
 712            Assert.AreEqual("Name!", deserialized.Name);
 713            CustomAssert.IsInstanceOfType(typeof(TypeNameProperty), deserialized.Value);
 714
 715            TypeNameProperty nested = (TypeNameProperty)deserialized.Value;
 716            Assert.AreEqual("Nested!", nested.Name);
 717            Assert.AreEqual(null, nested.Value);
 718        }
 719
 720        [Test]
 721        public void WriteListTypeNameForProperty()
 722        {
 723            string listRef = ReflectionUtils.GetTypeName(typeof(List<int>), TypeNameAssemblyFormatHandling.Simple, null);
 724
 725            TypeNameProperty typeNameProperty = new TypeNameProperty
 726            {
 727                Name = "Name!",
 728                Value = new List<int> { 1, 2, 3, 4, 5 }
 729            };
 730
 731            string json = JsonConvert.SerializeObject(typeNameProperty, Formatting.Indented);
 732
 733            StringAssert.AreEqual(@"{
 734  ""Name"": ""Name!"",
 735  ""Value"": {
 736    ""$type"": """ + listRef + @""",
 737    ""$values"": [
 738      1,
 739      2,
 740      3,
 741      4,
 742      5
 743    ]
 744  }
 745}", json);
 746
 747            TypeNameProperty deserialized = JsonConvert.DeserializeObject<TypeNameProperty>(json);
 748            Assert.AreEqual("Name!", deserialized.Name);
 749            CustomAssert.IsInstanceOfType(typeof(List<int>), deserialized.Value);
 750
 751            List<int> nested = (List<int>)deserialized.Value;
 752            Assert.AreEqual(5, nested.Count);
 753            Assert.AreEqual(1, nested[0]);
 754            Assert.AreEqual(2, nested[1]);
 755            Assert.AreEqual(3, nested[2]);
 756            Assert.AreEqual(4, nested[3]);
 757            Assert.AreEqual(5, nested[4]);
 758        }
 759
 760        [Test]
 761        public void DeserializeUsingCustomBinder()
 762        {
 763            string json = @"{
 764  ""$id"": ""1"",
 765  ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Employee"",
 766  ""Name"": ""Name!""
 767}";
 768
 769            object p = JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings
 770            {
 771                TypeNameHandling = TypeNameHandling.Objects,
 772#pragma warning disable CS0618 // Type or member is obsolete
 773                Binder = new CustomSerializationBinder()
 774#pragma warning restore CS0618 // Type or member is obsolete
 775            });
 776
 777            CustomAssert.IsInstanceOfType(typeof(Person), p);
 778
 779            Person person = (Person)p;
 780
 781            Assert.AreEqual("Name!", person.Name);
 782        }
 783
 784        public class CustomSerializationBinder : SerializationBinder
 785        {
 786            public override Type BindToType(string assemblyName, string typeName)
 787            {
 788                return typeof(Person);
 789            }
 790        }
 791
 792#if !(NET20 || NET35)
 793        [Test]
 794        public void SerializeUsingCustomBinder()
 795        {
 796            TypeNameSerializationBinder binder = new TypeNameSerializationBinder("Newtonsoft.Json.Tests.Serialization.{0}, Newtonsoft.Json.Tests");
 797
 798            IList<object> values = new List<object>
 799            {
 800                new Customer
 801                {
 802                    Name = "Caroline Customer"
 803                },
 804                new Purchase
 805                {
 806                    ProductName = "Elbow Grease",
 807                    Price = 5.99m,
 808                    Quantity = 1
 809                }
 810            };
 811
 812            string json = JsonConvert.SerializeObject(values, Formatting.Indented, new JsonSerializerSettings
 813            {
 814                TypeNameHandling = TypeNameHandling.Auto,
 815#pragma warning disable CS0618 // Type or member is obsolete
 816                Binder = binder
 817#pragma warning restore CS0618 // Type or member is obsolete
 818            });
 819
 820            //[
 821            //  {
 822            //    "$type": "Customer",
 823            //    "Name": "Caroline Customer"
 824            //  },
 825            //  {
 826            //    "$type": "Purchase",
 827            //    "ProductName": "Elbow Grease",
 828            //    "Price": 5.99,
 829            //    "Quantity": 1
 830            //  }
 831            //]
 832
 833            StringAssert.AreEqual(@"[
 834  {
 835    ""$type"": ""Customer"",
 836    ""Name"": ""Caroline Customer""
 837  },
 838  {
 839    ""$type"": ""Purchase"",
 840    ""ProductName"": ""Elbow Grease"",
 841    ""Price"": 5.99,
 842    ""Quantity"": 1
 843  }
 844]", json);
 845
 846            IList<object> newValues = JsonConvert.DeserializeObject<IList<object>>(json, new JsonSerializerSettings
 847            {
 848                TypeNameHandling = TypeNameHandling.Auto,
 849#pragma warning disable CS0618 // Type or member is obsolete
 850                Binder = new TypeNameSerializationBinder("Newtonsoft.Json.Tests.Serialization.{0}, Newtonsoft.Json.Tests")
 851#pragma warning restore CS0618 // Type or member is obsolete
 852            });
 853
 854            CustomAssert.IsInstanceOfType(typeof(Customer), newValues[0]);
 855            Customer customer = (Customer)newValues[0];
 856            Assert.AreEqual("Caroline Customer", customer.Name);
 857
 858            CustomAssert.IsInstanceOfType(typeof(Purchase), newValues[1]);
 859            Purchase purchase = (Purchase)newValues[1];
 860            Assert.AreEqual("Elbow Grease", purchase.ProductName);
 861        }
 862
 863        public class TypeNameSerializationBinder : SerializationBinder
 864        {
 865            public string TypeFormat { get; private set; }
 866
 867            public TypeNameSerializationBinder(string typeFormat)
 868            {
 869                TypeFormat = typeFormat;
 870            }
 871
 872            public override void BindToName(Type serializedType, out string assemblyName, out string typeName)
 873            {
 874                assemblyName = null;
 875                typeName = serializedType.Name;
 876            }
 877
 878            public override Type BindToType(string assemblyName, string typeName)
 879            {
 880                string resolvedTypeName = string.Format(TypeFormat, typeName);
 881
 882                return Type.GetType(resolvedTypeName, true);
 883            }
 884        }
 885#endif
 886
 887        [Test]
 888        public void NewSerializeUsingCustomBinder()
 889        {
 890            NewTypeNameSerializationBinder binder = new NewTypeNameSerializationBinder("Newtonsoft.Json.Tests.Serialization.{0}, Newtonsoft.Json.Tests");
 891
 892            IList<object> values = new List<object>
 893            {
 894                new Customer
 895                {
 896                    Name = "Caroline Customer"
 897                },
 898                new Purchase
 899                {
 900                    ProductName = "Elbow Grease",
 901                    Price = 5.99m,
 902                    Quantity = 1
 903                }
 904            };
 905
 906            string json = JsonConvert.SerializeObject(values, Formatting.Indented, new JsonSerializerSettings
 907            {
 908                TypeNameHandling = TypeNameHandling.Auto,
 909                SerializationBinder = binder
 910            });
 911
 912            //[
 913            //  {
 914            //    "$type": "Customer",
 915            //    "Name": "Caroline Customer"
 916            //  },
 917            //  {
 918            //    "$type": "Purchase",
 919            //    "ProductName": "Elbow Grease",
 920            //    "Price": 5.99,
 921            //    "Quantity": 1
 922            //  }
 923            //]
 924
 925            StringAssert.AreEqual(@"[
 926  {
 927    ""$type"": ""Customer"",
 928    ""Name"": ""Caroline Customer""
 929  },
 930  {
 931    ""$type"": ""Purchase"",
 932    ""ProductName"": ""Elbow Grease"",
 933    ""Price"": 5.99,
 934    ""Quantity"": 1
 935  }
 936]", json);
 937
 938            IList<object> newValues = JsonConvert.DeserializeObject<IList<object>>(json, new JsonSerializerSettings
 939            {
 940                TypeNameHandling = TypeNameHandling.Auto,
 941                SerializationBinder = new NewTypeNameSerializationBinder("Newtonsoft.Json.Tests.Serialization.{0}, Newtonsoft.Json.Tests")
 942            });
 943
 944            CustomAssert.IsInstanceOfType(typeof(Customer), newValues[0]);
 945            Customer customer = (Customer)newValues[0];
 946            Assert.AreEqual("Caroline Customer", customer.Name);
 947
 948            CustomAssert.IsInstanceOfType(typeof(Purchase), newValues[1]);
 949            Purchase purchase = (Purchase)newValues[1];
 950            Assert.AreEqual("Elbow Grease", purchase.ProductName);
 951        }
 952
 953        public class NewTypeNameSerializationBinder : ISerializationBinder
 954        {
 955            public string TypeFormat { get; private set; }
 956
 957            public NewTypeNameSerializationBinder(string typeFormat)
 958            {
 959                TypeFormat = typeFormat;
 960            }
 961
 962            public void BindToName(Type serializedType, out string assemblyName, out string typeName)
 963            {
 964                assemblyName = null;
 965                typeName = serializedType.Name;
 966            }
 967
 968            public Type BindToType(string assemblyName, string typeName)
 969            {
 970                string resolvedTypeName = string.Format(TypeFormat, typeName);
 971
 972                return Type.GetType(resolvedTypeName, true);
 973            }
 974        }
 975
 976        [Test]
 977        public void CollectionWithAbstractItems()
 978        {
 979            HolderClass testObject = new HolderClass();
 980            testObject.TestMember = new ContentSubClass("First One");
 981            testObject.AnotherTestMember = new Dictionary<int, IList<ContentBaseClass>>();
 982            testObject.AnotherTestMember.Add(1, new List<ContentBaseClass>());
 983            testObject.AnotherTestMember[1].Add(new ContentSubClass("Second One"));
 984            testObject.AThirdTestMember = new ContentSubClass("Third One");
 985
 986            JsonSerializer serializingTester = new JsonSerializer();
 987            serializingTester.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
 988
 989            StringWriter sw = new StringWriter();
 990            using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
 991            {
 992                jsonWriter.Formatting = Formatting.Indented;
 993                serializingTester.TypeNameHandling = TypeNameHandling.Auto;
 994                serializingTester.Serialize(jsonWriter, testObject);
 995            }
 996
 997            string json = sw.ToString();
 998
 999            string contentSubClassRef = ReflectionUtils.GetTypeName(typeof(ContentSubClass), TypeNameAssemblyFormatHandling.Simple, null);
1000            string dictionaryRef = ReflectionUtils.GetTypeName(typeof(Dictionary<int, IList<ContentBaseClass>>), TypeNameAssemblyFormatHandling.Simple, null);
1001            string listRef = ReflectionUtils.GetTypeName(typeof(List<ContentBaseClass>), TypeNameAssemblyFormatHandling.Simple, null);
1002
1003            string expected = @"{
1004  ""TestMember"": {
1005    ""$type"": """ + contentSubClassRef + @""",
1006    ""SomeString"": ""First One""
1007  },
1008  ""AnotherTestMember"": {
1009    ""$type"": """ + dictionaryRef + @""",
1010    ""1"": [
1011      {
1012        ""$type"": """ + contentSubClassRef + @""",
1013        ""SomeString"": ""Second One""
1014      }
1015    ]
1016  },
1017  ""AThirdTestMember"": {
1018    ""$type"": """ + contentSubClassRef + @""",
1019    ""SomeString"": ""Third One""
1020  }
1021}";
1022
1023            StringAssert.AreEqual(expected, json);
1024
1025            StringReader sr = new StringReader(json);
1026
1027            JsonSerializer deserializingTester = new JsonSerializer();
1028
1029            HolderClass anotherTestObject;
1030
1031            using (JsonTextReader jsonReader = new JsonTextReader(sr))
1032            {
1033                deserializingTester.TypeNameHandling = TypeNameHandling.Auto;
1034
1035                anotherTestObject = deserializingTester.Deserialize<HolderClass>(jsonReader);
1036            }
1037
1038            Assert.IsNotNull(anotherTestObject);
1039            CustomAssert.IsInstanceOfType(typeof(ContentSubClass), anotherTestObject.TestMember);
1040            CustomAssert.IsInstanceOfType(typeof(Dictionary<int, IList<ContentBaseClass>>), anotherTestObject.AnotherTestMember);
1041            Assert.AreEqual(1, anotherTestObject.AnotherTestMember.Count);
1042
1043            IList<ContentBaseClass> list = anotherTestObject.AnotherTestMember[1];
1044
1045            CustomAssert.IsInstanceOfType(typeof(List<ContentBaseClass>), list);
1046            Assert.AreEqual(1, list.Count);
1047            CustomAssert.IsInstanceOfType(typeof(ContentSubClass), list[0]);
1048        }
1049
1050        [Test]
1051        public void WriteObjectTypeNameForPropertyDemo()
1052        {
1053            Message message = new Message();
1054            message.Address = "http://www.google.com";
1055            message.Body = new SearchDetails
1056            {
1057                Query = "Json.NET",
1058                Language = "en-us"
1059            };
1060
1061            string json = JsonConvert.SerializeObject(message, Formatting.Indented);
1062            // {
1063            //   "Address": "http://www.google.com",
1064            //   "Body": {
1065            //     "$type": "Newtonsoft.Json.Tests.Serialization.SearchDetails, Newtonsoft.Json.Tests",
1066            //     "Query": "Json.NET",
1067            //     "Language": "en-us"
1068            //   }
1069            // }
1070
1071            Message deserialized = JsonConvert.DeserializeObject<Message>(json);
1072
1073            SearchDetails searchDetails = (SearchDetails)deserialized.Body;
1074            // Json.NET
1075        }
1076
1077        public class UrlStatus
1078        {
1079            public int Status { get; set; }
1080            public string Url { get; set; }
1081        }
1082
1083        [Test]
1084        public void GenericDictionaryObject()
1085        {
1086            Dictionary<string, object> collection = new Dictionary<string, object>()
1087            {
1088                { "First", new UrlStatus { Status = 404, Url = @"http://www.bing.com" } },
1089                { "Second", new UrlStatus { Status = 400, Url = @"http://www.google.com" } },
1090                {
1091                    "List", new List<UrlStatus>
1092                    {
1093                        new UrlStatus { Status = 300, Url = @"http://www.yahoo.com" },
1094                        new UrlStatus { Status = 200, Url = @"http://www.askjeeves.com" }
1095                    }
1096                }
1097            };
1098
1099            string json = JsonConvert.SerializeObject(collection, Formatting.Indented, new JsonSerializerSettings
1100            {
1101                TypeNameHandling = TypeNameHandling.All,
1102#pragma warning disable 618
1103                TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple
1104#pragma warning restore 618
1105            });
1106
1107            string urlStatusTypeName = ReflectionUtils.GetTypeName(typeof(UrlStatus), TypeNameAssemblyFormatHandling.Simple, null);
1108
1109            StringAssert.AreEqual(@"{
1110  ""$type"": ""System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Object, mscorlib]], mscorlib"",
1111  ""First"": {
1112    ""$type"": """ + urlStatusTypeName + @""",
1113    ""Status"": 404,
1114    ""Url"": ""http://www.bing.com""
1115  },
1116  ""Second"": {
1117    ""$type"": """ + urlStatusTypeName + @""",
1118    ""Status"": 400,
1119    ""Url"": ""http://www.google.com""
1120  },
1121  ""List"": {
1122    ""$type"": ""System.Collections.Generic.List`1[[" + urlStatusTypeName + @"]], mscorlib"",
1123    ""$values"": [
1124      {
1125        ""$type"": """ + urlStatusTypeName + @""",
1126        ""Status"": 300,
1127        ""Url"": ""http://www.yahoo.com""
1128      },
1129      {
1130        ""$type"": """ + urlStatusTypeName + @""",
1131        ""Status"": 200,
1132        ""Url"": ""http://www.askjeeves.com""
1133      }
1134    ]
1135  }
1136}", json);
1137
1138            object c = JsonConvert.DeserializeObject(json, new JsonSerializerSettings
1139            {
1140                TypeNameHandling = TypeNameHandling.All,
1141#pragma warning disable 618
1142                TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple
1143#pragma warning restore 618
1144            });
1145
1146            CustomAssert.IsInstanceOfType(typeof(Dictionary<string, object>), c);
1147
1148            Dictionary<string, object> newCollection = (Dictionary<string, object>)c;
1149            Assert.AreEqual(3, newCollection.Count);
1150            Assert.AreEqual(@"http://www.bing.com", ((UrlStatus)newCollection["First"]).Url);
1151
1152            List<UrlStatus> statues = (List<UrlStatus>)newCollection["List"];
1153            Assert.AreEqual(2, statues.Count);
1154        }
1155
1156        [Test]
1157        public void SerializingIEnumerableOfTShouldRetainGenericTypeInfo()
1158        {
1159            string productClassRef = ReflectionUtils.GetTypeName(typeof(CustomEnumerable<Product>), TypeNameAssemblyFormatHandling.Simple, null);
1160
1161            CustomEnumerable<Product> products = new CustomEnumerable<Product>();
1162
1163            string json = JsonConvert.SerializeObject(products, Formatting.Indented, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All });
1164
1165            StringAssert.AreEqual(@"{
1166  ""$type"": """ + productClassRef + @""",
1167  ""$values"": []
1168}", json);
1169        }
1170
1171        public class CustomEnumerable<T> : IEnumerable<T>
1172        {
1173            //NOTE: a simple linked list
1174            private readonly T value;
1175            private readonly CustomEnumerable<T> next;
1176            private readonly int count;
1177
1178            private CustomEnumerable(T value, CustomEnumerable<T> next)
1179            {
1180                this.value = value;
1181                this.next = next;
1182                count = this.next.count + 1;
1183            }
1184
1185            public CustomEnumerable()
1186            {
1187                count = 0;
1188            }
1189
1190            public CustomEnumerable<T> AddFirst(T newVal)
1191            {
1192                return new CustomEnumerable<T>(newVal, this);
1193            }
1194
1195            public IEnumerator<T> GetEnumerator()
1196            {
1197                if (count == 0) // last node
1198                {
1199                    yield break;
1200                }
1201                yield return value;
1202
1203                var nextInLine = next;
1204                while (nextInLine != null)
1205                {
1206                    if (nextInLine.count != 0)
1207                    {
1208                        yield return nextInLine.value;
1209                    }
1210                    nextInLine = nextInLine.next;
1211                }
1212            }
1213
1214            IEnumerator IEnumerable.GetEnumerator()
1215            {
1216                return GetEnumerator();
1217            }
1218        }
1219
1220        public class Car
1221        {
1222            // included in JSON
1223            public string Model { get; set; }
1224            public DateTime Year { get; set; }
1225            public List<string> Features { get; set; }
1226            public object[] Objects { get; set; }
1227
1228            // ignored
1229            [JsonIgnore]
1230            public DateTime LastModified { get; set; }
1231        }
1232
1233        [Test]
1234        public void ByteArrays()
1235        {
1236            Car testerObject = new Car();
1237            testerObject.Year = new DateTime(2000, 10, 5, 1, 1, 1, DateTimeKind.Utc);
1238            byte[] data = new byte[] { 75, 65, 82, 73, 82, 65 };
1239            testerObject.Objects = new object[] { data, "prueba" };
1240
1241            JsonSerializerSettings jsonSettings = new JsonSerializerSettings();
1242            jsonSettings.NullValueHandling = NullValueHandling.Ignore;
1243            jsonSettings.TypeNameHandling = TypeNameHandling.All;
1244
1245            string output = JsonConvert.SerializeObject(testerObject, Formatting.Indented, jsonSettings);
1246
1247            string carClassRef = ReflectionUtils.GetTypeName(typeof(Car), TypeNameAssemblyFormatHandling.Simple, null);
1248
1249            StringAssert.AreEqual(output, @"{
1250  ""$type"": """ + carClassRef + @""",
1251  ""Year"": ""2000-10-05T01:01:01Z"",
1252  ""Objects"": {
1253    ""$type"": ""System.Object[], mscorlib"",
1254    ""$values"": [
1255      {
1256        ""$type"": ""System.Byte[], mscorlib"",
1257        ""$value"": ""S0FSSVJB""
1258      },
1259      ""prueba""
1260    ]
1261  }
1262}");
1263            Car obj = JsonConvert.DeserializeObject<Car>(output, jsonSettings);
1264
1265            Assert.IsNotNull(obj);
1266
1267            Assert.IsTrue(obj.Objects[0] is byte[]);
1268
1269            byte[] d = (byte[])obj.Objects[0];
1270            CollectionAssert.AreEquivalent(data, d);
1271        }
1272
1273#if !(DNXCORE50)
1274        [Test]
1275        public void ISerializableTypeNameHandlingTest()
1276        {
1277            //Create an instance of our example type
1278            IExample e = new Example("Rob");
1279
1280            SerializableWrapper w = new SerializableWrapper
1281            {
1282                Content = e
1283            };
1284
1285            //Test Binary Serialization Round Trip
1286            //This will work find because the Binary Formatter serializes type names
1287            //this.TestBinarySerializationRoundTrip(e);
1288
1289            //Test Json Serialization
1290            //This fails because the JsonSerializer doesn't serialize type names correctly for ISerializable objects
1291            //Type Names should be serialized for All, Auto and Object modes
1292            TestJsonSerializationRoundTrip(w, TypeNameHandling.All);
1293            TestJsonSerializationRoundTrip(w, TypeNameHandling.Auto);
1294            TestJsonSerializationRoundTrip(w, TypeNameHandling.Objects);
1295        }
1296
1297        private void TestJsonSerializationRoundTrip(SerializableWrapper e, TypeNameHandling flag)
1298        {
1299            StringWriter writer = new StringWriter();
1300
1301            //Create our serializer and set Type Name Handling appropriately
1302            JsonSerializer serializer = new JsonSerializer();
1303            serializer.TypeNameHandling = flag;
1304
1305            //Do the actual serialization and dump to Console for inspection
1306            serializer.Serialize(new JsonTextWriter(writer), e);
1307
1308            //Now try to deserialize
1309            //Json.Net will cause an error here as it will try and instantiate
1310            //the interface directly because it failed to respect the
1311            //TypeNameHandling property on serialization
1312            SerializableWrapper f = serializer.Deserialize<SerializableWrapper>(new JsonTextReader(new StringReader(writer.ToString())));
1313
1314            //Check Round Trip
1315            Assert.AreEqual(e, f, "Objects should be equal after round trip json serialization");
1316        }
1317#endif
1318
1319#if !(NET20 || NET35)
1320        [Test]
1321        public void SerializationBinderWithFullName()
1322        {
1323            Message message = new Message
1324            {
1325                Address = "jamesnk@testtown.com",
1326                Body = new Version(1, 2, 3, 4)
1327            };
1328
1329            string json = JsonConvert.SerializeObject(message, Formatting.Indented, new JsonSerializerSettings
1330            {
1331                TypeNameHandling = TypeNameHandling.All,
1332#pragma warning disable CS0618 // Type or member is obsolete
1333                TypeNameAssemblyFormat = FormatterAssemblyStyle.Full,
1334                Binder = new MetroBinder(),
1335#pragma warning restore CS0618 // Type or member is obsolete
1336                ContractResolver = new DefaultContractResolver
1337                {
1338#if !(PORTABLE || DNXCORE50)
1339                    IgnoreSerializableAttribute = true
1340#endif
1341                }
1342            });
1343
1344            StringAssert.AreEqual(@"{
1345  ""$type"": "":::MESSAGE:::, AssemblyName"",
1346  ""Address"": ""jamesnk@testtown.com"",
1347  ""Body"": {
1348    ""$type"": "":::VERSION:::, AssemblyName"",
1349    ""Major"": 1,
1350    ""Minor"": 2,
1351    ""Build"": 3,
1352    ""Revision"": 4,
1353    ""MajorRevision"": 0,
1354    ""MinorRevision"": 4
1355  }
1356}", json);
1357        }
1358
1359        public class MetroBinder : SerializationBinder
1360        {
1361            public override Type BindToType(string assemblyName, string typeName)
1362            {
1363                return null;
1364            }
1365
1366            public override void BindToName(Type serializedType, out string assemblyName, out string typeName)
1367            {
1368                assemblyName = "AssemblyName";
1369#if !(DNXCORE50)
1370                typeName = ":::" + serializedType.Name.ToUpper(CultureInfo.InvariantCulture) + ":::";
1371#else
1372                typeName = ":::" + serializedType.Name.ToUpper() + ":::";
1373#endif
1374            }
1375        }
1376#endif
1377
1378        [Test]
1379        public void TypeNameIntList()
1380        {
1381            TypeNameList<int> l = new TypeNameList<int>();
1382            l.Add(1);
1383            l.Add(2);
1384            l.Add(3);
1385
1386            string json = JsonConvert.SerializeObject(l, Formatting.Indented);
1387            StringAssert.AreEqual(@"[
1388  1,
1389  2,
1390  3
1391]", json);
1392        }
1393
1394        [Test]
1395        public void TypeNameComponentList()
1396        {
1397            var c1 = new TestComponentSimple();
1398
1399            TypeNameList<object> l = new TypeNameList<object>();
1400            l.Add(c1);
1401            l.Add(new Employee
1402            {
1403                BirthDate = new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc),
1404                Department = "Department!"
1405            });
1406            l.Add("String!");
1407            l.Add(long.MaxValue);
1408
1409            string json = JsonConvert.SerializeObject(l, Formatting.Indented);
1410            StringAssert.AreEqual(@"[
1411  {
1412    ""$type"": ""Newtonsoft.Json.Tests.TestObjects.TestComponentSimple, Newtonsoft.Json.Tests"",
1413    ""MyProperty"": 0
1414  },
1415  {
1416    ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Organization.Employee, Newtonsoft.Json.Tests"",
1417    ""FirstName"": null,
1418    ""LastName"": null,
1419    ""BirthDate"": ""2000-12-12T12:12:12Z"",
1420    ""Department"": ""Department!"",
1421    ""JobTitle"": null
1422  },
1423  ""String!"",
1424  9223372036854775807
1425]", json);
1426
1427            TypeNameList<object> l2 = JsonConvert.DeserializeObject<TypeNameList<object>>(json);
1428            Assert.AreEqual(4, l2.Count);
1429
1430            CustomAssert.IsInstanceOfType(typeof(TestComponentSimple), l2[0]);
1431            CustomAssert.IsInstanceOfType(typeof(Employee), l2[1]);
1432            CustomAssert.IsInstanceOfType(typeof(string), l2[2]);
1433            CustomAssert.IsInstanceOfType(typeof(long), l2[3]);
1434        }
1435
1436        [Test]
1437        public void TypeNameDictionary()
1438        {
1439            TypeNameDictionary<object> l = new TypeNameDictionary<object>();
1440            l.Add("First", new TestComponentSimple { MyProperty = 1 });
1441            l.Add("Second", "String!");
1442            l.Add("Third", long.MaxValue);
1443
1444            string json = JsonConvert.SerializeObject(l, Formatting.Indented);
1445            StringAssert.AreEqual(@"{
1446  ""First"": {
1447    ""$type"": ""Newtonsoft.Json.Tests.TestObjects.TestComponentSimple, Newtonsoft.Json.Tests"",
1448    ""MyProperty"": 1
1449  },
1450  ""Second"": ""String!"",
1451  ""Third"": 9223372036854775807
1452}", json);
1453
1454            TypeNameDictionary<object> l2 = JsonConvert.DeserializeObject<TypeNameDictionary<object>>(json);
1455            Assert.AreEqual(3, l2.Count);
1456
1457            CustomAssert.IsInstanceOfType(typeof(TestComponentSimple), l2["First"]);
1458            Assert.AreEqual(1, ((TestComponentSimple)l2["First"]).MyProperty);
1459            CustomAssert.IsInstanceOfType(typeof(string), l2["Second"]);
1460            CustomAssert.IsInstanceOfType(typeof(long), l2["Third"]);
1461        }
1462
1463        [Test]
1464        public void TypeNameObjectItems()
1465        {
1466            TypeNameObject o1 = new TypeNameObject();
1467
1468            o1.Object1 = new TestComponentSimple { MyProperty = 1 };
1469            o1.Object2 = 123;
1470            o1.ObjectNotHandled = new TestComponentSimple { MyProperty = int.MaxValue };
1471            o1.String = "String!";
1472            o1.Integer = int.MaxValue;
1473
1474            string json = JsonConvert.SerializeObject(

Large files files are truncated, but you can click here to view the full file