PageRenderTime 105ms CodeModel.GetById 8ms app.highlight 70ms RepoModel.GetById 1ms app.codeStats 3ms

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

https://github.com/99strong99/Newtonsoft.Json
C# | 10919 lines | 9618 code | 1115 blank | 186 comment | 90 complexity | 81370c05b63ccbc8000265efea61c55d 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
  26using System;
  27using System.ComponentModel;
  28#if !(NET35 || NET20)
  29using System.Collections.Concurrent;
  30#endif
  31using System.Collections.Generic;
  32#if !(NET20 || NET35 || PORTABLE)
  33using System.Numerics;
  34#endif
  35#if !NET20 && !NETFX_CORE
  36using System.ComponentModel.DataAnnotations;
  37using System.Configuration;
  38using System.Runtime.CompilerServices;
  39using System.Runtime.Serialization.Formatters;
  40using System.Threading;
  41using System.Web.Script.Serialization;
  42#endif
  43using System.Text;
  44using System.Text.RegularExpressions;
  45#if !NETFX_CORE
  46using NUnit.Framework;
  47#else
  48using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
  49using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute;
  50using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute;
  51#endif
  52using Newtonsoft.Json;
  53using System.IO;
  54using System.Collections;
  55using System.Xml;
  56using System.Xml.Serialization;
  57using System.Collections.ObjectModel;
  58using Newtonsoft.Json.Bson;
  59using Newtonsoft.Json.Linq;
  60using Newtonsoft.Json.Converters;
  61#if !NET20
  62using System.Runtime.Serialization.Json;
  63#endif
  64using Newtonsoft.Json.Serialization;
  65using Newtonsoft.Json.Tests.Linq;
  66using Newtonsoft.Json.Tests.TestObjects;
  67using System.Runtime.Serialization;
  68using System.Globalization;
  69using Newtonsoft.Json.Utilities;
  70using System.Reflection;
  71#if !NET20
  72using System.Xml.Linq;
  73using System.Collections.Specialized;
  74using System.Linq.Expressions;
  75#endif
  76#if !(NET35 || NET20)
  77using System.Dynamic;
  78#endif
  79#if NET20
  80using Newtonsoft.Json.Utilities.LinqBridge;
  81#else
  82using System.Linq;
  83#endif
  84#if !(NETFX_CORE)
  85using System.Drawing;
  86using System.Diagnostics;
  87#endif
  88
  89namespace Newtonsoft.Json.Tests.Serialization
  90{
  91    [TestFixture]
  92    public class JsonSerializerTest : TestFixtureBase
  93    {
  94        [Test]
  95        public void ExtensionDataWithNull()
  96        {
  97            string json = @"{
  98              'TaxRate': 0.125,
  99              'a':null
 100            }";
 101
 102            var invoice = JsonConvert.DeserializeObject<ExtendedObject>(json);
 103
 104            Assert.AreEqual(JTokenType.Null, invoice._additionalData["a"].Type);
 105            Assert.AreEqual(typeof(double), ((JValue)invoice._additionalData["TaxRate"]).Value.GetType());
 106
 107            string result = JsonConvert.SerializeObject(invoice);
 108
 109            Assert.AreEqual(@"{""TaxRate"":0.125,""a"":null}", result);
 110        }
 111
 112        [Test]
 113        public void ExtensionDataFloatParseHandling()
 114        {
 115            string json = @"{
 116              'TaxRate': 0.125,
 117              'a':null
 118            }";
 119
 120            var invoice = JsonConvert.DeserializeObject<ExtendedObject>(json, new JsonSerializerSettings
 121            {
 122                FloatParseHandling = FloatParseHandling.Decimal
 123            });
 124
 125            Assert.AreEqual(typeof(decimal), ((JValue)invoice._additionalData["TaxRate"]).Value.GetType());
 126        }
 127
 128#pragma warning disable 649
 129        class ExtendedObject
 130        {
 131            [JsonExtensionData]
 132            internal IDictionary<string, JToken> _additionalData;
 133        }
 134#pragma warning restore 649
 135
 136        public class GenericItem<T>
 137        {
 138            public T Value { get; set; }
 139        }
 140
 141        public class NonGenericItem : GenericItem<string>
 142        {
 143        }
 144
 145        public class GenericClass<T, TValue> : IEnumerable<T>
 146            where T : GenericItem<TValue>, new()
 147        {
 148            public IList<T> Items { get; set; }
 149
 150            public GenericClass()
 151            {
 152                Items = new List<T>();
 153            }
 154
 155            public IEnumerator<T> GetEnumerator()
 156            {
 157                if (Items != null)
 158                {
 159                    foreach (T item in Items)
 160                    {
 161                        yield return item;
 162                    }
 163                }
 164                else
 165                    yield break;
 166            }
 167
 168            IEnumerator IEnumerable.GetEnumerator()
 169            {
 170                return GetEnumerator();
 171            }
 172        }
 173
 174        public class NonGenericClass : GenericClass<GenericItem<string>, string>
 175        {
 176        }
 177
 178#pragma warning disable 169
 179        public class CustomerInvoice
 180        {
 181            // we're only modifing the tax rate
 182            public decimal TaxRate { get; set; }
 183
 184            // everything else gets stored here
 185            [JsonExtensionData]
 186            private IDictionary<string, JToken> _additionalData;
 187        }
 188#pragma warning restore 169
 189
 190        [Test]
 191        public void ExtensionDataExample()
 192        {
 193            string json = @"{
 194        'HourlyRate': 150,
 195        'Hours': 40,
 196        'TaxRate': 0.125
 197      }";
 198
 199            var invoice = JsonConvert.DeserializeObject<CustomerInvoice>(json);
 200
 201            // increase tax to 15%
 202            invoice.TaxRate = 0.15m;
 203
 204            string result = JsonConvert.SerializeObject(invoice);
 205            // {
 206            //   'TaxRate': 0.15,
 207            //   'HourlyRate': 150,
 208            //   'Hours': 40
 209            // }
 210
 211            Assert.AreEqual(@"{""TaxRate"":0.15,""HourlyRate"":150,""Hours"":40}", result);
 212        }
 213
 214        public class ExtensionDataTestClass
 215        {
 216            public string Name { get; set; }
 217
 218            [JsonProperty("custom_name")]
 219            public string CustomName { get; set; }
 220
 221            [JsonIgnore]
 222            public IList<int> Ignored { get; set; }
 223
 224            public bool GetPrivate { get; internal set; }
 225
 226            public bool GetOnly
 227            {
 228                get { return true; }
 229            }
 230
 231            public readonly string Readonly = "Readonly";
 232            public IList<int> Ints { get; set; }
 233
 234            [JsonExtensionData]
 235            internal IDictionary<string, JToken> ExtensionData { get; set; }
 236
 237            public ExtensionDataTestClass()
 238            {
 239                Ints = new List<int> { 0 };
 240            }
 241        }
 242
 243        public class JObjectExtensionDataTestClass
 244        {
 245            public string Name { get; set; }
 246
 247            [JsonExtensionData]
 248            public JObject ExtensionData { get; set; }
 249        }
 250
 251        [Test]
 252        public void RoundTripJObjectExtensionData()
 253        {
 254            JObjectExtensionDataTestClass c = new JObjectExtensionDataTestClass();
 255            c.Name = "Name!";
 256            c.ExtensionData = new JObject
 257            {
 258                { "one", 1 },
 259                { "two", "II" },
 260                { "three", new JArray(1, 1, 1) }
 261            };
 262
 263            string json = JsonConvert.SerializeObject(c, Formatting.Indented);
 264
 265            JObjectExtensionDataTestClass c2 = JsonConvert.DeserializeObject<JObjectExtensionDataTestClass>(json);
 266
 267            Assert.AreEqual("Name!", c2.Name);
 268            Assert.IsTrue(JToken.DeepEquals(c.ExtensionData, c2.ExtensionData));
 269        }
 270
 271        public class BaseClass
 272        {
 273            internal bool IsTransient { get; set; }
 274        }
 275
 276        public class ChildClass : BaseClass
 277        {
 278            public new bool IsTransient { get; set; }
 279        }
 280
 281        [Test]
 282        public void NewProperty()
 283        {
 284            Assert.AreEqual(@"{""IsTransient"":true}", JsonConvert.SerializeObject(new ChildClass { IsTransient = true }));
 285
 286            var childClass = JsonConvert.DeserializeObject<ChildClass>(@"{""IsTransient"":true}");
 287            Assert.AreEqual(true, childClass.IsTransient);
 288        }
 289
 290        public class BaseClassVirtual
 291        {
 292            internal virtual bool IsTransient { get; set; }
 293        }
 294
 295        public class ChildClassVirtual : BaseClassVirtual
 296        {
 297            public virtual new bool IsTransient { get; set; }
 298        }
 299
 300        [Test]
 301        public void NewPropertyVirtual()
 302        {
 303            Assert.AreEqual(@"{""IsTransient"":true}", JsonConvert.SerializeObject(new ChildClassVirtual { IsTransient = true }));
 304
 305            var childClass = JsonConvert.DeserializeObject<ChildClassVirtual>(@"{""IsTransient"":true}");
 306            Assert.AreEqual(true, childClass.IsTransient);
 307        }
 308
 309        public class ResponseWithNewGenericProperty<T> : SimpleResponse
 310        {
 311            public new T Data { get; set; }
 312        }
 313
 314        public class ResponseWithNewGenericPropertyVirtual<T> : SimpleResponse
 315        {
 316            public virtual new T Data { get; set; }
 317        }
 318
 319        public class ResponseWithNewGenericPropertyOverride<T> : ResponseWithNewGenericPropertyVirtual<T>
 320        {
 321            public override T Data { get; set; }
 322        }
 323
 324        public abstract class SimpleResponse
 325        {
 326            public string Result { get; set; }
 327            public string Message { get; set; }
 328            public object Data { get; set; }
 329
 330            protected SimpleResponse()
 331            {
 332
 333            }
 334
 335            protected SimpleResponse(string message)
 336            {
 337                Message = message;
 338            }
 339        }
 340
 341        [Test]
 342        public void CanSerializeWithBuiltInTypeAsGenericArgument()
 343        {
 344            var input = new ResponseWithNewGenericProperty<int>()
 345            {
 346                Message = "Trying out integer as type parameter",
 347                Data = 25,
 348                Result = "This should be fine"
 349            };
 350
 351            var json = JsonConvert.SerializeObject(input);
 352            var deserialized = JsonConvert.DeserializeObject<ResponseWithNewGenericProperty<int>>(json);
 353
 354            Assert.AreEqual(input.Data, deserialized.Data);
 355            Assert.AreEqual(input.Message, deserialized.Message);
 356            Assert.AreEqual(input.Result, deserialized.Result);
 357        }
 358
 359        [Test]
 360        public void CanSerializeWithBuiltInTypeAsGenericArgumentVirtual()
 361        {
 362            var input = new ResponseWithNewGenericPropertyVirtual<int>()
 363            {
 364                Message = "Trying out integer as type parameter",
 365                Data = 25,
 366                Result = "This should be fine"
 367            };
 368
 369            var json = JsonConvert.SerializeObject(input);
 370            var deserialized = JsonConvert.DeserializeObject<ResponseWithNewGenericPropertyVirtual<int>>(json);
 371
 372            Assert.AreEqual(input.Data, deserialized.Data);
 373            Assert.AreEqual(input.Message, deserialized.Message);
 374            Assert.AreEqual(input.Result, deserialized.Result);
 375        }
 376
 377        [Test]
 378        public void CanSerializeWithBuiltInTypeAsGenericArgumentOverride()
 379        {
 380            var input = new ResponseWithNewGenericPropertyOverride<int>()
 381            {
 382                Message = "Trying out integer as type parameter",
 383                Data = 25,
 384                Result = "This should be fine"
 385            };
 386
 387            var json = JsonConvert.SerializeObject(input);
 388            var deserialized = JsonConvert.DeserializeObject<ResponseWithNewGenericPropertyOverride<int>>(json);
 389
 390            Assert.AreEqual(input.Data, deserialized.Data);
 391            Assert.AreEqual(input.Message, deserialized.Message);
 392            Assert.AreEqual(input.Result, deserialized.Result);
 393        }
 394
 395        [Test]
 396        public void CanSerializedWithGenericClosedTypeAsArgument()
 397        {
 398            var input = new ResponseWithNewGenericProperty<List<int>>()
 399            {
 400                Message = "More complex case - generic list of int",
 401                Data = Enumerable.Range(50, 70).ToList(),
 402                Result = "This should be fine too"
 403            };
 404
 405            var json = JsonConvert.SerializeObject(input);
 406            var deserialized = JsonConvert.DeserializeObject<ResponseWithNewGenericProperty<List<int>>>(json);
 407
 408            Assert.AreEqual(input.Data, deserialized.Data);
 409            Assert.AreEqual(input.Message, deserialized.Message);
 410            Assert.AreEqual(input.Result, deserialized.Result);
 411        }
 412
 413        [Test]
 414        public void JsonSerializerProperties()
 415        {
 416            JsonSerializer serializer = new JsonSerializer();
 417
 418            DefaultSerializationBinder customBinder = new DefaultSerializationBinder();
 419            serializer.Binder = customBinder;
 420            Assert.AreEqual(customBinder, serializer.Binder);
 421
 422            serializer.CheckAdditionalContent = true;
 423            Assert.AreEqual(true, serializer.CheckAdditionalContent);
 424
 425            serializer.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor;
 426            Assert.AreEqual(ConstructorHandling.AllowNonPublicDefaultConstructor, serializer.ConstructorHandling);
 427
 428#if !NETFX_CORE
 429            serializer.Context = new StreamingContext(StreamingContextStates.Other);
 430            Assert.AreEqual(new StreamingContext(StreamingContextStates.Other), serializer.Context);
 431#endif
 432
 433            CamelCasePropertyNamesContractResolver resolver = new CamelCasePropertyNamesContractResolver();
 434            serializer.ContractResolver = resolver;
 435            Assert.AreEqual(resolver, serializer.ContractResolver);
 436
 437            serializer.Converters.Add(new StringEnumConverter());
 438            Assert.AreEqual(1, serializer.Converters.Count);
 439
 440            serializer.Culture = new CultureInfo("en-nz");
 441            Assert.AreEqual("en-NZ", serializer.Culture.ToString());
 442
 443            serializer.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat;
 444            Assert.AreEqual(DateFormatHandling.MicrosoftDateFormat, serializer.DateFormatHandling);
 445
 446            serializer.DateFormatString = "yyyy";
 447            Assert.AreEqual("yyyy", serializer.DateFormatString);
 448
 449            serializer.DateParseHandling = DateParseHandling.None;
 450            Assert.AreEqual(DateParseHandling.None, serializer.DateParseHandling);
 451
 452            serializer.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
 453            Assert.AreEqual(DateTimeZoneHandling.Utc, serializer.DateTimeZoneHandling);
 454
 455            serializer.DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate;
 456            Assert.AreEqual(DefaultValueHandling.IgnoreAndPopulate, serializer.DefaultValueHandling);
 457
 458            serializer.FloatFormatHandling = FloatFormatHandling.Symbol;
 459            Assert.AreEqual(FloatFormatHandling.Symbol, serializer.FloatFormatHandling);
 460
 461            serializer.FloatParseHandling = FloatParseHandling.Decimal;
 462            Assert.AreEqual(FloatParseHandling.Decimal, serializer.FloatParseHandling);
 463
 464            serializer.Formatting = Formatting.Indented;
 465            Assert.AreEqual(Formatting.Indented, serializer.Formatting);
 466
 467            serializer.MaxDepth = 9001;
 468            Assert.AreEqual(9001, serializer.MaxDepth);
 469
 470            serializer.MissingMemberHandling = MissingMemberHandling.Error;
 471            Assert.AreEqual(MissingMemberHandling.Error, serializer.MissingMemberHandling);
 472
 473            serializer.NullValueHandling = NullValueHandling.Ignore;
 474            Assert.AreEqual(NullValueHandling.Ignore, serializer.NullValueHandling);
 475
 476            serializer.ObjectCreationHandling = ObjectCreationHandling.Replace;
 477            Assert.AreEqual(ObjectCreationHandling.Replace, serializer.ObjectCreationHandling);
 478
 479            serializer.PreserveReferencesHandling = PreserveReferencesHandling.All;
 480            Assert.AreEqual(PreserveReferencesHandling.All, serializer.PreserveReferencesHandling);
 481
 482            serializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
 483            Assert.AreEqual(ReferenceLoopHandling.Ignore, serializer.ReferenceLoopHandling);
 484
 485            IdReferenceResolver referenceResolver = new IdReferenceResolver();
 486            serializer.ReferenceResolver = referenceResolver;
 487            Assert.AreEqual(referenceResolver, serializer.ReferenceResolver);
 488
 489            serializer.StringEscapeHandling = StringEscapeHandling.EscapeNonAscii;
 490            Assert.AreEqual(StringEscapeHandling.EscapeNonAscii, serializer.StringEscapeHandling);
 491
 492            MemoryTraceWriter traceWriter = new MemoryTraceWriter();
 493            serializer.TraceWriter = traceWriter;
 494            Assert.AreEqual(traceWriter, serializer.TraceWriter);
 495
 496#if !(PORTABLE || PORTABLE40 || NETFX_CORE || NET20)
 497            serializer.TypeNameAssemblyFormat = FormatterAssemblyStyle.Full;
 498            Assert.AreEqual(FormatterAssemblyStyle.Full, serializer.TypeNameAssemblyFormat);
 499#endif
 500
 501            serializer.TypeNameHandling = TypeNameHandling.All;
 502            Assert.AreEqual(TypeNameHandling.All, serializer.TypeNameHandling);
 503        }
 504
 505        [Test]
 506        public void JsonSerializerSettingsProperties()
 507        {
 508            JsonSerializerSettings settings = new JsonSerializerSettings();
 509
 510            DefaultSerializationBinder customBinder = new DefaultSerializationBinder();
 511            settings.Binder = customBinder;
 512            Assert.AreEqual(customBinder, settings.Binder);
 513
 514            settings.CheckAdditionalContent = true;
 515            Assert.AreEqual(true, settings.CheckAdditionalContent);
 516
 517            settings.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor;
 518            Assert.AreEqual(ConstructorHandling.AllowNonPublicDefaultConstructor, settings.ConstructorHandling);
 519
 520#if !NETFX_CORE
 521            settings.Context = new StreamingContext(StreamingContextStates.Other);
 522            Assert.AreEqual(new StreamingContext(StreamingContextStates.Other), settings.Context);
 523#endif
 524
 525            CamelCasePropertyNamesContractResolver resolver = new CamelCasePropertyNamesContractResolver();
 526            settings.ContractResolver = resolver;
 527            Assert.AreEqual(resolver, settings.ContractResolver);
 528
 529            settings.Converters.Add(new StringEnumConverter());
 530            Assert.AreEqual(1, settings.Converters.Count);
 531
 532            settings.Culture = new CultureInfo("en-nz");
 533            Assert.AreEqual("en-NZ", settings.Culture.ToString());
 534
 535            settings.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat;
 536            Assert.AreEqual(DateFormatHandling.MicrosoftDateFormat, settings.DateFormatHandling);
 537
 538            settings.DateFormatString = "yyyy";
 539            Assert.AreEqual("yyyy", settings.DateFormatString);
 540
 541            settings.DateParseHandling = DateParseHandling.None;
 542            Assert.AreEqual(DateParseHandling.None, settings.DateParseHandling);
 543
 544            settings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
 545            Assert.AreEqual(DateTimeZoneHandling.Utc, settings.DateTimeZoneHandling);
 546
 547            settings.DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate;
 548            Assert.AreEqual(DefaultValueHandling.IgnoreAndPopulate, settings.DefaultValueHandling);
 549
 550            settings.FloatFormatHandling = FloatFormatHandling.Symbol;
 551            Assert.AreEqual(FloatFormatHandling.Symbol, settings.FloatFormatHandling);
 552
 553            settings.FloatParseHandling = FloatParseHandling.Decimal;
 554            Assert.AreEqual(FloatParseHandling.Decimal, settings.FloatParseHandling);
 555
 556            settings.Formatting = Formatting.Indented;
 557            Assert.AreEqual(Formatting.Indented, settings.Formatting);
 558
 559            settings.MaxDepth = 9001;
 560            Assert.AreEqual(9001, settings.MaxDepth);
 561
 562            settings.MissingMemberHandling = MissingMemberHandling.Error;
 563            Assert.AreEqual(MissingMemberHandling.Error, settings.MissingMemberHandling);
 564
 565            settings.NullValueHandling = NullValueHandling.Ignore;
 566            Assert.AreEqual(NullValueHandling.Ignore, settings.NullValueHandling);
 567
 568            settings.ObjectCreationHandling = ObjectCreationHandling.Replace;
 569            Assert.AreEqual(ObjectCreationHandling.Replace, settings.ObjectCreationHandling);
 570
 571            settings.PreserveReferencesHandling = PreserveReferencesHandling.All;
 572            Assert.AreEqual(PreserveReferencesHandling.All, settings.PreserveReferencesHandling);
 573
 574            settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
 575            Assert.AreEqual(ReferenceLoopHandling.Ignore, settings.ReferenceLoopHandling);
 576
 577            IdReferenceResolver referenceResolver = new IdReferenceResolver();
 578            settings.ReferenceResolver = referenceResolver;
 579            Assert.AreEqual(referenceResolver, settings.ReferenceResolver);
 580
 581            settings.StringEscapeHandling = StringEscapeHandling.EscapeNonAscii;
 582            Assert.AreEqual(StringEscapeHandling.EscapeNonAscii, settings.StringEscapeHandling);
 583
 584            MemoryTraceWriter traceWriter = new MemoryTraceWriter();
 585            settings.TraceWriter = traceWriter;
 586            Assert.AreEqual(traceWriter, settings.TraceWriter);
 587
 588#if !(PORTABLE || PORTABLE40 || NETFX_CORE || NET20)
 589            settings.TypeNameAssemblyFormat = FormatterAssemblyStyle.Full;
 590            Assert.AreEqual(FormatterAssemblyStyle.Full, settings.TypeNameAssemblyFormat);
 591#endif
 592
 593            settings.TypeNameHandling = TypeNameHandling.All;
 594            Assert.AreEqual(TypeNameHandling.All, settings.TypeNameHandling);
 595        }
 596
 597        [Test]
 598        public void JsonSerializerProxyProperties()
 599        {
 600            JsonSerializerProxy serializerProxy = new JsonSerializerProxy(new JsonSerializerInternalReader(new JsonSerializer()));
 601
 602            DefaultSerializationBinder customBinder = new DefaultSerializationBinder();
 603            serializerProxy.Binder = customBinder;
 604            Assert.AreEqual(customBinder, serializerProxy.Binder);
 605
 606            serializerProxy.CheckAdditionalContent = true;
 607            Assert.AreEqual(true, serializerProxy.CheckAdditionalContent);
 608
 609            serializerProxy.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor;
 610            Assert.AreEqual(ConstructorHandling.AllowNonPublicDefaultConstructor, serializerProxy.ConstructorHandling);
 611
 612#if !NETFX_CORE
 613            serializerProxy.Context = new StreamingContext(StreamingContextStates.Other);
 614            Assert.AreEqual(new StreamingContext(StreamingContextStates.Other), serializerProxy.Context);
 615#endif
 616
 617            CamelCasePropertyNamesContractResolver resolver = new CamelCasePropertyNamesContractResolver();
 618            serializerProxy.ContractResolver = resolver;
 619            Assert.AreEqual(resolver, serializerProxy.ContractResolver);
 620
 621            serializerProxy.Converters.Add(new StringEnumConverter());
 622            Assert.AreEqual(1, serializerProxy.Converters.Count);
 623
 624            serializerProxy.Culture = new CultureInfo("en-nz");
 625            Assert.AreEqual("en-NZ", serializerProxy.Culture.ToString());
 626
 627            serializerProxy.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat;
 628            Assert.AreEqual(DateFormatHandling.MicrosoftDateFormat, serializerProxy.DateFormatHandling);
 629
 630            serializerProxy.DateFormatString = "yyyy";
 631            Assert.AreEqual("yyyy", serializerProxy.DateFormatString);
 632
 633            serializerProxy.DateParseHandling = DateParseHandling.None;
 634            Assert.AreEqual(DateParseHandling.None, serializerProxy.DateParseHandling);
 635
 636            serializerProxy.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
 637            Assert.AreEqual(DateTimeZoneHandling.Utc, serializerProxy.DateTimeZoneHandling);
 638
 639            serializerProxy.DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate;
 640            Assert.AreEqual(DefaultValueHandling.IgnoreAndPopulate, serializerProxy.DefaultValueHandling);
 641
 642            serializerProxy.FloatFormatHandling = FloatFormatHandling.Symbol;
 643            Assert.AreEqual(FloatFormatHandling.Symbol, serializerProxy.FloatFormatHandling);
 644
 645            serializerProxy.FloatParseHandling = FloatParseHandling.Decimal;
 646            Assert.AreEqual(FloatParseHandling.Decimal, serializerProxy.FloatParseHandling);
 647
 648            serializerProxy.Formatting = Formatting.Indented;
 649            Assert.AreEqual(Formatting.Indented, serializerProxy.Formatting);
 650
 651            serializerProxy.MaxDepth = 9001;
 652            Assert.AreEqual(9001, serializerProxy.MaxDepth);
 653
 654            serializerProxy.MissingMemberHandling = MissingMemberHandling.Error;
 655            Assert.AreEqual(MissingMemberHandling.Error, serializerProxy.MissingMemberHandling);
 656
 657            serializerProxy.NullValueHandling = NullValueHandling.Ignore;
 658            Assert.AreEqual(NullValueHandling.Ignore, serializerProxy.NullValueHandling);
 659
 660            serializerProxy.ObjectCreationHandling = ObjectCreationHandling.Replace;
 661            Assert.AreEqual(ObjectCreationHandling.Replace, serializerProxy.ObjectCreationHandling);
 662
 663            serializerProxy.PreserveReferencesHandling = PreserveReferencesHandling.All;
 664            Assert.AreEqual(PreserveReferencesHandling.All, serializerProxy.PreserveReferencesHandling);
 665
 666            serializerProxy.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
 667            Assert.AreEqual(ReferenceLoopHandling.Ignore, serializerProxy.ReferenceLoopHandling);
 668
 669            IdReferenceResolver referenceResolver = new IdReferenceResolver();
 670            serializerProxy.ReferenceResolver = referenceResolver;
 671            Assert.AreEqual(referenceResolver, serializerProxy.ReferenceResolver);
 672
 673            serializerProxy.StringEscapeHandling = StringEscapeHandling.EscapeNonAscii;
 674            Assert.AreEqual(StringEscapeHandling.EscapeNonAscii, serializerProxy.StringEscapeHandling);
 675
 676            MemoryTraceWriter traceWriter = new MemoryTraceWriter();
 677            serializerProxy.TraceWriter = traceWriter;
 678            Assert.AreEqual(traceWriter, serializerProxy.TraceWriter);
 679
 680#if !(PORTABLE || PORTABLE40 || NETFX_CORE || NET20)
 681            serializerProxy.TypeNameAssemblyFormat = FormatterAssemblyStyle.Full;
 682            Assert.AreEqual(FormatterAssemblyStyle.Full, serializerProxy.TypeNameAssemblyFormat);
 683#endif
 684
 685            serializerProxy.TypeNameHandling = TypeNameHandling.All;
 686            Assert.AreEqual(TypeNameHandling.All, serializerProxy.TypeNameHandling);
 687        }
 688
 689#if !(NETFX_CORE || PORTABLE || PORTABLE40)
 690        [Test]
 691        public void DeserializeISerializableIConvertible()
 692        {
 693            Ratio ratio = new Ratio(2, 1);
 694            string json = JsonConvert.SerializeObject(ratio);
 695
 696            Assert.AreEqual(@"{""n"":2,""d"":1}", json);
 697
 698            Ratio ratio2 = JsonConvert.DeserializeObject<Ratio>(json);
 699
 700            Assert.AreEqual(ratio.Denominator, ratio2.Denominator);
 701            Assert.AreEqual(ratio.Numerator, ratio2.Numerator);
 702        }
 703#endif
 704
 705        [Test]
 706        public void DeserializeLargeFloat()
 707        {
 708            object o = JsonConvert.DeserializeObject("100000000000000000000000000000000000000.0");
 709
 710            CustomAssert.IsInstanceOfType(typeof(double), o);
 711
 712            Assert.IsTrue(MathUtils.ApproxEquals(1E+38, (double)o));
 713        }
 714
 715        [Test]
 716        public void SerializeDeserializeRegex()
 717        {
 718            Regex regex = new Regex("(hi)", RegexOptions.CultureInvariant);
 719
 720            string json = JsonConvert.SerializeObject(regex, Formatting.Indented);
 721
 722            Regex r2 = JsonConvert.DeserializeObject<Regex>(json);
 723
 724            Assert.AreEqual("(hi)", r2.ToString());
 725            Assert.AreEqual(RegexOptions.CultureInvariant, r2.Options);
 726        }
 727
 728        [Test]
 729        public void ExtensionDataTest()
 730        {
 731            string json = @"{
 732  ""Ints"": [1,2,3],
 733  ""Ignored"": [1,2,3],
 734  ""Readonly"": ""Readonly"",
 735  ""Name"": ""Actually set!"",
 736  ""CustomName"": ""Wrong name!"",
 737  ""GetPrivate"": true,
 738  ""GetOnly"": true,
 739  ""NewValueSimple"": true,
 740  ""NewValueComplex"": [1,2,3]
 741}";
 742
 743            ExtensionDataTestClass c = JsonConvert.DeserializeObject<ExtensionDataTestClass>(json);
 744
 745            Assert.AreEqual("Actually set!", c.Name);
 746            Assert.AreEqual(4, c.Ints.Count);
 747
 748            Assert.AreEqual("Readonly", (string)c.ExtensionData["Readonly"]);
 749            Assert.AreEqual("Wrong name!", (string)c.ExtensionData["CustomName"]);
 750            Assert.AreEqual(true, (bool)c.ExtensionData["GetPrivate"]);
 751            Assert.AreEqual(true, (bool)c.ExtensionData["GetOnly"]);
 752            Assert.AreEqual(true, (bool)c.ExtensionData["NewValueSimple"]);
 753            Assert.IsTrue(JToken.DeepEquals(new JArray(1, 2, 3), c.ExtensionData["NewValueComplex"]));
 754            Assert.IsTrue(JToken.DeepEquals(new JArray(1, 2, 3), c.ExtensionData["Ignored"]));
 755
 756            Assert.AreEqual(7, c.ExtensionData.Count);
 757        }
 758
 759        public class MultipleExtensionDataAttributesTestClass
 760        {
 761            public string Name { get; set; }
 762
 763            [JsonExtensionData]
 764            internal IDictionary<string, JToken> ExtensionData1 { get; set; }
 765
 766            [JsonExtensionData]
 767            internal IDictionary<string, JToken> ExtensionData2 { get; set; }
 768        }
 769
 770        public class ExtensionDataAttributesInheritanceTestClass : MultipleExtensionDataAttributesTestClass
 771        {
 772            [JsonExtensionData]
 773            internal IDictionary<string, JToken> ExtensionData0 { get; set; }
 774        }
 775
 776        public class FieldExtensionDataAttributeTestClass
 777        {
 778            [JsonExtensionData]
 779            internal IDictionary<object, object> ExtensionData;
 780        }
 781
 782        public class PublicExtensionDataAttributeTestClass
 783        {
 784            public string Name { get; set; }
 785
 786            [JsonExtensionData]
 787            public IDictionary<object, object> ExtensionData;
 788        }
 789
 790        public class PublicExtensionDataAttributeTestClassWithNonDefaultConstructor
 791        {
 792            public string Name { get; set; }
 793
 794            public PublicExtensionDataAttributeTestClassWithNonDefaultConstructor(string name)
 795            {
 796                Name = name;
 797            }
 798
 799            [JsonExtensionData]
 800            public IDictionary<object, object> ExtensionData;
 801        }
 802
 803        public class PublicNoReadExtensionDataAttributeTestClass
 804        {
 805            public string Name { get; set; }
 806
 807            [JsonExtensionData(ReadData = false)]
 808            public IDictionary<object, object> ExtensionData;
 809        }
 810
 811        public class PublicNoWriteExtensionDataAttributeTestClass
 812        {
 813            public string Name { get; set; }
 814
 815            [JsonExtensionData(WriteData = false)]
 816            public IDictionary<object, object> ExtensionData;
 817        }
 818
 819        public class PublicJTokenExtensionDataAttributeTestClass
 820        {
 821            public string Name { get; set; }
 822
 823            [JsonExtensionData]
 824            public IDictionary<string, JToken> ExtensionData;
 825        }
 826
 827        [Test]
 828        public void DeserializeDirectoryAccount()
 829        {
 830            string json = @"{'DisplayName':'John Smith', 'SAMAccountName':'contoso\\johns'}";
 831
 832            DirectoryAccount account = JsonConvert.DeserializeObject<DirectoryAccount>(json);
 833
 834            Assert.AreEqual("John Smith", account.DisplayName);
 835            Assert.AreEqual("contoso", account.Domain);
 836            Assert.AreEqual("johns", account.UserName);
 837        }
 838
 839        [Test]
 840        public void SerializePublicExtensionData()
 841        {
 842            string json = JsonConvert.SerializeObject(new PublicExtensionDataAttributeTestClass
 843            {
 844                Name = "Name!",
 845                ExtensionData = new Dictionary<object, object>
 846                {
 847                    { "Test", 1 }
 848                }
 849            });
 850
 851            Assert.AreEqual(@"{""Name"":""Name!"",""Test"":1}", json);
 852        }
 853
 854        [Test]
 855        public void SerializePublicExtensionDataNull()
 856        {
 857            string json = JsonConvert.SerializeObject(new PublicExtensionDataAttributeTestClass
 858            {
 859                Name = "Name!"
 860            });
 861
 862            Assert.AreEqual(@"{""Name"":""Name!""}", json);
 863        }
 864
 865        [Test]
 866        public void SerializePublicNoWriteExtensionData()
 867        {
 868            string json = JsonConvert.SerializeObject(new PublicNoWriteExtensionDataAttributeTestClass
 869            {
 870                Name = "Name!",
 871                ExtensionData = new Dictionary<object, object>
 872                {
 873                    { "Test", 1 }
 874                }
 875            });
 876
 877            Assert.AreEqual(@"{""Name"":""Name!""}", json);
 878        }
 879
 880        [Test]
 881        public void DeserializeNoReadPublicExtensionData()
 882        {
 883            PublicNoReadExtensionDataAttributeTestClass c = JsonConvert.DeserializeObject<PublicNoReadExtensionDataAttributeTestClass>(@"{""Name"":""Name!"",""Test"":1}");
 884
 885            Assert.AreEqual(null, c.ExtensionData);
 886        }
 887
 888        [Test]
 889        public void SerializePublicExtensionDataCircularReference()
 890        {
 891            var c = new PublicExtensionDataAttributeTestClass
 892            {
 893                Name = "Name!",
 894                ExtensionData = new Dictionary<object, object>
 895                {
 896                    { "Test", 1 }
 897                }
 898            };
 899            c.ExtensionData["Self"] = c;
 900
 901            string json = JsonConvert.SerializeObject(c, new JsonSerializerSettings
 902            {
 903                PreserveReferencesHandling = PreserveReferencesHandling.All,
 904                Formatting = Formatting.Indented
 905            });
 906
 907            Assert.AreEqual(@"{
 908  ""$id"": ""1"",
 909  ""Name"": ""Name!"",
 910  ""Test"": 1,
 911  ""Self"": {
 912    ""$ref"": ""1""
 913  }
 914}", json);
 915
 916            var c2 = JsonConvert.DeserializeObject<PublicExtensionDataAttributeTestClass>(json, new JsonSerializerSettings
 917            {
 918                PreserveReferencesHandling = PreserveReferencesHandling.All
 919            });
 920
 921            Assert.AreEqual("Name!", c2.Name);
 922
 923            PublicExtensionDataAttributeTestClass bizzaroC2 = (PublicExtensionDataAttributeTestClass)c2.ExtensionData["Self"];
 924
 925            Assert.AreEqual(c2, bizzaroC2);
 926            Assert.AreEqual(1, (long)bizzaroC2.ExtensionData["Test"]);
 927        }
 928
 929        [Test]
 930        public void DeserializePublicJTokenExtensionDataCircularReference()
 931        {
 932            string json = @"{
 933  ""$id"": ""1"",
 934  ""Name"": ""Name!"",
 935  ""Test"": 1,
 936  ""Self"": {
 937    ""$ref"": ""1""
 938  }
 939}";
 940
 941            var c2 = JsonConvert.DeserializeObject<PublicJTokenExtensionDataAttributeTestClass>(json, new JsonSerializerSettings
 942            {
 943                PreserveReferencesHandling = PreserveReferencesHandling.All
 944            });
 945
 946            Assert.AreEqual("Name!", c2.Name);
 947
 948            JObject bizzaroC2 = (JObject)c2.ExtensionData["Self"];
 949
 950            Assert.AreEqual("Name!", (string)bizzaroC2["Name"]);
 951            Assert.AreEqual(1, (int)bizzaroC2["Test"]);
 952
 953            Assert.AreEqual(1, (int)c2.ExtensionData["Test"]);
 954        }
 955
 956        [Test]
 957        public void DeserializePublicExtensionDataTypeNamdHandling()
 958        {
 959            string json = @"{
 960  ""$id"": ""1"",
 961  ""Name"": ""Name!"",
 962  ""Test"": 1,
 963  ""Self"": {
 964    ""$type"": ""Newtonsoft.Json.Tests.TestObjects.WagePerson, Newtonsoft.Json.Tests"",
 965    ""HourlyWage"": 2.0,
 966    ""Name"": null,
 967    ""BirthDate"": ""0001-01-01T00:00:00"",
 968    ""LastModified"": ""0001-01-01T00:00:00""
 969  }
 970}";
 971
 972            PublicExtensionDataAttributeTestClass c2 = JsonConvert.DeserializeObject<PublicExtensionDataAttributeTestClass>(json, new JsonSerializerSettings
 973            {
 974                TypeNameHandling = TypeNameHandling.Objects
 975            });
 976
 977            Assert.AreEqual("Name!", c2.Name);
 978
 979            WagePerson bizzaroC2 = (WagePerson)c2.ExtensionData["Self"];
 980
 981            Assert.AreEqual(2m, bizzaroC2.HourlyWage);
 982        }
 983
 984        [Test]
 985        public void DeserializePublicExtensionDataTypeNamdHandlingNonDefaultConstructor()
 986        {
 987            string json = @"{
 988  ""$id"": ""1"",
 989  ""Name"": ""Name!"",
 990  ""Test"": 1,
 991  ""Self"": {
 992    ""$type"": ""Newtonsoft.Json.Tests.TestObjects.WagePerson, Newtonsoft.Json.Tests"",
 993    ""HourlyWage"": 2.0,
 994    ""Name"": null,
 995    ""BirthDate"": ""0001-01-01T00:00:00"",
 996    ""LastModified"": ""0001-01-01T00:00:00""
 997  }
 998}";
 999
1000            PublicExtensionDataAttributeTestClassWithNonDefaultConstructor c2 = JsonConvert.DeserializeObject<PublicExtensionDataAttributeTestClassWithNonDefaultConstructor>(json, new JsonSerializerSettings
1001            {
1002                TypeNameHandling = TypeNameHandling.Objects
1003            });
1004
1005            Assert.AreEqual("Name!", c2.Name);
1006
1007            WagePerson bizzaroC2 = (WagePerson)c2.ExtensionData["Self"];
1008
1009            Assert.AreEqual(2m, bizzaroC2.HourlyWage);
1010        }
1011
1012        [Test]
1013        public void SerializePublicExtensionDataTypeNamdHandling()
1014        {
1015            PublicExtensionDataAttributeTestClass c = new PublicExtensionDataAttributeTestClass
1016            {
1017                Name = "Name!",
1018                ExtensionData = new Dictionary<object, object>
1019                {
1020                    {
1021                        "Test", new WagePerson
1022                        {
1023                            HourlyWage = 2.1m
1024                        }
1025                    }
1026                }
1027            };
1028
1029            string json = JsonConvert.SerializeObject(c, new JsonSerializerSettings
1030            {
1031                TypeNameHandling = TypeNameHandling.Objects,
1032                Formatting = Formatting.Indented
1033            });
1034
1035            Assert.AreEqual(@"{
1036  ""$type"": ""Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+PublicExtensionDataAttributeTestClass, Newtonsoft.Json.Tests"",
1037  ""Name"": ""Name!"",
1038  ""Test"": {
1039    ""$type"": ""Newtonsoft.Json.Tests.TestObjects.WagePerson, Newtonsoft.Json.Tests"",
1040    ""HourlyWage"": 2.1,
1041    ""Name"": null,
1042    ""BirthDate"": ""0001-01-01T00:00:00"",
1043    ""LastModified"": ""0001-01-01T00:00:00""
1044  }
1045}", json);
1046        }
1047
1048        [Test]
1049        public void DeserializePublicExtensionData()
1050        {
1051            string json = @"{
1052  'Name':'Name!',
1053  'NoMatch':'NoMatch!',
1054  'ExtensionData':{'HAI':true}
1055}";
1056
1057            var c = JsonConvert.DeserializeObject<PublicExtensionDataAttributeTestClass>(json);
1058
1059            Assert.AreEqual("Name!", c.Name);
1060            Assert.AreEqual(2, c.ExtensionData.Count);
1061
1062            Assert.AreEqual("NoMatch!", (string)c.ExtensionData["NoMatch"]);
1063
1064            // the ExtensionData property is put into the extension data
1065            // inception
1066            var o = (JObject)c.ExtensionData["ExtensionData"];
1067            Assert.AreEqual(1, o.Count);
1068            Assert.IsTrue(JToken.DeepEquals(new JObject { { "HAI", true } }, o));
1069        }
1070
1071        [Test]
1072        public void FieldExtensionDataAttributeTest_Serialize()
1073        {
1074            FieldExtensionDataAttributeTestClass c = new FieldExtensionDataAttributeTestClass
1075            {
1076                ExtensionData = new Dictionary<object, object>()
1077            };
1078
1079            string json = JsonConvert.SerializeObject(c);
1080
1081            Assert.AreEqual("{}", json);
1082        }
1083
1084        [Test]
1085        public void FieldExtensionDataAttributeTest_Deserialize()
1086        {
1087            var c = JsonConvert.DeserializeObject<FieldExtensionDataAttributeTestClass>("{'first':1,'second':2}");
1088
1089            Assert.AreEqual(2, c.ExtensionData.Count);
1090            Assert.AreEqual(1, (long)c.ExtensionData["first"]);
1091            Assert.AreEqual(2, (long)c.ExtensionData["second"]);
1092        }
1093
1094        [Test]
1095        public void MultipleExtensionDataAttributesTest()
1096        {
1097            var c = JsonConvert.DeserializeObject<MultipleExtensionDataAttributesTestClass>("{'first':[1],'second':[2]}");
1098
1099            Assert.AreEqual(null, c.ExtensionData1);
1100            Assert.AreEqual(2, c.ExtensionData2.Count);
1101            Assert.AreEqual(1, (int)((JArray)c.ExtensionData2["first"])[0]);
1102            Assert.AreEqual(2, (int)((JArray)c.ExtensionData2["second"])[0]);
1103        }
1104
1105        [Test]
1106        public void ExtensionDataAttributesInheritanceTest()
1107        {
1108            var c = JsonConvert.DeserializeObject<ExtensionDataAttributesInheritanceTestClass>("{'first':1,'second':2}");
1109
1110            Assert.AreEqual(null, c.ExtensionData1);
1111            Assert.AreEqual(null, c.ExtensionData2);
1112            Assert.AreEqual(2, c.ExtensionData0.Count);
1113            Assert.AreEqual(1, (int)c.ExtensionData0["first"]);
1114            Assert.AreEqual(2, (int)c.ExtensionData0["second"]);
1115        }
1116
1117        [Test]
1118        public void GenericCollectionInheritance()
1119        {
1120            string json;
1121
1122            GenericClass<GenericItem<string>, string> foo1 = new GenericClass<GenericItem<string>, string>();
1123            foo1.Items.Add(new GenericItem<string> { Value = "Hello" });
1124
1125            json = JsonConvert.SerializeObject(new { selectList = foo1 });
1126            Assert.AreEqual(@"{""selectList"":[{""Value"":""Hello""}]}", json);
1127
1128            GenericClass<NonGenericItem, string> foo2 = new GenericClass<NonGenericItem, string>();
1129            foo2.Items.Add(new NonGenericItem { Value = "Hello" });
1130
1131            json = JsonConvert.SerializeObject(new { selectList = foo2 });
1132            Assert.AreEqual(@"{""selectList"":[{""Value"":""Hello""}]}", json);
1133
1134            NonGenericClass foo3 = new NonGenericClass();
1135            foo3.Items.Add(new NonGenericItem { Value = "Hello" });
1136
1137            json = JsonConvert.SerializeObject(new { selectList = foo3 });
1138            Assert.AreEqual(@"{""selectList"":[{""Value"":""Hello""}]}", json);
1139        }
1140
1141#if !NET20
1142        [DataContract]
1143        public class BaseDataContractWithHidden
1144        {
1145            [DataMember(Name = "virtualMember")]
1146            public virtual string VirtualMember { get; set; }
1147
1148            [DataMember(Name = "nonVirtualMember")]
1149            public string NonVirtualMember { get; set; }
1150
1151            public virtual object NewMember { get; set; }
1152        }
1153
1154        public class ChildDataContractWithHidden : BaseDataContractWithHidden
1155        {
1156            [DataMember(Name = "NewMember")]
1157            public new virtual string NewMember { get; set; }
1158
1159            public override string VirtualMember { get; set; }
1160            public string AddedMember { get; set; }
1161        }
1162
1163        [Test]
1164        public void ChildDataContractTestWithHidden()
1165        {
1166            var cc = new ChildDataContractWithHidden
1167            {
1168                VirtualMember = "VirtualMember!",
1169                NonVirtualMember = "NonVirtualMember!",
1170                NewMember = "NewMember!"
1171            };
1172
1173            string result = JsonConvert.SerializeObject(cc);
1174            Assert.AreEqual(@"{""NewMember"":""NewMember!"",""virtualMember"":""VirtualMember!"",""nonVirtualMember"":""NonVirtualMember!""}", result);
1175        }
1176
1177        // ignore hiding members compiler warning
1178#pragma warning disable 108,114
1179        [DataContract]
1180        public class BaseWithContract
1181        {
1182            [DataMember(Name = "VirtualWithDataMemberBase")]
1183            public virtual string VirtualWithDataMember { get; set; }
1184
1185            [DataMember]
1186            public virtual string Virtual { get; set; }
1187
1188            [DataMember(Name = "WithDataMemberBase")]
1189            public string WithDataMember { get; set; }
1190
1191            [DataMember]
1192            public string JustAProperty { get; set; }
1193        }
1194
1195        [DataContract]
1196        public class BaseWithoutContract
1197        {
1198            [DataMember(Name = "VirtualWithDataMemberBase")]
1199            public virtual string VirtualWithDataMember { get; set; }
1200
1201            [DataMember]
1202            public virtual string Virtual { get; set; }
1203
1204            [DataMember(Name = "WithDataMemberBase")]
1205            public string WithDataMember { get; set; }
1206
1207            [DataMember]
1208            public string JustAProperty { get; set; }
1209        }
1210
1211        [DataContract]
1212        public class SubWithoutContractNewProperties : BaseWithContract
1213        {
1214            [DataMember(Name = "VirtualWithDataMemberSub")]
1215            public string VirtualWithDataMember { get; set; }
1216
1217            public string Virtual { get; set; }
1218
1219            [DataMember(Name = "WithDataMemberSub")]
1220            public string WithDataMember { get; set; }
1221
1222            public string JustAProperty { get; set; }
1223        }
1224
1225        [DataContract]
1226        public class SubWithoutContractVirtualProperties : BaseWithContract
1227        {
1228            public override string VirtualWithDataMember { get; set; }
1229
1230            [DataMember(Name = "VirtualSub")]
1231            public override string Virtual { get; set; }
1232        }
1233
1234        [DataContract]
1235        public class SubWithContractNewProperties : BaseWithContract
1236        {
1237            [DataMember(Name = "VirtualWithDataMemberSub")]
1238            public string VirtualWithDataMember { get; set; }
1239
1240            [DataMember(Name = "Virtual2")]
1241            public string Virtual { get; set; }
1242
1243            [DataMember(Name = "WithDataMemberSub")]
1244            public string WithDataMember { get; set; }
1245
1246            [DataMember(Name = "JustAProperty2")]
1247            public string JustAProperty { get; set; }
1248        }
1249
1250        [DataContract]
1251        public class SubWithContractVirtualProperties : BaseWithContract
1252        {
1253            [DataMember(Name = "VirtualWithDataMemberSub")]
1254            public virtual string VirtualWithDataMember { get; set; }
1255        }
1256#pragma warning restore 108,114
1257
1258        [Test]
1259        public void SubWithoutContractNewPropertiesTest()
1260        {
1261            BaseWithContract baseWith = new SubWithoutContractNewProperties
1262            {
1263                JustAProperty = "JustAProperty!",
1264                Virtual = "Virtual!",
1265                VirtualWithDataMember = "VirtualWithDataMember!",
1266                WithDataMember = "WithDataMember!"
1267            };
1268
1269            baseWith.JustAProperty = "JustAProperty2!";
1270            baseWith.Virtual = "Virtual2!";
1271            baseWith.VirtualWithDataMember = "VirtualWithDataMember2!";
1272            baseWith.WithDataMember = "WithDataMember2!";
1273
1274            string json = AssertSerializeDeserializeEqual(baseWith);
1275
1276            Assert.AreEqual(@"{
1277  ""JustAProperty"": ""JustAProperty2!"",
1278  ""Virtual"": ""Virtual2!"",
1279  ""VirtualWithDataMemberBase"": ""VirtualWithDataMember2!"",
1280  ""VirtualWithDataMemberSub"": ""VirtualWithDataMember!"",
1281  ""WithDataMemberBase"": ""WithDataMember2!"",
1282  ""WithDataMemberSub"": ""WithDataMember!""
1283}", json);
1284        }
1285
1286        [Test]
1287        public void SubWithoutContractVirtualPropertiesTest()
1288        {
1289            BaseWithContract baseWith = new SubWithoutContractVirtualProperties
1290            {
1291                JustAProperty = "JustAProperty!",
1292                Virtual = "Virtual!",
1293                VirtualWithDataMember = "VirtualWithDataMember!",
1294                WithDataMember = "WithDataMember!"
1295            };
1296
1297            baseWith.JustAProperty = "JustAProperty2!";
1298            baseWith.Virtual = "Virtual2!";
1299            baseWith.VirtualWithDataMember = "VirtualWithDataMember2!";
1300            baseWith.WithDataMember = "WithDataMember2!";
1301
1302            string json = JsonConvert.SerializeObject(baseWith, Formatting.Indented);
1303
1304            Console.WriteLine(json);
1305
1306            Assert.AreEqual(@"{
1307  ""VirtualWithDataMemberBase"": ""VirtualWithDataMember2!"",
1308  ""VirtualSub"": ""Virtual2!"",
1309  ""WithDataMemberBase"": ""WithDataMember2!"",
1310  ""JustAProperty"": ""JustAProperty2!""
1311}", json);
1312        }
1313
1314        [Test]
1315        public void SubWithContractNewPropertiesTest()
1316        {
1317            BaseWithContract baseWith = new SubWithContractNewProperties
1318            {
1319                JustAProperty = "JustAProperty!",
1320                Virtual = "Virtual!",
1321                VirtualWithDataMember = "VirtualWithDataMember!",
1322                WithDataMember = "WithDataMember!"
1323            };
1324
1325            baseWith.JustAProperty = "JustAProperty2!";
1326            baseWith.Virtual = "Virtual2!";
1327            baseWith.VirtualWithDataMember = "VirtualWithDataMember2!";
1328            baseWith.WithDataMember = "WithDataMember2!";
1329
1330            string json = AssertSerializeDeserializeEqual(baseWith);
1331
1332            Assert.AreEqual(@"{
1333  ""JustAProperty"": ""JustAProperty2!"",
1334  ""JustAProperty2"": ""JustAProperty!"",
1335  ""Virtual"": ""Virtual2!"",
1336  ""Virtual2"": ""Virtual!"",
1337  ""VirtualWithDataMemberBase"": ""VirtualWithDataMember2!"",
1338  ""VirtualWithDataMemberSub"": ""VirtualWithDataMember!"",
1339  ""WithDataMemberBase"": ""WithDataMember2!"",
1340  ""WithDataMemberSub"": ""WithDataMember!""
1341}", json);
1342        }
1343
1344        [Test]
1345        public void SubWithContractVirtualPropertiesTest()
1346        {
1347            BaseWithContract baseWith = new SubWithContractVirtualProperties
1348            {
1349                JustAProperty = "JustAProperty!",
1350                Virtual = "Virtual!",
1351                VirtualWithDataMember = "VirtualWithDataMember!",
1352                WithDataMember = "WithDataMember!"
1353            };
1354
1355            baseWith.JustAProperty = "JustAProperty2!";
1356            baseWith.Virtual = "Virtual2!";
1357            baseWith.VirtualWithDataMember = "VirtualWithDataMember2!";
1358            baseWith.WithDataMember = "WithDataMember2!";
1359
1360            string json = AssertSerializeDeserializeEqual(baseWith);
1361
1362            Assert.AreEqual(@"{
1363  ""JustAProperty"": ""JustAProperty2!"",
1364  ""Virtual"": ""Virtual2!"",
1365  ""VirtualWithDataMemberBase"": ""VirtualWithDataMember2!"",
1366  ""VirtualWithDataMemberSub"": ""VirtualWithDataMember!"",
1367  ""WithDataMemberBase"": ""WithDataMember2!""
1368}", jso

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