diff options
author | JamesNK <james@newtonking.com> | 2011-05-02 14:52:01 +0400 |
---|---|---|
committer | JamesNK <james@newtonking.com> | 2011-05-02 14:52:01 +0400 |
commit | 045a1ec334421a2ac7df5db65fad68f85c297466 (patch) | |
tree | e6c0e7bce4f1acd42366607c7229507f8eaa3cd7 /Src/Newtonsoft.Json | |
parent | 21a2a7e4f793e395987d60b3ae0296de885c5774 (diff) |
-Improved support for deserializing objects using non-default constructors
-JsonConverterAttribute now allowed on constructor parameters
-JsonPropertyAttribute now allowed on constructor parameters
Diffstat (limited to 'Src/Newtonsoft.Json')
7 files changed, 194 insertions, 90 deletions
diff --git a/Src/Newtonsoft.Json/JsonConverterAttribute.cs b/Src/Newtonsoft.Json/JsonConverterAttribute.cs index e28fd79..ae3a8d5 100644 --- a/Src/Newtonsoft.Json/JsonConverterAttribute.cs +++ b/Src/Newtonsoft.Json/JsonConverterAttribute.cs @@ -10,7 +10,7 @@ namespace Newtonsoft.Json /// <summary>
/// Instructs the <see cref="JsonSerializer"/> to use the specified <see cref="JsonConverter"/> when serializing the member or class.
/// </summary>
- [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface | AttributeTargets.Enum, AllowMultiple = false)]
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface | AttributeTargets.Enum | AttributeTargets.Parameter, AllowMultiple = false)]
public sealed class JsonConverterAttribute : Attribute
{
private readonly Type _converterType;
diff --git a/Src/Newtonsoft.Json/JsonPropertyAttribute.cs b/Src/Newtonsoft.Json/JsonPropertyAttribute.cs index 5df13e6..465d2d5 100644 --- a/Src/Newtonsoft.Json/JsonPropertyAttribute.cs +++ b/Src/Newtonsoft.Json/JsonPropertyAttribute.cs @@ -5,7 +5,7 @@ namespace Newtonsoft.Json /// <summary>
/// Instructs the <see cref="JsonSerializer"/> to always serialize the member with the specified name.
/// </summary>
- [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false)]
public sealed class JsonPropertyAttribute : Attribute
{
// yuck. can't set nullable properties on an attribute in C#
diff --git a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs index 75ed64f..c67da98 100644 --- a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs +++ b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs @@ -110,7 +110,7 @@ using System.Security; // by using the '*' as shown below:
[assembly: AssemblyVersion("4.0.2.0")]
#if !PocketPC
-[assembly: AssemblyFileVersion("4.0.2.13622")]
+[assembly: AssemblyFileVersion("4.0.2.13702")]
#endif
[assembly: CLSCompliant(true)]
diff --git a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs index c93ffa3..cc1cd29 100644 --- a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs +++ b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs @@ -280,11 +280,26 @@ namespace Newtonsoft.Json.Serialization contract.MemberSerialization = JsonTypeReflector.GetObjectMemberSerialization(objectType);
contract.Properties.AddRange(CreateProperties(contract.UnderlyingType, contract.MemberSerialization));
+
+ // check if a JsonConstructorAttribute has been defined and use that
if (objectType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Any(c => c.IsDefined(typeof(JsonConstructorAttribute), true)))
- contract.OverrideConstructor = GetAttributeConstructor(objectType);
+ {
+ ConstructorInfo constructor = GetAttributeConstructor(objectType);
+ if (constructor != null)
+ {
+ contract.OverrideConstructor = constructor;
+ contract.ConstructorParameters.AddRange(CreateConstructorParameters(constructor, contract.Properties));
+ }
+ }
else if (contract.DefaultCreator == null || contract.DefaultCreatorNonPublic)
- contract.ParametrizedConstructor = GetParametrizedConstructor(objectType);
-
+ {
+ ConstructorInfo constructor = GetParametrizedConstructor(objectType);
+ if (constructor != null)
+ {
+ contract.ParametrizedConstructor = constructor;
+ contract.ConstructorParameters.AddRange(CreateConstructorParameters(constructor, contract.Properties));
+ }
+ }
return contract;
}
@@ -311,6 +326,72 @@ namespace Newtonsoft.Json.Serialization }
/// <summary>
+ /// Creates the constructor parameters.
+ /// </summary>
+ /// <param name="constructor">The constructor to create properties for.</param>
+ /// <param name="memberProperties">The type's member properties.</param>
+ /// <returns>Properties for the given <see cref="ConstructorInfo"/>.</returns>
+ protected virtual IList<JsonProperty> CreateConstructorParameters(ConstructorInfo constructor, JsonPropertyCollection memberProperties)
+ {
+ var constructorParameters = constructor.GetParameters();
+
+ JsonPropertyCollection parameterCollection = new JsonPropertyCollection(constructor.DeclaringType);
+
+ foreach (ParameterInfo parameterInfo in constructorParameters)
+ {
+ JsonProperty matchingMemberProperty = memberProperties.GetClosestMatchProperty(parameterInfo.Name);
+ // type must match as well as name
+ if (matchingMemberProperty != null && matchingMemberProperty.PropertyType != parameterInfo.ParameterType)
+ matchingMemberProperty = null;
+
+ JsonProperty property = CreatePropertyFromConstructorParameter(matchingMemberProperty, parameterInfo);
+
+ if (property != null)
+ {
+ parameterCollection.AddProperty(property);
+ }
+ }
+
+ return parameterCollection;
+ }
+
+ /// <summary>
+ /// Creates a <see cref="JsonProperty"/> for the given <see cref="ParameterInfo"/>.
+ /// </summary>
+ /// <param name="matchingMemberProperty">The matching member property.</param>
+ /// <param name="parameterInfo">The constructor parameter.</param>
+ /// <returns>A created <see cref="JsonProperty"/> for the given <see cref="ParameterInfo"/>.</returns>
+ protected virtual JsonProperty CreatePropertyFromConstructorParameter(JsonProperty matchingMemberProperty, ParameterInfo parameterInfo)
+ {
+ JsonProperty property = new JsonProperty();
+ property.PropertyType = parameterInfo.ParameterType;
+
+ bool allowNonPublicAccess;
+ SetPropertySettingsFromAttributes(property, parameterInfo, parameterInfo.Name, parameterInfo.Member.DeclaringType, MemberSerialization.OptOut, out allowNonPublicAccess);
+
+ property.Readable = false;
+ property.Writable = true;
+
+ // "inherit" values from matching member property if unset on parameter
+ if (matchingMemberProperty != null)
+ {
+ property.PropertyName = (property.PropertyName != parameterInfo.Name) ? property.PropertyName : matchingMemberProperty.PropertyName;
+ property.Converter = property.Converter ?? matchingMemberProperty.Converter;
+ property.MemberConverter = property.MemberConverter ?? matchingMemberProperty.MemberConverter;
+ property.DefaultValue = property.DefaultValue ?? matchingMemberProperty.DefaultValue;
+ property.Required = (property.Required != Required.Default) ? property.Required : matchingMemberProperty.Required;
+ property.IsReference = property.IsReference ?? matchingMemberProperty.IsReference;
+ property.NullValueHandling = property.NullValueHandling ?? matchingMemberProperty.NullValueHandling;
+ property.DefaultValueHandling = property.DefaultValueHandling ?? matchingMemberProperty.DefaultValueHandling;
+ property.ReferenceLoopHandling = property.ReferenceLoopHandling ?? matchingMemberProperty.ReferenceLoopHandling;
+ property.ObjectCreationHandling = property.ObjectCreationHandling ?? matchingMemberProperty.ObjectCreationHandling;
+ property.TypeNameHandling = property.TypeNameHandling ?? matchingMemberProperty.TypeNameHandling;
+ }
+
+ return property;
+ }
+
+ /// <summary>
/// Resolves the default <see cref="JsonConverter" /> for the contract.
/// </summary>
/// <param name="objectType">Type of the object.</param>
@@ -667,22 +748,32 @@ namespace Newtonsoft.Json.Serialization property.PropertyType = ReflectionUtils.GetMemberUnderlyingType(member);
property.ValueProvider = CreateMemberValueProvider(member);
- // resolve converter for property
- // the class type might have a converter but the property converter takes presidence
- property.Converter = JsonTypeReflector.GetJsonConverter(member, property.PropertyType);
+ bool allowNonPublicAccess;
+ SetPropertySettingsFromAttributes(property, member, member.Name, member.DeclaringType, memberSerialization, out allowNonPublicAccess);
+
+ property.Readable = ReflectionUtils.CanReadMemberValue(member, allowNonPublicAccess);
+ property.Writable = ReflectionUtils.CanSetMemberValue(member, allowNonPublicAccess);
+ property.ShouldSerialize = CreateShouldSerializeTest(member);
+
+ SetIsSpecifiedActions(property, member);
+
+ return property;
+ }
+ private void SetPropertySettingsFromAttributes(JsonProperty property, ICustomAttributeProvider attributeProvider, string name, Type declaringType, MemberSerialization memberSerialization, out bool allowNonPublicAccess)
+ {
#if !PocketPC && !NET20
- DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(member.DeclaringType);
+ DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(declaringType);
DataMemberAttribute dataMemberAttribute;
if (dataContractAttribute != null)
- dataMemberAttribute = JsonTypeReflector.GetAttribute<DataMemberAttribute>(member);
+ dataMemberAttribute = JsonTypeReflector.GetAttribute<DataMemberAttribute>(attributeProvider);
else
dataMemberAttribute = null;
#endif
- JsonPropertyAttribute propertyAttribute = JsonTypeReflector.GetAttribute<JsonPropertyAttribute>(member);
- bool hasIgnoreAttribute = (JsonTypeReflector.GetAttribute<JsonIgnoreAttribute>(member) != null);
+ JsonPropertyAttribute propertyAttribute = JsonTypeReflector.GetAttribute<JsonPropertyAttribute>(attributeProvider);
+ bool hasIgnoreAttribute = (JsonTypeReflector.GetAttribute<JsonIgnoreAttribute>(attributeProvider) != null);
string mappedName;
if (propertyAttribute != null && propertyAttribute.PropertyName != null)
@@ -692,9 +783,10 @@ namespace Newtonsoft.Json.Serialization mappedName = dataMemberAttribute.Name;
#endif
else
- mappedName = member.Name;
+ mappedName = name;
property.PropertyName = ResolvePropertyName(mappedName);
+ property.UnderlyingName = name;
if (propertyAttribute != null)
property.Required = propertyAttribute.Required;
@@ -713,22 +805,12 @@ namespace Newtonsoft.Json.Serialization #endif
));
- bool allowNonPublicAccess = false;
- if ((DefaultMembersSearchFlags & BindingFlags.NonPublic) == BindingFlags.NonPublic)
- allowNonPublicAccess = true;
- if (propertyAttribute != null)
- allowNonPublicAccess = true;
-#if !PocketPC && !NET20
- if (dataMemberAttribute != null)
- allowNonPublicAccess = true;
-#endif
-
- property.Readable = ReflectionUtils.CanReadMemberValue(member, allowNonPublicAccess);
- property.Writable = ReflectionUtils.CanSetMemberValue(member, allowNonPublicAccess);
-
- property.MemberConverter = JsonTypeReflector.GetJsonConverter(member, ReflectionUtils.GetMemberUnderlyingType(member));
+ // resolve converter for property
+ // the class type might have a converter but the property converter takes presidence
+ property.Converter = JsonTypeReflector.GetJsonConverter(attributeProvider, property.PropertyType);
+ property.MemberConverter = JsonTypeReflector.GetJsonConverter(attributeProvider, property.PropertyType);
- DefaultValueAttribute defaultValueAttribute = JsonTypeReflector.GetAttribute<DefaultValueAttribute>(member);
+ DefaultValueAttribute defaultValueAttribute = JsonTypeReflector.GetAttribute<DefaultValueAttribute>(attributeProvider);
property.DefaultValue = (defaultValueAttribute != null) ? defaultValueAttribute.Value : null;
property.NullValueHandling = (propertyAttribute != null) ? propertyAttribute._nullValueHandling : null;
@@ -738,11 +820,15 @@ namespace Newtonsoft.Json.Serialization property.TypeNameHandling = (propertyAttribute != null) ? propertyAttribute._typeNameHandling : null;
property.IsReference = (propertyAttribute != null) ? propertyAttribute._isReference : null;
- property.ShouldSerialize = CreateShouldSerializeTest(member);
-
- SetIsSpecifiedActions(property, member);
-
- return property;
+ allowNonPublicAccess = false;
+ if ((DefaultMembersSearchFlags & BindingFlags.NonPublic) == BindingFlags.NonPublic)
+ allowNonPublicAccess = true;
+ if (propertyAttribute != null)
+ allowNonPublicAccess = true;
+#if !PocketPC && !NET20
+ if (dataMemberAttribute != null)
+ allowNonPublicAccess = true;
+#endif
}
private Predicate<object> CreateShouldSerializeTest(MemberInfo member)
diff --git a/Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs b/Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs index c3d4e6e..426a469 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonObjectContract.cs @@ -44,6 +44,11 @@ namespace Newtonsoft.Json.Serialization /// </summary>
/// <value>The object's properties.</value>
public JsonPropertyCollection Properties { get; private set; }
+
+ /// <summary>
+ /// Gets the constructor parameters required for any non-default constructor
+ /// </summary>
+ public JsonPropertyCollection ConstructorParameters { get; private set; }
/// <summary>
/// Gets or sets the override constructor used to create the object.
@@ -66,7 +71,8 @@ namespace Newtonsoft.Json.Serialization public JsonObjectContract(Type underlyingType)
: base(underlyingType)
{
- Properties = new JsonPropertyCollection(UnderlyingType);
+ Properties = new JsonPropertyCollection(UnderlyingType);
+ ConstructorParameters = new JsonPropertyCollection(UnderlyingType);
}
}
}
\ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/JsonProperty.cs b/Src/Newtonsoft.Json/Serialization/JsonProperty.cs index 0b2512e..ccc39d0 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonProperty.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonProperty.cs @@ -28,17 +28,23 @@ using System; namespace Newtonsoft.Json.Serialization
{
/// <summary>
- /// Maps a JSON property to a .NET member.
+ /// Maps a JSON property to a .NET member or constructor parameter.
/// </summary>
public class JsonProperty
{
/// <summary>
- /// Gets the name of the property.
+ /// Gets or sets the name of the property.
/// </summary>
/// <value>The name of the property.</value>
public string PropertyName { get; set; }
/// <summary>
+ /// Gets or sets the name of the underlying member or parameter.
+ /// </summary>
+ /// <value>The name of the underlying member or parameter.</value>
+ public string UnderlyingName { get; set; }
+
+ /// <summary>
/// Gets the <see cref="IValueProvider"/> that will get and set the <see cref="JsonProperty"/> during serialization.
/// </summary>
/// <value>The <see cref="IValueProvider"/> that will get and set the <see cref="JsonProperty"/> during serialization.</value>
@@ -58,6 +64,12 @@ namespace Newtonsoft.Json.Serialization public JsonConverter Converter { get; set; }
/// <summary>
+ /// Gets the member converter.
+ /// </summary>
+ /// <value>The member converter.</value>
+ public JsonConverter MemberConverter { get; set; }
+
+ /// <summary>
/// Gets a value indicating whether this <see cref="JsonProperty"/> is ignored.
/// </summary>
/// <value><c>true</c> if ignored; otherwise, <c>false</c>.</value>
@@ -76,12 +88,6 @@ namespace Newtonsoft.Json.Serialization public bool Writable { get; set; }
/// <summary>
- /// Gets the member converter.
- /// </summary>
- /// <value>The member converter.</value>
- public JsonConverter MemberConverter { get; set; }
-
- /// <summary>
/// Gets the default value.
/// </summary>
/// <value>The default value.</value>
diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs index 1ac9ee3..35e4705 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs @@ -43,10 +43,11 @@ namespace Newtonsoft.Json.Serialization {
private JsonSerializerProxy _internalSerializer;
#if !SILVERLIGHT && !PocketPC
- private JsonFormatterConverter _formatterConverter;
+ private JsonFormatterConverter _formatterConverter;
#endif
- public JsonSerializerInternalReader(JsonSerializer serializer) : base(serializer)
+ public JsonSerializerInternalReader(JsonSerializer serializer)
+ : base(serializer)
{
}
@@ -81,9 +82,9 @@ namespace Newtonsoft.Json.Serialization }
if (contract is JsonDictionaryContract)
- PopulateDictionary(CollectionUtils.CreateDictionaryWrapper(target), reader, (JsonDictionaryContract) contract, id);
+ PopulateDictionary(CollectionUtils.CreateDictionaryWrapper(target), reader, (JsonDictionaryContract)contract, id);
else if (contract is JsonObjectContract)
- PopulateObject(target, reader, (JsonObjectContract) contract, id);
+ PopulateObject(target, reader, (JsonObjectContract)contract, id);
else
throw new JsonSerializationException("Cannot populate JSON object onto type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType));
}
@@ -248,7 +249,7 @@ namespace Newtonsoft.Json.Serialization return constructorName;
case JsonToken.Null:
case JsonToken.Undefined:
- if (objectType == typeof (DBNull))
+ if (objectType == typeof(DBNull))
return DBNull.Value;
return EnsureType(reader.Value, CultureInfo.InvariantCulture, objectType);
@@ -413,7 +414,7 @@ namespace Newtonsoft.Json.Serialization return CreateDynamic(reader, dynamicContract, id);
}
#endif
-
+
throw new JsonSerializationException("Cannot deserialize JSON object into type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType));
}
@@ -456,11 +457,11 @@ namespace Newtonsoft.Json.Serialization private bool HasDefinedType(Type type)
{
- return (type != null && type != typeof (object) && !typeof(JToken).IsAssignableFrom(type)
+ return (type != null && type != typeof(object) && !typeof(JToken).IsAssignableFrom(type)
#if !(NET35 || NET20 || WINDOWS_PHONE)
- && type != typeof(IDynamicMetaObjectProvider)
+ && type != typeof(IDynamicMetaObjectProvider)
#endif
- );
+);
}
private object EnsureType(object value, CultureInfo culture, Type targetType)
@@ -638,7 +639,7 @@ namespace Newtonsoft.Json.Serialization break;
case JsonToken.EndObject:
contract.InvokeOnDeserialized(dictionary.UnderlyingDictionary, Serializer.Context);
-
+
return dictionary.UnderlyingDictionary;
default:
throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType);
@@ -788,7 +789,7 @@ namespace Newtonsoft.Json.Serialization Serializer.ReferenceResolver.AddReference(this, id, newObject);
contract.InvokeOnDeserializing(newObject, Serializer.Context);
-
+
bool exit = false;
do
{
@@ -807,7 +808,7 @@ namespace Newtonsoft.Json.Serialization }
else
{
- Type t = (JsonReader.IsPrimitiveToken(reader.TokenType)) ? reader.ValueType : typeof (IDynamicMetaObjectProvider);
+ Type t = (JsonReader.IsPrimitiveToken(reader.TokenType)) ? reader.ValueType : typeof(IDynamicMetaObjectProvider);
object value = CreateValueNonProperty(reader, t, GetContractSafe(t, null));
@@ -865,8 +866,44 @@ namespace Newtonsoft.Json.Serialization Type objectType = contract.UnderlyingType;
- IDictionary<JsonProperty, object> propertyValues = new Dictionary<JsonProperty, object>();
+ IDictionary<JsonProperty, object> propertyValues = ResolvePropertyAndConstructorValues(contract, reader, objectType);
+
+ IDictionary<ParameterInfo, object> constructorParameters = constructorInfo.GetParameters().ToDictionary(p => p, p => (object)null);
+ IDictionary<JsonProperty, object> remainingPropertyValues = new Dictionary<JsonProperty, object>();
+
+ foreach (KeyValuePair<JsonProperty, object> propertyValue in propertyValues)
+ {
+ ParameterInfo matchingConstructorParameter = constructorParameters.ForgivingCaseSensitiveFind(kv => kv.Key.Name, propertyValue.Key.UnderlyingName).Key;
+ if (matchingConstructorParameter != null)
+ constructorParameters[matchingConstructorParameter] = propertyValue.Value;
+ else
+ remainingPropertyValues.Add(propertyValue);
+ }
+
+ object createdObject = constructorInfo.Invoke(constructorParameters.Values.ToArray());
+
+ if (id != null)
+ Serializer.ReferenceResolver.AddReference(this, id, createdObject);
+
+ contract.InvokeOnDeserializing(createdObject, Serializer.Context);
+
+ // go through unused values and set the newly created object's properties
+ foreach (KeyValuePair<JsonProperty, object> remainingPropertyValue in remainingPropertyValues)
+ {
+ JsonProperty property = remainingPropertyValue.Key;
+ object value = remainingPropertyValue.Value;
+
+ if (ShouldSetPropertyValue(remainingPropertyValue.Key, remainingPropertyValue.Value))
+ property.ValueProvider.SetValue(createdObject, value);
+ }
+
+ contract.InvokeOnDeserialized(createdObject, Serializer.Context);
+ return createdObject;
+ }
+ private IDictionary<JsonProperty, object> ResolvePropertyAndConstructorValues(JsonObjectContract contract, JsonReader reader, Type objectType)
+ {
+ IDictionary<JsonProperty, object> propertyValues = new Dictionary<JsonProperty, object>();
bool exit = false;
do
{
@@ -877,7 +914,8 @@ namespace Newtonsoft.Json.Serialization // attempt exact case match first
// then try match ignoring case
- JsonProperty property = contract.Properties.GetClosestMatchProperty(memberName);
+ JsonProperty property = contract.ConstructorParameters.GetClosestMatchProperty(memberName) ??
+ contract.Properties.GetClosestMatchProperty(memberName);
if (property != null)
{
@@ -900,8 +938,6 @@ namespace Newtonsoft.Json.Serialization reader.Skip();
}
break;
- case JsonToken.Comment:
- break;
case JsonToken.EndObject:
exit = true;
break;
@@ -910,37 +946,7 @@ namespace Newtonsoft.Json.Serialization }
} while (!exit && reader.Read());
- IDictionary<ParameterInfo, object> constructorParameters = constructorInfo.GetParameters().ToDictionary(p => p, p => (object)null);
- IDictionary<JsonProperty, object> remainingPropertyValues = new Dictionary<JsonProperty, object>();
-
- foreach (KeyValuePair<JsonProperty, object> propertyValue in propertyValues)
- {
- ParameterInfo matchingConstructorParameter = constructorParameters.ForgivingCaseSensitiveFind(kv => kv.Key.Name, propertyValue.Key.PropertyName).Key;
- if (matchingConstructorParameter != null)
- constructorParameters[matchingConstructorParameter] = propertyValue.Value;
- else
- remainingPropertyValues.Add(propertyValue);
- }
-
- object createdObject = constructorInfo.Invoke(constructorParameters.Values.ToArray());
-
- if (id != null)
- Serializer.ReferenceResolver.AddReference(this, id, createdObject);
-
- contract.InvokeOnDeserializing(createdObject, Serializer.Context);
-
- // go through unused values and set the newly created object's properties
- foreach (KeyValuePair<JsonProperty, object> remainingPropertyValue in remainingPropertyValues)
- {
- JsonProperty property = remainingPropertyValue.Key;
- object value = remainingPropertyValue.Value;
-
- if (ShouldSetPropertyValue(remainingPropertyValue.Key, remainingPropertyValue.Value))
- property.ValueProvider.SetValue(createdObject, value);
- }
-
- contract.InvokeOnDeserialized(createdObject, Serializer.Context);
- return createdObject;
+ return propertyValues;
}
private bool ReadForType(JsonReader reader, Type t, JsonConverter propertyConverter)
|