示例#1
0
        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);
            }
        }
示例#2
0
        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());
            }
        }
示例#4
0
        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());
            }
        }
示例#5
0
        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));
            }
        }
示例#6
0
        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));
            }
        }