protected override IList <JsonProperty> CreateConstructorParameters(ConstructorInfo constructor, JsonPropertyCollection memberProperties) { var constructorParameters = constructor.GetParameters(); JsonPropertyCollection parameterCollection = new JsonPropertyCollection(constructor.DeclaringType); foreach (ParameterInfo parameterInfo in constructorParameters) { JsonProperty matchingMemberProperty = (parameterInfo.Name != null) ? memberProperties.GetClosestMatchProperty(parameterInfo.Name) : null; // Constructor type must be assignable from property type. // Note that this is the only difference between this method and the method it overrides in DefaultContractResolver. // In DefaultContractResolver, the types must match exactly. if (matchingMemberProperty != null && !parameterInfo.ParameterType.IsAssignableFrom(matchingMemberProperty.PropertyType)) { matchingMemberProperty = null; } if (matchingMemberProperty != null || parameterInfo.Name != null) { JsonProperty property = CreatePropertyFromConstructorParameterWithConstructorInfo(matchingMemberProperty, parameterInfo, constructor); if (property != null) { parameterCollection.AddProperty(property); } } } return(parameterCollection); }
protected override IList <JsonProperty> CreateConstructorParameters(ConstructorInfo constructor, JsonPropertyCollection memberProperties) { var constructorParameters = constructor.GetParameters(); JsonPropertyCollection parameterCollection = new JsonPropertyCollection(constructor.DeclaringType); foreach (ParameterInfo parameterInfo in constructorParameters) { var matchingMemberProperty = (parameterInfo.Name != null) ? memberProperties.GetClosestMatchProperty(parameterInfo.Name) : null; // Constructor type must be assignable from property type. // Note that this is the only difference between this method and the method it overrides in DefaultContractResolver. // In DefaultContractResolver, the types must match exactly. if (matchingMemberProperty != null) { var memberType = matchingMemberProperty.PropertyType; var memberTypeIsGeneric = memberType.IsGenericType; var memberGenericArguments = memberType.GetGenericArguments(); var parameterTypeIsArray = parameterInfo.ParameterType.IsArray; var parameterElementType = parameterInfo.ParameterType.GetElementType(); if (parameterTypeIsArray && memberTypeIsGeneric && memberGenericArguments.Length == 1 && memberType.IsAssignableTo(typeof(IEnumerable <>).MakeGenericType(parameterElementType))) { // NO-OP - this allows for the constructor parameter to be a "params" array while still using a collection property as the source. } else if (memberType.IsAssignableTo(parameterInfo.ParameterType)) { // NO-OP - vanilla assignable type to constructor check. } else { // no way to do this so null out and the let the next step error with a clean message. matchingMemberProperty = null; } } if (matchingMemberProperty != null || parameterInfo.Name != null) { var property = this.CreatePropertyFromConstructorParameterWithConstructorInfo(matchingMemberProperty, parameterInfo, constructor); if (property != null) { parameterCollection.AddProperty(property); } } } return(parameterCollection); }
protected virtual IList<JsonProperty> CreateConstructorParameters(ConstructorInfo constructor, JsonPropertyCollection memberProperties) { ParameterInfo[] parameters = constructor.GetParameters(); JsonPropertyCollection propertyCollection = new JsonPropertyCollection(constructor.DeclaringType); foreach (ParameterInfo parameterInfo in parameters) { JsonProperty matchingMemberProperty = parameterInfo.Name != null ? memberProperties.GetClosestMatchProperty(parameterInfo.Name) : (JsonProperty) null; if (matchingMemberProperty != null && matchingMemberProperty.PropertyType != parameterInfo.ParameterType) matchingMemberProperty = (JsonProperty) null; JsonProperty constructorParameter = this.CreatePropertyFromConstructorParameter(matchingMemberProperty, parameterInfo); if (constructorParameter != null) propertyCollection.AddProperty(constructorParameter); } return (IList<JsonProperty>) propertyCollection; }
protected override IList <JsonProperty> CreateConstructorParameters( ConstructorInfo constructor, JsonPropertyCollection memberProperties) { var constructorParameters = constructor.GetParameters(); var result = new JsonPropertyCollection(constructor.DeclaringType); foreach (var parameterInfo in constructorParameters) { var matchingMemberProperty = (parameterInfo.Name != null) ? memberProperties.GetClosestMatchProperty(parameterInfo.Name) : null; // Constructor type must be assignable from property type. // Note that this is the only difference between this method and the method it overrides in DefaultContractResolver. // In DefaultContractResolver, the types must match exactly. if (matchingMemberProperty != null) { var memberType = matchingMemberProperty.PropertyType; var memberTypeIsGeneric = memberType.IsGenericType; var memberGenericArguments = memberType.GenericTypeArguments; var parameterTypeIsArray = parameterInfo.ParameterType.IsArray; var parameterElementType = parameterInfo.ParameterType.GetElementType(); if (parameterTypeIsArray && memberTypeIsGeneric && memberGenericArguments.Length == 1 && memberType.IsAssignableTo(typeof(IEnumerable <>).MakeGenericType(parameterElementType))) { // NO-OP // this allows for the constructor parameter to be a "params" array while still using a collection property as the source. } else if (memberType.IsAssignableTo(parameterInfo.ParameterType)) { // NO-OP // The property type and the constructor parameter type are equal. // OR // The property type is assignable to the constructor parameter type. // In this case, the constructor is taking a less derived type and converting it // to a more derived type before assigning to the property // (e.g. constructor takes IEnumerable<string>, but property is an IReadOnlyCollection<string> // because the constructor calls .ToList() before assigning to the property). } else if (parameterInfo.ParameterType.IsAssignableTo(memberType)) { // NO-OP // The constructor parameter type is assignable to the property type. // In this case, the constructor is taking a more derived type and assigning // it to the property that is less derived. // (e.g. constructor takes IReadOnlyCollection<string> and assigns it to a property // of type IEnumerable<string>). } else { // no way to do this so null out and the let the next step error with a clean message. matchingMemberProperty = null; } } if (matchingMemberProperty != null || parameterInfo.Name != null) { var property = this.CreatePropertyFromConstructorParameterWithConstructorInfo(matchingMemberProperty, parameterInfo, constructor); if (property != null) { result.AddProperty(property); } } } return(result); }