private void ProcessDefaultValue <T>(MemberInfo memberInfo, MemberMapping <T> memberMapping) { DefaultValueAttribute?defaultValueAttribute = memberInfo.GetCustomAttribute <DefaultValueAttribute>(); if (defaultValueAttribute != null) { memberMapping.SetDefaultValue(defaultValueAttribute.Value); } DataMemberAttribute?dataMemberAttribute = memberInfo.GetCustomAttribute <DataMemberAttribute>(); if (dataMemberAttribute != null && !dataMemberAttribute.EmitDefaultValue) { memberMapping.SetIngoreIfDefault(true); } }
private void ProcessConverter <T>(MemberInfo memberInfo, MemberMapping <T> memberMapping) { JsonConverterAttribute?converterAttribute = memberInfo.GetCustomAttribute <JsonConverterAttribute>(); if (converterAttribute != null) { Type converterType = converterAttribute.ConverterType; JsonConverter?converter = (JsonConverter?)Activator.CreateInstance(converterType); if (converter == null) { throw new JsonException($"Cannot instantiate {converterType}"); } memberMapping.SetConverter(converter); } }
private void ProcessShouldSerializeMethod <T>(MemberMapping <T> memberMapping) { string shouldSerializeMethodName = "ShouldSerialize" + memberMapping.MemberInfo.Name; Type objectType = memberMapping.MemberInfo.DeclaringType; MethodInfo shouldSerializeMethodInfo = objectType.GetMethod(shouldSerializeMethodName, new Type[] { }); if (shouldSerializeMethodInfo != null && shouldSerializeMethodInfo.IsPublic && shouldSerializeMethodInfo.ReturnType == typeof(bool)) { // obj => ((TClass) obj).ShouldSerializeXyz() ParameterExpression objParameter = Expression.Parameter(typeof(object), "obj"); Expression <Func <object, bool> > lambdaExpression = Expression.Lambda <Func <object, bool> >( Expression.Call( Expression.Convert(objParameter, objectType), shouldSerializeMethodInfo), objParameter); memberMapping.SetShouldSerializeMethod(lambdaExpression.Compile()); } }
private void ProcessShouldSerializeMethod <T>(MemberMapping <T> memberMapping) { string shouldSerializeMethodName = "ShouldSerialize" + memberMapping.MemberInfo.Name; Type objectType = typeof(T); MethodInfo?shouldSerializeMethodInfo = objectType.GetMethod( shouldSerializeMethodName, BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance, null, new Type[] { }, null); if (shouldSerializeMethodInfo != null && shouldSerializeMethodInfo.ReturnType == typeof(bool)) { // obj => ((TClass) obj).ShouldSerializeXyz() ParameterExpression objParameter = Expression.Parameter(typeof(object), "obj"); Expression <Func <object, bool> > lambdaExpression = Expression.Lambda <Func <object, bool> >( Expression.Call( Expression.Convert(objParameter, objectType), shouldSerializeMethodInfo), objParameter); memberMapping.SetShouldSerializeMethod(lambdaExpression.Compile()); } }
public void Apply <T>(JsonSerializerOptions options, ObjectMapping <T> objectMapping) { Type type = objectMapping.ObjectType; List <MemberMapping <T> > memberMappings = new List <MemberMapping <T> >(); PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (PropertyInfo propertyInfo in properties) { if (!propertyInfo.IsDefined(typeof(DataMemberAttribute))) { continue; } MemberMapping <T> memberMapping = new MemberMapping <T>(options, objectMapping, propertyInfo, propertyInfo.PropertyType); ProcessDefaultValue(propertyInfo, memberMapping); ProcessShouldSerializeMethod(memberMapping); ProcessRequired(propertyInfo, memberMapping); ProcessMemberName(propertyInfo, memberMapping); memberMappings.Add(memberMapping); } foreach (FieldInfo fieldInfo in fields) { if (!fieldInfo.IsDefined(typeof(DataMemberAttribute))) { continue; } Type fieldType = fieldInfo.FieldType; MemberMapping <T> memberMapping = new MemberMapping <T>(options, objectMapping, fieldInfo, fieldInfo.FieldType); ProcessDefaultValue(fieldInfo, memberMapping); ProcessShouldSerializeMethod(memberMapping); ProcessRequired(fieldInfo, memberMapping); ProcessMemberName(fieldInfo, memberMapping); memberMappings.Add(memberMapping); } objectMapping.AddMemberMappings(memberMappings); ConstructorInfo[] constructorInfos = type.GetConstructors(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); // if no default constructor, pick up first one if (constructorInfos.Length > 0 && !constructorInfos.Any(c => c.GetParameters().Length == 0)) { objectMapping.MapCreator(constructorInfos[0]); } MethodInfo?methodInfo = type.GetMethods() .FirstOrDefault(m => m.IsDefined(typeof(OnDeserializingAttribute))); if (methodInfo != null) { objectMapping.SetOnDeserializingMethod(GenerateCallbackDelegate <T>(methodInfo)); } else if (type.GetInterfaces().Any(i => i == typeof(ISupportInitialize))) { objectMapping.SetOnDeserializingMethod(t => ((ISupportInitialize?)t)?.BeginInit()); } methodInfo = type.GetMethods() .FirstOrDefault(m => m.IsDefined(typeof(OnDeserializedAttribute))); if (methodInfo != null) { objectMapping.SetOnDeserializedMethod(GenerateCallbackDelegate <T>(methodInfo)); } else if (type.GetInterfaces().Any(i => i == typeof(ISupportInitialize))) { objectMapping.SetOnDeserializedMethod(t => ((ISupportInitialize?)t)?.EndInit()); } methodInfo = type.GetMethods() .FirstOrDefault(m => m.IsDefined(typeof(OnSerializingAttribute))); if (methodInfo != null) { objectMapping.SetOnSerializingMethod(GenerateCallbackDelegate <T>(methodInfo)); } methodInfo = type.GetMethods() .FirstOrDefault(m => m.IsDefined(typeof(OnSerializedAttribute))); if (methodInfo != null) { objectMapping.SetOnSerializedMethod(GenerateCallbackDelegate <T>(methodInfo)); } }
public void Apply <T>(JsonSerializerOptions options, ObjectMapping <T> objectMapping) { Type type = objectMapping.ObjectType; List <MemberMapping <T> > memberMappings = new List <MemberMapping <T> >(); JsonDiscriminatorAttribute?discriminatorAttribute = type.GetCustomAttribute <JsonDiscriminatorAttribute>(); if (discriminatorAttribute != null && options.GetDiscriminatorConventionRegistry().AnyConvention()) { objectMapping.SetDiscriminator(discriminatorAttribute.Discriminator); objectMapping.SetDiscriminatorPolicy(discriminatorAttribute.Policy); } Type?namingPolicyType = type.GetCustomAttribute <JsonNamingPolicyAttribute>()?.NamingPolicyType; if (namingPolicyType != null) { JsonNamingPolicy?namingPolicy = (JsonNamingPolicy?)Activator.CreateInstance(namingPolicyType); if (namingPolicy == null) { throw new JsonException($"Cannot instantiate naming policy {namingPolicyType}"); } objectMapping.SetPropertyNamingPolicy(namingPolicy); } PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (PropertyInfo propertyInfo in properties) { if (propertyInfo.IsDefined(typeof(JsonIgnoreAttribute))) { continue; } if (propertyInfo.IsDefined(typeof(JsonExtensionDataAttribute))) { objectMapping.MapExtensionData(propertyInfo); continue; } MethodInfo?getMethod = propertyInfo.GetMethod; if (getMethod == null) { continue; } if ((getMethod.IsPrivate || getMethod.IsStatic) && !propertyInfo.IsDefined(typeof(JsonPropertyNameAttribute)) && !propertyInfo.IsDefined(typeof(JsonPropertyAttribute))) { continue; } MemberMapping <T> memberMapping = new MemberMapping <T>(options, objectMapping, propertyInfo, propertyInfo.PropertyType); ProcessDefaultValue(propertyInfo, memberMapping); ProcessShouldSerializeMethod(memberMapping); ProcessRequired(propertyInfo, memberMapping); ProcessMemberName(propertyInfo, memberMapping); ProcessConverter(propertyInfo, memberMapping); ProcessDeserialize(propertyInfo, memberMapping); memberMappings.Add(memberMapping); } foreach (FieldInfo fieldInfo in fields) { if (fieldInfo.IsDefined(typeof(JsonIgnoreAttribute))) { continue; } if ((fieldInfo.IsPrivate || fieldInfo.IsStatic) && !fieldInfo.IsDefined(typeof(JsonPropertyNameAttribute)) && !fieldInfo.IsDefined(typeof(JsonPropertyAttribute))) { continue; } Type fieldType = fieldInfo.FieldType; MemberMapping <T> memberMapping = new MemberMapping <T>(options, objectMapping, fieldInfo, fieldInfo.FieldType); ProcessDefaultValue(fieldInfo, memberMapping); ProcessShouldSerializeMethod(memberMapping); ProcessRequired(fieldInfo, memberMapping); ProcessMemberName(fieldInfo, memberMapping); ProcessConverter(fieldInfo, memberMapping); memberMappings.Add(memberMapping); } objectMapping.AddMemberMappings(memberMappings); ConstructorInfo[] constructorInfos = type.GetConstructors(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); ConstructorInfo constructorInfo = constructorInfos .FirstOrDefault(c => c.IsDefined(typeof(JsonConstructorAttribute))); if (constructorInfo != null) { JsonConstructorAttribute?constructorAttribute = constructorInfo.GetCustomAttribute <JsonConstructorAttribute>(); CreatorMapping creatorMapping = objectMapping.MapCreator(constructorInfo); if (constructorAttribute != null && constructorAttribute.MemberNames != null) { creatorMapping.SetMemberNames(constructorAttribute.MemberNames); } } // if no default constructor, pick up first one else if (constructorInfos.Length > 0 && !constructorInfos.Any(c => c.GetParameters().Length == 0)) { constructorInfo = constructorInfos[0]; objectMapping.MapCreator(constructorInfo); } MethodInfo methodInfo = type.GetMethods() .FirstOrDefault(m => m.IsDefined(typeof(OnDeserializingAttribute))); if (methodInfo != null) { objectMapping.SetOnDeserializingMethod(GenerateCallbackDelegate <T>(methodInfo)); } else if (type.GetInterfaces().Any(i => i == typeof(ISupportInitialize))) { objectMapping.SetOnDeserializingMethod(t => ((ISupportInitialize?)t)?.BeginInit()); } methodInfo = type.GetMethods() .FirstOrDefault(m => m.IsDefined(typeof(OnDeserializedAttribute))); if (methodInfo != null) { objectMapping.SetOnDeserializedMethod(GenerateCallbackDelegate <T>(methodInfo)); } else if (type.GetInterfaces().Any(i => i == typeof(ISupportInitialize))) { objectMapping.SetOnDeserializedMethod(t => ((ISupportInitialize?)t)?.EndInit()); } methodInfo = type.GetMethods() .FirstOrDefault(m => m.IsDefined(typeof(OnSerializingAttribute))); if (methodInfo != null) { objectMapping.SetOnSerializingMethod(GenerateCallbackDelegate <T>(methodInfo)); } methodInfo = type.GetMethods() .FirstOrDefault(m => m.IsDefined(typeof(OnSerializedAttribute))); if (methodInfo != null) { objectMapping.SetOnSerializedMethod(GenerateCallbackDelegate <T>(methodInfo)); } }