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