Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/Newtonsoft.Json.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/Src
diff options
context:
space:
mode:
Diffstat (limited to 'Src')
-rw-r--r--Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs2
-rw-r--r--Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs112
-rw-r--r--Src/Newtonsoft.Json/Properties/AssemblyInfo.cs2
-rw-r--r--Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs4
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs97
-rw-r--r--Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs39
6 files changed, 235 insertions, 21 deletions
diff --git a/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs
index 813250c..1c4dd3e 100644
--- a/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs
+++ b/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs
@@ -41,5 +41,5 @@ using System.Runtime.InteropServices;
// by using the '*' as shown below:
[assembly: AssemblyVersion("4.0.2.0")]
#if !PocketPC
-[assembly: AssemblyFileVersion("4.0.2.13721")]
+[assembly: AssemblyFileVersion("4.0.2.13722")]
#endif
diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs
index 73c50a0..821e335 100644
--- a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs
+++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs
@@ -4329,5 +4329,117 @@ keyword such as type of business.""
string json = JsonConvert.SerializeObject(new EnumerableArrayPropertyClass());
JsonConvert.DeserializeObject<EnumerableArrayPropertyClass>(json);
}
+
+#if !NET20
+ [DataContract]
+ public class BaseDataContract
+ {
+ [DataMember(Name = "virtualMember")]
+ public virtual string VirtualMember { get; set; }
+
+ [DataMember(Name = "nonVirtualMember")]
+ public string NonVirtualMember { get; set; }
+ }
+
+ public class ChildDataContract : BaseDataContract
+ {
+ public override string VirtualMember { get; set; }
+ public string NewMember { get; set; }
+ }
+
+ [Test]
+ public void ChildDataContractTest()
+ {
+ ChildDataContract cc = new ChildDataContract
+ {
+ VirtualMember = "VirtualMember!",
+ NonVirtualMember = "NonVirtualMember!"
+ };
+
+ string result = JsonConvert.SerializeObject(cc);
+ Assert.AreEqual(@"{""virtualMember"":""VirtualMember!"",""nonVirtualMember"":""NonVirtualMember!""}", result);
+ }
+#endif
+
+ [JsonObject(MemberSerialization = MemberSerialization.OptIn)]
+ public class BaseObject
+ {
+ [JsonProperty(PropertyName = "virtualMember")]
+ public virtual string VirtualMember { get; set; }
+
+ [JsonProperty(PropertyName = "nonVirtualMember")]
+ public string NonVirtualMember { get; set; }
+ }
+
+ public class ChildObject : BaseObject
+ {
+ public override string VirtualMember { get; set; }
+ public string NewMember { get; set; }
+ }
+
+ public class ChildWithDifferentOverrideObject : BaseObject
+ {
+ [JsonProperty(PropertyName = "differentVirtualMember")]
+ public override string VirtualMember { get; set; }
+ }
+
+ [Test]
+ public void ChildObjectTest()
+ {
+ ChildObject cc = new ChildObject
+ {
+ VirtualMember = "VirtualMember!",
+ NonVirtualMember = "NonVirtualMember!"
+ };
+
+ string result = JsonConvert.SerializeObject(cc);
+ Assert.AreEqual(@"{""virtualMember"":""VirtualMember!"",""nonVirtualMember"":""NonVirtualMember!""}", result);
+ }
+
+ [Test]
+ public void ChildWithDifferentOverrideObjectTest()
+ {
+ ChildWithDifferentOverrideObject cc = new ChildWithDifferentOverrideObject
+ {
+ VirtualMember = "VirtualMember!",
+ NonVirtualMember = "NonVirtualMember!"
+ };
+
+ string result = JsonConvert.SerializeObject(cc);
+ Assert.AreEqual(@"{""differentVirtualMember"":""VirtualMember!"",""nonVirtualMember"":""NonVirtualMember!""}", result);
+ }
+
+ [JsonObject(MemberSerialization = MemberSerialization.OptIn)]
+ public interface IInterfaceObject
+ {
+ [JsonProperty(PropertyName = "virtualMember")]
+ [JsonConverter(typeof(IsoDateTimeConverter))]
+ DateTime InterfaceMember { get; set; }
+ }
+
+ public class ImplementInterfaceObject : IInterfaceObject
+ {
+ public DateTime InterfaceMember { get; set; }
+ public string NewMember { get; set; }
+ [JsonProperty(PropertyName = "newMemberWithProperty")]
+ public string NewMemberWithProperty { get; set; }
+ }
+
+ [Test]
+ public void ImplementInterfaceObjectTest()
+ {
+ ImplementInterfaceObject cc = new ImplementInterfaceObject
+ {
+ InterfaceMember = new DateTime(2010, 12, 31, 0, 0, 0, DateTimeKind.Utc),
+ NewMember = "NewMember!"
+ };
+
+ string result = JsonConvert.SerializeObject(cc, Formatting.Indented);
+
+ Assert.AreEqual(@"{
+ ""virtualMember"": ""2010-12-31T00:00:00Z"",
+ ""newMemberWithProperty"": null
+}", result);
+ }
}
} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs
index b1c274d..e37cbec 100644
--- a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs
+++ b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs
@@ -110,7 +110,7 @@ using System.Security;
// by using the '*' as shown below:
[assembly: AssemblyVersion("4.0.2.0")]
#if !PocketPC
-[assembly: AssemblyFileVersion("4.0.2.13721")]
+[assembly: AssemblyFileVersion("4.0.2.13722")]
#endif
[assembly: CLSCompliant(true)]
diff --git a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs
index cc1cd29..8078c04 100644
--- a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs
+++ b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs
@@ -766,8 +766,8 @@ namespace Newtonsoft.Json.Serialization
DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(declaringType);
DataMemberAttribute dataMemberAttribute;
- if (dataContractAttribute != null)
- dataMemberAttribute = JsonTypeReflector.GetAttribute<DataMemberAttribute>(attributeProvider);
+ if (dataContractAttribute != null && attributeProvider is MemberInfo)
+ dataMemberAttribute = JsonTypeReflector.GetDataMemberAttribute((MemberInfo)attributeProvider);
else
dataMemberAttribute = null;
#endif
diff --git a/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs b/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs
index e1f0857..c4e3157 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs
@@ -96,7 +96,48 @@ namespace Newtonsoft.Json.Serialization
#if !PocketPC && !NET20
public static DataContractAttribute GetDataContractAttribute(Type type)
{
- return CachedAttributeGetter<DataContractAttribute>.GetAttribute(type);
+ // DataContractAttribute does not have inheritance
+ DataContractAttribute result = null;
+ Type currentType = type;
+ while (result == null && currentType != null)
+ {
+ result = CachedAttributeGetter<DataContractAttribute>.GetAttribute(currentType);
+ currentType = currentType.BaseType;
+ }
+
+ return result;
+ }
+
+ public static DataMemberAttribute GetDataMemberAttribute(MemberInfo memberInfo)
+ {
+ // DataMemberAttribute does not have inheritance
+
+ // can't override a field
+ if (memberInfo.MemberType == MemberTypes.Field)
+ return CachedAttributeGetter<DataMemberAttribute>.GetAttribute(memberInfo);
+
+ // search property and then search base properties if nothing is returned and the property is virtual
+ PropertyInfo propertyInfo = (PropertyInfo) memberInfo;
+ DataMemberAttribute result = CachedAttributeGetter<DataMemberAttribute>.GetAttribute(propertyInfo);
+ if (result == null)
+ {
+ if (propertyInfo.IsVirtual())
+ {
+ Type currentType = propertyInfo.DeclaringType;
+ Type[] types = propertyInfo.GetIndexParameters().Select(p => p.ParameterType).ToArray();
+
+ while (result == null && currentType != null)
+ {
+ PropertyInfo baseProperty = (PropertyInfo)ReflectionUtils.GetMemberInfoFromType(currentType, propertyInfo);
+ if (baseProperty != null && baseProperty.IsVirtual())
+ result = CachedAttributeGetter<DataMemberAttribute>.GetAttribute(baseProperty);
+
+ currentType = currentType.BaseType;
+ }
+ }
+ }
+
+ return result;
}
#endif
@@ -204,38 +245,72 @@ namespace Newtonsoft.Json.Serialization
return _cachedMetadataTypeAttributeType;
}
+#endif
private static T GetAttribute<T>(Type type) where T : Attribute
{
+ T attribute;
+
+#if !SILVERLIGHT && !PocketPC && !NET20
Type metadataType = GetAssociatedMetadataType(type);
if (metadataType != null)
{
- T attribute = ReflectionUtils.GetAttribute<T>(metadataType, true);
+ attribute = ReflectionUtils.GetAttribute<T>(metadataType, true);
if (attribute != null)
return attribute;
}
+#endif
- return ReflectionUtils.GetAttribute<T>(type, true);
+ attribute = ReflectionUtils.GetAttribute<T>(type, true);
+ if (attribute != null)
+ return attribute;
+
+ foreach (Type typeInterface in type.GetInterfaces())
+ {
+ attribute = ReflectionUtils.GetAttribute<T>(typeInterface, true);
+ if (attribute != null)
+ return attribute;
+ }
+
+ return null;
}
private static T GetAttribute<T>(MemberInfo memberInfo) where T : Attribute
{
+ T attribute;
+
+#if !SILVERLIGHT && !PocketPC && !NET20
Type metadataType = GetAssociatedMetadataType(memberInfo.DeclaringType);
if (metadataType != null)
{
- MemberInfo metadataTypeMemberInfo = metadataType.GetMember(memberInfo.Name,
- memberInfo.MemberType,
- BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance).SingleOrDefault();
+ MemberInfo metadataTypeMemberInfo = ReflectionUtils.GetMemberInfoFromType(metadataType, memberInfo);
if (metadataTypeMemberInfo != null)
{
- T attribute = ReflectionUtils.GetAttribute<T>(metadataTypeMemberInfo, true);
+ attribute = ReflectionUtils.GetAttribute<T>(metadataTypeMemberInfo, true);
if (attribute != null)
return attribute;
}
}
+#endif
+
+ attribute = ReflectionUtils.GetAttribute<T>(memberInfo, true);
+ if (attribute != null)
+ return attribute;
+
+ foreach (Type typeInterface in memberInfo.DeclaringType.GetInterfaces())
+ {
+ MemberInfo interfaceTypeMemberInfo = ReflectionUtils.GetMemberInfoFromType(typeInterface, memberInfo);
- return ReflectionUtils.GetAttribute<T>(memberInfo, true);
+ if (interfaceTypeMemberInfo != null)
+ {
+ attribute = ReflectionUtils.GetAttribute<T>(interfaceTypeMemberInfo, true);
+ if (attribute != null)
+ return attribute;
+ }
+ }
+
+ return null;
}
public static T GetAttribute<T>(ICustomAttributeProvider attributeProvider) where T : Attribute
@@ -250,12 +325,6 @@ namespace Newtonsoft.Json.Serialization
return ReflectionUtils.GetAttribute<T>(attributeProvider, true);
}
-#else
- public static T GetAttribute<T>(ICustomAttributeProvider attributeProvider) where T : Attribute
- {
- return ReflectionUtils.GetAttribute<T>(attributeProvider, true);
- }
-#endif
private static bool? _dynamicCodeGeneration;
diff --git a/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs b/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs
index 69a1571..a125e04 100644
--- a/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs
+++ b/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs
@@ -37,6 +37,21 @@ namespace Newtonsoft.Json.Utilities
{
internal static class ReflectionUtils
{
+ public static bool IsVirtual(this PropertyInfo propertyInfo)
+ {
+ ValidationUtils.ArgumentNotNull(propertyInfo, "propertyInfo");
+
+ MethodInfo m = propertyInfo.GetGetMethod();
+ if (m != null && m.IsVirtual)
+ return true;
+
+ m = propertyInfo.GetSetMethod();
+ if (m != null && m.IsVirtual)
+ return true;
+
+ return false;
+ }
+
public static Type GetObjectType(object v)
{
return (v != null) ? v.GetType() : null;
@@ -706,6 +721,9 @@ namespace Newtonsoft.Json.Utilities
// http://hyperthink.net/blog/getcustomattributes-gotcha/
// ICustomAttributeProvider doesn't do inheritance
+ if (attributeProvider is Type)
+ return (T[])((Type)attributeProvider).GetCustomAttributes(typeof(T), inherit);
+
if (attributeProvider is Assembly)
return (T[])Attribute.GetCustomAttributes((Assembly)attributeProvider, typeof(T), inherit);
@@ -851,6 +869,23 @@ namespace Newtonsoft.Json.Utilities
return null;
}
+ public static MemberInfo GetMemberInfoFromType(Type targetType, MemberInfo memberInfo)
+ {
+ BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
+
+ switch (memberInfo.MemberType)
+ {
+ case MemberTypes.Property:
+ PropertyInfo propertyInfo = (PropertyInfo) memberInfo;
+
+ Type[] types = propertyInfo.GetIndexParameters().Select(p => p.ParameterType).ToArray();
+
+ return targetType.GetProperty(propertyInfo.Name, bindingAttr, null, propertyInfo.PropertyType, types, null);
+ default:
+ return targetType.GetMember(memberInfo.Name, memberInfo.MemberType, bindingAttr).SingleOrDefault();
+ }
+ }
+
public static IEnumerable<FieldInfo> GetFields(Type targetType, BindingFlags bindingAttr)
{
ValidationUtils.ArgumentNotNull(targetType, "targetType");
@@ -896,9 +931,7 @@ namespace Newtonsoft.Json.Utilities
PropertyInfo member = propertyInfos[i];
if (member.DeclaringType != targetType)
{
- Type[] types = member.GetIndexParameters().Select(p => p.ParameterType).ToArray();
-
- PropertyInfo declaredMember = member.DeclaringType.GetProperty(member.Name, bindingAttr, null, member.PropertyType, types, null);
+ PropertyInfo declaredMember = (PropertyInfo)GetMemberInfoFromType(member.DeclaringType, member);
propertyInfos[i] = declaredMember;
}
}