Example #1
0
        public void JsonConstructor(Type dataBlobType)
        {
            ConstructorInfo[] constructors             = dataBlobType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
            Attribute         jsonConstructorAttribute = new JsonConstructorAttribute();

            foreach (ConstructorInfo constructorInfo in constructors.Where(constructorInfo => constructorInfo.GetCustomAttributes().Contains(jsonConstructorAttribute)))
            {
                // Test for any constructor marked with a [JsonConstructor] attribute.
                Assert.Pass(dataBlobType.ToString() + " will deserialize with the constructor marked with [JsonConstructor]");
            }

            foreach (ConstructorInfo constructorInfo in constructors.Where(constructorInfo => constructorInfo.GetParameters().Length == 0 && constructorInfo.IsPublic))
            {
                // Test for a public constructor with no parameters.
                Assert.Pass(dataBlobType.ToString() + " will deserialize with the default parameterless constructor.");
            }

            if (constructors.Length == 1)
            {
                if (constructors[0].GetParameters().Length != 0)
                {
                    // Test the datablob to see if it has only 1 constructor, and that constructor has parameters.
                    Assert.Pass(dataBlobType.ToString() + " will deserialize with the only parametrized constructor available. Make sure parameters match the Json property names saved in the Json file.");
                }
            }

            foreach (ConstructorInfo constructorInfo in constructors.Where(constructorInfo => constructorInfo.GetParameters().Length == 0 && constructorInfo.IsPrivate))
            {
                // Test if the datablob has a private constructor with no parameters (JSON can use a private constructor, though undesirable)
                Assert.Pass(dataBlobType.ToString() + " will deserialize with the private default parameterless constructor.");
            }

            // No constructors exist for this datablob that JSON can use to instantiate this datablob type during deserialization.
            Assert.Fail(dataBlobType.ToString() + " does not have a Json constructor");
        }
 public JsonObjectDescription(ConstructorInfo constructor, JsonConstructorAttribute attribute, JsonMemberInfo[] members)
 {
     Members     = members;
     Constructor = constructor;
     Attribute   = attribute;
     if (Constructor != null)
     {
         ConstructorMapping = BuildMapping();
     }
 }
Example #3
0
        protected static bool TryGetBaseClassJsonConstructorAttribute(Type type, out JsonConstructorAttribute attribute)
        {
            if (BaseClassJsonConstructorMap.TryGetValue(type, out attribute))
            {
                return(true);
            }

            if (type.IsGenericType && BaseClassJsonConstructorMap.TryGetValue(type.GetGenericTypeDefinition(), out attribute))
            {
                return(true);
            }

            return(false);
        }
        public JsonObjectDescription(ConstructorInfo constructor, JsonConstructorAttribute attribute, JsonMemberInfo[] members, JsonExtensionMemberInfo extensionMemberInfo)
        {
            Members             = members;
            ExtensionMemberInfo = extensionMemberInfo;
            Constructor         = constructor;
            Attribute           = attribute;
            if (Constructor != null)
            {
                ConstructorMapping = BuildMapping();
                // we need to sort all the members which are not assigned in the ctor after the ctor assigment, otherwise the object is not ctor'd.
                Array.Sort(Members, (x, y) =>
                {
                    if (ReferenceEquals(x, y))
                    {
                        return(0);
                    }

                    var xIsCtorMapping = ConstructorMapping.TryGetValue(x.MemberName, out var xElement);
                    var yIsCtorMapping = ConstructorMapping.TryGetValue(y.MemberName, out var yElement);
                    if (!xIsCtorMapping && !yIsCtorMapping) // both are not in, it doesn't matter
                    {
                        return(StringComparer.Ordinal.Compare(x.MemberName, y.MemberName));
                    }
                    if (xIsCtorMapping && !yIsCtorMapping) // x is in ctor and y not, move x up
                    {
                        return(-1);
                    }

                    if (!xIsCtorMapping && yIsCtorMapping) // x is not in ctor and y is, move x down
                    {
                        return(1);
                    }

                    return(xElement.Index.CompareTo(yElement.Index));
                });
            }
        }
            protected override void TryGetAnnotatedAttributeConstructor(Type type, out ConstructorInfo constructor, out JsonConstructorAttribute attribute)
            {
                constructor = type.GetConstructors(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)
                              .FirstOrDefault(a => a.GetCustomAttribute <JsonConstructorAttribute>() != null);
                if (constructor != null)
                {
                    attribute = constructor.GetCustomAttribute <JsonConstructorAttribute>();
                    return;
                }

                if (TryGetBaseClassJsonConstructorAttribute(type, out attribute))
                {
                    // We basically take the one with the most parameters, this needs to match the dictionary // TODO find better method
                    constructor = type.GetConstructors(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)
                                  .OrderByDescending(a => a.GetParameters().Length)
                                  .FirstOrDefault();
                    return;
                }

                constructor = default;
                attribute   = default;
            }
        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)
            {
                objectMapping.SetDiscriminator(discriminatorAttribute.Discriminator);
                objectMapping.SetDiscriminatorPolicy(discriminatorAttribute.Policy);
            }

            Type namingPolicyType = type.GetCustomAttribute <JsonNamingPolicyAttribute>()?.NamingPolicyType;

            if (namingPolicyType != null)
            {
                objectMapping.SetPropertyNamingPolicy((JsonNamingPolicy)Activator.CreateInstance(namingPolicyType));
            }

            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;
                }

                if ((propertyInfo.GetMethod.IsPrivate || propertyInfo.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.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));
            }
        }