diff --git a/Build/build.ps1 b/Build/build.ps1 index 633e88c5..d5f94049 100644 --- a/Build/build.ps1 +++ b/Build/build.ps1 @@ -1,6 +1,6 @@ properties { $zipFileName = "Json60r1.zip" - $majorVersion = "4.5" + $majorVersion = "6.0" $majorWithReleaseVersion = "6.0.1" $version = GetVersion $majorWithReleaseVersion $signAssemblies = $false diff --git a/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs index 8148c450..ed21e90e 100644 --- a/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs +++ b/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs @@ -74,5 +74,5 @@ using System.Security; // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("4.5.0.0")] -[assembly: AssemblyFileVersion("6.0.1.16919")] +[assembly: AssemblyVersion("6.0.0.0")] +[assembly: AssemblyFileVersion("6.0.1.16929")] diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs index 917f1f89..5a654f6d 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs @@ -7341,7 +7341,7 @@ Parameter name: value", JsonSerializer serializer = new JsonSerializer(); MultipleItemsClass foo = serializer.Deserialize(reader); - + values.Add(foo); } @@ -8775,7 +8775,7 @@ Parameter name: value", ExtensionDataDeserializeWithNonDefaultConstructor c = new ExtensionDataDeserializeWithNonDefaultConstructor("Name!"); c._extensionData = new Dictionary { - {"Key!", "Value!"} + { "Key!", "Value!" } }; string json = JsonConvert.SerializeObject(c, Formatting.Indented); diff --git a/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs index c5a894c9..5684dbbc 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs @@ -54,6 +54,61 @@ namespace Newtonsoft.Json.Tests.Serialization [TestFixture] public class TypeNameHandlingTests : TestFixtureBase { + [Test] + public void DictionaryAuto() + { + Dictionary dic = new Dictionary + { + { "movie", new Movie { Name = "Die Hard"}} + }; + + string json = JsonConvert.SerializeObject(dic, Formatting.Indented, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Auto + }); + + Assert.AreEqual(@"{ + ""movie"": { + ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Movie, Newtonsoft.Json.Tests"", + ""Name"": ""Die Hard"", + ""Description"": null, + ""Classification"": null, + ""Studio"": null, + ""ReleaseDate"": null, + ""ReleaseCountries"": null + } +}", json); + } + + [Test] + public void KeyValuePairAuto() + { + IList> dic = new List> + { + new KeyValuePair("movie", new Movie { Name = "Die Hard"}) + }; + + string json = JsonConvert.SerializeObject(dic, Formatting.Indented, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Auto + }); + + Assert.AreEqual(@"[ + { + ""Key"": ""movie"", + ""Value"": { + ""$type"": ""Newtonsoft.Json.Tests.TestObjects.Movie, Newtonsoft.Json.Tests"", + ""Name"": ""Die Hard"", + ""Description"": null, + ""Classification"": null, + ""Studio"": null, + ""ReleaseDate"": null, + ""ReleaseCountries"": null + } + } +]", json); + } + [Test] public void NestedValueObjects() { diff --git a/Src/Newtonsoft.Json.Tests/Serialization/WebApiIntegrationTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/WebApiIntegrationTests.cs index d9b190ad..1f77c184 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/WebApiIntegrationTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/WebApiIntegrationTests.cs @@ -143,7 +143,7 @@ namespace Newtonsoft.Json.Tests.Serialization #else [JsonIgnore] #endif - public string nonSerializedField; + public string nonSerializedField; public bool Equals(SerializableType other) { diff --git a/Src/Newtonsoft.Json/Converters/KeyValuePairConverter.cs b/Src/Newtonsoft.Json/Converters/KeyValuePairConverter.cs index d76c05ef..fa0b157c 100644 --- a/Src/Newtonsoft.Json/Converters/KeyValuePairConverter.cs +++ b/Src/Newtonsoft.Json/Converters/KeyValuePairConverter.cs @@ -48,6 +48,10 @@ namespace Newtonsoft.Json.Converters public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { Type t = value.GetType(); + IList genericArguments = t.GetGenericArguments(); + Type keyType = genericArguments[0]; + Type valueType = genericArguments[1]; + PropertyInfo keyProperty = t.GetProperty(KeyName); PropertyInfo valueProperty = t.GetProperty(ValueName); @@ -56,9 +60,9 @@ namespace Newtonsoft.Json.Converters writer.WriteStartObject(); writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(KeyName) : KeyName); - serializer.Serialize(writer, ReflectionUtils.GetMemberValue(keyProperty, value)); + serializer.Serialize(writer, ReflectionUtils.GetMemberValue(keyProperty, value), keyType); writer.WritePropertyName((resolver != null) ? resolver.GetResolvedPropertyName(ValueName) : ValueName); - serializer.Serialize(writer, ReflectionUtils.GetMemberValue(valueProperty, value)); + serializer.Serialize(writer, ReflectionUtils.GetMemberValue(valueProperty, value), valueType); writer.WriteEndObject(); } diff --git a/Src/Newtonsoft.Json/JsonConvert.cs b/Src/Newtonsoft.Json/JsonConvert.cs index 20d60d17..0da0461e 100644 --- a/Src/Newtonsoft.Json/JsonConvert.cs +++ b/Src/Newtonsoft.Json/JsonConvert.cs @@ -642,6 +642,7 @@ namespace Newtonsoft.Json /// /// A task that represents the asynchronous serialize operation. The value of the TResult parameter contains a JSON string representation of the object. /// + [ObsoleteAttribute("SerializeObjectAsync is obsolete. Use the Task.Factory.StartNew method to serialize JSON asynchronously: Task.Factory.StartNew(() => SerializeObject(value))")] public static Task SerializeObjectAsync(object value) { return SerializeObjectAsync(value, Formatting.None, null); @@ -656,6 +657,7 @@ namespace Newtonsoft.Json /// /// A task that represents the asynchronous serialize operation. The value of the TResult parameter contains a JSON string representation of the object. /// + [ObsoleteAttribute("SerializeObjectAsync is obsolete. Use the Task.Factory.StartNew method to serialize JSON asynchronously: Task.Factory.StartNew(() => SerializeObject(value, formatting))")] public static Task SerializeObjectAsync(object value, Formatting formatting) { return SerializeObjectAsync(value, formatting, null); @@ -672,6 +674,7 @@ namespace Newtonsoft.Json /// /// A task that represents the asynchronous serialize operation. The value of the TResult parameter contains a JSON string representation of the object. /// + [ObsoleteAttribute("SerializeObjectAsync is obsolete. Use the Task.Factory.StartNew method to serialize JSON asynchronously: Task.Factory.StartNew(() => SerializeObject(value, formatting, settings))")] public static Task SerializeObjectAsync(object value, Formatting formatting, JsonSerializerSettings settings) { return Task.Factory.StartNew(() => SerializeObject(value, formatting, settings)); @@ -841,6 +844,7 @@ namespace Newtonsoft.Json /// /// A task that represents the asynchronous deserialize operation. The value of the TResult parameter contains the deserialized object from the JSON string. /// + [ObsoleteAttribute("DeserializeObjectAsync is obsolete. Use the Task.Factory.StartNew method to deserialize JSON asynchronously: Task.Factory.StartNew(() => DeserializeObject(value))")] public static Task DeserializeObjectAsync(string value) { return DeserializeObjectAsync(value, null); @@ -859,6 +863,7 @@ namespace Newtonsoft.Json /// /// A task that represents the asynchronous deserialize operation. The value of the TResult parameter contains the deserialized object from the JSON string. /// + [ObsoleteAttribute("DeserializeObjectAsync is obsolete. Use the Task.Factory.StartNew method to deserialize JSON asynchronously: Task.Factory.StartNew(() => DeserializeObject(value, settings))")] public static Task DeserializeObjectAsync(string value, JsonSerializerSettings settings) { return Task.Factory.StartNew(() => DeserializeObject(value, settings)); @@ -872,6 +877,7 @@ namespace Newtonsoft.Json /// /// A task that represents the asynchronous deserialize operation. The value of the TResult parameter contains the deserialized object from the JSON string. /// + [ObsoleteAttribute("DeserializeObjectAsync is obsolete. Use the Task.Factory.StartNew method to deserialize JSON asynchronously: Task.Factory.StartNew(() => DeserializeObject(value))")] public static Task DeserializeObjectAsync(string value) { return DeserializeObjectAsync(value, null, null); @@ -890,6 +896,7 @@ namespace Newtonsoft.Json /// /// A task that represents the asynchronous deserialize operation. The value of the TResult parameter contains the deserialized object from the JSON string. /// + [ObsoleteAttribute("DeserializeObjectAsync is obsolete. Use the Task.Factory.StartNew method to deserialize JSON asynchronously: Task.Factory.StartNew(() => DeserializeObject(value, type, settings))")] public static Task DeserializeObjectAsync(string value, Type type, JsonSerializerSettings settings) { return Task.Factory.StartNew(() => DeserializeObject(value, type, settings)); diff --git a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs index 8bfddb03..c0e3a986 100644 --- a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs +++ b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs @@ -90,6 +90,6 @@ using System.Security; // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("4.5.0.0")] -[assembly: AssemblyFileVersion("6.0.1.16919")] +[assembly: AssemblyVersion("6.0.0.0")] +[assembly: AssemblyFileVersion("6.0.1.16929")] [assembly: CLSCompliant(true)] diff --git a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs index 777b0abf..74c30563 100644 --- a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs +++ b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs @@ -143,7 +143,7 @@ namespace Newtonsoft.Json.Serialization /// Gets or sets the default members search flags. /// /// The default members search flags. - [ObsoleteAttribute("DefaultMembersSearchFlags is obsolete. Inherit from DefaultContractResolver and override the GetSerializableMembers method instead.")] + [ObsoleteAttribute("DefaultMembersSearchFlags is obsolete. To modify the members serialized inherit from DefaultContractResolver and override the GetSerializableMembers method instead.")] public BindingFlags DefaultMembersSearchFlags { get; set; } #else private BindingFlags DefaultMembersSearchFlags = BindingFlags.Instance | BindingFlags.Public; diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs index 33466430..81f4aaa3 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs @@ -49,6 +49,7 @@ namespace Newtonsoft.Json.Serialization internal class JsonSerializerInternalWriter : JsonSerializerInternalBase { private JsonContract _rootContract; + private int _rootLevel; private readonly List _serializeStack = new List(); private JsonSerializerProxy _internalSerializer; @@ -62,14 +63,13 @@ namespace Newtonsoft.Json.Serialization if (jsonWriter == null) throw new ArgumentNullException("jsonWriter"); - if (objectType != null) - _rootContract = Serializer._contractResolver.ResolveContract(objectType); + _rootContract = (objectType != null) ? Serializer._contractResolver.ResolveContract(objectType) : null; + _rootLevel = _serializeStack.Count + 1; JsonContract contract = GetContractSafe(value); try { - SerializeValue(jsonWriter, value, contract, null, null, null); } catch (Exception ex) @@ -87,6 +87,12 @@ namespace Newtonsoft.Json.Serialization throw; } } + finally + { + // clear root contract to ensure that if level was > 1 then it won't + // accidently be used for non root values + _rootContract = null; + } } private JsonSerializerProxy GetInternalSerializer() @@ -869,7 +875,7 @@ To fix this error either change the environment to be fully trusted, change the if (containerContract.ItemContract == null || contract.UnderlyingType != containerContract.ItemContract.CreatedType) return true; } - else if (_rootContract != null && _serializeStack.Count == 1) + else if (_rootContract != null && _serializeStack.Count == _rootLevel) { if (contract.UnderlyingType != _rootContract.CreatedType) return true;