/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs
C# | 10337 lines | 9699 code | 589 blank | 49 comment | 57 complexity | ed917c878c953a32550256444c83dfaa MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- #region License
- // Copyright (c) 2007 James Newton-King
- //
- // Permission is hereby granted, free of charge, to any person
- // obtaining a copy of this software and associated documentation
- // files (the "Software"), to deal in the Software without
- // restriction, including without limitation the rights to use,
- // copy, modify, merge, publish, distribute, sublicense, and/or sell
- // copies of the Software, and to permit persons to whom the
- // Software is furnished to do so, subject to the following
- // conditions:
- //
- // The above copyright notice and this permission notice shall be
- // included in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- // OTHER DEALINGS IN THE SOFTWARE.
- #endregion
- using System;
- using System.ComponentModel;
- #if !(NET35 || NET20)
- using System.Collections.Concurrent;
- #endif
- using System.Collections.Generic;
- #if !(NET20 || NET35 || PORTABLE) || NETSTANDARD1_1
- using System.Numerics;
- #endif
- #if !(NET20 || DNXCORE50)
- using System.ComponentModel.DataAnnotations;
- using System.Configuration;
- using System.Runtime.CompilerServices;
- using System.Runtime.Serialization.Formatters;
- using System.Threading;
- using System.Web.Script.Serialization;
- #endif
- using System.Text;
- using System.Text.RegularExpressions;
- #if DNXCORE50
- using Xunit;
- using Test = Xunit.FactAttribute;
- using Assert = Newtonsoft.Json.Tests.XUnitAssert;
- #else
- using NUnit.Framework;
- #endif
- using Newtonsoft.Json;
- using System.IO;
- using System.Collections;
- using System.Xml;
- using System.Xml.Serialization;
- using System.Collections.ObjectModel;
- using System.Diagnostics;
- using Newtonsoft.Json.Bson;
- using Newtonsoft.Json.Linq;
- using Newtonsoft.Json.Converters;
- #if !(NET20 || NET35)
- using System.Runtime.Serialization.Json;
- #endif
- using Newtonsoft.Json.Serialization;
- using Newtonsoft.Json.Tests.Linq;
- using Newtonsoft.Json.Tests.TestObjects;
- using Newtonsoft.Json.Tests.TestObjects.Events;
- using Newtonsoft.Json.Tests.TestObjects.GeoCoding;
- using Newtonsoft.Json.Tests.TestObjects.Organization;
- using System.Runtime.Serialization;
- using System.Globalization;
- using Newtonsoft.Json.Utilities;
- using System.Reflection;
- #if !NET20
- using System.Xml.Linq;
- using System.Collections.Specialized;
- using System.Linq.Expressions;
- #endif
- #if !(NET35 || NET20)
- using System.Dynamic;
- #endif
- #if NET20
- using Newtonsoft.Json.Utilities.LinqBridge;
- using Action = Newtonsoft.Json.Serialization.Action;
- #else
- using System.Linq;
- #endif
- #if !(DNXCORE50)
- using System.Drawing;
- #endif
- namespace Newtonsoft.Json.Tests.Serialization
- {
- [TestFixture]
- public class JsonSerializerTest : TestFixtureBase
- {
- public struct ImmutableStruct
- {
- public ImmutableStruct(string value)
- {
- Value = value;
- Value2 = 0;
- }
- public string Value { get; }
- public int Value2 { get; set; }
- }
- [Test]
- public void DeserializeImmutableStruct()
- {
- var result = JsonConvert.DeserializeObject<ImmutableStruct>("{ \"Value\": \"working\", \"Value2\": 2 }");
- Assert.AreEqual("working", result.Value);
- Assert.AreEqual(2, result.Value2);
- }
- public struct AlmostImmutableStruct
- {
- public AlmostImmutableStruct(string value, int value2)
- {
- Value = value;
- Value2 = value2;
- }
- public string Value { get; }
- public int Value2 { get; set; }
- }
- [Test]
- public void DeserializeAlmostImmutableStruct()
- {
- var result = JsonConvert.DeserializeObject<AlmostImmutableStruct>("{ \"Value\": \"working\", \"Value2\": 2 }");
- Assert.AreEqual(null, result.Value);
- Assert.AreEqual(2, result.Value2);
- }
- public class ErroringClass
- {
- public DateTime Tags { get; set; }
- }
- [Test]
- public void DontCloseInputOnDeserializeError()
- {
- using (var s = System.IO.File.OpenRead("large.json"))
- {
- try
- {
- using (JsonTextReader reader = new JsonTextReader(new StreamReader(s)))
- {
- reader.SupportMultipleContent = true;
- reader.CloseInput = false;
- // read into array
- reader.Read();
- var ser = new JsonSerializer();
- ser.CheckAdditionalContent = false;
- ser.Deserialize<IList<ErroringClass>>(reader);
- }
- Assert.Fail();
- }
- catch (Exception)
- {
- Assert.IsTrue(s.Position > 0);
- s.Seek(0, SeekOrigin.Begin);
- Assert.AreEqual(0, s.Position);
- }
- }
- }
- public interface ISubclassBase
- {
- int ID { get; set; }
- string Name { get; set; }
- bool P1 { get; }
- }
- public interface ISubclass : ISubclassBase
- {
- new bool P1 { get; set; }
- int P2 { get; set; }
- }
- public interface IMainClass
- {
- int ID { get; set; }
- string Name { get; set; }
- ISubclass Subclass { get; set; }
- }
- public class Subclass : ISubclass
- {
- public int ID { get; set; }
- public string Name { get; set; }
- public bool P1 { get; set; }
- public int P2 { get; set; }
- }
- public class MainClass : IMainClass
- {
- public int ID { get; set; }
- public string Name { get; set; }
- public ISubclass Subclass { get; set; }
- }
- public class MyFactory
- {
- public static ISubclass InstantiateSubclass()
- {
- return new Subclass
- {
- ID = 123,
- Name = "ABC",
- P1 = true,
- P2 = 44
- };
- }
- public static IMainClass InstantiateManiClass()
- {
- return new MainClass
- {
- ID = 567,
- Name = "XYZ",
- Subclass = InstantiateSubclass()
- };
- }
- }
- [Test]
- public void SerializeInterfaceWithHiddenProperties()
- {
- var mySubclass = MyFactory.InstantiateSubclass();
- var myMainClass = MyFactory.InstantiateManiClass();
- //Class implementing interface with hidden members - flat object.
- var strJsonSubclass = JsonConvert.SerializeObject(mySubclass, Formatting.Indented);
- StringAssert.AreEqual(@"{
- ""ID"": 123,
- ""Name"": ""ABC"",
- ""P1"": true,
- ""P2"": 44
- }", strJsonSubclass);
- //Class implementing interface with hidden members - member of another class.
- var strJsonMainClass = JsonConvert.SerializeObject(myMainClass, Formatting.Indented);
- StringAssert.AreEqual(@"{
- ""ID"": 567,
- ""Name"": ""XYZ"",
- ""Subclass"": {
- ""ID"": 123,
- ""Name"": ""ABC"",
- ""P1"": true,
- ""P2"": 44
- }
- }", strJsonMainClass);
- }
- [Test]
- public void DeserializeGenericIEnumerableWithImplicitConversion()
- {
- string deserialized = @"{
- ""Enumerable"": [ ""abc"", ""def"" ]
- }";
- var enumerableClass = JsonConvert.DeserializeObject<GenericIEnumerableWithImplicitConversion>(deserialized);
- var enumerableObject = enumerableClass.Enumerable.ToArray();
- Assert.AreEqual(2, enumerableObject.Length);
- Assert.AreEqual("abc", enumerableObject[0].Value);
- Assert.AreEqual("def", enumerableObject[1].Value);
- }
- public class GenericIEnumerableWithImplicitConversion
- {
- public IEnumerable<ClassWithImplicitOperator> Enumerable { get; set; }
- }
- public class ClassWithImplicitOperator
- {
- public string Value { get; set; }
- public static implicit operator ClassWithImplicitOperator(string value)
- {
- return new ClassWithImplicitOperator() { Value = value };
- }
- }
- #if !(PORTABLE || PORTABLE40 || NET20 || NET35)
- [Test]
- public void LargeIntegerAsString()
- {
- var largeBrokenNumber = JsonConvert.DeserializeObject<Foo64>("{\"Blah\": 43443333222211111117 }");
- Assert.AreEqual("43443333222211111117", largeBrokenNumber.Blah);
- var largeOddWorkingNumber = JsonConvert.DeserializeObject<Foo64>("{\"Blah\": 53443333222211111117 }");
- Assert.AreEqual("53443333222211111117", largeOddWorkingNumber.Blah);
- }
- public class Foo64
- {
- public string Blah { get; set; }
- }
- #endif
- #if !NET20
- [Test]
- public void DeserializeMSDateTimeOffset()
- {
- DateTimeOffset d = JsonConvert.DeserializeObject<DateTimeOffset>(@"""/Date(1418924498000+0800)/""");
- long initialTicks = DateTimeUtils.ConvertDateTimeToJavaScriptTicks(d.DateTime, d.Offset);
- Assert.AreEqual(1418924498000, initialTicks);
- Assert.AreEqual(8, d.Offset.Hours);
- }
- #endif
- [Test]
- public void DeserializeBoolean_Null()
- {
- ExceptionAssert.Throws<JsonSerializationException>(
- () => JsonConvert.DeserializeObject<IList<bool>>(@"[null]"),
- "Error converting value {null} to type 'System.Boolean'. Path '[0]', line 1, position 5.");
- }
- [Test]
- public void DeserializeBoolean_DateTime()
- {
- ExceptionAssert.Throws<JsonReaderException>(
- () => JsonConvert.DeserializeObject<IList<bool>>(@"['2000-12-20T10:55:55Z']"),
- "Could not convert string to boolean: 2000-12-20T10:55:55Z. Path '[0]', line 1, position 23.");
- }
- [Test]
- public void DeserializeBoolean_BadString()
- {
- ExceptionAssert.Throws<JsonReaderException>(
- () => JsonConvert.DeserializeObject<IList<bool>>(@"['pie']"),
- @"Could not convert string to boolean: pie. Path '[0]', line 1, position 6.");
- }
- [Test]
- public void DeserializeBoolean_EmptyString()
- {
- ExceptionAssert.Throws<JsonSerializationException>(
- () => JsonConvert.DeserializeObject<IList<bool>>(@"['']"),
- @"Error converting value {null} to type 'System.Boolean'. Path '[0]', line 1, position 3.");
- }
- #if !(PORTABLE || PORTABLE40 || NET35 || NET20)
- [Test]
- public void DeserializeBooleans()
- {
- IList<bool> l = JsonConvert.DeserializeObject<IList<bool>>(@"[
- 1,
- 0,
- 1.1,
- 0.0,
- 0.000000000001,
- 9999999999,
- -9999999999,
- 9999999999999999999999999999999999999999999999999999999999999999999999,
- -9999999999999999999999999999999999999999999999999999999999999999999999,
- 'true',
- 'TRUE',
- 'false',
- 'FALSE'
- ]");
- int i = 0;
- Assert.AreEqual(true, l[i++]);
- Assert.AreEqual(false, l[i++]);
- Assert.AreEqual(true, l[i++]);
- Assert.AreEqual(false, l[i++]);
- Assert.AreEqual(true, l[i++]);
- Assert.AreEqual(true, l[i++]);
- Assert.AreEqual(true, l[i++]);
- Assert.AreEqual(true, l[i++]);
- Assert.AreEqual(true, l[i++]);
- Assert.AreEqual(true, l[i++]);
- Assert.AreEqual(true, l[i++]);
- Assert.AreEqual(false, l[i++]);
- Assert.AreEqual(false, l[i++]);
- }
- [Test]
- public void DeserializeNullableBooleans()
- {
- IList<bool?> l = JsonConvert.DeserializeObject<IList<bool?>>(@"[
- 1,
- 0,
- 1.1,
- 0.0,
- 0.000000000001,
- 9999999999,
- -9999999999,
- 9999999999999999999999999999999999999999999999999999999999999999999999,
- -9999999999999999999999999999999999999999999999999999999999999999999999,
- 'true',
- 'TRUE',
- 'false',
- 'FALSE',
- '',
- null
- ]");
- int i = 0;
- Assert.AreEqual(true, l[i++]);
- Assert.AreEqual(false, l[i++]);
- Assert.AreEqual(true, l[i++]);
- Assert.AreEqual(false, l[i++]);
- Assert.AreEqual(true, l[i++]);
- Assert.AreEqual(true, l[i++]);
- Assert.AreEqual(true, l[i++]);
- Assert.AreEqual(true, l[i++]);
- Assert.AreEqual(true, l[i++]);
- Assert.AreEqual(true, l[i++]);
- Assert.AreEqual(true, l[i++]);
- Assert.AreEqual(false, l[i++]);
- Assert.AreEqual(false, l[i++]);
- Assert.AreEqual(null, l[i++]);
- Assert.AreEqual(null, l[i++]);
- }
- #endif
- [Test]
- public void CaseInsensitiveRequiredPropertyConstructorCreation()
- {
- FooRequired foo1 = new FooRequired(new[] { "A", "B", "C" });
- string json = JsonConvert.SerializeObject(foo1);
- StringAssert.AreEqual(@"{""Bars"":[""A"",""B"",""C""]}", json);
- FooRequired foo2 = JsonConvert.DeserializeObject<FooRequired>(json);
- Assert.AreEqual(foo1.Bars.Count, foo2.Bars.Count);
- Assert.AreEqual(foo1.Bars[0], foo2.Bars[0]);
- Assert.AreEqual(foo1.Bars[1], foo2.Bars[1]);
- Assert.AreEqual(foo1.Bars[2], foo2.Bars[2]);
- }
- public class FooRequired
- {
- [JsonProperty(Required = Required.Always)]
- public List<string> Bars { get; private set; }
- public FooRequired(IEnumerable<string> bars)
- {
- Bars = new List<string>();
- if (bars != null)
- {
- Bars.AddRange(bars);
- }
- }
- }
- [Test]
- public void CoercedEmptyStringWithRequired()
- {
- ExceptionAssert.Throws<JsonSerializationException>(() => { JsonConvert.DeserializeObject<Binding>("{requiredProperty:''}"); }, "Required property 'RequiredProperty' expects a value but got null. Path '', line 1, position 21.");
- }
- [Test]
- public void CoercedEmptyStringWithRequired_DisallowNull()
- {
- ExceptionAssert.Throws<JsonSerializationException>(() => { JsonConvert.DeserializeObject<Binding_DisallowNull>("{requiredProperty:''}"); }, "Required property 'RequiredProperty' expects a non-null value. Path '', line 1, position 21.");
- }
- [Test]
- public void DisallowNull_NoValue()
- {
- Binding_DisallowNull o = JsonConvert.DeserializeObject<Binding_DisallowNull>("{}");
- Assert.IsNull(o.RequiredProperty);
- }
- [Test]
- public void CoercedEmptyStringWithRequiredConstructor()
- {
- ExceptionAssert.Throws<JsonSerializationException>(() => { JsonConvert.DeserializeObject<FooRequired>("{Bars:''}"); }, "Required property 'Bars' expects a value but got null. Path '', line 1, position 9.");
- }
- public class IgnoredProperty
- {
- [JsonIgnore]
- [JsonProperty(Required = Required.Always)]
- public string StringProp1 { get; set; }
- [JsonIgnore]
- public string StringProp2 { get; set; }
- }
- [Test]
- public void NoErrorWhenValueDoesNotMatchIgnoredProperty()
- {
- IgnoredProperty p = JsonConvert.DeserializeObject<IgnoredProperty>("{'StringProp1':[1,2,3],'StringProp2':{}}");
- Assert.IsNull(p.StringProp1);
- Assert.IsNull(p.StringProp2);
- }
- public class Binding
- {
- [JsonProperty(Required = Required.Always)]
- public Binding RequiredProperty { get; set; }
- }
- public class Binding_DisallowNull
- {
- [JsonProperty(Required = Required.DisallowNull)]
- public Binding RequiredProperty { get; set; }
- }
- [Test]
- public void Serialize_Required_DisallowedNull()
- {
- ExceptionAssert.Throws<JsonSerializationException>(() => { JsonConvert.SerializeObject(new Binding_DisallowNull()); }, "Cannot write a null value for property 'RequiredProperty'. Property requires a non-null value. Path ''.");
- }
- [Test]
- public void Serialize_Required_DisallowedNull_NullValueHandlingIgnore()
- {
- string json = JsonConvert.SerializeObject(new Binding_DisallowNull(), new JsonSerializerSettings
- {
- NullValueHandling = NullValueHandling.Ignore
- });
- Assert.AreEqual("{}", json);
- }
- [JsonObject(ItemRequired = Required.DisallowNull)]
- public class DictionaryWithNoNull
- {
- public string Name { get; set; }
- }
- [Test]
- public void Serialize_ItemRequired_DisallowedNull()
- {
- ExceptionAssert.Throws<JsonSerializationException>(() => { JsonConvert.SerializeObject(new DictionaryWithNoNull()); }, "Cannot write a null value for property 'Name'. Property requires a non-null value. Path ''.");
- }
- public class DictionaryKeyContractResolver : DefaultContractResolver
- {
- protected override string ResolveDictionaryKey(string dictionaryKey)
- {
- return dictionaryKey;
- }
- protected override string ResolvePropertyName(string propertyName)
- {
- #if DNXCORE50
- return propertyName.ToUpperInvariant();
- #else
- return propertyName.ToUpper(CultureInfo.InvariantCulture);
- #endif
- }
- }
- [Test]
- public void DictionaryKeyContractResolverTest()
- {
- var person = new
- {
- Name = "James",
- Age = 1,
- RoleNames = new Dictionary<string, bool>
- {
- { "IsAdmin", true },
- { "IsModerator", false }
- }
- };
- string json = JsonConvert.SerializeObject(person, Formatting.Indented, new JsonSerializerSettings
- {
- ContractResolver = new DictionaryKeyContractResolver()
- });
- Assert.AreEqual(@"{
- ""NAME"": ""James"",
- ""AGE"": 1,
- ""ROLENAMES"": {
- ""IsAdmin"": true,
- ""IsModerator"": false
- }
- }", json);
- }
- [Test]
- public void IncompleteContainers()
- {
- ExceptionAssert.Throws<JsonSerializationException>(
- () => JsonConvert.DeserializeObject<IList<object>>("[1,"),
- "Unexpected end when deserializing array. Path '[0]', line 1, position 3.");
- ExceptionAssert.Throws<JsonSerializationException>(
- () => JsonConvert.DeserializeObject<IList<int>>("[1,"),
- "Unexpected end when deserializing array. Path '[0]', line 1, position 3.");
- ExceptionAssert.Throws<JsonSerializationException>(
- () => JsonConvert.DeserializeObject<IList<int>>("[1"),
- "Unexpected end when deserializing array. Path '[0]', line 1, position 2.");
- ExceptionAssert.Throws<JsonSerializationException>(
- () => JsonConvert.DeserializeObject<IDictionary<string, int>>("{'key':1,"),
- "Unexpected end when deserializing object. Path 'key', line 1, position 9.");
- ExceptionAssert.Throws<JsonSerializationException>(
- () => JsonConvert.DeserializeObject<IDictionary<string, int>>("{'key':1"),
- "Unexpected end when deserializing object. Path 'key', line 1, position 8.");
- ExceptionAssert.Throws<JsonSerializationException>(
- () => JsonConvert.DeserializeObject<IncompleteTestClass>("{'key':1,"),
- "Unexpected end when deserializing object. Path 'key', line 1, position 9.");
- ExceptionAssert.Throws<JsonSerializationException>(
- () => JsonConvert.DeserializeObject<IncompleteTestClass>("{'key':1"),
- "Unexpected end when deserializing object. Path 'key', line 1, position 8.");
- }
- public class IncompleteTestClass
- {
- public int Key { get; set; }
- }
- #if !NET20
- public enum EnumA
- {
- [EnumMember(Value = "value_a")]
- ValueA
- }
- [Test]
- public void DeserializeEnumsByName()
- {
- var e1 = JsonConvert.DeserializeObject<EnumA>("'ValueA'");
- Assert.AreEqual(EnumA.ValueA, e1);
- var e2 = JsonConvert.DeserializeObject<EnumA>("'value_a'", new StringEnumConverter());
- Assert.AreEqual(EnumA.ValueA, e2);
- }
- #endif
- public class RequiredPropertyTestClass
- {
- [JsonRequired]
- internal string Name { get; set; }
- }
- [Test]
- public void RequiredPropertyTest()
- {
- RequiredPropertyTestClass c1 = new RequiredPropertyTestClass();
- ExceptionAssert.Throws<JsonSerializationException>(
- () => JsonConvert.SerializeObject(c1),
- "Cannot write a null value for property 'Name'. Property requires a value. Path ''.");
- RequiredPropertyTestClass c2 = new RequiredPropertyTestClass
- {
- Name = "Name!"
- };
- string json = JsonConvert.SerializeObject(c2);
- Assert.AreEqual(@"{""Name"":""Name!""}", json);
- ExceptionAssert.Throws<JsonSerializationException>(
- () => JsonConvert.DeserializeObject<RequiredPropertyTestClass>(@"{}"),
- "Required property 'Name' not found in JSON. Path '', line 1, position 2.");
- ExceptionAssert.Throws<JsonSerializationException>(
- () => JsonConvert.DeserializeObject<RequiredPropertyTestClass>(@"{""Name"":null}"),
- "Required property 'Name' expects a value but got null. Path '', line 1, position 13.");
- RequiredPropertyTestClass c3 = JsonConvert.DeserializeObject<RequiredPropertyTestClass>(@"{""Name"":""Name!""}");
- Assert.AreEqual("Name!", c3.Name);
- }
- public class RequiredPropertyConstructorTestClass
- {
- public RequiredPropertyConstructorTestClass(string name)
- {
- Name = name;
- }
- [JsonRequired]
- internal string Name { get; set; }
- }
- [Test]
- public void RequiredPropertyConstructorTest()
- {
- RequiredPropertyConstructorTestClass c1 = new RequiredPropertyConstructorTestClass(null);
- ExceptionAssert.Throws<JsonSerializationException>(
- () => JsonConvert.SerializeObject(c1),
- "Cannot write a null value for property 'Name'. Property requires a value. Path ''.");
- RequiredPropertyConstructorTestClass c2 = new RequiredPropertyConstructorTestClass("Name!");
- string json = JsonConvert.SerializeObject(c2);
- Assert.AreEqual(@"{""Name"":""Name!""}", json);
- ExceptionAssert.Throws<JsonSerializationException>(
- () => JsonConvert.DeserializeObject<RequiredPropertyConstructorTestClass>(@"{}"),
- "Required property 'Name' not found in JSON. Path '', line 1, position 2.");
- RequiredPropertyConstructorTestClass c3 = JsonConvert.DeserializeObject<RequiredPropertyConstructorTestClass>(@"{""Name"":""Name!""}");
- Assert.AreEqual("Name!", c3.Name);
- }
- public class IgnoredPropertiesTestClass
- {
- [JsonIgnore]
- public Version IgnoredProperty { get; set; }
- [JsonIgnore]
- public List<Version> IgnoredList { get; set; }
- [JsonIgnore]
- public Dictionary<string, Version> IgnoredDictionary { get; set; }
- [JsonProperty(Required = Required.Always)]
- public string Name { get; set; }
- }
- public class IgnoredPropertiesContractResolver : DefaultContractResolver
- {
- public override JsonContract ResolveContract(Type type)
- {
- if (type == typeof(Version))
- {
- throw new Exception("Error!");
- }
- return base.ResolveContract(type);
- }
- }
- [Test]
- public void NeverResolveIgnoredPropertyTypes()
- {
- Version v = new Version(1, 2, 3, 4);
- IgnoredPropertiesTestClass c1 = new IgnoredPropertiesTestClass
- {
- IgnoredProperty = v,
- IgnoredList = new List<Version>
- {
- v
- },
- IgnoredDictionary = new Dictionary<string, Version>
- {
- { "Value", v }
- },
- Name = "Name!"
- };
- string json = JsonConvert.SerializeObject(c1, Formatting.Indented, new JsonSerializerSettings
- {
- ContractResolver = new IgnoredPropertiesContractResolver()
- });
- Assert.AreEqual(@"{
- ""Name"": ""Name!""
- }", json);
- string deserializeJson = @"{
- ""IgnoredList"": [
- {
- ""Major"": 1,
- ""Minor"": 2,
- ""Build"": 3,
- ""Revision"": 4,
- ""MajorRevision"": 0,
- ""MinorRevision"": 4
- }
- ],
- ""IgnoredDictionary"": {
- ""Value"": {
- ""Major"": 1,
- ""Minor"": 2,
- ""Build"": 3,
- ""Revision"": 4,
- ""MajorRevision"": 0,
- ""MinorRevision"": 4
- }
- },
- ""Name"": ""Name!""
- }";
- IgnoredPropertiesTestClass c2 = JsonConvert.DeserializeObject<IgnoredPropertiesTestClass>(deserializeJson, new JsonSerializerSettings
- {
- ContractResolver = new IgnoredPropertiesContractResolver()
- });
- Assert.AreEqual("Name!", c2.Name);
- }
- #if !(NET20 || NET35)
- [Test]
- public void SerializeValueTuple()
- {
- ValueTuple<int, int, string> t = ValueTuple.Create(1, 2, "string");
- string json = JsonConvert.SerializeObject(t, Formatting.Indented);
- StringAssert.AreEqual(@"{
- ""Item1"": 1,
- ""Item2"": 2,
- ""Item3"": ""string""
- }", json);
- ValueTuple<int, int, string> t2 = JsonConvert.DeserializeObject<ValueTuple<int, int, string>>(json);
- Assert.AreEqual(1, t2.Item1);
- Assert.AreEqual(2, t2.Item2);
- Assert.AreEqual("string", t2.Item3);
- }
- #endif
- [Test]
- public void DeserializeStructWithConstructorAttribute()
- {
- ImmutableStructWithConstructorAttribute result = JsonConvert.DeserializeObject<ImmutableStructWithConstructorAttribute>("{ \"Value\": \"working\" }");
- Assert.AreEqual("working", result.Value);
- }
- public struct ImmutableStructWithConstructorAttribute
- {
- [JsonConstructor]
- public ImmutableStructWithConstructorAttribute(string value)
- {
- Value = value;
- }
- public string Value { get; }
- }
- #if !(DNXCORE50 || NET20)
- [MetadataType(typeof(CustomerValidation))]
- public partial class CustomerWithMetadataType
- {
- public System.Guid UpdatedBy_Id { get; set; }
- public class CustomerValidation
- {
- [JsonIgnore]
- public System.Guid UpdatedBy_Id { get; set; }
- }
- }
- [Test]
- public void SerializeMetadataType()
- {
- CustomerWithMetadataType c = new CustomerWithMetadataType()
- {
- UpdatedBy_Id = Guid.NewGuid()
- };
- string json = JsonConvert.SerializeObject(c);
- Assert.AreEqual("{}", json);
- CustomerWithMetadataType c2 = JsonConvert.DeserializeObject<CustomerWithMetadataType>("{'UpdatedBy_Id':'F6E0666D-13C7-4745-B486-800812C8F6DE'}");
- Assert.AreEqual(Guid.Empty, c2.UpdatedBy_Id);
- }
- [Serializable]
- public partial class FaqItem
- {
- public FaqItem()
- {
- this.Sections = new HashSet<FaqSection>();
- }
- public int FaqId { get; set; }
- public string Name { get; set; }
- public bool IsDeleted { get; set; }
- public virtual ICollection<FaqSection> Sections { get; set; }
- }
- [MetadataType(typeof(FaqItemMetadata))]
- partial class FaqItem
- {
- [JsonProperty("FullSectionsProp")]
- public ICollection<FaqSection> FullSections
- {
- get { return Sections; }
- }
- }
- public class FaqItemMetadata
- {
- [JsonIgnore]
- public virtual ICollection<FaqSection> Sections { get; set; }
- }
- public class FaqSection
- {
- }
- public class FaqItemProxy : FaqItem
- {
- public bool IsProxy { get; set; }
- public override ICollection<FaqSection> Sections
- {
- get { return base.Sections; }
- set { base.Sections = value; }
- }
- }
- [Test]
- public void SerializeMetadataType2()
- {
- FaqItem c = new FaqItem()
- {
- FaqId = 1,
- Sections =
- {
- new FaqSection()
- }
- };
- string json = JsonConvert.SerializeObject(c, Formatting.Indented);
- StringAssert.AreEqual(@"{
- ""FaqId"": 1,
- ""Name"": null,
- ""IsDeleted"": false,
- ""FullSectionsProp"": [
- {}
- ]
- }", json);
- FaqItem c2 = JsonConvert.DeserializeObject<FaqItem>(json);
- Assert.AreEqual(1, c2.FaqId);
- Assert.AreEqual(1, c2.Sections.Count);
- }
- [Test]
- public void SerializeMetadataTypeInheritance()
- {
- FaqItemProxy c = new FaqItemProxy();
- c.FaqId = 1;
- c.Sections.Add(new FaqSection());
- c.IsProxy = true;
- string json = JsonConvert.SerializeObject(c, Formatting.Indented);
- StringAssert.AreEqual(@"{
- ""IsProxy"": true,
- ""FaqId"": 1,
- ""Name"": null,
- ""IsDeleted"": false,
- ""FullSectionsProp"": [
- {}
- ]
- }", json);
- FaqItemProxy c2 = JsonConvert.DeserializeObject<FaqItemProxy>(json);
- Assert.AreEqual(1, c2.FaqId);
- Assert.AreEqual(1, c2.Sections.Count);
- }
- #endif
- public class NullTestClass
- {
- public JObject Value1 { get; set; }
- public JValue Value2 { get; set; }
- public JRaw Value3 { get; set; }
- public JToken Value4 { get; set; }
- public object Value5 { get; set; }
- }
- [Test]
- public void DeserializeNullToJTokenProperty()
- {
- NullTestClass otc = JsonConvert.DeserializeObject<NullTestClass>(@"{
- ""Value1"": null,
- ""Value2"": null,
- ""Value3"": null,
- ""Value4"": null,
- ""Value5"": null
- }");
- Assert.IsNull(otc.Value1);
- Assert.AreEqual(JTokenType.Null, otc.Value2.Type);
- Assert.AreEqual(JTokenType.Raw, otc.Value3.Type);
- Assert.AreEqual(JTokenType.Null, otc.Value4.Type);
- Assert.IsNull(otc.Value5);
- }
- public class Link
- {
- /// <summary>
- /// The unique identifier.
- /// </summary>
- public int Id;
- /// <summary>
- /// The parent information identifier.
- /// </summary>
- public int ParentId;
- /// <summary>
- /// The child information identifier.
- /// </summary>
- public int ChildId;
- }
- #if !(NET20 || NET35 || PORTABLE40 || PORTABLE)
- [Test]
- public void ReadIntegerWithError()
- {
- string json = @"{
- ParentId: 1,
- ChildId: 333333333333333333333333333333333333333
- }";
- Link l = JsonConvert.DeserializeObject<Link>(json, new JsonSerializerSettings
- {
- Error = (s, a) => a.ErrorContext.Handled = true
- });
- Assert.AreEqual(0, l.ChildId);
- }
- #endif
- #if !(NET20 || NET35)
- [Test]
- public void DeserializeObservableCollection()
- {
- ObservableCollection<string> s = JsonConvert.DeserializeObject<ObservableCollection<string>>("['1','2']");
- Assert.AreEqual(2, s.Count);
- Assert.AreEqual("1", s[0]);
- Assert.AreEqual("2", s[1]);
- }
- #endif
- [Test]
- public void DeserializeBoolAsStringInDictionary()
- {
- Dictionary<string, string> d = JsonConvert.DeserializeObject<Dictionary<string, string>>("{\"Test1\":false}");
- Assert.AreEqual(1, d.Count);
- Assert.AreEqual("false", d["Test1"]);
- }
- #if !NET20
- [Test]
- public void PopulateResetSettings()
- {
- JsonTextReader reader = new JsonTextReader(new StringReader(@"[""2000-01-01T01:01:01+00:00""]"));
- Assert.AreEqual(DateParseHandling.DateTime, reader.DateParseHandling);
- JsonSerializer serializer = new JsonSerializer();
- serializer.DateParseHandling = DateParseHandling.DateTimeOffset;
- IList<object> l = new List<object>();
- serializer.Populate(reader, l);
- Assert.AreEqual(typeof(DateTimeOffset), l[0].GetType());
- Assert.AreEqual(new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero), l[0]);
- Assert.AreEqual(DateParseHandling.DateTime, reader.DateParseHandling);
- }
- #endif
- public class BaseClass
- {
- internal bool IsTransient { get; set; }
- }
- public class ChildClass : BaseClass
- {
- public new bool IsTransient { get; set; }
- }
- [Test]
- public void NewProperty()
- {
- Assert.AreEqual(@"{""IsTransient"":true}", JsonConvert.SerializeObject(new ChildClass { IsTransient = true }));
- var childClass = JsonConvert.DeserializeObject<ChildClass>(@"{""IsTransient"":true}");
- Assert.AreEqual(true, childClass.IsTransient);
- }
- public class BaseClassVirtual
- {
- internal virtual bool IsTransient { get; set; }
- }
- public class ChildClassVirtual : BaseClassVirtual
- {
- public new virtual bool IsTransient { get; set; }
- }
- [Test]
- public void NewPropertyVirtual()
- {
- Assert.AreEqual(@"{""IsTransient"":true}", JsonConvert.SerializeObject(new ChildClassVirtual { IsTransient = true }));
- var childClass = JsonConvert.DeserializeObject<ChildClassVirtual>(@"{""IsTransient"":true}");
- Assert.AreEqual(true, childClass.IsTransient);
- }
- public class ResponseWithNewGenericProperty<T> : SimpleResponse
- {
- public new T Data { get; set; }
- }
- public class ResponseWithNewGenericPropertyVirtual<T> : SimpleResponse
- {
- public new virtual T Data { get; set; }
- }
- public class ResponseWithNewGenericPropertyOverride<T> : ResponseWithNewGenericPropertyVirtual<T>
- {
- public override T Data { get; set; }
- }
- public abstract class SimpleResponse
- {
- public string Result { get; set; }
- public string Message { get; set; }
- public object Data { get; set; }
- protected SimpleResponse()
- {
- }
- protected SimpleResponse(string message)
- {
- Message = message;
- }
- }
- [Test]
- public void CanSerializeWithBuiltInTypeAsGenericArgument()
- {
- var input = new ResponseWithNewGenericProperty<int>()
- {
- Message = "Trying out integer as type parameter",
- Data = 25,
- Result = "This should be fine"
- };
- var json = JsonConvert.SerializeObject(input);
- var deserialized = JsonConvert.DeserializeObject<ResponseWithNewGenericProperty<int>>(json);
- Assert.AreEqual(input.Data, deserialized.Data);
- Assert.AreEqual(input.Message, deserialized.Message);
- Assert.AreEqual(input.Result, deserialized.Result);
- }
- [Test]
- public void CanSerializeWithBuiltInTypeAsGenericArgumentVirtual()
- {
- var input = new ResponseWithNewGenericPropertyVirtual<int>()
- {
- Message = "Trying out integer as type parameter",
- Data = 25,
- Result = "This should be fine"
- };
- var json = JsonConvert.SerializeObject(input);
- var deserialized = JsonConvert.DeserializeObject<ResponseWithNewGenericPropertyVirtual<int>>(json);
- Assert.AreEqual(input.Data, deserialized.Data);
- Assert.AreEqual(input.Message, deserialized.Message);
- Assert.AreEqual(input.Result, deserialized.Result);
- }
- [Test]
- public void CanSerializeWithBuiltInTypeAsGenericArgumentOverride()
- {
- var input = new ResponseWithNewGenericPropertyOverride<int>()
- {
- Message = "Trying out integer as type parameter",
- Data = 25,
- Result = "This should be fine"
- };
- var json = JsonConvert.SerializeObject(input);
- var deserialized = JsonConvert.DeserializeObject<ResponseWithNewGenericPropertyOverride<int>>(json);
- Assert.AreEqual(input.Data, deserialized.Data);
- Assert.AreEqual(input.Message, deserialized.Message);
- Assert.AreEqual(input.Result, deserialized.Result);
- }
- [Test]
- public void CanSerializedWithGenericClosedTypeAsArgument()
- {
- var input = new ResponseWithNewGenericProperty<List<int>>()
- {
- Message = "More complex case - generic list of int",
- Data = Enumerable.Range(50, 70).ToList(),
- Result = "This should be fine too"
- };
- var json = JsonConvert.SerializeObject(input);
- var deserialized = JsonConvert.DeserializeObject<ResponseWithNewGenericProperty<List<int>>>(json);
- CollectionAssert.AreEqual(input.Data, deserialized.Data);
- Assert.AreEqual(input.Message, deserialized.Message);
- Assert.AreEqual(input.Result, deserialized.Result);
- }
- [Test]
- public void DeserializeVersionString()
- {
- string json = "['1.2.3.4']";
- List<Version> deserialized = JsonConvert.DeserializeObject<List<Version>>(json);
- Assert.AreEqual(1, deserialized[0].Major);
- Assert.AreEqual(2, deserialized[0].Minor);
- Assert.AreEqual(3, deserialized[0].Build);
- Assert.AreEqual(4, deserialized[0].Revision);
- }
- [Test]
- public void DeserializeVersionString_Fail()
- {
- string json = "['1.2.3.4444444444444444444444']";
- ExceptionAssert.Throws<JsonSerializationException>(() => { JsonConvert.DeserializeObject<List<Version>>(json); }, @"Error converting value ""1.2.3.4444444444444444444444"" to type 'System.Version'. Path '[0]', line 1, position 31.");
- }
- [Test]
- public void DeserializeJObjectWithComments()
- {
- string json = @"/* Test */
- {
- /*Test*/""A"":/* Test */true/* Test */,
- /* Test */""B"":/* Test */false/* Test */,
- /* Test */""C"":/* Test */[
- /* Test */
- 1/* Test */
- ]/* Test */
- }
- /* Test */";
- JObject o = (JObject)JsonConvert.DeserializeObject(json);
- Assert.AreEqual(3, o.Count);
- Assert.AreEqual(true, (bool)o["A"]);
- Assert.AreEqual(false, (bool)o["B"]);
- Assert.AreEqual(1, o["C"].Count());
- Assert.AreEqual(1, (int)o["C"][0]);
- Assert.IsTrue(JToken.DeepEquals(o, JObject.Parse(json)));
- json = @"{/* Test */}";
- o = (JObject)JsonConvert.DeserializeObject(json);
- Assert.AreEqual(0, o.Count);
- Assert.IsTrue(JToken.DeepEquals(o, JObject.Parse(json)));
- json = @"{""A"": true/* Test */}";
- o = (JObject)JsonConvert.DeserializeObject(json);
- Assert.AreEqual(1, o.Count);
- Assert.AreEqual(true, (bool)o["A"]);
- Assert.IsTrue(JToken.DeepEquals(o, JObject.Parse(json)));
- }
- public class CommentTestObject
- {
- public bool? A { get; set; }
- }
- [Test]
- public void DeserializeCommentTestObjectWithComments()
- {
- CommentTestObject o = JsonConvert.DeserializeObject<CommentTestObject>(@"{/* Test */}");
- Assert.AreEqual(null, o.A);
- o = JsonConvert.DeserializeObject<CommentTestObject>(@"{""A"": true/* Test */}");
- Assert.AreEqual(true, o.A);
- }
- [Test]
- public void JsonSerializerProperties()
- {
- JsonSerializer serializer = new JsonSerializer();
- DefaultSerializationBinder customBinder = new DefaultSerializationBinder();
- #pragma warning disable CS0618 // Type or member is obsolete
- serializer.Binder = customBinder;
- Assert.AreEqual(customBinder, serializer.Binder);
- #pragma warning restore CS0618 // Type or member is obsolete
- Assert.IsInstanceOf(typeof(SerializationBinderAdapter), serializer.SerializationBinder);
- serializer.SerializationBinder = customBinder;
- Assert.AreEqual(customBinder, serializer.SerializationBinder);
- ExceptionAssert.Throws<InvalidOperationException>(() =>
- {
- #pragma warning disable CS0618 // Type or member is obsolete
- var serializationBinder = serializer.Binder;
- #pragma warning restore CS0618 // Type or member is obsolete
- serializationBinder.ToString();
- }, "Cannot get SerializationBinder because an ISerializationBinder was previously set.");
- serializer.CheckAdditionalContent = true;
- Assert.AreEqual(true, serializer.CheckAdditionalContent);
- serializer.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor;
- Assert.AreEqual(ConstructorHandling.AllowNonPublicDefaultConstructor, serializer.ConstructorHandling);
- #if !(DNXCORE50)
- serializer.Context = new StreamingContext(StreamingContextStates.Other);
- Assert.AreEqual(new StreamingContext(StreamingContextStates.Other), serializer.Context);
- #endif
- CamelCasePropertyNamesContractResolver resolver = new CamelCasePropertyNamesContractResolver();
- serializer.ContractResolver = resolver;
- Assert.AreEqual(resolver, serializer.ContractResolver);
- serializer.Converters.Add(new StringEnumConverter());
- Assert.AreEqual(1, serializer.Converters.Count);
- serializer.Culture = new CultureInfo("en-nz");
- Assert.AreEqual("en-NZ", serializer.Culture.ToString());
- serializer.EqualityComparer = EqualityComparer<object>.Default;
- Assert.AreEqual(EqualityComparer<object>.Default, serializer.EqualityComparer);
- serializer.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat;
- Assert.AreEqual(DateFormatHandling.MicrosoftDateFormat, serializer.DateFormatHandling);
- serializer.DateFormatString = "yyyy";
- Assert.AreEqual("yyyy", serializer.DateFormatString);
- serializer.DateParseHandling = DateParseHandling.None;
- Assert.AreEqual(DateParseHandling.None, serializer.DateParseHandling);
- serializer.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
- Assert.AreEqual(DateTimeZoneHandling.Utc, serializer.DateTimeZoneHandling);
- serializer.DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate;
- Assert.AreEqual(DefaultValueHandling.IgnoreAndPopulate, serializer.DefaultValueHandling);
- serializer.FloatFormatHandling = FloatFormatHandling.Symbol;
- Assert.AreEqual(FloatFormatHandling.Symbol, serializer.FloatFormatHandling);
- serializer.FloatParseHandling = FloatParseHandling.Decimal;
- Assert.AreEqual(FloatParseHandling.Decimal, serializer.FloatParseHandling);
- serializer.Formatting = Formatting.Indented;
- Assert.AreEqual(Formatting.Indented, serializer.Formatting);
- serializer.MaxDepth = 9001;
- Assert.AreEqual(9001, serializer.MaxDepth);
- serializer.MissingMemberHandling = MissingMemberHandling.Error;
- Assert.AreEqual(MissingMemberHandling.Error, serializer.MissingMemberHandling);
- serializer.NullValueHandling = NullValueHandling.Ignore;
- Assert.AreEqual(NullValueHandling.Ignore, serializer.NullValueHandling);
- serializer.ObjectCreationHandling = ObjectCreationHandling.Replace;
- Assert.AreEqual(ObjectCreationHandling.Replace, serializer.ObjectCreationHandling);
- serializer.PreserveReferencesHandling = PreserveReferencesHandling.All;
- Assert.AreEqual(PreserveReferencesHandling.All, serializer.PreserveReferencesHandling);
- serializer.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
- Assert.AreEqual(ReferenceLoopHandling.Ignore, serializer.ReferenceLoopHandling);
- IdReferenceResolver referenceResolver = new IdReferenceResolver();
- serializer.ReferenceResolver = referenceResolver;
- Assert.AreEqual(referenceResolver, serializer.ReferenceResolver);
- serializer.StringEscapeHandling = StringEscapeHandling.EscapeNonAscii;
- Assert.AreEqual(StringEscapeHandling.EscapeNonAscii, serializer.StringEscapeHandling);
- MemoryTraceWriter traceWriter = new MemoryTraceWriter();
- serializer.TraceWriter = traceWriter;
- Assert.AreEqual(traceWriter, serializer.TraceWriter);
- #if !(PORTABLE || PORTABLE40 || NET20 || DNXCORE50)
- #pragma warning disable 618
- serializer.TypeNameAssemblyFormat = FormatterAssemblyStyle.Full;
- Assert.AreEqual(FormatterAssemblyStyle.Full, serializer.TypeNameAssemblyFormat);
- #pragma warning restore 618
- Assert.AreEqual(TypeNameAssemblyFormatHandling.Full, serializer.TypeNameAssemblyFormatHandling);
- serializer.TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple;
- #pragma warning disable 618
- Assert.AreEqual(FormatterAssemblyStyle.Simple, serializer.TypeNameAssemblyFormat);
- #pragma warning restore 618
- #endif
- serializer.TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Full;
- Assert.AreEqual(TypeNameAssemblyFormatHandling.Full, serializer.TypeNameAssemblyFormatHandling);
- serializer.TypeNameHandling = TypeNameHandling.All;
- Assert.AreEqual(TypeNameHandling.All, serializer.TypeNameHandling);
- }
- [Test]
- public void JsonSerializerSettingsProperties()
- {
- JsonSerializerSettings settings = new JsonSerializerSettings();
- DefaultSerializationBinder customBinder = new DefaultSerializationBinder();
- #pragma warning disable CS0618 // Type or member is obsolete
- settings.Binder = customBinder;
- Assert.AreEqual(customBinder, settings.Binder);
- #pragma warning restore CS0618 // Type or member is obsolete
- settings.CheckAdditionalContent = true;
- Assert.AreEqual(true, settings.CheckAdditionalContent);
- settings.ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor;
- Assert.AreEqual(ConstructorHandling.AllowNonPublicDefaultConstructor, settings.ConstructorHandling);
- #if !(DNXCORE50)
- settings.Context = new StreamingContext(StreamingContextStates.Other);
- Assert.AreEqual(new StreamingContext(StreamingContextStates.Other), settings.Context);
- #endif
- CamelCasePropertyNamesContractResolver resolver = new CamelCasePropertyNamesContractResolver();
- settings.ContractResolver = resolver;
- Assert.AreEqual(resolver, settings.ContractResolver);
- settings.Converters.Add(new StringEnumConverter());
- Assert.AreEqual(1, settings.Converters.Count);
- settings.Culture = new CultureInfo("en-nz");
- Assert.AreEqual("en-NZ", settings.Culture.ToString());
- settings.EqualityComparer = EqualityComparer<object>.Default;
- Assert.AreEqual(EqualityComparer<object>.Default, settings.EqualityComparer);
- settings.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat;
- Assert.AreEqual(DateFormatHandling.MicrosoftDateFormat, settings.DateFormatHandling);
- settings.DateFormatString = "yyyy";
- As…
Large files files are truncated, but you can click here to view the full file