<PackageReference Include="Newtonsoft.Json" Version="6.0.5" />

DefaultContractResolver

Used by JsonSerializer to resolves a JsonContract for a given Type.
using Newtonsoft.Json.Converters; using Newtonsoft.Json.Linq; using Newtonsoft.Json.Utilities; using Newtonsoft.Json.Utilities.LinqBridge; using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Serialization; namespace Newtonsoft.Json.Serialization { public class DefaultContractResolver : IContractResolver { internal struct DictionaryEnumerator<TEnumeratorKey, TEnumeratorValue> : IEnumerable<KeyValuePair<object, object>>, IEnumerable, IEnumerator<KeyValuePair<object, object>>, IDisposable, IEnumerator { private readonly IEnumerator<KeyValuePair<TEnumeratorKey, TEnumeratorValue>> _e; public KeyValuePair<object, object> Current => new KeyValuePair<object, object>(_e.Current.Key, _e.Current.Value); object IEnumerator.Current { get { return Current; } } public DictionaryEnumerator(IEnumerable<KeyValuePair<TEnumeratorKey, TEnumeratorValue>> e) { ValidationUtils.ArgumentNotNull(e, "e"); _e = e.GetEnumerator(); } public bool MoveNext() { return _e.MoveNext(); } public void Reset() { _e.Reset(); } public void Dispose() { _e.Dispose(); } public IEnumerator<KeyValuePair<object, object>> GetEnumerator() { return this; } IEnumerator IEnumerable.GetEnumerator() { return this; } } private static readonly IContractResolver _instance = new DefaultContractResolver(true); private static readonly IList<JsonConverter> BuiltInConverters = new List<JsonConverter> { new XmlNodeConverter(), new BinaryConverter(), new DataSetConverter(), new DataTableConverter(), new KeyValuePairConverter(), new BsonObjectIdConverter(), new RegexConverter() }; private static Dictionary<ResolverContractKey, JsonContract> _sharedContractCache; private static readonly object _typeContractCacheLock = new object(); private Dictionary<ResolverContractKey, JsonContract> _instanceContractCache; private readonly bool _sharedCache; internal static IContractResolver Instance => _instance; public bool DynamicCodeGeneration => JsonTypeReflector.DynamicCodeGeneration; [Obsolete("DefaultMembersSearchFlags is obsolete. To modify the members serialized inherit from DefaultContractResolver and override the GetSerializableMembers method instead.")] public BindingFlags DefaultMembersSearchFlags { get; set; } public bool SerializeCompilerGeneratedMembers { get; set; } public bool IgnoreSerializableInterface { get; set; } public bool IgnoreSerializableAttribute { get; set; } public DefaultContractResolver() : this(false) { } public DefaultContractResolver(bool shareCache) { DefaultMembersSearchFlags = (BindingFlags.Instance | BindingFlags.Public); IgnoreSerializableAttribute = true; _sharedCache = shareCache; } private Dictionary<ResolverContractKey, JsonContract> GetCache() { if (_sharedCache) return _sharedContractCache; return _instanceContractCache; } private void UpdateCache(Dictionary<ResolverContractKey, JsonContract> cache) { if (_sharedCache) _sharedContractCache = cache; else _instanceContractCache = cache; } public virtual JsonContract ResolveContract(Type type) { if ((object)type == null) throw new ArgumentNullException("type"); ResolverContractKey key = new ResolverContractKey(GetType(), type); Dictionary<ResolverContractKey, JsonContract> cache = GetCache(); if (cache == null || !cache.TryGetValue(key, out JsonContract value)) { value = CreateContract(type); lock (_typeContractCacheLock) { cache = GetCache(); Dictionary<ResolverContractKey, JsonContract> dictionary = (cache != null) ? new Dictionary<ResolverContractKey, JsonContract>(cache) : new Dictionary<ResolverContractKey, JsonContract>(); dictionary[key] = value; UpdateCache(dictionary); return value; } } return value; } protected virtual List<MemberInfo> GetSerializableMembers(Type objectType) { bool ignoreSerializableAttribute = IgnoreSerializableAttribute; MemberSerialization objectMemberSerialization = JsonTypeReflector.GetObjectMemberSerialization(objectType, ignoreSerializableAttribute); List<MemberInfo> list = (from m in ReflectionUtils.GetFieldsAndProperties(objectType, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) where !ReflectionUtils.IsIndexedProperty(m) select m).ToList(); List<MemberInfo> list2 = new List<MemberInfo>(); if (objectMemberSerialization != MemberSerialization.Fields) { List<MemberInfo> list3 = (from m in ReflectionUtils.GetFieldsAndProperties(objectType, DefaultMembersSearchFlags) where !ReflectionUtils.IsIndexedProperty(m) select m).ToList(); { foreach (MemberInfo item in list) { if (SerializeCompilerGeneratedMembers || !item.IsDefined(typeof(CompilerGeneratedAttribute), true)) { if (list3.Contains(item)) list2.Add(item); else if (JsonTypeReflector.GetAttribute<JsonPropertyAttribute>(item) != null) { list2.Add(item); } else if (objectMemberSerialization == MemberSerialization.Fields && item.MemberType() == MemberTypes.Field) { list2.Add(item); } } } return list2; } } foreach (MemberInfo item2 in list) { FieldInfo fieldInfo = item2 as FieldInfo; if ((object)fieldInfo != null && !fieldInfo.IsStatic) list2.Add(item2); } return list2; } protected virtual JsonObjectContract CreateObjectContract(Type objectType) { JsonObjectContract jsonObjectContract = new JsonObjectContract(objectType); InitializeContract(jsonObjectContract); bool ignoreSerializableAttribute = IgnoreSerializableAttribute; jsonObjectContract.MemberSerialization = JsonTypeReflector.GetObjectMemberSerialization(jsonObjectContract.NonNullableUnderlyingType, ignoreSerializableAttribute); jsonObjectContract.Properties.AddRange(CreateProperties(jsonObjectContract.NonNullableUnderlyingType, jsonObjectContract.MemberSerialization)); JsonObjectAttribute cachedAttribute = JsonTypeReflector.GetCachedAttribute<JsonObjectAttribute>(jsonObjectContract.NonNullableUnderlyingType); if (cachedAttribute != null) jsonObjectContract.ItemRequired = cachedAttribute._itemRequired; if (jsonObjectContract.IsInstantiable) { ConstructorInfo attributeConstructor = GetAttributeConstructor(jsonObjectContract.NonNullableUnderlyingType); if ((object)attributeConstructor != null) { jsonObjectContract.OverrideConstructor = attributeConstructor; jsonObjectContract.CreatorParameters.AddRange(CreateConstructorParameters(attributeConstructor, jsonObjectContract.Properties)); } else if (jsonObjectContract.MemberSerialization == MemberSerialization.Fields) { if (JsonTypeReflector.FullyTrusted) jsonObjectContract.DefaultCreator = jsonObjectContract.GetUninitializedObject; } else if (jsonObjectContract.DefaultCreator == null || jsonObjectContract.DefaultCreatorNonPublic) { ConstructorInfo parametrizedConstructor = GetParametrizedConstructor(jsonObjectContract.NonNullableUnderlyingType); if ((object)parametrizedConstructor != null) { jsonObjectContract.ParametrizedConstructor = parametrizedConstructor; jsonObjectContract.CreatorParameters.AddRange(CreateConstructorParameters(parametrizedConstructor, jsonObjectContract.Properties)); } } } MemberInfo extensionDataMemberForType = GetExtensionDataMemberForType(jsonObjectContract.NonNullableUnderlyingType); if ((object)extensionDataMemberForType != null) SetExtensionDataDelegates(jsonObjectContract, extensionDataMemberForType); return jsonObjectContract; } private MemberInfo GetExtensionDataMemberForType(Type type) { IEnumerable<MemberInfo> source = GetClassHierarchyForType(type).SelectMany(delegate(Type baseType) { IList<MemberInfo> list = new List<MemberInfo>(); list.AddRange(baseType.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)); list.AddRange(baseType.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)); return list; }); return source.LastOrDefault(delegate(MemberInfo m) { MemberTypes memberTypes = m.MemberType(); if (memberTypes != MemberTypes.Property && memberTypes != MemberTypes.Field) return false; if (!m.IsDefined(typeof(JsonExtensionDataAttribute), false)) return false; Type memberUnderlyingType = ReflectionUtils.GetMemberUnderlyingType(m); if (ReflectionUtils.ImplementsGenericDefinition(memberUnderlyingType, typeof(IDictionary<, >), out Type implementingType)) { Type type2 = implementingType.GetGenericArguments()[0]; Type type3 = implementingType.GetGenericArguments()[1]; if (type2.IsAssignableFrom(typeof(string)) && type3.IsAssignableFrom(typeof(JToken))) return true; } throw new JsonException("Invalid extension data attribute on '{0}'. Member '{1}' type must implement IDictionary<string, JToken>.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(m.DeclaringType), m.Name)); }); } private static void SetExtensionDataDelegates(JsonObjectContract contract, MemberInfo member) { JsonExtensionDataAttribute attribute = ReflectionUtils.GetAttribute<JsonExtensionDataAttribute>(member); if (attribute != null) { Type type = ReflectionUtils.GetMemberUnderlyingType(member); ReflectionUtils.ImplementsGenericDefinition(type, typeof(IDictionary<, >), out Type implementingType); Type type2 = implementingType.GetGenericArguments()[0]; Type type3 = implementingType.GetGenericArguments()[1]; bool isJTokenValueType = typeof(JToken).IsAssignableFrom(type3); if (ReflectionUtils.IsGenericDefinition(type, typeof(IDictionary<, >))) type = typeof(Dictionary<, >).MakeGenericType(type2, type3); MethodInfo method = type.GetMethod("Add", new Type[2] { type2, type3 }); Func<object, object> getExtensionDataDictionary = JsonTypeReflector.ReflectionDelegateFactory.CreateGet<object>(member); Action<object, object> setExtensionDataDictionary = JsonTypeReflector.ReflectionDelegateFactory.CreateSet<object>(member); Func<object> createExtensionDataDictionary = JsonTypeReflector.ReflectionDelegateFactory.CreateDefaultConstructor<object>(type); MethodCall<object, object> setExtensionDataDictionaryValue = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall<object>(method); ExtensionDataSetter extensionDataSetter = delegate(object o, string key, object value) { object obj2 = getExtensionDataDictionary(o); if (obj2 == null) { obj2 = createExtensionDataDictionary(); setExtensionDataDictionary(o, obj2); } if (isJTokenValueType && !(value is JToken)) value = ((value != null) ? JToken.FromObject(value) : JValue.CreateNull()); setExtensionDataDictionaryValue(obj2, key, value); }; Type type4 = typeof(DictionaryEnumerator<, >).MakeGenericType(type2, type3); ConstructorInfo method2 = type4.GetConstructors().First(); ObjectConstructor<object> createEnumerableWrapper = JsonTypeReflector.ReflectionDelegateFactory.CreateParametrizedConstructor(method2); ExtensionDataGetter extensionDataGetter = delegate(object o) { object obj = getExtensionDataDictionary(o); if (obj == null) return null; return (IEnumerable<KeyValuePair<object, object>>)createEnumerableWrapper(obj); }; if (attribute.ReadData) contract.ExtensionDataSetter = extensionDataSetter; if (attribute.WriteData) contract.ExtensionDataGetter = extensionDataGetter; } } private ConstructorInfo GetAttributeConstructor(Type objectType) { IList<ConstructorInfo> list = (from c in objectType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) where c.IsDefined(typeof(JsonConstructorAttribute), true) select c).ToList(); if (list.Count > 1) throw new JsonException("Multiple constructors with the JsonConstructorAttribute."); if (list.Count == 1) return list[0]; if ((object)objectType == typeof(Version)) return objectType.GetConstructor(new Type[4] { typeof(int), typeof(int), typeof(int), typeof(int) }); return null; } private ConstructorInfo GetParametrizedConstructor(Type objectType) { IList<ConstructorInfo> list = objectType.GetConstructors(BindingFlags.Instance | BindingFlags.Public).ToList(); if (list.Count == 1) return list[0]; return null; } protected virtual IList<JsonProperty> CreateConstructorParameters(ConstructorInfo constructor, JsonPropertyCollection memberProperties) { ParameterInfo[] parameters = constructor.GetParameters(); JsonPropertyCollection jsonPropertyCollection = new JsonPropertyCollection(constructor.DeclaringType); ParameterInfo[] array = parameters; foreach (ParameterInfo parameterInfo in array) { JsonProperty jsonProperty = (parameterInfo.Name != null) ? memberProperties.GetClosestMatchProperty(parameterInfo.Name) : null; if (jsonProperty != null && (object)jsonProperty.PropertyType != parameterInfo.ParameterType) jsonProperty = null; if (jsonProperty != null || parameterInfo.Name != null) { JsonProperty jsonProperty2 = CreatePropertyFromConstructorParameter(jsonProperty, parameterInfo); if (jsonProperty2 != null) jsonPropertyCollection.AddProperty(jsonProperty2); } } return jsonPropertyCollection; } protected virtual JsonProperty CreatePropertyFromConstructorParameter(JsonProperty matchingMemberProperty, ParameterInfo parameterInfo) { JsonProperty jsonProperty = new JsonProperty(); jsonProperty.PropertyType = parameterInfo.ParameterType; SetPropertySettingsFromAttributes(jsonProperty, parameterInfo, parameterInfo.Name, parameterInfo.Member.DeclaringType, MemberSerialization.OptOut, out bool _); jsonProperty.Readable = false; jsonProperty.Writable = true; if (matchingMemberProperty != null) { jsonProperty.PropertyName = ((jsonProperty.PropertyName != parameterInfo.Name) ? jsonProperty.PropertyName : matchingMemberProperty.PropertyName); jsonProperty.Converter = (jsonProperty.Converter ?? matchingMemberProperty.Converter); jsonProperty.MemberConverter = (jsonProperty.MemberConverter ?? matchingMemberProperty.MemberConverter); if (!jsonProperty._hasExplicitDefaultValue && matchingMemberProperty._hasExplicitDefaultValue) jsonProperty.DefaultValue = matchingMemberProperty.DefaultValue; jsonProperty._required = (jsonProperty._required ?? matchingMemberProperty._required); jsonProperty.IsReference = (jsonProperty.IsReference ?? matchingMemberProperty.IsReference); jsonProperty.NullValueHandling = (jsonProperty.NullValueHandling ?? matchingMemberProperty.NullValueHandling); jsonProperty.DefaultValueHandling = (jsonProperty.DefaultValueHandling ?? matchingMemberProperty.DefaultValueHandling); jsonProperty.ReferenceLoopHandling = (jsonProperty.ReferenceLoopHandling ?? matchingMemberProperty.ReferenceLoopHandling); jsonProperty.ObjectCreationHandling = (jsonProperty.ObjectCreationHandling ?? matchingMemberProperty.ObjectCreationHandling); jsonProperty.TypeNameHandling = (jsonProperty.TypeNameHandling ?? matchingMemberProperty.TypeNameHandling); } return jsonProperty; } protected virtual JsonConverter ResolveContractConverter(Type objectType) { return JsonTypeReflector.GetJsonConverter(objectType); } private Func<object> GetDefaultCreator(Type createdType) { return JsonTypeReflector.ReflectionDelegateFactory.CreateDefaultConstructor<object>(createdType); } private void InitializeContract(JsonContract contract) { JsonContainerAttribute cachedAttribute = JsonTypeReflector.GetCachedAttribute<JsonContainerAttribute>(contract.NonNullableUnderlyingType); if (cachedAttribute != null) contract.IsReference = cachedAttribute._isReference; contract.Converter = ResolveContractConverter(contract.NonNullableUnderlyingType); contract.InternalConverter = JsonSerializer.GetMatchingConverter(BuiltInConverters, contract.NonNullableUnderlyingType); if (contract.IsInstantiable && (ReflectionUtils.HasDefaultConstructor(contract.CreatedType, true) || contract.CreatedType.IsValueType())) { contract.DefaultCreator = GetDefaultCreator(contract.CreatedType); contract.DefaultCreatorNonPublic = (!contract.CreatedType.IsValueType() && (object)ReflectionUtils.GetDefaultConstructor(contract.CreatedType) == null); } ResolveCallbackMethods(contract, contract.NonNullableUnderlyingType); } private void ResolveCallbackMethods(JsonContract contract, Type t) { GetCallbackMethodsForType(t, out List<SerializationCallback> onSerializing, out List<SerializationCallback> onSerialized, out List<SerializationCallback> onDeserializing, out List<SerializationCallback> onDeserialized, out List<SerializationErrorCallback> onError); if (onSerializing != null) contract.OnSerializingCallbacks.AddRange(onSerializing); if (onSerialized != null) contract.OnSerializedCallbacks.AddRange(onSerialized); if (onDeserializing != null) contract.OnDeserializingCallbacks.AddRange(onDeserializing); if (onDeserialized != null) contract.OnDeserializedCallbacks.AddRange(onDeserialized); if (onError != null) contract.OnErrorCallbacks.AddRange(onError); } private void GetCallbackMethodsForType(Type type, out List<SerializationCallback> onSerializing, out List<SerializationCallback> onSerialized, out List<SerializationCallback> onDeserializing, out List<SerializationCallback> onDeserialized, out List<SerializationErrorCallback> onError) { onSerializing = null; onSerialized = null; onDeserializing = null; onDeserialized = null; onError = null; foreach (Type item in GetClassHierarchyForType(type)) { MethodInfo currentCallback = null; MethodInfo currentCallback2 = null; MethodInfo currentCallback3 = null; MethodInfo currentCallback4 = null; MethodInfo currentCallback5 = null; MethodInfo[] methods = item.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (!methodInfo.ContainsGenericParameters) { Type prevAttributeType = null; ParameterInfo[] parameters = methodInfo.GetParameters(); if (IsValidCallback(methodInfo, parameters, typeof(OnSerializingAttribute), currentCallback, ref prevAttributeType)) { onSerializing = (onSerializing ?? new List<SerializationCallback>()); onSerializing.Add(JsonContract.CreateSerializationCallback(methodInfo)); currentCallback = methodInfo; } if (IsValidCallback(methodInfo, parameters, typeof(OnSerializedAttribute), currentCallback2, ref prevAttributeType)) { onSerialized = (onSerialized ?? new List<SerializationCallback>()); onSerialized.Add(JsonContract.CreateSerializationCallback(methodInfo)); currentCallback2 = methodInfo; } if (IsValidCallback(methodInfo, parameters, typeof(OnDeserializingAttribute), currentCallback3, ref prevAttributeType)) { onDeserializing = (onDeserializing ?? new List<SerializationCallback>()); onDeserializing.Add(JsonContract.CreateSerializationCallback(methodInfo)); currentCallback3 = methodInfo; } if (IsValidCallback(methodInfo, parameters, typeof(OnDeserializedAttribute), currentCallback4, ref prevAttributeType)) { onDeserialized = (onDeserialized ?? new List<SerializationCallback>()); onDeserialized.Add(JsonContract.CreateSerializationCallback(methodInfo)); currentCallback4 = methodInfo; } if (IsValidCallback(methodInfo, parameters, typeof(OnErrorAttribute), currentCallback5, ref prevAttributeType)) { onError = (onError ?? new List<SerializationErrorCallback>()); onError.Add(JsonContract.CreateSerializationErrorCallback(methodInfo)); currentCallback5 = methodInfo; } } } } } private List<Type> GetClassHierarchyForType(Type type) { List<Type> list = new List<Type>(); Type type2 = type; while ((object)type2 != null && (object)type2 != typeof(object)) { list.Add(type2); type2 = type2.BaseType(); } list.Reverse(); return list; } protected virtual JsonDictionaryContract CreateDictionaryContract(Type objectType) { JsonDictionaryContract jsonDictionaryContract = new JsonDictionaryContract(objectType); InitializeContract(jsonDictionaryContract); jsonDictionaryContract.PropertyNameResolver = ResolvePropertyName; return jsonDictionaryContract; } protected virtual JsonArrayContract CreateArrayContract(Type objectType) { JsonArrayContract jsonArrayContract = new JsonArrayContract(objectType); InitializeContract(jsonArrayContract); return jsonArrayContract; } protected virtual JsonPrimitiveContract CreatePrimitiveContract(Type objectType) { JsonPrimitiveContract jsonPrimitiveContract = new JsonPrimitiveContract(objectType); InitializeContract(jsonPrimitiveContract); return jsonPrimitiveContract; } protected virtual JsonLinqContract CreateLinqContract(Type objectType) { JsonLinqContract jsonLinqContract = new JsonLinqContract(objectType); InitializeContract(jsonLinqContract); return jsonLinqContract; } protected virtual JsonISerializableContract CreateISerializableContract(Type objectType) { JsonISerializableContract jsonISerializableContract = new JsonISerializableContract(objectType); InitializeContract(jsonISerializableContract); ConstructorInfo constructor = jsonISerializableContract.NonNullableUnderlyingType.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2] { typeof(SerializationInfo), typeof(StreamingContext) }, null); if ((object)constructor != null) { ObjectConstructor<object> objectConstructor2 = jsonISerializableContract.ISerializableCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateParametrizedConstructor(constructor); } return jsonISerializableContract; } protected virtual JsonStringContract CreateStringContract(Type objectType) { JsonStringContract jsonStringContract = new JsonStringContract(objectType); InitializeContract(jsonStringContract); return jsonStringContract; } protected virtual JsonContract CreateContract(Type objectType) { if (IsJsonPrimitiveType(objectType)) return CreatePrimitiveContract(objectType); Type type = ReflectionUtils.EnsureNotNullableType(objectType); JsonContainerAttribute cachedAttribute = JsonTypeReflector.GetCachedAttribute<JsonContainerAttribute>(type); if (cachedAttribute is JsonObjectAttribute) return CreateObjectContract(objectType); if (cachedAttribute is JsonArrayAttribute) return CreateArrayContract(objectType); if (cachedAttribute is JsonDictionaryAttribute) return CreateDictionaryContract(objectType); if ((object)type == typeof(JToken) || type.IsSubclassOf(typeof(JToken))) return CreateLinqContract(objectType); if (CollectionUtils.IsDictionaryType(type)) return CreateDictionaryContract(objectType); if (typeof(IEnumerable).IsAssignableFrom(type)) return CreateArrayContract(objectType); if (CanConvertToString(type)) return CreateStringContract(objectType); if (!IgnoreSerializableInterface && typeof(ISerializable).IsAssignableFrom(type)) return CreateISerializableContract(objectType); if (IsIConvertible(type)) return CreatePrimitiveContract(type); return CreateObjectContract(objectType); } internal static bool IsJsonPrimitiveType(Type t) { PrimitiveTypeCode typeCode = ConvertUtils.GetTypeCode(t); if (typeCode != 0) return typeCode != PrimitiveTypeCode.Object; return false; } internal static bool IsIConvertible(Type t) { if (typeof(IConvertible).IsAssignableFrom(t) || (ReflectionUtils.IsNullableType(t) && typeof(IConvertible).IsAssignableFrom(Nullable.GetUnderlyingType(t)))) return !typeof(JToken).IsAssignableFrom(t); return false; } internal static bool CanConvertToString(Type type) { TypeConverter converter = ConvertUtils.GetConverter(type); if (converter != null && !(converter is ComponentConverter) && !(converter is ReferenceConverter) && (object)converter.GetType() != typeof(TypeConverter) && converter.CanConvertTo(typeof(string))) return true; if ((object)type == typeof(Type) || type.IsSubclassOf(typeof(Type))) return true; return false; } private static bool IsValidCallback(MethodInfo method, ParameterInfo[] parameters, Type attributeType, MethodInfo currentCallback, ref Type prevAttributeType) { if (!method.IsDefined(attributeType, false)) return false; if ((object)currentCallback != null) throw new JsonException("Invalid attribute. Both '{0}' and '{1}' in type '{2}' have '{3}'.".FormatWith(CultureInfo.InvariantCulture, method, currentCallback, GetClrTypeFullName(method.DeclaringType), attributeType)); if ((object)prevAttributeType != null) throw new JsonException("Invalid Callback. Method '{3}' in type '{2}' has both '{0}' and '{1}'.".FormatWith(CultureInfo.InvariantCulture, prevAttributeType, attributeType, GetClrTypeFullName(method.DeclaringType), method)); if (method.IsVirtual) throw new JsonException("Virtual Method '{0}' of type '{1}' cannot be marked with '{2}' attribute.".FormatWith(CultureInfo.InvariantCulture, method, GetClrTypeFullName(method.DeclaringType), attributeType)); if ((object)method.ReturnType != typeof(void)) throw new JsonException("Serialization Callback '{1}' in type '{0}' must return void.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(method.DeclaringType), method)); if ((object)attributeType == typeof(OnErrorAttribute)) { if (parameters == null || parameters.Length != 2 || (object)parameters[0].ParameterType != typeof(StreamingContext) || (object)parameters[1].ParameterType != typeof(ErrorContext)) throw new JsonException("Serialization Error Callback '{1}' in type '{0}' must have two parameters of type '{2}' and '{3}'.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(method.DeclaringType), method, typeof(StreamingContext), typeof(ErrorContext))); } else if (parameters == null || parameters.Length != 1 || (object)parameters[0].ParameterType != typeof(StreamingContext)) { throw new JsonException("Serialization Callback '{1}' in type '{0}' must have a single parameter of type '{2}'.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(method.DeclaringType), method, typeof(StreamingContext))); } prevAttributeType = attributeType; return true; } internal static string GetClrTypeFullName(Type type) { if (type.IsGenericTypeDefinition() || !type.ContainsGenericParameters()) return type.FullName; return string.Format(CultureInfo.InvariantCulture, "{0}.{1}", new object[2] { type.Namespace, type.Name }); } protected virtual IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) { List<MemberInfo> serializableMembers = GetSerializableMembers(type); if (serializableMembers == null) throw new JsonSerializationException("Null collection of seralizable members returned."); JsonPropertyCollection jsonPropertyCollection = new JsonPropertyCollection(type); foreach (MemberInfo item in serializableMembers) { JsonProperty jsonProperty = CreateProperty(item, memberSerialization); if (jsonProperty != null) jsonPropertyCollection.AddProperty(jsonProperty); } return (from p in jsonPropertyCollection orderby p.Order ?? (-1) select p).ToList(); } protected virtual IValueProvider CreateMemberValueProvider(MemberInfo member) { if (!DynamicCodeGeneration) return new ReflectionValueProvider(member); return new DynamicValueProvider(member); } protected virtual JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) { JsonProperty jsonProperty = new JsonProperty(); jsonProperty.PropertyType = ReflectionUtils.GetMemberUnderlyingType(member); jsonProperty.DeclaringType = member.DeclaringType; jsonProperty.ValueProvider = CreateMemberValueProvider(member); SetPropertySettingsFromAttributes(jsonProperty, member, member.Name, member.DeclaringType, memberSerialization, out bool allowNonPublicAccess); if (memberSerialization != MemberSerialization.Fields) { jsonProperty.Readable = ReflectionUtils.CanReadMemberValue(member, allowNonPublicAccess); jsonProperty.Writable = ReflectionUtils.CanSetMemberValue(member, allowNonPublicAccess, jsonProperty.HasMemberAttribute); } else { jsonProperty.Readable = true; jsonProperty.Writable = true; } jsonProperty.ShouldSerialize = CreateShouldSerializeTest(member); SetIsSpecifiedActions(jsonProperty, member, allowNonPublicAccess); return jsonProperty; } private void SetPropertySettingsFromAttributes(JsonProperty property, object attributeProvider, string name, Type declaringType, MemberSerialization memberSerialization, out bool allowNonPublicAccess) { JsonPropertyAttribute attribute = JsonTypeReflector.GetAttribute<JsonPropertyAttribute>(attributeProvider); if (attribute != null) property.HasMemberAttribute = true; string propertyName = (attribute == null || attribute.PropertyName == null) ? name : attribute.PropertyName; property.PropertyName = ResolvePropertyName(propertyName); property.UnderlyingName = name; bool flag = false; if (attribute != null) { property._required = attribute._required; property.Order = attribute._order; property.DefaultValueHandling = attribute._defaultValueHandling; flag = true; } bool flag2 = JsonTypeReflector.GetAttribute<JsonIgnoreAttribute>(attributeProvider) != null || JsonTypeReflector.GetAttribute<JsonExtensionDataAttribute>(attributeProvider) != null || JsonTypeReflector.GetAttribute<NonSerializedAttribute>(attributeProvider) != null; if (memberSerialization != MemberSerialization.OptIn) { bool flag3 = false; property.Ignored = (flag2 || flag3); } else property.Ignored = (flag2 || !flag); property.Converter = JsonTypeReflector.GetJsonConverter(attributeProvider); property.MemberConverter = JsonTypeReflector.GetJsonConverter(attributeProvider); DefaultValueAttribute attribute2 = JsonTypeReflector.GetAttribute<DefaultValueAttribute>(attributeProvider); if (attribute2 != null) property.DefaultValue = attribute2.Value; property.NullValueHandling = attribute?._nullValueHandling; property.ReferenceLoopHandling = attribute?._referenceLoopHandling; property.ObjectCreationHandling = attribute?._objectCreationHandling; property.TypeNameHandling = attribute?._typeNameHandling; property.IsReference = attribute?._isReference; property.ItemIsReference = attribute?._itemIsReference; property.ItemConverter = ((attribute != null && (object)attribute.ItemConverterType != null) ? JsonTypeReflector.CreateJsonConverterInstance(attribute.ItemConverterType) : null); property.ItemReferenceLoopHandling = attribute?._itemReferenceLoopHandling; property.ItemTypeNameHandling = attribute?._itemTypeNameHandling; allowNonPublicAccess = false; if ((DefaultMembersSearchFlags & BindingFlags.NonPublic) == BindingFlags.NonPublic) allowNonPublicAccess = true; if (attribute != null) allowNonPublicAccess = true; if (memberSerialization == MemberSerialization.Fields) allowNonPublicAccess = true; } private Predicate<object> CreateShouldSerializeTest(MemberInfo member) { MethodInfo method = member.DeclaringType.GetMethod("ShouldSerialize" + member.Name, ReflectionUtils.EmptyTypes); if ((object)method == null || (object)method.ReturnType != typeof(bool)) return null; MethodCall<object, object> shouldSerializeCall = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall<object>(method); return (object o) => (bool)shouldSerializeCall(o); } private void SetIsSpecifiedActions(JsonProperty property, MemberInfo member, bool allowNonPublicAccess) { MemberInfo memberInfo = member.DeclaringType.GetProperty(member.Name + "Specified"); if ((object)memberInfo == null) memberInfo = member.DeclaringType.GetField(member.Name + "Specified"); if ((object)memberInfo != null && (object)ReflectionUtils.GetMemberUnderlyingType(memberInfo) == typeof(bool)) { Func<object, object> specifiedPropertyGet = JsonTypeReflector.ReflectionDelegateFactory.CreateGet<object>(memberInfo); property.GetIsSpecified = ((object o) => (bool)specifiedPropertyGet(o)); if (ReflectionUtils.CanSetMemberValue(memberInfo, allowNonPublicAccess, false)) property.SetIsSpecified = JsonTypeReflector.ReflectionDelegateFactory.CreateSet<object>(memberInfo); } } protected internal virtual string ResolvePropertyName(string propertyName) { return propertyName; } public string GetResolvedPropertyName(string propertyName) { return ResolvePropertyName(propertyName); } } }