diff --git a/Src/Newtonsoft.Json.TestConsole/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json.TestConsole/Properties/AssemblyInfo.cs index cdf2801c..0a4e149b 100644 --- a/Src/Newtonsoft.Json.TestConsole/Properties/AssemblyInfo.cs +++ b/Src/Newtonsoft.Json.TestConsole/Properties/AssemblyInfo.cs @@ -57,4 +57,4 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("7.0.0.0")] -[assembly: AssemblyFileVersion("7.0.1.18023")] +[assembly: AssemblyFileVersion("7.0.1.18111")] diff --git a/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs index ad393cfe..a90382a8 100644 --- a/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs +++ b/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs @@ -76,4 +76,4 @@ using System.Security; // by using the '*' as shown below: [assembly: AssemblyVersion("7.0.0.0")] -[assembly: AssemblyFileVersion("7.0.1.18023")] +[assembly: AssemblyFileVersion("7.0.1.18111")] diff --git a/Src/Newtonsoft.Json.Tests/Serialization/ExtensionDataTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/ExtensionDataTests.cs index b417ba35..24cee043 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/ExtensionDataTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/ExtensionDataTests.cs @@ -723,5 +723,26 @@ namespace Newtonsoft.Json.Tests.Serialization Assert.AreEqual(1, (int)c.ExtensionData0["first"]); Assert.AreEqual(2, (int)c.ExtensionData0["second"]); } + + public class Test + { + [JsonProperty("LastActivityDate")] + public DateTime? LastActivityDate { get; set; } + + [JsonExtensionData] + public Dictionary CustomFields { get; set; } + } + + [Test] + public void DeserializeNullableProperty() + { + string json = @"{ ""LastActivityDate"":null, ""CustomField1"":""Testing"" }"; + + var c = JsonConvert.DeserializeObject(json); + + Assert.AreEqual(null, c.LastActivityDate); + Assert.AreEqual(1, c.CustomFields.Count); + Assert.AreEqual("Testing", (string)c.CustomFields["CustomField1"]); + } } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerCollectionsTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerCollectionsTests.cs index 5753f509..72bc6a8b 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerCollectionsTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerCollectionsTests.cs @@ -25,6 +25,7 @@ using System; using System.Collections; +using System.Collections.Specialized; #if !(NET35 || NET20 || PORTABLE || ASPNETCORE50 || PORTABLE40) using System.Collections.Concurrent; #endif @@ -57,6 +58,19 @@ namespace Newtonsoft.Json.Tests.Serialization [TestFixture] public class JsonSerializerCollectionsTests : TestFixtureBase { + public class NameValueCollectionTestClass + { + public NameValueCollection Collection { get; set; } + } + + [Test] + public void DeserializeNameValueCollection() + { + ExceptionAssert.Throws( + () => JsonConvert.DeserializeObject("{Collection:[]}"), + "Cannot create and populate list type System.Collections.Specialized.NameValueCollection. Path 'Collection', line 1, position 13."); + } + [Test] public void MultiDObjectArray() { diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs index aa16a55b..40256c57 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs @@ -8472,6 +8472,27 @@ Path '', line 1, position 1."); Assert.AreEqual(typeof(DateTimeOffset), v.Value.GetType()); Assert.AreEqual(dt, (DateTimeOffset)v.Value); } + + [DataContract] + public class ConstantTestClass + { + [DataMember] + public const char MY_CONSTANT = '.'; + } + + [Test] + public void DeserializeConstantProperty() + { + ConstantTestClass c1 = new ConstantTestClass(); + + string json = JsonConvert.SerializeObject(c1, Formatting.Indented); + + StringAssert.AreEqual(@"{ + ""MY_CONSTANT"": ""."" +}", json); + + JsonConvert.DeserializeObject(json); + } #endif [Test] @@ -8610,15 +8631,15 @@ Path '', line 1, position 1."); ""AlternateViews"": [] }"; - System.Net.Mail.MailMessage mailMessage = JsonConvert.DeserializeObject( - JsonMessage, - new MailAddressReadConverter(), - new AttachmentReadConverter(), - new EncodingReadConverter()); - - Assert.AreEqual("Family tree", mailMessage.Subject); - Assert.AreEqual("Luke Skywalker", mailMessage.To[0].DisplayName); - Assert.AreEqual("skywalker family tree.jpg", mailMessage.Attachments[0].ContentDisposition.FileName); + ExceptionAssert.Throws(() => + { + JsonConvert.DeserializeObject( + JsonMessage, + new MailAddressReadConverter(), + new AttachmentReadConverter(), + new EncodingReadConverter()); + }, + "Cannot populate list type System.Net.Mime.HeaderCollection. Path 'Headers', line 26, position 15."); } public class MailAddressReadConverter : JsonConverter diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Net35.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Net35.csproj index b5942172..df70d6ec 100644 --- a/Src/Newtonsoft.Json/Newtonsoft.Json.Net35.csproj +++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Net35.csproj @@ -57,6 +57,7 @@ Newtonsoft.Json.ruleset + true pdbonly diff --git a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs index f4964748..5c4eee98 100644 --- a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs +++ b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs @@ -92,5 +92,5 @@ using System.Security; // by using the '*' as shown below: [assembly: AssemblyVersion("7.0.0.0")] -[assembly: AssemblyFileVersion("7.0.1.18023")] +[assembly: AssemblyFileVersion("7.0.1.18111")] [assembly: CLSCompliant(true)] diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs index d28234fe..592c95a5 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs @@ -814,12 +814,8 @@ namespace Newtonsoft.Json.Serialization } else { - // can't populate something like an IEnumerable if (!arrayContract.CanDeserialize) - { - reader.Skip(); - return existingValue; - } + throw JsonSerializationException.Create(reader, "Cannot populate list type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.CreatedType)); value = PopulateList((arrayContract.ShouldCreateWrapper) ? arrayContract.CreateWrapper(existingValue) : (IList)existingValue, reader, arrayContract, member, id); } diff --git a/Src/Newtonsoft.Json/Utilities/DynamicReflectionDelegateFactory.cs b/Src/Newtonsoft.Json/Utilities/DynamicReflectionDelegateFactory.cs index 6710c148..efd14ff4 100644 --- a/Src/Newtonsoft.Json/Utilities/DynamicReflectionDelegateFactory.cs +++ b/Src/Newtonsoft.Json/Utilities/DynamicReflectionDelegateFactory.cs @@ -252,6 +252,13 @@ namespace Newtonsoft.Json.Utilities public override Func CreateGet(FieldInfo fieldInfo) { + if (fieldInfo.IsLiteral) + { + object constantValue = fieldInfo.GetValue(null); + Func getter = o => constantValue; + return getter; + } + DynamicMethod dynamicMethod = CreateDynamicMethod("Get" + fieldInfo.Name, typeof(T), new[] { typeof(object) }, fieldInfo.DeclaringType); ILGenerator generator = dynamicMethod.GetILGenerator(); diff --git a/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs b/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs index 0252ddf6..b60203a2 100644 --- a/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs +++ b/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs @@ -567,11 +567,13 @@ namespace Newtonsoft.Json.Utilities case MemberTypes.Field: FieldInfo fieldInfo = (FieldInfo)member; + if (fieldInfo.IsLiteral) + return false; if (fieldInfo.IsInitOnly && !canSetReadOnly) return false; if (nonPublic) return true; - else if (fieldInfo.IsPublic) + if (fieldInfo.IsPublic) return true; return false; case MemberTypes.Property: @@ -691,8 +693,16 @@ namespace Newtonsoft.Json.Utilities if (provider is Type) { Type t = (Type)provider; - object[] attributes = (attributeType != null) ? t.GetCustomAttributes(attributeType, inherit) : t.GetCustomAttributes(inherit); - return attributes.Cast().ToArray(); + object[] a = (attributeType != null) ? t.GetCustomAttributes(attributeType, inherit) : t.GetCustomAttributes(inherit); + Attribute[] attributes = a.Cast().ToArray(); + +#if (NET20 || NET35) + // ye olde .NET GetCustomAttributes doesn't respect the inherit argument + if (inherit && t.BaseType != null) + attributes = attributes.Union(GetAttributes(t.BaseType, attributeType, inherit)).ToArray(); +#endif + + return attributes; } if (provider is Assembly)