-modify DefaultContractResolver to walk class hierarchy

This commit is contained in:
Paul Betts
2013-02-12 11:35:29 -08:00
parent 2108d65a83
commit a1bfcde445
@@ -597,39 +597,80 @@ namespace Newtonsoft.Json.Serialization
onDeserialized = null; onDeserialized = null;
onError = null; onError = null;
foreach (MethodInfo method in type.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) foreach (Type baseType in GetClassHierarchyForType(type))
{ {
// compact framework errors when getting parameters for a generic method // while we allow more than one OnSerialized total, only one can be defined
// lame, but generic methods should not be callbacks anyway // per class
if (method.ContainsGenericParameters) MethodInfo currentOnSerializing = null;
continue; MethodInfo currentOnSerialized = null;
MethodInfo currentOnDeserializing = null;
MethodInfo currentOnDeserialized = null;
MethodInfo currentOnError = null;
Type prevAttributeType = null; foreach (MethodInfo method in baseType.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
ParameterInfo[] parameters = method.GetParameters(); {
// compact framework errors when getting parameters for a generic method
// lame, but generic methods should not be callbacks anyway
if (method.ContainsGenericParameters)
continue;
if (IsValidCallback(method, parameters, typeof(OnSerializingAttribute), onSerializing, ref prevAttributeType)) Type prevAttributeType = null;
{ ParameterInfo[] parameters = method.GetParameters();
onSerializing = method;
} if (IsValidCallback(method, parameters, typeof(OnSerializingAttribute), currentOnSerializing, ref prevAttributeType))
if (IsValidCallback(method, parameters, typeof(OnSerializedAttribute), onSerialized, ref prevAttributeType)) {
{ onSerializing = onSerializing ?? new List<MethodInfo>();
onSerialized = method; onSerializing.Add(method);
} currentOnSerializing = method;
if (IsValidCallback(method, parameters, typeof(OnDeserializingAttribute), onDeserializing, ref prevAttributeType)) }
{ if (IsValidCallback(method, parameters, typeof(OnSerializedAttribute), currentOnSerialized, ref prevAttributeType))
onDeserializing = method; {
} onSerialized = onSerialized ?? new List<MethodInfo>();
if (IsValidCallback(method, parameters, typeof(OnDeserializedAttribute), onDeserialized, ref prevAttributeType)) onSerialized.Add(method);
{ currentOnSerialized = method;
onDeserialized = method; }
} if (IsValidCallback(method, parameters, typeof(OnDeserializingAttribute), currentOnDeserializing, ref prevAttributeType))
if (IsValidCallback(method, parameters, typeof(OnErrorAttribute), onError, ref prevAttributeType)) {
{ onDeserializing = onDeserializing ?? new List<MethodInfo>();
onError = method; onDeserializing.Add(method);
currentOnDeserializing = method;
}
if (IsValidCallback(method, parameters, typeof(OnDeserializedAttribute), currentOnDeserialized, ref prevAttributeType))
{
onDeserialized = onDeserialized ?? new List<MethodInfo>();
onDeserialized.Add(method);
currentOnDeserialized = method;
}
if (IsValidCallback(method, parameters, typeof(OnErrorAttribute), currentOnError, ref prevAttributeType))
{
onError = onError ?? new List<MethodInfo>();
onError.Add(method);
currentOnError = method;
}
} }
} }
} }
private List<Type> GetClassHierarchyForType(Type type)
{
List<Type> ret = new List<Type>();
Type current = type;
while (current != null && current != typeof(object))
{
ret.Add(current);
#if NETFX_CORE
current = current.BaseType();
#else
current = current.BaseType;
#endif
}
// Return the class list in order of simple => complex
ret.Reverse();
return ret;
}
/// <summary> /// <summary>
/// Creates a <see cref="JsonDictionaryContract"/> for the given type. /// Creates a <see cref="JsonDictionaryContract"/> for the given type.
/// </summary> /// </summary>
@@ -1108,4 +1149,4 @@ namespace Newtonsoft.Json.Serialization
return ResolvePropertyName(propertyName); return ResolvePropertyName(propertyName);
} }
} }
} }