diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.WinRT.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.WinRT.csproj index eb7d71a6..c8e81c09 100644 --- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.WinRT.csproj +++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.WinRT.csproj @@ -281,6 +281,7 @@ + diff --git a/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs index 2fa9c1a8..209936a1 100644 --- a/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs +++ b/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs @@ -75,4 +75,4 @@ 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("5.0.4.16024")] +[assembly: AssemblyFileVersion("5.0.4.16025")] diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/Movie.cs b/Src/Newtonsoft.Json.Tests/TestObjects/Movie.cs index 2af68844..0719a778 100644 --- a/Src/Newtonsoft.Json.Tests/TestObjects/Movie.cs +++ b/Src/Newtonsoft.Json.Tests/TestObjects/Movie.cs @@ -36,5 +36,20 @@ namespace Newtonsoft.Json.Tests.TestObjects public string Studio { get; set; } public DateTime? ReleaseDate { get; set; } public List ReleaseCountries { get; set; } + + public override string ToString() + { + return base.ToString(); + } + + public override bool Equals(object obj) + { + return base.Equals(obj); + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Utilities/ExpressionReflectionDelegateFactoryTests.cs b/Src/Newtonsoft.Json.Tests/Utilities/ExpressionReflectionDelegateFactoryTests.cs index c0351f73..36d3f50c 100644 --- a/Src/Newtonsoft.Json.Tests/Utilities/ExpressionReflectionDelegateFactoryTests.cs +++ b/Src/Newtonsoft.Json.Tests/Utilities/ExpressionReflectionDelegateFactoryTests.cs @@ -65,7 +65,7 @@ namespace Newtonsoft.Json.Tests.Utilities [Test] public void DefaultConstructor_Abstract() { - ExceptionAssert.Throws("Cannot create an abstract class.", + ExceptionAssert.Throws("Cannot create an abstract class.", () => { Func create = ExpressionReflectionDelegateFactory.Instance.CreateDefaultConstructor(typeof(Type)); diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.WinRT.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.WinRT.csproj index d51d8057..d52a0f08 100644 --- a/Src/Newtonsoft.Json/Newtonsoft.Json.WinRT.csproj +++ b/Src/Newtonsoft.Json/Newtonsoft.Json.WinRT.csproj @@ -221,6 +221,7 @@ + @@ -269,6 +270,7 @@ + diff --git a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs index deaf24ef..6a35f831 100644 --- a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs +++ b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs @@ -92,6 +92,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("5.0.4.16024")] +[assembly: AssemblyFileVersion("5.0.4.16025")] [assembly: CLSCompliant(true)] diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs index a7240e56..558a9c98 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs @@ -362,13 +362,8 @@ namespace Newtonsoft.Json.Serialization if (ReadSpecialProperties(reader, ref objectType, ref contract, member, containerContract, containerMember, existingValue, out newValue, out id)) return newValue; - if (contract == null || objectType == typeof(object) || objectType == typeof(IDynamicMetaObjectProvider)) - { - if (!HasDefinedType(objectType)) - return CreateJObject(reader); - - throw JsonSerializationException.Create(reader, "Could not resolve type '{0}' to a JsonContract.".FormatWith(CultureInfo.InvariantCulture, objectType)); - } + if (HasNoDefinedType(contract)) + return CreateJObject(reader); switch (contract.ContractType) { @@ -609,72 +604,69 @@ To fix this error either change the JSON to a {1} or change the deserialized typ private object CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, object existingValue, string id) { object value; - if (HasDefinedType(objectType)) + + if (HasNoDefinedType(contract)) + return CreateJToken(reader, contract); + + JsonArrayContract arrayContract = EnsureArrayContract(reader, objectType, contract); + + if (existingValue == null) { - JsonArrayContract arrayContract = EnsureArrayContract(reader, objectType, contract); + bool createdFromNonDefaultConstructor; + IList list = CreateNewList(reader, arrayContract, out createdFromNonDefaultConstructor); - if (existingValue == null) - { - bool createdFromNonDefaultConstructor; - IList list = CreateNewList(reader, arrayContract, out createdFromNonDefaultConstructor); + if (id != null && createdFromNonDefaultConstructor) + throw JsonSerializationException.Create(reader, "Cannot preserve reference to array or readonly list, or list created from a non-default constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); - if (id != null && createdFromNonDefaultConstructor) - throw JsonSerializationException.Create(reader, "Cannot preserve reference to array or readonly list, or list created from a non-default constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); + if (contract.OnSerializingCallbacks.Count > 0 && createdFromNonDefaultConstructor) + throw JsonSerializationException.Create(reader, "Cannot call OnSerializing on an array or readonly list, or list created from a non-default constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); - if (contract.OnSerializingCallbacks.Count > 0 && createdFromNonDefaultConstructor) - throw JsonSerializationException.Create(reader, "Cannot call OnSerializing on an array or readonly list, or list created from a non-default constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); + if (contract.OnErrorCallbacks.Count > 0 && createdFromNonDefaultConstructor) + throw JsonSerializationException.Create(reader, "Cannot call OnError on an array or readonly list, or list created from a non-default constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); - if (contract.OnErrorCallbacks.Count > 0 && createdFromNonDefaultConstructor) - throw JsonSerializationException.Create(reader, "Cannot call OnError on an array or readonly list, or list created from a non-default constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); - - if (!arrayContract.IsMultidimensionalArray) - PopulateList(list, reader, arrayContract, member, id); - else - PopulateMultidimensionalArray(list, reader, arrayContract, member, id); - - if (createdFromNonDefaultConstructor) - { - if (arrayContract.IsMultidimensionalArray) - { - list = CollectionUtils.ToMultidimensionalArray(list, arrayContract.CollectionItemType, contract.CreatedType.GetArrayRank()); - } - else if (contract.CreatedType.IsArray) - { - Array a = Array.CreateInstance(arrayContract.CollectionItemType, list.Count); - list.CopyTo(a, 0); - list = a; - } - else - { - // call constructor that takes IEnumerable - return arrayContract.ParametrizedConstructor.Invoke(new object[] { list }); - } - } - else if (list is IWrappedCollection) - { - return ((IWrappedCollection)list).UnderlyingCollection; - } - - value = list; - } + if (!arrayContract.IsMultidimensionalArray) + PopulateList(list, reader, arrayContract, member, id); else + PopulateMultidimensionalArray(list, reader, arrayContract, member, id); + + if (createdFromNonDefaultConstructor) { - value = PopulateList((arrayContract.ShouldCreateWrapper) ? arrayContract.CreateWrapper(existingValue) : (IList) existingValue, reader, arrayContract, member, id); + if (arrayContract.IsMultidimensionalArray) + { + list = CollectionUtils.ToMultidimensionalArray(list, arrayContract.CollectionItemType, contract.CreatedType.GetArrayRank()); + } + else if (contract.CreatedType.IsArray) + { + Array a = Array.CreateInstance(arrayContract.CollectionItemType, list.Count); + list.CopyTo(a, 0); + list = a; + } + else + { + // call constructor that takes IEnumerable + return arrayContract.ParametrizedConstructor.Invoke(new object[] { list }); + } } + else if (list is IWrappedCollection) + { + return ((IWrappedCollection)list).UnderlyingCollection; + } + + value = list; } else { - value = CreateJToken(reader, contract); + value = PopulateList((arrayContract.ShouldCreateWrapper) ? arrayContract.CreateWrapper(existingValue) : (IList) existingValue, reader, arrayContract, member, id); } return value; } - private bool HasDefinedType(Type type) + private bool HasNoDefinedType(JsonContract contract) { - return (type != null && type != typeof (object) && !typeof (JToken).IsSubclassOf(type) + return (contract == null || contract.UnderlyingType == typeof (object) || contract.ContractType == JsonContractType.Linq #if !(NET35 || NET20 || PORTABLE40) - && type != typeof (IDynamicMetaObjectProvider) + || contract.UnderlyingType == typeof(IDynamicMetaObjectProvider) #endif ); } @@ -1336,7 +1328,7 @@ To fix this error either change the environment to be fully trusted, change the { IDynamicMetaObjectProvider newObject; - if (contract.UnderlyingType.IsInterface() || contract.UnderlyingType.IsAbstract()) + if (!contract.IsInstantiable) throw JsonSerializationException.Create(reader, "Could not create an instance of type {0}. Type is an interface or abstract class and cannot be instantiated.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType)); if (contract.DefaultCreator != null && diff --git a/Src/Newtonsoft.Json/Utilities/ExpressionReflectionDelegateFactory.cs b/Src/Newtonsoft.Json/Utilities/ExpressionReflectionDelegateFactory.cs index 8416e035..e8d4c570 100644 --- a/Src/Newtonsoft.Json/Utilities/ExpressionReflectionDelegateFactory.cs +++ b/Src/Newtonsoft.Json/Utilities/ExpressionReflectionDelegateFactory.cs @@ -96,16 +96,25 @@ namespace Newtonsoft.Json.Utilities if (type.IsAbstract()) return () => (T)Activator.CreateInstance(type); - Type resultType = typeof(T); + try + { + Type resultType = typeof(T); - Expression expression = Expression.New(type); + Expression expression = Expression.New(type); - expression = EnsureCastExpression(expression, resultType); + expression = EnsureCastExpression(expression, resultType); - LambdaExpression lambdaExpression = Expression.Lambda(typeof(Func), expression); + LambdaExpression lambdaExpression = Expression.Lambda(typeof(Func), expression); - Func compiled = (Func)lambdaExpression.Compile(); - return compiled; + Func compiled = (Func)lambdaExpression.Compile(); + return compiled; + } + catch + { + // an error can be thrown if constructor is not valid on Win8 + // will have INVOCATION_FLAGS_NON_W8P_FX_API invocation flag + return () => (T)Activator.CreateInstance(type); + } } public override Func CreateGet(PropertyInfo propertyInfo)