diff --git a/Build/build.ps1 b/Build/build.ps1 index 32c71c50..4846208d 100644 --- a/Build/build.ps1 +++ b/Build/build.ps1 @@ -17,7 +17,7 @@ $releaseDir = "$baseDir\Release" $workingDir = "$baseDir\Working" $builds = @( - @{Name = "Newtonsoft.Json"; TestsName = "Newtonsoft.Json.Tests"; Constants=""; FinalDir="Net45"; NuGetDir = "net45"; Framework="net-4.0"; Sign=$true} + @{Name = "Newtonsoft.Json"; TestsName = "Newtonsoft.Json.Tests"; Constants=""; FinalDir="Net45"; NuGetDir = "net45"; Framework="net-4.0"; Sign=$true}, @{Name = "Newtonsoft.Json.Portable"; TestsName = "Newtonsoft.Json.Tests.Portable"; Constants="PORTABLE"; FinalDir="Portable"; NuGetDir = "portable-net45+wp80+win8"; Framework="net-4.0"; Sign=$true}, @{Name = "Newtonsoft.Json.Portable40"; TestsName = "Newtonsoft.Json.Tests.Portable40"; Constants="PORTABLE40"; FinalDir="Portable40"; NuGetDir = "portable-net40+sl4+wp7+win8"; Framework="net-4.0"; Sign=$true}, @{Name = "Newtonsoft.Json.WinRT"; TestsName = $null; Constants="NETFX_CORE"; FinalDir="WinRT"; NuGetDir = "netcore45"; Framework="net-4.5"; Sign=$true}, @@ -77,11 +77,11 @@ task Package -depends Build { if ($buildNuGet) { New-Item -Path $workingDir\NuGet -ItemType Directory - New-Item -Path $workingDir\NuGet\tools -ItemType Directory + #New-Item -Path $workingDir\NuGet\tools -ItemType Directory Copy-Item -Path "$buildDir\Newtonsoft.Json.nuspec" -Destination $workingDir\NuGet\Newtonsoft.Json.nuspec -recurse - Copy-Item -Path "$buildDir\install.ps1" -Destination $workingDir\NuGet\tools\install.ps1 -recurse + #Copy-Item -Path "$buildDir\install.ps1" -Destination $workingDir\NuGet\tools\install.ps1 -recurse foreach ($build in $builds) { diff --git a/Build/install.ps1 b/Build/install.ps1 index 62311ec5..4550d277 100644 --- a/Build/install.ps1 +++ b/Build/install.ps1 @@ -3,8 +3,6 @@ param($installPath, $toolsPath, $package, $project) # open json.net splash page on package install # don't open if json.net is installed as a dependency -# yolo - try { $url = "http://www.json.net" @@ -90,4 +88,6 @@ catch { # stop potential errors from bubbling up # worst case the splash page won't open -} \ No newline at end of file +} + +# yolo \ 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 d7c6a081..1c89b93c 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/TypeNameHandlingTests.cs @@ -1539,6 +1539,159 @@ namespace Newtonsoft.Json.Tests.Serialization Assert.AreEqual(someValue, deserializedObject[contextKey]); } + + [Test] + public void TypeNameHandlingWithISerializableValues() + { + MyParent p = new MyParent + { + Child = new MyChild + { + MyProperty = "string!" + } + }; + + JsonSerializerSettings settings = new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Auto, + DateFormatHandling = DateFormatHandling.IsoDateFormat, + MissingMemberHandling = MissingMemberHandling.Ignore, + DefaultValueHandling = DefaultValueHandling.Ignore, + NullValueHandling = NullValueHandling.Ignore, + Formatting = Formatting.Indented + }; + + string json = JsonConvert.SerializeObject(p, settings); + + Assert.AreEqual(@"{ + ""c"": { + ""$type"": ""Newtonsoft.Json.Tests.Serialization.MyChild, Newtonsoft.Json.Tests"", + ""p"": ""string!"" + } +}", json); + + MyParent p2 = JsonConvert.DeserializeObject(json, settings); + CustomAssert.IsInstanceOfType(typeof(MyChild), p2.Child); + Assert.AreEqual("string!", ((MyChild)p2.Child).MyProperty); + } + + [Test] + public void TypeNameHandlingWithISerializableValuesAndArray() + { + MyParent p = new MyParent + { + Child = new MyChildList + { + "string!" + } + }; + + JsonSerializerSettings settings = new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Auto, + DateFormatHandling = DateFormatHandling.IsoDateFormat, + MissingMemberHandling = MissingMemberHandling.Ignore, + DefaultValueHandling = DefaultValueHandling.Ignore, + NullValueHandling = NullValueHandling.Ignore, + Formatting = Formatting.Indented + }; + + string json = JsonConvert.SerializeObject(p, settings); + + Assert.AreEqual(@"{ + ""c"": { + ""$type"": ""Newtonsoft.Json.Tests.Serialization.MyChildList, Newtonsoft.Json.Tests"", + ""$values"": [ + ""string!"" + ] + } +}", json); + + MyParent p2 = JsonConvert.DeserializeObject(json, settings); + CustomAssert.IsInstanceOfType(typeof(MyChildList), p2.Child); + Assert.AreEqual(1, ((MyChildList)p2.Child).Count); + Assert.AreEqual("string!", ((MyChildList)p2.Child)[0]); + } + + [Test] + public void ParentTypeNameHandlingWithISerializableValues() + { + ParentParent pp = new ParentParent(); + + pp.ParentProp = new MyParent + { + Child = new MyChild + { + MyProperty = "string!" + } + }; + + JsonSerializerSettings settings = new JsonSerializerSettings + { + DateFormatHandling = DateFormatHandling.IsoDateFormat, + MissingMemberHandling = MissingMemberHandling.Ignore, + DefaultValueHandling = DefaultValueHandling.Ignore, + NullValueHandling = NullValueHandling.Ignore, + Formatting = Formatting.Indented + }; + + string json = JsonConvert.SerializeObject(pp, settings); + + Assert.AreEqual(@"{ + ""ParentProp"": { + ""c"": { + ""$type"": ""Newtonsoft.Json.Tests.Serialization.MyChild, Newtonsoft.Json.Tests"", + ""p"": ""string!"" + } + } +}", json); + + ParentParent pp2 = JsonConvert.DeserializeObject(json, settings); + MyParent p2 = pp2.ParentProp; + CustomAssert.IsInstanceOfType(typeof(MyChild), p2.Child); + Assert.AreEqual("string!", ((MyChild)p2.Child).MyProperty); + } + } + + public class ParentParent + { + [JsonProperty(ItemTypeNameHandling = TypeNameHandling.Auto)] + public MyParent ParentProp { get; set; } + } + + [Serializable] + public class MyParent : ISerializable + { + public ISomeBase Child { get; internal set; } + + public MyParent(SerializationInfo info, StreamingContext context) + { + Child = (ISomeBase)info.GetValue("c", typeof(ISomeBase)); + } + + public MyParent() + { + } + + void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) + { + info.AddValue("c", Child); + } + } + + [DataContract] + public class MyChild : ISomeBase + { + [DataMember(Name = "p")] + public String MyProperty { get; internal set; } + } + + public class MyChildList : List, ISomeBase + { + } + + public interface ISomeBase + { } public class Message diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs index 93e2b5c2..88807518 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs @@ -450,7 +450,7 @@ namespace Newtonsoft.Json.Serialization #if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) case JsonContractType.Serializable: JsonISerializableContract serializableContract = (JsonISerializableContract) contract; - return CreateISerializable(reader, serializableContract, id); + return CreateISerializable(reader, serializableContract, member, id); #endif } @@ -1264,7 +1264,7 @@ To fix this error either change the JSON to a {1} or change the deserialized typ } #if !(SILVERLIGHT || NETFX_CORE || PORTABLE40 || PORTABLE) - private object CreateISerializable(JsonReader reader, JsonISerializableContract contract, string id) + private object CreateISerializable(JsonReader reader, JsonISerializableContract contract, JsonProperty member, string id) { Type objectType = contract.UnderlyingType; @@ -1290,7 +1290,16 @@ To fix this error either change the environment to be fully trusted, change the if (!reader.Read()) throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName)); - serializationInfo.AddValue(memberName, JToken.ReadFrom(reader)); + if (reader.TokenType == JsonToken.StartObject) + { + // this will read any potential type names embedded in json + object o = CreateObject(reader, null, null, null, contract, member, null); + serializationInfo.AddValue(memberName, o); + } + else + { + serializationInfo.AddValue(memberName, JToken.ReadFrom(reader)); + } break; case JsonToken.Comment: break; diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs index 8b226912..5056479a 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs @@ -818,9 +818,9 @@ To fix this error either change the environment to be fully trusted, change the if (contract.UnderlyingType != member.PropertyContract.CreatedType) return true; } - else if (containerContract != null && containerContract.ItemContract != null) + else if (containerContract != null) { - if (contract.UnderlyingType != containerContract.ItemContract.CreatedType) + if (containerContract.ItemContract == null || contract.UnderlyingType != containerContract.ItemContract.CreatedType) return true; } else if (_rootContract != null && _serializeStack.Count == 1)