diff --git a/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs index f98ad14d..b33bd86b 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs @@ -243,6 +243,8 @@ namespace Newtonsoft.Json.Tests.Linq byte[] data = new byte[0]; Assert.AreEqual(data, (byte[])(new JValue(data))); + + Assert.AreEqual(5, (int)(new JValue(StringComparison.OrdinalIgnoreCase))); } [Test] diff --git a/Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs index f2798e2c..0f158f7f 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs @@ -66,6 +66,10 @@ namespace Newtonsoft.Json.Tests.Linq Assert.AreEqual(data, v.Value); Assert.AreEqual(JTokenType.Bytes, v.Type); + + v.Value = StringComparison.OrdinalIgnoreCase; + Assert.AreEqual(StringComparison.OrdinalIgnoreCase, v.Value); + Assert.AreEqual(JTokenType.Integer, v.Type); } [Test] diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Compact.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Compact.csproj index c8a92c47..5b44a1b9 100644 --- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Compact.csproj +++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Compact.csproj @@ -23,7 +23,7 @@ true full false - bin\Debug\ + bin\Debug\Compact\ TRACE;DEBUG;PocketPC true true @@ -35,7 +35,7 @@ pdbonly true - bin\Release\ + bin\Release\Compact\ TRACE;$(PlatformFamilyName) true true diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj index a5382d9e..c08454b2 100644 --- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj +++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj @@ -33,7 +33,7 @@ true full false - bin\Debug\ + bin\Debug\DotNet20\ TRACE;DEBUG;NET20 prompt 4 @@ -41,7 +41,7 @@ pdbonly true - bin\Release\ + bin\Release\DotNet20\ TRACE prompt 4 diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj index 08b88c78..f337bdc2 100644 --- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj +++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj @@ -22,7 +22,7 @@ true full false - Bin\Debug + Bin\Debug\Silverlight\ DEBUG;TRACE;SILVERLIGHT true true @@ -32,7 +32,7 @@ pdbonly true - Bin\Release + Bin\Release\Silverlight\ TRACE;SILVERLIGHT true true diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj index 121ef0fa..54352dbd 100644 --- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj +++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj @@ -31,7 +31,7 @@ true full false - bin\Debug\ + bin\Debug\DotNet\ DEBUG;TRACE prompt 4 @@ -39,7 +39,7 @@ pdbonly true - bin\Release\ + bin\Release\DotNet\ TRACE prompt 4 diff --git a/Src/Newtonsoft.Json.Tests/PerformanceTests.cs b/Src/Newtonsoft.Json.Tests/PerformanceTests.cs index 70e2e3d0..038e3617 100644 --- a/Src/Newtonsoft.Json.Tests/PerformanceTests.cs +++ b/Src/Newtonsoft.Json.Tests/PerformanceTests.cs @@ -33,8 +33,8 @@ namespace Newtonsoft.Json.Tests public class PerformanceTests : TestFixtureBase { - private const int Iterations = 100; - //private const int Iterations = 5000; + //private const int Iterations = 100; + private const int Iterations = 5000; #region Data private const string BsonHex = @@ -472,6 +472,39 @@ namespace Newtonsoft.Json.Tests return (T)formatter.Deserialize(new MemoryStream(bytes)); } #endregion + + + + [Test] + public void SerializeLargeObject() + { + LargeRecursiveTestClass rootValue = null; + LargeRecursiveTestClass parentValue = null; + for (int i = 0; i < 20; i++) + { + LargeRecursiveTestClass currentValue = new LargeRecursiveTestClass() + { + Integer = int.MaxValue, + Text = "The quick red fox jumped over the lazy dog." + }; + + if (rootValue == null) + rootValue = currentValue; + if (parentValue != null) + parentValue.Child = currentValue; + + parentValue = currentValue; + } + + BenchmarkSerializeMethod(SerializeMethod.JsonNetBinary, rootValue); + } + } + + public class LargeRecursiveTestClass + { + public LargeRecursiveTestClass Child { get; set; } + public string Text { get; set; } + public int Integer { get; set; } } #region Classes diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs index f6991179..450e30d6 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs @@ -3372,5 +3372,31 @@ keyword such as type of business."" Assert.AreEqual(4.3, d[1]); Assert.AreEqual(null, d[2]); } + +#if !SILVERLIGHT && !NET20 && !PocketPC + [Test] + public void SerializeHashSet() + { + string jsonText = JsonConvert.SerializeObject(new HashSet() + { + "One", + "2", + "III" + }, Formatting.Indented); + + Assert.AreEqual(@"[ + ""One"", + ""2"", + ""III"" +]", jsonText); + + HashSet d = JsonConvert.DeserializeObject>(jsonText); + + Assert.AreEqual(3, d.Count); + Assert.IsTrue(d.Contains("One")); + Assert.IsTrue(d.Contains("2")); + Assert.IsTrue(d.Contains("III")); + } +#endif } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs index ec3c40e3..a3e844f2 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs @@ -26,10 +26,13 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.Serialization.Formatters; using System.Text; using Newtonsoft.Json.Linq; using Newtonsoft.Json.Tests.TestObjects; using NUnit.Framework; +using Newtonsoft.Json.Utilities; +using System.Net; namespace Newtonsoft.Json.Tests.Serialization { @@ -38,7 +41,7 @@ namespace Newtonsoft.Json.Tests.Serialization [Test] public void WriteTypeNameForObjects() { - string employeeRef = typeof(EmployeeReference).AssemblyQualifiedName; + string employeeRef = ReflectionUtils.GetTypeName(typeof(EmployeeReference), FormatterAssemblyStyle.Simple); EmployeeReference employee = new EmployeeReference(); @@ -58,7 +61,7 @@ namespace Newtonsoft.Json.Tests.Serialization [Test] public void DeserializeTypeName() { - string employeeRef = typeof(EmployeeReference).AssemblyQualifiedName; + string employeeRef = ReflectionUtils.GetTypeName(typeof(EmployeeReference), FormatterAssemblyStyle.Simple); string json = @"{ ""$id"": ""1"", @@ -76,6 +79,26 @@ namespace Newtonsoft.Json.Tests.Serialization Assert.AreEqual("Name!", ((EmployeeReference)employee).Name); } +#if !SILVERLIGHT && !PocketPC + [Test] + public void DeserializeTypeNameFromGacAssembly() + { + string cookieRef = ReflectionUtils.GetTypeName(typeof(Cookie), FormatterAssemblyStyle.Simple); + + string json = @"{ + ""$id"": ""1"", + ""$type"": """ + cookieRef + @""" +}"; + + object cookie = JsonConvert.DeserializeObject(json, null, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Objects + }); + + Assert.IsInstanceOfType(typeof(Cookie), cookie); + } +#endif + [Test] public void SerializeGenericObjectListWithTypeName() { @@ -101,7 +124,8 @@ namespace Newtonsoft.Json.Tests.Serialization string json = JsonConvert.SerializeObject(values, Formatting.Indented, new JsonSerializerSettings { - TypeNameHandling = TypeNameHandling.Objects + TypeNameHandling = TypeNameHandling.Objects, + TypeNameAssemblyFormat = FormatterAssemblyStyle.Full }); Assert.AreEqual(@"[ @@ -157,7 +181,8 @@ namespace Newtonsoft.Json.Tests.Serialization List values = (List)JsonConvert.DeserializeObject(json, typeof(List), new JsonSerializerSettings { - TypeNameHandling = TypeNameHandling.Objects + TypeNameHandling = TypeNameHandling.Objects, + TypeNameAssemblyFormat = FormatterAssemblyStyle.Full }); Assert.AreEqual(4, values.Count); @@ -191,7 +216,8 @@ namespace Newtonsoft.Json.Tests.Serialization JsonConvert.DeserializeObject(json, typeof(Person), new JsonSerializerSettings { - TypeNameHandling = TypeNameHandling.Objects + TypeNameHandling = TypeNameHandling.Objects, + TypeNameAssemblyFormat = FormatterAssemblyStyle.Full }); } @@ -275,7 +301,8 @@ namespace Newtonsoft.Json.Tests.Serialization ICorrelatedMessage message = JsonConvert.DeserializeObject(json, new JsonSerializerSettings { - TypeNameHandling = TypeNameHandling.Objects + TypeNameHandling = TypeNameHandling.Objects, + TypeNameAssemblyFormat = FormatterAssemblyStyle.Full }); Assert.IsInstanceOfType(typeof(SendHttpRequest), message); @@ -302,7 +329,8 @@ namespace Newtonsoft.Json.Tests.Serialization new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, - TypeNameHandling = TypeNameHandling.All + TypeNameHandling = TypeNameHandling.All, + TypeNameAssemblyFormat = FormatterAssemblyStyle.Full }); Assert.AreEqual(@"{ @@ -317,5 +345,86 @@ namespace Newtonsoft.Json.Tests.Serialization } }", json); } + + public class TypeNameProperty + { + public string Name { get; set; } + [JsonProperty(TypeNameHandling = TypeNameHandling.All)] + public object Value { get; set; } + } + + [Test] + public void WriteObjectTypeNameForProperty() + { + string typeNamePropertyRef = ReflectionUtils.GetTypeName(typeof(TypeNameProperty), FormatterAssemblyStyle.Simple); + + TypeNameProperty typeNameProperty = new TypeNameProperty + { + Name = "Name!", + Value = new TypeNameProperty + { + Name = "Nested!" + } + }; + + string json = JsonConvert.SerializeObject(typeNameProperty, Formatting.Indented); + + Assert.AreEqual(@"{ + ""Name"": ""Name!"", + ""Value"": { + ""$type"": """ + typeNamePropertyRef + @""", + ""Name"": ""Nested!"", + ""Value"": null + } +}", json); + + TypeNameProperty deserialized = JsonConvert.DeserializeObject(json); + Assert.AreEqual("Name!", deserialized.Name); + Assert.IsInstanceOfType(typeof(TypeNameProperty), deserialized.Value); + + TypeNameProperty nested = (TypeNameProperty)deserialized.Value; + Assert.AreEqual("Nested!", nested.Name); + Assert.AreEqual(null, nested.Value); + } + + [Test] + public void WriteListTypeNameForProperty() + { + string listRef = ReflectionUtils.GetTypeName(typeof(List), FormatterAssemblyStyle.Simple); + + TypeNameProperty typeNameProperty = new TypeNameProperty + { + Name = "Name!", + Value = new List { 1, 2, 3, 4, 5 } + }; + + string json = JsonConvert.SerializeObject(typeNameProperty, Formatting.Indented); + + Assert.AreEqual(@"{ + ""Name"": ""Name!"", + ""Value"": { + ""$type"": """ + listRef + @""", + ""$values"": [ + 1, + 2, + 3, + 4, + 5 + ] + } +}", json); + + TypeNameProperty deserialized = JsonConvert.DeserializeObject(json); + Assert.AreEqual("Name!", deserialized.Name); + Assert.IsInstanceOfType(typeof(List), deserialized.Value); + + List nested = (List)deserialized.Value; + Assert.AreEqual(5, nested.Count); + Assert.AreEqual(1, nested[0]); + Assert.AreEqual(2, nested[1]); + Assert.AreEqual(3, nested[2]); + Assert.AreEqual(4, nested[3]); + Assert.AreEqual(5, nested[4]); + } } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Converters/JavaScriptDateTimeConverter.cs b/Src/Newtonsoft.Json/Converters/JavaScriptDateTimeConverter.cs index 323e85b1..4d709db4 100644 --- a/Src/Newtonsoft.Json/Converters/JavaScriptDateTimeConverter.cs +++ b/Src/Newtonsoft.Json/Converters/JavaScriptDateTimeConverter.cs @@ -48,6 +48,7 @@ namespace Newtonsoft.Json.Converters /// /// The to read from. /// Type of the object. + /// The existing property value of the JSON that is being converted. /// The calling serializer. /// The object value. public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) diff --git a/Src/Newtonsoft.Json/FormatterAssemblyStyle.cs b/Src/Newtonsoft.Json/FormatterAssemblyStyle.cs new file mode 100644 index 00000000..7cfff8ba --- /dev/null +++ b/Src/Newtonsoft.Json/FormatterAssemblyStyle.cs @@ -0,0 +1,19 @@ +#if SILVERLIGHT || PocketPC +namespace System.Runtime.Serialization.Formatters +{ + /// + /// Indicates the method that will be used during deserialization for locating and loading assemblies. + /// + public enum FormatterAssemblyStyle + { + /// + /// In simple mode, the assembly used during deserialization need not match exactly the assembly used during serialization. Specifically, the version numbers need not match as the LoadWithPartialName method is used to load the assembly. + /// + Simple, + /// + /// In full mode, the assembly used during deserialization must match exactly the assembly used during serialization. The Load method of the Assembly class is used to load the assembly. + /// + Full + } +} +#endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json/JsonPropertyAttribute.cs b/Src/Newtonsoft.Json/JsonPropertyAttribute.cs index bde08649..f4b2895d 100644 --- a/Src/Newtonsoft.Json/JsonPropertyAttribute.cs +++ b/Src/Newtonsoft.Json/JsonPropertyAttribute.cs @@ -14,6 +14,7 @@ namespace Newtonsoft.Json internal DefaultValueHandling? _defaultValueHandling; internal ReferenceLoopHandling? _referenceLoopHandling; internal ObjectCreationHandling? _objectCreationHandling; + internal TypeNameHandling? _typeNameHandling; internal bool? _isReference; /// @@ -56,6 +57,12 @@ namespace Newtonsoft.Json set { _objectCreationHandling = value; } } + public TypeNameHandling TypeNameHandling + { + get { return _typeNameHandling ?? default(TypeNameHandling); } + set { _typeNameHandling = value; } + } + /// /// Gets or sets whether this property's value is serialized as a reference. /// diff --git a/Src/Newtonsoft.Json/JsonSerializer.cs b/Src/Newtonsoft.Json/JsonSerializer.cs index f759597c..655db63f 100644 --- a/Src/Newtonsoft.Json/JsonSerializer.cs +++ b/Src/Newtonsoft.Json/JsonSerializer.cs @@ -26,6 +26,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Runtime.Serialization.Formatters; using Newtonsoft.Json.Converters; using Newtonsoft.Json.Serialization; using Newtonsoft.Json.Utilities; @@ -42,6 +43,7 @@ namespace Newtonsoft.Json { #region Properties private TypeNameHandling _typeNameHandling; + private FormatterAssemblyStyle _typeNameAssemblyFormat; private PreserveReferencesHandling _preserveReferencesHandling; private ReferenceLoopHandling _referenceLoopHandling; private MissingMemberHandling _missingMemberHandling; @@ -114,6 +116,22 @@ namespace Newtonsoft.Json } } + /// + /// Gets or sets how a type name assembly is written and resolved by the serializer. + /// + /// The type name assembly format. + public virtual FormatterAssemblyStyle TypeNameAssemblyFormat + { + get { return _typeNameAssemblyFormat; } + set + { + if (value < FormatterAssemblyStyle.Simple || value > FormatterAssemblyStyle.Full) + throw new ArgumentOutOfRangeException("value"); + + _typeNameAssemblyFormat = value; + } + } + /// /// Gets or sets how object references are preserved by the serializer. /// @@ -296,6 +314,7 @@ namespace Newtonsoft.Json jsonSerializer.Converters.AddRange(settings.Converters); jsonSerializer.TypeNameHandling = settings.TypeNameHandling; + jsonSerializer.TypeNameAssemblyFormat = settings.TypeNameAssemblyFormat; jsonSerializer.PreserveReferencesHandling = settings.PreserveReferencesHandling; jsonSerializer.ReferenceLoopHandling = settings.ReferenceLoopHandling; jsonSerializer.MissingMemberHandling = settings.MissingMemberHandling; diff --git a/Src/Newtonsoft.Json/JsonSerializerSettings.cs b/Src/Newtonsoft.Json/JsonSerializerSettings.cs index d8532f43..6537c66d 100644 --- a/Src/Newtonsoft.Json/JsonSerializerSettings.cs +++ b/Src/Newtonsoft.Json/JsonSerializerSettings.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.Serialization.Formatters; using System.Text; using Newtonsoft.Json.Serialization; using Newtonsoft.Json.Utilities; @@ -21,6 +22,7 @@ namespace Newtonsoft.Json internal const PreserveReferencesHandling DefaultPreserveReferencesHandling = PreserveReferencesHandling.None; internal const ConstructorHandling DefaultConstructorHandling = ConstructorHandling.Default; internal const TypeNameHandling DefaultTypeNameHandling = TypeNameHandling.None; + internal const FormatterAssemblyStyle DefaultTypeNameAssemblyFormat = FormatterAssemblyStyle.Simple; internal static readonly StreamingContext DefaultContext = new StreamingContext(); /// @@ -28,41 +30,55 @@ namespace Newtonsoft.Json /// /// Reference loop handling. public ReferenceLoopHandling ReferenceLoopHandling { get; set; } + /// /// Gets or sets how missing members (e.g. JSON contains a property that isn't a member on the object) are handled during deserialization. /// /// Missing member handling. public MissingMemberHandling MissingMemberHandling { get; set; } + /// /// Gets or sets how objects are created during deserialization. /// /// The object creation handling. public ObjectCreationHandling ObjectCreationHandling { get; set; } + /// /// Gets or sets how null values are handled during serialization and deserialization. /// /// Null value handling. public NullValueHandling NullValueHandling { get; set; } + /// /// Gets or sets how null default are handled during serialization and deserialization. /// /// The default value handling. public DefaultValueHandling DefaultValueHandling { get; set; } + /// /// Gets or sets a collection that will be used during serialization. /// /// The converters. public IList Converters { get; set; } + /// /// Gets or sets how object references are preserved by the serializer. /// /// The preserve references handling. public PreserveReferencesHandling PreserveReferencesHandling { get; set; } + /// /// Gets or sets how type name writing and reading is handled by the serializer. /// /// The type name handling. public TypeNameHandling TypeNameHandling { get; set; } + + /// + /// Gets or sets how a type name assembly is written and resolved by the serializer. + /// + /// The type name assembly format. + public FormatterAssemblyStyle TypeNameAssemblyFormat { get; set; } + /// /// Gets or sets how constructors are used during deserialization. /// @@ -75,11 +91,13 @@ namespace Newtonsoft.Json /// /// The contract resolver. public IContractResolver ContractResolver { get; set; } + /// /// Gets or sets the used by the serializer when resolving references. /// /// The reference resolver. public IReferenceResolver ReferenceResolver { get; set; } + /// /// Gets or sets the used by the serializer when resolving type names. /// @@ -110,6 +128,7 @@ namespace Newtonsoft.Json DefaultValueHandling = DefaultDefaultValueHandling; PreserveReferencesHandling = DefaultPreserveReferencesHandling; TypeNameHandling = DefaultTypeNameHandling; + TypeNameAssemblyFormat = DefaultTypeNameAssemblyFormat; Context = DefaultContext; Converters = new List(); } diff --git a/Src/Newtonsoft.Json/Linq/JValue.cs b/Src/Newtonsoft.Json/Linq/JValue.cs index 3150345c..79d8155a 100644 --- a/Src/Newtonsoft.Json/Linq/JValue.cs +++ b/Src/Newtonsoft.Json/Linq/JValue.cs @@ -209,6 +209,8 @@ namespace Newtonsoft.Json.Linq else if (value is long || value is int || value is short || value is sbyte || value is ulong || value is uint || value is ushort || value is byte) return JTokenType.Integer; + else if (value is Enum) + return JTokenType.Integer; else if (value is double || value is float || value is decimal) return JTokenType.Float; else if (value is DateTime) diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj index 0bd69f59..68b28712 100644 --- a/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj +++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj @@ -23,7 +23,7 @@ true full false - bin\Debug\ + bin\Debug\Compact\ DEBUG;TRACE;$(PlatformFamilyName) true true @@ -37,7 +37,7 @@ pdbonly true - bin\Release\ + bin\Release\Compact\ TRACE;$(PlatformFamilyName) true true @@ -45,7 +45,7 @@ 512 4 Off - bin\Release\Newtonsoft.Json.Compact.xml + bin\Release\Compact\Newtonsoft.Json.Compact.xml @@ -75,6 +75,7 @@ + diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj index 9317497b..cc2dfb51 100644 --- a/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj +++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj @@ -48,22 +48,22 @@ true full false - bin\Debug\ + bin\Debug\DotNet20\ TRACE;DEBUG;NET20 prompt 4 - bin\Debug\Newtonsoft.Json.Net20.xml + bin\Debug\DotNet20\Newtonsoft.Json.Net20.xml true -Microsoft.Design#CA1012;-Microsoft.Design#CA2210;-Microsoft.Design#CA1040;-Microsoft.Design#CA1005;-Microsoft.Design#CA1020;-Microsoft.Design#CA1021;-Microsoft.Design#CA1010;-Microsoft.Design#CA1011;-Microsoft.Design#CA1009;-Microsoft.Design#CA1050;-Microsoft.Design#CA1026;-Microsoft.Design#CA1019;-Microsoft.Design#CA1031;-Microsoft.Design#CA1047;-Microsoft.Design#CA1000;-Microsoft.Design#CA1048;-Microsoft.Design#CA1051;-Microsoft.Design#CA1002;-Microsoft.Design#CA1061;-Microsoft.Design#CA1006;-Microsoft.Design#CA1046;-Microsoft.Design#CA1045;-Microsoft.Design#CA1065;-Microsoft.Design#CA1038;-Microsoft.Design#CA1008;-Microsoft.Design#CA1028;-Microsoft.Design#CA1064;-Microsoft.Design#CA1004;-Microsoft.Design#CA1035;-Microsoft.Design#CA1063;-Microsoft.Design#CA1032;-Microsoft.Design#CA1023;-Microsoft.Design#CA1033;-Microsoft.Design#CA1039;-Microsoft.Design#CA1016;-Microsoft.Design#CA1014;-Microsoft.Design#CA1017;-Microsoft.Design#CA1018;-Microsoft.Design#CA1027;-Microsoft.Design#CA1059;-Microsoft.Design#CA1060;-Microsoft.Design#CA1034;-Microsoft.Design#CA1013;-Microsoft.Design#CA1036;-Microsoft.Design#CA1044;-Microsoft.Design#CA1041;-Microsoft.Design#CA1025;-Microsoft.Design#CA1052;-Microsoft.Design#CA1053;-Microsoft.Design#CA1057;-Microsoft.Design#CA1058;-Microsoft.Design#CA1001;-Microsoft.Design#CA1049;-Microsoft.Design#CA1054;-Microsoft.Design#CA1056;-Microsoft.Design#CA1055;-Microsoft.Design#CA1030;-Microsoft.Design#CA1003;-Microsoft.Design#CA1007;-Microsoft.Design#CA1043;-Microsoft.Design#CA1024;-Microsoft.Globalization#CA1301;-Microsoft.Globalization#CA1302;-Microsoft.Globalization#CA1308;-Microsoft.Globalization#CA1306;-Microsoft.Globalization#CA2101;-Microsoft.Globalization#CA1300;-Microsoft.Globalization#CA1307;-Microsoft.Globalization#CA1309;-Microsoft.Interoperability#CA1403;-Microsoft.Interoperability#CA1406;-Microsoft.Interoperability#CA1413;-Microsoft.Interoperability#CA1402;-Microsoft.Interoperability#CA1407;-Microsoft.Interoperability#CA1404;-Microsoft.Interoperability#CA1410;-Microsoft.Interoperability#CA1411;-Microsoft.Interoperability#CA1405;-Microsoft.Interoperability#CA1409;-Microsoft.Interoperability#CA1415;-Microsoft.Interoperability#CA1408;-Microsoft.Interoperability#CA1414;-Microsoft.Interoperability#CA1412;-Microsoft.Interoperability#CA1400;-Microsoft.Interoperability#CA1401;-Microsoft.Maintainability#CA1506;-Microsoft.Maintainability#CA1502;-Microsoft.Maintainability#CA1501;-Microsoft.Maintainability#CA1505;-Microsoft.Maintainability#CA1504;-Microsoft.Maintainability#CA1500;-Microsoft.Mobility#CA1600;-Microsoft.Mobility#CA1601;-Microsoft.Naming#CA1702;-Microsoft.Naming#CA1700;-Microsoft.Naming#CA1712;-Microsoft.Naming#CA1713;-Microsoft.Naming#CA1714;-Microsoft.Naming#CA1709;-Microsoft.Naming#CA1704;-Microsoft.Naming#CA1708;-Microsoft.Naming#CA1715;-Microsoft.Naming#CA1710;-Microsoft.Naming#CA1720;-Microsoft.Naming#CA1707;-Microsoft.Naming#CA1722;-Microsoft.Naming#CA1711;-Microsoft.Naming#CA1716;-Microsoft.Naming#CA1717;-Microsoft.Naming#CA1725;-Microsoft.Naming#CA1719;-Microsoft.Naming#CA1721;-Microsoft.Naming#CA1701;-Microsoft.Naming#CA1703;-Microsoft.Naming#CA1724;-Microsoft.Naming#CA1726;-Microsoft.Performance#CA1809;-Microsoft.Performance#CA1811;-Microsoft.Performance#CA1812;-Microsoft.Performance#CA1813;-Microsoft.Performance#CA1823;-Microsoft.Performance#CA1800;-Microsoft.Performance#CA1805;-Microsoft.Performance#CA1810;-Microsoft.Performance#CA1824;-Microsoft.Performance#CA1822;-Microsoft.Performance#CA1815;-Microsoft.Performance#CA1814;-Microsoft.Performance#CA1819;-Microsoft.Performance#CA1821;-Microsoft.Performance#CA1804;-Microsoft.Performance#CA1820;-Microsoft.Performance#CA1802;+!Microsoft.Portability#CA1903;-Microsoft.Portability#CA1901;-Microsoft.Portability#CA1900;-Microsoft.Reliability#CA2001;-Microsoft.Reliability#CA2002;-Microsoft.Reliability#CA2003;-Microsoft.Reliability#CA2004;-Microsoft.Reliability#CA2006;-Microsoft.Security#CA2116;-Microsoft.Security#CA2117;-Microsoft.Security#CA2105;-Microsoft.Security#CA2115;-Microsoft.Security#CA2102;-Microsoft.Security#CA2104;-Microsoft.Security#CA2122;-Microsoft.Security#CA2114;-Microsoft.Security#CA2123;-Microsoft.Security#CA2111;-Microsoft.Security#CA2108;-Microsoft.Security#CA2107;-Microsoft.Security#CA2103;-Microsoft.Security#CA2118;-Microsoft.Security#CA2109;-Microsoft.Security#CA2119;-Microsoft.Security#CA2106;-Microsoft.Security#CA2112;-Microsoft.Security#CA2120;-Microsoft.Security#CA2121;-Microsoft.Security#CA2126;-Microsoft.Security#CA2124;-Microsoft.Security#CA2127;-Microsoft.Security#CA2128;-Microsoft.Security#CA2129;-Microsoft.Usage#CA2243;-Microsoft.Usage#CA2236;-Microsoft.Usage#CA1816;-Microsoft.Usage#CA2227;-Microsoft.Usage#CA2213;-Microsoft.Usage#CA2216;-Microsoft.Usage#CA2214;-Microsoft.Usage#CA2222;-Microsoft.Usage#CA1806;-Microsoft.Usage#CA2217;-Microsoft.Usage#CA2212;-Microsoft.Usage#CA2219;-Microsoft.Usage#CA2201;-Microsoft.Usage#CA2228;-Microsoft.Usage#CA2221;-Microsoft.Usage#CA2220;-Microsoft.Usage#CA2240;-Microsoft.Usage#CA2229;-Microsoft.Usage#CA2238;-Microsoft.Usage#CA2207;-Microsoft.Usage#CA2208;-Microsoft.Usage#CA2235;-Microsoft.Usage#CA2237;-Microsoft.Usage#CA2232;-Microsoft.Usage#CA2223;-Microsoft.Usage#CA2211;-Microsoft.Usage#CA2233;-Microsoft.Usage#CA2225;-Microsoft.Usage#CA2226;-Microsoft.Usage#CA2231;-Microsoft.Usage#CA2224;-Microsoft.Usage#CA2218;-Microsoft.Usage#CA2234;-Microsoft.Usage#CA2239;-Microsoft.Usage#CA2200;-Microsoft.Usage#CA1801;-Microsoft.Usage#CA2242;-Microsoft.Usage#CA2205;-Microsoft.Usage#CA2230 pdbonly true - bin\Release\ + bin\Release\DotNet20\ TRACE;NET20 prompt 4 - bin\Release\Newtonsoft.Json.Net20.xml + bin\Release\DotNet20\Newtonsoft.Json.Net20.xml diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj index f11cc1f1..b13d894b 100644 --- a/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj +++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj @@ -24,24 +24,24 @@ true full false - Bin\Debug + Bin\Debug\Silverlight\ DEBUG;TRACE;SILVERLIGHT true true prompt 4 - Bin\Debug\Newtonsoft.Json.Silverlight.xml + Bin\Debug\Silverlight\Newtonsoft.Json.Silverlight.xml pdbonly true - Bin\Release + Bin\Release\Silverlight\ TRACE;SILVERLIGHT true true prompt 4 - Bin\Release\Newtonsoft.Json.Silverlight.xml + Bin\Release\Silverlight\Newtonsoft.Json.Silverlight.xml @@ -77,6 +77,7 @@ + diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.csproj index 313e58bc..49cb6bd8 100644 --- a/Src/Newtonsoft.Json/Newtonsoft.Json.csproj +++ b/Src/Newtonsoft.Json/Newtonsoft.Json.csproj @@ -46,22 +46,22 @@ true full false - bin\Debug\ + bin\Debug\DotNet\ DEBUG;TRACE prompt 4 - bin\Debug\Newtonsoft.Json.xml + bin\Debug\DotNet\Newtonsoft.Json.xml true -Microsoft.Design#CA1012;-Microsoft.Design#CA2210;-Microsoft.Design#CA1040;-Microsoft.Design#CA1005;-Microsoft.Design#CA1020;-Microsoft.Design#CA1021;-Microsoft.Design#CA1010;-Microsoft.Design#CA1011;-Microsoft.Design#CA1009;-Microsoft.Design#CA1050;-Microsoft.Design#CA1026;-Microsoft.Design#CA1019;-Microsoft.Design#CA1031;-Microsoft.Design#CA1047;-Microsoft.Design#CA1000;-Microsoft.Design#CA1048;-Microsoft.Design#CA1051;-Microsoft.Design#CA1002;-Microsoft.Design#CA1061;-Microsoft.Design#CA1006;-Microsoft.Design#CA1046;-Microsoft.Design#CA1045;-Microsoft.Design#CA1065;-Microsoft.Design#CA1038;-Microsoft.Design#CA1008;-Microsoft.Design#CA1028;-Microsoft.Design#CA1064;-Microsoft.Design#CA1004;-Microsoft.Design#CA1035;-Microsoft.Design#CA1063;-Microsoft.Design#CA1032;-Microsoft.Design#CA1023;-Microsoft.Design#CA1033;-Microsoft.Design#CA1039;-Microsoft.Design#CA1016;-Microsoft.Design#CA1014;-Microsoft.Design#CA1017;-Microsoft.Design#CA1018;-Microsoft.Design#CA1027;-Microsoft.Design#CA1059;-Microsoft.Design#CA1060;-Microsoft.Design#CA1034;-Microsoft.Design#CA1013;-Microsoft.Design#CA1036;-Microsoft.Design#CA1044;-Microsoft.Design#CA1041;-Microsoft.Design#CA1025;-Microsoft.Design#CA1052;-Microsoft.Design#CA1053;-Microsoft.Design#CA1057;-Microsoft.Design#CA1058;-Microsoft.Design#CA1001;-Microsoft.Design#CA1049;-Microsoft.Design#CA1054;-Microsoft.Design#CA1056;-Microsoft.Design#CA1055;-Microsoft.Design#CA1030;-Microsoft.Design#CA1003;-Microsoft.Design#CA1007;-Microsoft.Design#CA1043;-Microsoft.Design#CA1024;-Microsoft.Globalization#CA1301;-Microsoft.Globalization#CA1302;-Microsoft.Globalization#CA1308;-Microsoft.Globalization#CA1306;-Microsoft.Globalization#CA2101;-Microsoft.Globalization#CA1300;-Microsoft.Globalization#CA1307;-Microsoft.Globalization#CA1309;-Microsoft.Interoperability#CA1403;-Microsoft.Interoperability#CA1406;-Microsoft.Interoperability#CA1413;-Microsoft.Interoperability#CA1402;-Microsoft.Interoperability#CA1407;-Microsoft.Interoperability#CA1404;-Microsoft.Interoperability#CA1410;-Microsoft.Interoperability#CA1411;-Microsoft.Interoperability#CA1405;-Microsoft.Interoperability#CA1409;-Microsoft.Interoperability#CA1415;-Microsoft.Interoperability#CA1408;-Microsoft.Interoperability#CA1414;-Microsoft.Interoperability#CA1412;-Microsoft.Interoperability#CA1400;-Microsoft.Interoperability#CA1401;-Microsoft.Maintainability#CA1506;-Microsoft.Maintainability#CA1502;-Microsoft.Maintainability#CA1501;-Microsoft.Maintainability#CA1505;-Microsoft.Maintainability#CA1504;-Microsoft.Maintainability#CA1500;-Microsoft.Mobility#CA1600;-Microsoft.Mobility#CA1601;-Microsoft.Naming#CA1702;-Microsoft.Naming#CA1700;-Microsoft.Naming#CA1712;-Microsoft.Naming#CA1713;-Microsoft.Naming#CA1714;-Microsoft.Naming#CA1709;-Microsoft.Naming#CA1704;-Microsoft.Naming#CA1708;-Microsoft.Naming#CA1715;-Microsoft.Naming#CA1710;-Microsoft.Naming#CA1720;-Microsoft.Naming#CA1707;-Microsoft.Naming#CA1722;-Microsoft.Naming#CA1711;-Microsoft.Naming#CA1716;-Microsoft.Naming#CA1717;-Microsoft.Naming#CA1725;-Microsoft.Naming#CA1719;-Microsoft.Naming#CA1721;-Microsoft.Naming#CA1701;-Microsoft.Naming#CA1703;-Microsoft.Naming#CA1724;-Microsoft.Naming#CA1726;-Microsoft.Performance#CA1809;-Microsoft.Performance#CA1811;-Microsoft.Performance#CA1812;-Microsoft.Performance#CA1813;-Microsoft.Performance#CA1823;-Microsoft.Performance#CA1800;-Microsoft.Performance#CA1805;-Microsoft.Performance#CA1810;-Microsoft.Performance#CA1824;-Microsoft.Performance#CA1822;-Microsoft.Performance#CA1815;-Microsoft.Performance#CA1814;-Microsoft.Performance#CA1819;-Microsoft.Performance#CA1821;-Microsoft.Performance#CA1804;-Microsoft.Performance#CA1820;-Microsoft.Performance#CA1802;-Microsoft.Portability#CA1901;-Microsoft.Portability#CA1900;-Microsoft.Reliability#CA2001;-Microsoft.Reliability#CA2002;-Microsoft.Reliability#CA2003;-Microsoft.Reliability#CA2004;-Microsoft.Reliability#CA2006;-Microsoft.Security#CA2116;-Microsoft.Security#CA2117;-Microsoft.Security#CA2105;-Microsoft.Security#CA2115;-Microsoft.Security#CA2102;-Microsoft.Security#CA2104;-Microsoft.Security#CA2122;-Microsoft.Security#CA2114;-Microsoft.Security#CA2123;-Microsoft.Security#CA2111;-Microsoft.Security#CA2108;-Microsoft.Security#CA2107;-Microsoft.Security#CA2103;-Microsoft.Security#CA2118;-Microsoft.Security#CA2109;-Microsoft.Security#CA2119;-Microsoft.Security#CA2106;-Microsoft.Security#CA2112;-Microsoft.Security#CA2120;-Microsoft.Security#CA2121;-Microsoft.Security#CA2126;-Microsoft.Security#CA2124;-Microsoft.Security#CA2127;-Microsoft.Security#CA2128;-Microsoft.Security#CA2129;-Microsoft.Usage#CA2243;-Microsoft.Usage#CA2236;-Microsoft.Usage#CA1816;-Microsoft.Usage#CA2227;-Microsoft.Usage#CA2213;-Microsoft.Usage#CA2216;-Microsoft.Usage#CA2214;-Microsoft.Usage#CA2222;-Microsoft.Usage#CA1806;-Microsoft.Usage#CA2217;-Microsoft.Usage#CA2212;-Microsoft.Usage#CA2219;-Microsoft.Usage#CA2201;-Microsoft.Usage#CA2228;-Microsoft.Usage#CA2221;-Microsoft.Usage#CA2220;-Microsoft.Usage#CA2240;-Microsoft.Usage#CA2229;-Microsoft.Usage#CA2238;-Microsoft.Usage#CA2207;-Microsoft.Usage#CA2208;-Microsoft.Usage#CA2235;-Microsoft.Usage#CA2237;-Microsoft.Usage#CA2232;-Microsoft.Usage#CA2223;-Microsoft.Usage#CA2211;-Microsoft.Usage#CA2233;-Microsoft.Usage#CA2225;-Microsoft.Usage#CA2226;-Microsoft.Usage#CA2231;-Microsoft.Usage#CA2224;-Microsoft.Usage#CA2218;-Microsoft.Usage#CA2234;-Microsoft.Usage#CA2239;-Microsoft.Usage#CA2200;-Microsoft.Usage#CA1801;-Microsoft.Usage#CA2242;-Microsoft.Usage#CA2205;-Microsoft.Usage#CA2230 pdbonly true - bin\Release\ + bin\Release\DotNet\ TRACE prompt 4 - bin\Release\Newtonsoft.Json.xml + bin\Release\DotNet\Newtonsoft.Json.xml diff --git a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs index 06868e5d..ccf41511 100644 --- a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs +++ b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs @@ -460,22 +460,20 @@ namespace Newtonsoft.Json.Serialization if (objectType.IsSubclassOf(typeof(JToken))) return CreateLinqContract(objectType); - bool canConvertToString = CanConvertToString(objectType); - -#if !SILVERLIGHT && !PocketPC - if (typeof(ISerializable).IsAssignableFrom(objectType) && !canConvertToString) - return CreateISerializableContract(objectType); -#endif - if (CollectionUtils.IsDictionaryType(objectType)) return CreateDictionaryContract(objectType); if (typeof(IEnumerable).IsAssignableFrom(objectType)) return CreateArrayContract(objectType); - if (canConvertToString) + if (CanConvertToString(objectType)) return CreateStringContract(objectType); +#if !SILVERLIGHT && !PocketPC + if (typeof(ISerializable).IsAssignableFrom(objectType)) + return CreateISerializableContract(objectType); +#endif + return CreateObjectContract(objectType); } @@ -668,6 +666,7 @@ namespace Newtonsoft.Json.Serialization property.DefaultValueHandling = (propertyAttribute != null) ? propertyAttribute._defaultValueHandling : null; property.ReferenceLoopHandling = (propertyAttribute != null) ? propertyAttribute._referenceLoopHandling : null; property.ObjectCreationHandling = (propertyAttribute != null) ? propertyAttribute._objectCreationHandling : null; + property.TypeNameHandling = (propertyAttribute != null) ? propertyAttribute._typeNameHandling : null; property.IsReference = (propertyAttribute != null) ? propertyAttribute._isReference : null; property.ShouldSerialize = CreateShouldSerializeTest(member); diff --git a/Src/Newtonsoft.Json/Serialization/DefaultSerializationBinder.cs b/Src/Newtonsoft.Json/Serialization/DefaultSerializationBinder.cs index 8e102006..c4b6145d 100644 --- a/Src/Newtonsoft.Json/Serialization/DefaultSerializationBinder.cs +++ b/Src/Newtonsoft.Json/Serialization/DefaultSerializationBinder.cs @@ -50,13 +50,24 @@ namespace Newtonsoft.Json.Serialization { if (assemblyName != null) { - Assembly assembly = Assembly.Load(assemblyName); + Assembly assembly; + +#if !SILVERLIGHT && !PocketPC + // look, I don't like using obsolete methods as much as you do but this is the only way + // Assembly.Load won't check the GAC for a partial name +#pragma warning disable 618,612 + assembly = Assembly.LoadWithPartialName(assemblyName); +#pragma warning restore 618,612 +#else + assembly = Assembly.Load(assemblyName); +#endif + if (assembly == null) throw new JsonSerializationException("Could not load assembly '{0}'.".FormatWith(CultureInfo.InvariantCulture, assemblyName)); Type type = assembly.GetType(typeName); if (type == null) - throw new JsonSerializationException("Could not find type '{0}'.".FormatWith(CultureInfo.InvariantCulture, typeName)); + throw new JsonSerializationException("Could not find type '{0}' in assembly '{1}'.".FormatWith(CultureInfo.InvariantCulture, typeName, assembly.FullName)); return type; } diff --git a/Src/Newtonsoft.Json/Serialization/JsonProperty.cs b/Src/Newtonsoft.Json/Serialization/JsonProperty.cs index f7732344..77cec849 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonProperty.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonProperty.cs @@ -127,6 +127,8 @@ namespace Newtonsoft.Json.Serialization public Predicate ShouldSerialize { get; set; } + public TypeNameHandling? TypeNameHandling { get; set; } + /// /// Returns a that represents this instance. /// diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs index 3dfb147c..b2003e7d 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs @@ -192,7 +192,7 @@ namespace Newtonsoft.Json.Serialization return converter.ReadJson(reader, objectType, currentValue, GetInternalSerializer()); } - return CreateValueInternal(reader, objectType, contract, currentValue); + return CreateValueInternal(reader, objectType, contract, property, currentValue); } private object CreateValueNonProperty(JsonReader reader, Type objectType, JsonContract contract) @@ -202,10 +202,10 @@ namespace Newtonsoft.Json.Serialization if (converter != null && converter.CanRead) return converter.ReadJson(reader, objectType, null, GetInternalSerializer()); - return CreateValueInternal(reader, objectType, contract, null); + return CreateValueInternal(reader, objectType, contract, null, null); } - private object CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, object existingValue) + private object CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, object existingValue) { if (contract is JsonLinqContract) return CreateJToken(reader, contract); @@ -217,9 +217,9 @@ namespace Newtonsoft.Json.Serialization // populate a typed object or generic dictionary/array // depending upon whether an objectType was supplied case JsonToken.StartObject: - return CreateObject(reader, objectType, contract, existingValue); + return CreateObject(reader, objectType, contract, member, existingValue); case JsonToken.StartArray: - return CreateList(reader, objectType, contract, existingValue, null); + return CreateList(reader, objectType, contract, member, existingValue, null); case JsonToken.Integer: case JsonToken.Float: case JsonToken.Boolean: @@ -282,7 +282,7 @@ namespace Newtonsoft.Json.Serialization return converter; } - private object CreateObject(JsonReader reader, Type objectType, JsonContract contract, object existingValue) + private object CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, object existingValue) { CheckedRead(reader); @@ -317,7 +317,7 @@ namespace Newtonsoft.Json.Serialization CheckedRead(reader); - if (Serializer.TypeNameHandling != TypeNameHandling.None) + if ((((member != null) ? member.TypeNameHandling : null) ?? Serializer.TypeNameHandling) != TypeNameHandling.None) { string typeName; string assemblyName; @@ -355,7 +355,7 @@ namespace Newtonsoft.Json.Serialization else if (string.Equals(propertyName, JsonTypeReflector.ArrayValuesPropertyName, StringComparison.Ordinal)) { CheckedRead(reader); - object list = CreateList(reader, objectType, contract, existingValue, id); + object list = CreateList(reader, objectType, contract, member, existingValue, id); CheckedRead(reader); return list; } @@ -420,7 +420,7 @@ namespace Newtonsoft.Json.Serialization throw new JsonSerializationException("Unexpected end when deserializing object."); } - private object CreateList(JsonReader reader, Type objectType, JsonContract contract, object existingValue, string reference) + private object CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, object existingValue, string reference) { object value; if (HasDefinedType(objectType)) diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs index 43bafd81..b15b7957 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs @@ -30,6 +30,7 @@ using System.ComponentModel; using System.Globalization; using System.Linq; using System.Reflection; +using System.Runtime.Serialization.Formatters; using Newtonsoft.Json.Linq; using Newtonsoft.Json.Utilities; using System.Runtime.Serialization; @@ -80,9 +81,9 @@ namespace Newtonsoft.Json.Serialization return Serializer.ContractResolver.ResolveContract(value.GetType()); } - private void SerializeValue(JsonWriter writer, object value, JsonConverter memberConverter, JsonContract contract) + private void SerializeValue(JsonWriter writer, object value, JsonProperty member, JsonContract contract) { - JsonConverter converter = memberConverter; + JsonConverter converter = (member != null) ? member.Converter : null; if (value == null) { @@ -108,22 +109,22 @@ namespace Newtonsoft.Json.Serialization } else if (contract is JsonObjectContract) { - SerializeObject(writer, value, (JsonObjectContract) contract); + SerializeObject(writer, value, (JsonObjectContract) contract, member); } else if (contract is JsonDictionaryContract) { JsonDictionaryContract dictionaryContract = (JsonDictionaryContract) contract; - SerializeDictionary(writer, dictionaryContract.CreateWrapper(value), dictionaryContract); + SerializeDictionary(writer, dictionaryContract.CreateWrapper(value), dictionaryContract, member); } else if (contract is JsonArrayContract) { if (value is IList) { - SerializeList(writer, (IList) value, (JsonArrayContract) contract); + SerializeList(writer, (IList) value, (JsonArrayContract) contract, member); } else if (value is IEnumerable) { - SerializeEnumerable(writer, (IEnumerable) value, (JsonArrayContract) contract); + SerializeList(writer, ((IEnumerable)value).Cast().ToList(), (JsonArrayContract)contract, member); } else { @@ -162,11 +163,7 @@ namespace Newtonsoft.Json.Serialization if (isReference == null) { - if (value is IList) - isReference = HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Arrays); - else if (value is IDictionary) - isReference = HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects); - else if (value is IEnumerable) + if (contract is JsonArrayContract) isReference = HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Arrays); else isReference = HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Objects); @@ -181,7 +178,6 @@ namespace Newtonsoft.Json.Serialization private void WriteMemberInfoProperty(JsonWriter writer, object memberValue, JsonProperty property, JsonContract contract) { string propertyName = property.PropertyName; - JsonConverter memberConverter = property.MemberConverter; object defaultValue = property.DefaultValue; if (property.NullValueHandling.GetValueOrDefault(Serializer.NullValueHandling) == NullValueHandling.Ignore && @@ -203,7 +199,7 @@ namespace Newtonsoft.Json.Serialization return; writer.WritePropertyName(propertyName); - SerializeValue(writer, memberValue, memberConverter, contract); + SerializeValue(writer, memberValue, property, contract); } private bool CheckForCircularReference(object value, ReferenceLoopHandling? referenceLoopHandling, JsonContract contract) @@ -290,7 +286,7 @@ namespace Newtonsoft.Json.Serialization contract.InvokeOnSerialized(value, Serializer.Context); } - private void SerializeObject(JsonWriter writer, object value, JsonObjectContract contract) + private void SerializeObject(JsonWriter writer, object value, JsonObjectContract contract, JsonProperty member) { contract.InvokeOnSerializing(value, Serializer.Context); @@ -303,7 +299,7 @@ namespace Newtonsoft.Json.Serialization writer.WritePropertyName(JsonTypeReflector.IdPropertyName); writer.WriteValue(Serializer.ReferenceResolver.GetReference(value)); } - if (HasFlag(Serializer.TypeNameHandling, TypeNameHandling.Objects)) + if (HasFlag(((member != null) ? member.TypeNameHandling : null) ?? Serializer.TypeNameHandling, TypeNameHandling.Objects)) { WriteTypeProperty(writer, contract.UnderlyingType); } @@ -340,7 +336,7 @@ namespace Newtonsoft.Json.Serialization private void WriteTypeProperty(JsonWriter writer, Type type) { writer.WritePropertyName(JsonTypeReflector.TypePropertyName); - writer.WriteValue(type.AssemblyQualifiedName); + writer.WriteValue(ReflectionUtils.GetTypeName(type, Serializer.TypeNameAssemblyFormat)); } private bool HasFlag(PreserveReferencesHandling value, PreserveReferencesHandling flag) @@ -372,19 +368,14 @@ namespace Newtonsoft.Json.Serialization } } - private void SerializeEnumerable(JsonWriter writer, IEnumerable values, JsonArrayContract contract) - { - SerializeList(writer, values.Cast().ToList(), contract); - } - - private void SerializeList(JsonWriter writer, IList values, JsonArrayContract contract) + private void SerializeList(JsonWriter writer, IList values, JsonArrayContract contract, JsonProperty member) { contract.InvokeOnSerializing(values, Serializer.Context); SerializeStack.Add(values); bool isReference = contract.IsReference ?? HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Arrays); - bool includeTypeDetails = HasFlag(Serializer.TypeNameHandling, TypeNameHandling.Arrays); + bool includeTypeDetails = HasFlag(((member != null) ? member.TypeNameHandling : null) ?? Serializer.TypeNameHandling, TypeNameHandling.Arrays); if (isReference || includeTypeDetails) { @@ -470,7 +461,7 @@ namespace Newtonsoft.Json.Serialization } #endif - private void SerializeDictionary(JsonWriter writer, IWrappedDictionary values, JsonDictionaryContract contract) + private void SerializeDictionary(JsonWriter writer, IWrappedDictionary values, JsonDictionaryContract contract, JsonProperty member) { contract.InvokeOnSerializing(values.UnderlyingDictionary, Serializer.Context); @@ -483,7 +474,7 @@ namespace Newtonsoft.Json.Serialization writer.WritePropertyName(JsonTypeReflector.IdPropertyName); writer.WriteValue(Serializer.ReferenceResolver.GetReference(values.UnderlyingDictionary)); } - if (HasFlag(Serializer.TypeNameHandling, TypeNameHandling.Objects)) + if (HasFlag(((member != null) ? member.TypeNameHandling : null) ?? Serializer.TypeNameHandling, TypeNameHandling.Objects)) { WriteTypeProperty(writer, values.UnderlyingDictionary.GetType()); } diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerProxy.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerProxy.cs index 11c8672b..44636821 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonSerializerProxy.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerProxy.cs @@ -24,6 +24,7 @@ #endregion using System; +using System.Runtime.Serialization.Formatters; using Newtonsoft.Json.Utilities; using System.Runtime.Serialization; @@ -100,6 +101,12 @@ namespace Newtonsoft.Json.Serialization set { _serializer.TypeNameHandling = value; } } + public override FormatterAssemblyStyle TypeNameAssemblyFormat + { + get { return _serializer.TypeNameAssemblyFormat; } + set { _serializer.TypeNameAssemblyFormat = value; } + } + public override ConstructorHandling ConstructorHandling { get { return _serializer.ConstructorHandling; } diff --git a/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs b/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs index 0482c70d..e1d72611 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs @@ -267,6 +267,8 @@ namespace Newtonsoft.Json.Serialization try { new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand(); + new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess).Demand(); + new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); _dynamicCodeGeneration = true; } catch (Exception) diff --git a/Src/Newtonsoft.Json/Utilities/CollectionUtils.cs b/Src/Newtonsoft.Json/Utilities/CollectionUtils.cs index 012fbede..7e20b0ef 100644 --- a/Src/Newtonsoft.Json/Utilities/CollectionUtils.cs +++ b/Src/Newtonsoft.Json/Utilities/CollectionUtils.cs @@ -473,7 +473,7 @@ namespace Newtonsoft.Json.Utilities } } - public static IList CreateAndPopulateList(Type listType, Action populateList) + public static object CreateAndPopulateList(Type listType, Action populateList) { ValidationUtils.ArgumentNotNull(listType, "listType"); ValidationUtils.ArgumentNotNull(populateList, "populateList"); @@ -526,9 +526,12 @@ namespace Newtonsoft.Json.Utilities else list = null; } - else if (ReflectionUtils.ImplementsGenericDefinition(listType, typeof(IList<>))) + else if (ReflectionUtils.ImplementsGenericDefinition(listType, typeof(ICollection<>))) { - list = CreateGenericList(ReflectionUtils.GetCollectionItemType(listType)); + if (ReflectionUtils.IsInstantiatableType(listType)) + list = CreateCollectionWrapper(Activator.CreateInstance(listType)); + else + list = null; } else { @@ -548,6 +551,10 @@ namespace Newtonsoft.Json.Utilities else if (ReflectionUtils.InheritsGenericDefinition(listType, typeof(ReadOnlyCollection<>))) list = (IList)ReflectionUtils.CreateInstance(listType, list); } + else if (list is IWrappedCollection) + { + return ((IWrappedCollection) list).UnderlyingCollection; + } return list; } diff --git a/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs b/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs index 5f33fa28..3d4a0ce6 100644 --- a/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs +++ b/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs @@ -29,6 +29,7 @@ using System.Reflection; using System.Collections; using System.Linq; using System.Globalization; +using System.Runtime.Serialization.Formatters; namespace Newtonsoft.Json.Utilities { @@ -39,6 +40,19 @@ namespace Newtonsoft.Json.Utilities return (v != null) ? v.GetType() : null; } + public static string GetTypeName(Type t, FormatterAssemblyStyle assemblyFormat) + { + switch (assemblyFormat) + { + case FormatterAssemblyStyle.Simple: + return t.FullName + ", " + t.Assembly.GetName().Name; + case FormatterAssemblyStyle.Full: + return t.AssemblyQualifiedName; + default: + throw new ArgumentOutOfRangeException(); + } + } + public static bool IsInstantiatableType(Type t) { ValidationUtils.ArgumentNotNull(t, "t");