diff --git a/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs index aeb533e9..f9df0c04 100644 --- a/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs +++ b/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs @@ -72,5 +72,5 @@ using System.Security; // by using the '*' as shown below: [assembly: AssemblyVersion("4.5.0.0")] #if !PocketPC -[assembly: AssemblyFileVersion("4.5.7.15030")] +[assembly: AssemblyFileVersion("4.5.7.15110")] #endif diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs index 9e208a9f..de15507e 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs @@ -6523,6 +6523,73 @@ Parameter name: value", ""value"": ""test value"" }", json); } + + [JsonObject(MemberSerialization.Fields)] + public class MyTuple + { + private readonly T1 m_Item1; + + public MyTuple(T1 item1) + { + m_Item1 = item1; + } + + public T1 Item1 + { + get { return m_Item1; } + } + } + + [Test] + public void SerializeCustomTupleWithSerializableAttribute() + { + var tuple = new MyTuple(500); + var json = JsonConvert.SerializeObject(tuple); + Assert.AreEqual(@"{""m_Item1"":500}", json); + + MyTuple obj = null; + + Action doStuff = () => + { + obj = JsonConvert.DeserializeObject>(json); + }; + +#if !(SILVERLIGHT || NETFX_CORE || PORTABLE) + doStuff(); + Assert.AreEqual(500, obj.Item1); +#else + ExceptionAssert.Throws( + "Unable to find a constructor to use for type Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+MyTuple`1[System.Int32]. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'm_Item1', line 1, position 11.", + doStuff); +#endif + } + +#if !(SILVERLIGHT || NETFX_CORE || PORTABLE || NET35 || NET20) + [Test] + public void SerializeTupleWithSerializableAttribute() + { + var tuple = Tuple.Create(500); + var json = JsonConvert.SerializeObject(tuple, new JsonSerializerSettings + { + ContractResolver = new SerializableContractResolver() + }); + Assert.AreEqual(@"{""m_Item1"":500}", json); + + var obj = JsonConvert.DeserializeObject>(json, new JsonSerializerSettings + { + ContractResolver = new SerializableContractResolver() + }); + Assert.AreEqual(500, obj.Item1); + } + + public class SerializableContractResolver : DefaultContractResolver + { + public SerializableContractResolver() + { + IgnoreSerializableAttribute = false; + } + } +#endif } #if !(SILVERLIGHT || NETFX_CORE || PORTABLE) diff --git a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs index 07dac1c7..86250245 100644 --- a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs +++ b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs @@ -90,7 +90,7 @@ using System.Security; // by using the '*' as shown below: [assembly: AssemblyVersion("4.5.0.0")] #if !PocketPC -[assembly: AssemblyFileVersion("4.5.7.15030")] +[assembly: AssemblyFileVersion("4.5.7.15110")] #endif [assembly: CLSCompliant(true)] diff --git a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs index 728f9d49..2f7a0ecc 100644 --- a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs +++ b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs @@ -372,6 +372,13 @@ namespace Newtonsoft.Json.Serialization contract.ConstructorParameters.AddRange(CreateConstructorParameters(constructor, contract.Properties)); } } + else if (contract.MemberSerialization == MemberSerialization.Fields) + { +#if !(SILVERLIGHT || NETFX_CORE || PORTABLE) + // mimic DataContractSerializer behaviour and create uninitialized object when populating fields + contract.DefaultCreator = contract.GetUninitializedObject; +#endif + } else if (contract.DefaultCreator == null || contract.DefaultCreatorNonPublic) { ConstructorInfo constructor = GetParametrizedConstructor(contract.NonNullableUnderlyingType); @@ -899,8 +906,17 @@ namespace Newtonsoft.Json.Serialization bool hasExplicitAttribute; SetPropertySettingsFromAttributes(property, member.GetCustomAttributeProvider(), member.Name, member.DeclaringType, memberSerialization, out allowNonPublicAccess, out hasExplicitAttribute); - property.Readable = ReflectionUtils.CanReadMemberValue(member, allowNonPublicAccess); - property.Writable = ReflectionUtils.CanSetMemberValue(member, allowNonPublicAccess, hasExplicitAttribute); + if (memberSerialization != MemberSerialization.Fields) + { + property.Readable = ReflectionUtils.CanReadMemberValue(member, allowNonPublicAccess); + property.Writable = ReflectionUtils.CanSetMemberValue(member, allowNonPublicAccess, hasExplicitAttribute); + } + else + { + // write to readonly fields + property.Readable = true; + property.Writable = true; + } property.ShouldSerialize = CreateShouldSerializeTest(member); SetIsSpecifiedActions(property, member, allowNonPublicAccess); diff --git a/Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs b/Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs index 2a424d35..05196f1c 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs @@ -25,6 +25,8 @@ using System; using System.Reflection; +using System.Runtime.Serialization; +using System.Security; namespace Newtonsoft.Json.Serialization { @@ -114,5 +116,13 @@ namespace Newtonsoft.Json.Serialization Properties = new JsonPropertyCollection(UnderlyingType); ConstructorParameters = new JsonPropertyCollection(UnderlyingType); } + +#if !(SILVERLIGHT || NETFX_CORE || PORTABLE) + [SecuritySafeCritical] + internal object GetUninitializedObject() + { + return FormatterServices.GetUninitializedObject(NonNullableUnderlyingType); + } +#endif } } \ No newline at end of file