diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs index 278bb5a8..c9eca02d 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs @@ -9199,6 +9199,41 @@ Path '', line 1, position 1."); } #endif + [Test] + public void SerializeObjectWithEvent() + { + MyObservableObject o = new MyObservableObject + { + TestString = "Test string" + }; + + string json = JsonConvert.SerializeObject(o, Formatting.Indented); + StringAssert.AreEqual(@"{ + ""PropertyChanged"": null, + ""TestString"": ""Test string"" +}", json); + + MyObservableObject o2 = JsonConvert.DeserializeObject(json); + Assert.AreEqual("Test string", o2.TestString); + } + + public class MyObservableObject : ObservableObject + { + public new string PropertyChanged; + + public string TestString { get; set; } + } + + public class ObservableObject : INotifyPropertyChanged + { + public event PropertyChangedEventHandler PropertyChanged; + + protected PropertyChangedEventHandler PropertyChangedHandler + { + get { return PropertyChanged; } + } + } + [Test] public void ParameterizedConstructorWithBasePrivateProperties() { diff --git a/Src/Newtonsoft.Json/Utilities/TypeExtensions.cs b/Src/Newtonsoft.Json/Utilities/TypeExtensions.cs index 16882702..ee7e0924 100644 --- a/Src/Newtonsoft.Json/Utilities/TypeExtensions.cs +++ b/Src/Newtonsoft.Json/Utilities/TypeExtensions.cs @@ -30,7 +30,6 @@ using System.Reflection; using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; - #endif namespace Newtonsoft.Json.Utilities @@ -50,7 +49,9 @@ namespace Newtonsoft.Json.Utilities { MethodInfo getMethod = propertyInfo.GetMethod; if (getMethod != null && (getMethod.IsPublic || nonPublic)) + { return getMethod; + } return null; } @@ -64,7 +65,9 @@ namespace Newtonsoft.Json.Utilities { MethodInfo setMethod = propertyInfo.SetMethod; if (setMethod != null && (setMethod.IsPublic || nonPublic)) + { return setMethod; + } return null; } @@ -85,7 +88,9 @@ namespace Newtonsoft.Json.Utilities public static bool IsInstanceOfType(this Type type, object o) { if (o == null) + { return false; + } return type.IsAssignableFrom(o.GetType()); } @@ -106,15 +111,25 @@ namespace Newtonsoft.Json.Utilities return memberInfo.MemberType; #else if (memberInfo is PropertyInfo) + { return MemberTypes.Property; + } else if (memberInfo is FieldInfo) + { return MemberTypes.Field; + } else if (memberInfo is EventInfo) + { return MemberTypes.Event; + } else if (memberInfo is MethodInfo) + { return MemberTypes.Method; + } else + { return MemberTypes.Other; + } #endif } @@ -207,13 +222,19 @@ namespace Newtonsoft.Json.Utilities return propertyInfos.Where(p => { if (name != null && name != p.Name) + { return false; + } if (propertyType != null && propertyType != p.PropertyType) + { return false; + } if (indexParameters != null) { if (!p.GetIndexParameters().Select(ip => ip.ParameterType).SequenceEqual(indexParameters)) + { return false; + } } return true; @@ -222,13 +243,19 @@ namespace Newtonsoft.Json.Utilities public static IEnumerable GetMember(this Type type, string name, MemberTypes memberType, BindingFlags bindingFlags) { +#if PORTABLE + return type.GetMemberInternal(name, memberType, bindingFlags); +#else return type.GetMember(name, bindingFlags).Where(m => { if (m.MemberType() != memberType) + { return false; + } return true; }); +#endif } #endif @@ -268,16 +295,21 @@ namespace Newtonsoft.Json.Utilities public static MethodInfo GetMethod(this Type type, string name, BindingFlags bindingFlags, object placeHolder1, IList parameterTypes, object placeHolder2) { - return type.GetTypeInfo().DeclaredMethods.Where(m => - { - if (name != null && m.Name != name) - return false; + return type.GetTypeInfo().DeclaredMethods.Where( + m => + { + if (name != null && m.Name != name) + { + return false; + } - if (!TestAccessibility(m, bindingFlags)) - return false; + if (!TestAccessibility(m, bindingFlags)) + { + return false; + } - return m.GetParameters().Select(p => p.ParameterType).SequenceEqual(parameterTypes); - }).SingleOrDefault(); + return m.GetParameters().Select(p => p.ParameterType).SequenceEqual(parameterTypes); + }).SingleOrDefault(); } public static IEnumerable GetConstructors(this Type type) @@ -292,16 +324,21 @@ namespace Newtonsoft.Json.Utilities private static IEnumerable GetConstructors(this Type type, BindingFlags bindingFlags, IList parameterTypes) { - return type.GetTypeInfo().DeclaredConstructors.Where(c => - { - if (!TestAccessibility(c, bindingFlags)) - return false; + return type.GetTypeInfo().DeclaredConstructors.Where( + c => + { + if (!TestAccessibility(c, bindingFlags)) + { + return false; + } - if (parameterTypes != null && !c.GetParameters().Select(p => p.ParameterType).SequenceEqual(parameterTypes)) - return false; + if (parameterTypes != null && !c.GetParameters().Select(p => p.ParameterType).SequenceEqual(parameterTypes)) + { + return false; + } - return true; - }); + return true; + }); } public static ConstructorInfo GetConstructor(this Type type, IList parameterTypes) @@ -316,12 +353,21 @@ namespace Newtonsoft.Json.Utilities public static MemberInfo[] GetMember(this Type type, string member) { - return type.GetMember(member, DefaultFlags); + return type.GetMemberInternal(member, null, DefaultFlags); } public static MemberInfo[] GetMember(this Type type, string member, BindingFlags bindingFlags) { - return type.GetTypeInfo().GetMembersRecursive().Where(m => m.Name == member && TestAccessibility(m, bindingFlags)).ToArray(); + return type.GetMemberInternal(member, null, bindingFlags); + } + + public static MemberInfo[] GetMemberInternal(this Type type, string member, MemberTypes? memberType, BindingFlags bindingFlags) + { + return type.GetTypeInfo().GetMembersRecursive().Where(m => + m.Name == member && + // test type before accessibility - accessibility doesn't support some types + (memberType == null || m.MemberType() == memberType) && + TestAccessibility(m, bindingFlags)).ToArray(); } public static MemberInfo GetField(this Type type, string member) @@ -337,8 +383,8 @@ namespace Newtonsoft.Json.Utilities public static IEnumerable GetProperties(this Type type, BindingFlags bindingFlags) { IList properties = (bindingFlags.HasFlag(BindingFlags.DeclaredOnly)) - ? type.GetTypeInfo().DeclaredProperties.ToList() - : type.GetTypeInfo().GetPropertiesRecursive(); + ? type.GetTypeInfo().DeclaredProperties.ToList() + : type.GetTypeInfo().GetPropertiesRecursive(); return properties.Where(p => TestAccessibility(p, bindingFlags)); } @@ -349,10 +395,12 @@ namespace Newtonsoft.Json.Utilities IList members = new List(); while (t != null) { - foreach (var member in t.DeclaredMembers) + foreach (MemberInfo member in t.DeclaredMembers) { if (!members.Any(p => p.Name == member.Name)) + { members.Add(member); + } } t = (t.BaseType != null) ? t.BaseType.GetTypeInfo() : null; } @@ -366,10 +414,12 @@ namespace Newtonsoft.Json.Utilities IList properties = new List(); while (t != null) { - foreach (var member in t.DeclaredProperties) + foreach (PropertyInfo member in t.DeclaredProperties) { if (!properties.Any(p => p.Name == member.Name)) + { properties.Add(member); + } } t = (t.BaseType != null) ? t.BaseType.GetTypeInfo() : null; } @@ -383,10 +433,12 @@ namespace Newtonsoft.Json.Utilities IList fields = new List(); while (t != null) { - foreach (var member in t.DeclaredFields) + foreach (FieldInfo member in t.DeclaredFields) { if (!fields.Any(p => p.Name == member.Name)) + { fields.Add(member); + } } t = (t.BaseType != null) ? t.BaseType.GetTypeInfo() : null; } @@ -417,8 +469,8 @@ namespace Newtonsoft.Json.Utilities public static IEnumerable GetFields(this Type type, BindingFlags bindingFlags) { IList fields = (bindingFlags.HasFlag(BindingFlags.DeclaredOnly)) - ? type.GetTypeInfo().DeclaredFields.ToList() - : type.GetTypeInfo().GetFieldsRecursive(); + ? type.GetTypeInfo().DeclaredFields.ToList() + : type.GetTypeInfo().GetFieldsRecursive(); return fields.Where(f => TestAccessibility(f, bindingFlags)).ToList(); } @@ -426,10 +478,14 @@ namespace Newtonsoft.Json.Utilities private static bool TestAccessibility(PropertyInfo member, BindingFlags bindingFlags) { if (member.GetMethod != null && TestAccessibility(member.GetMethod, bindingFlags)) + { return true; + } if (member.SetMethod != null && TestAccessibility(member.SetMethod, bindingFlags)) + { return true; + } return false; }