-Fixed not matching some parameters when deserializing via a cosntructor

This commit is contained in:
James Newton-King
2014-09-02 23:29:20 +12:00
parent 4a375721ac
commit 0c865efd96
4 changed files with 51 additions and 20 deletions
@@ -7611,6 +7611,28 @@ Parameter name: value",
}
#endif
public class FooConstructor
{
[JsonProperty(PropertyName = "something_else")]
public readonly string Bar;
public FooConstructor(string bar)
{
if (bar == null)
throw new ArgumentNullException("bar");
Bar = bar;
}
}
[Test]
public void DeserializeWithConstructor()
{
const string json = @"{""something_else"":""my value""}";
var foo = JsonConvert.DeserializeObject<FooConstructor>(json);
Assert.AreEqual("my value", foo.Bar);
}
[Test]
public void SerializeCustomReferenceResolver()
{
@@ -1623,7 +1623,19 @@ To fix this error either change the environment to be fully trusted, change the
foreach (KeyValuePair<JsonProperty, object> propertyValue in propertyValues)
{
JsonProperty matchingCreatorParameter = contract.CreatorParameters.ForgivingCaseSensitiveFind(p => p.PropertyName, propertyValue.Key.PropertyName);
JsonProperty property = propertyValue.Key;
JsonProperty matchingCreatorParameter;
if (contract.CreatorParameters.Contains(property))
{
matchingCreatorParameter = property;
}
else
{
// check to see if a parameter with the same name as the underlying property name exists and match to that
matchingCreatorParameter = contract.CreatorParameters.ForgivingCaseSensitiveFind(p => p.PropertyName, property.UnderlyingName);
}
if (matchingCreatorParameter != null)
{
int i = contract.CreatorParameters.IndexOf(matchingCreatorParameter);
@@ -1637,9 +1649,9 @@ To fix this error either change the environment to be fully trusted, change the
if (propertiesPresence != null)
{
// map from creator property to normal property
var property = propertiesPresence.Keys.FirstOrDefault(p => p.PropertyName == propertyValue.Key.PropertyName);
if (property != null)
propertiesPresence[property] = (propertyValue.Value == null) ? PropertyPresence.Null : PropertyPresence.Value;
JsonProperty presenceProperty = propertiesPresence.Keys.FirstOrDefault(p => p.PropertyName == property.PropertyName);
if (presenceProperty != null)
propertiesPresence[presenceProperty] = (propertyValue.Value == null) ? PropertyPresence.Null : PropertyPresence.Value;
}
}
@@ -75,11 +75,11 @@ namespace Newtonsoft.Json.Utilities
Label argsOk = generator.DefineLabel();
// throw an error if the number of argument values doesn't match method parameters
generator.Emit(OpCodes.Ldarg, argsIndex);
generator.Emit(OpCodes.Ldlen);
generator.Emit(OpCodes.Ldc_I4, args.Length);
generator.Emit(OpCodes.Beq, argsOk);
generator.Emit(OpCodes.Newobj, typeof(TargetParameterCountException).GetConstructor(ReflectionUtils.EmptyTypes));
generator.Emit(OpCodes.Throw);
@@ -104,9 +104,7 @@ namespace Newtonsoft.Json.Utilities
// don't need to set variable for 'out' parameter
if (!parameter.IsOut)
{
generator.Emit(OpCodes.Ldarg, argsIndex);
generator.Emit(OpCodes.Ldc_I4, i);
generator.Emit(OpCodes.Ldelem_Ref);
generator.PushArrayInstance(argsIndex, i);
if (parameterType.IsValueType())
{
@@ -123,9 +121,7 @@ namespace Newtonsoft.Json.Utilities
// parameter has value, get value from array again and unbox and set to variable
generator.MarkLabel(skipSettingDefault);
generator.Emit(OpCodes.Ldarg, argsIndex);
generator.Emit(OpCodes.Ldc_I4, i);
generator.Emit(OpCodes.Ldelem_Ref);
generator.PushArrayInstance(argsIndex, i);
generator.UnboxIfNeeded(parameterType);
generator.Emit(OpCodes.Stloc, localVariableCount);
@@ -145,9 +141,7 @@ namespace Newtonsoft.Json.Utilities
}
else if (parameterType.IsValueType())
{
generator.Emit(OpCodes.Ldarg, argsIndex);
generator.Emit(OpCodes.Ldc_I4, i);
generator.Emit(OpCodes.Ldelem_Ref);
generator.PushArrayInstance(argsIndex, i);
// have to check that value type parameters aren't null
// otherwise they will error when unboxed
@@ -166,9 +160,7 @@ namespace Newtonsoft.Json.Utilities
// parameter has value, get value from array again and unbox
generator.MarkLabel(skipSettingDefault);
generator.Emit(OpCodes.Ldarg, argsIndex);
generator.Emit(OpCodes.Ldc_I4, i);
generator.Emit(OpCodes.Ldelem_Ref);
generator.PushArrayInstance(argsIndex, i);
generator.UnboxIfNeeded(parameterType);
// parameter finished, we out!
@@ -177,9 +169,7 @@ namespace Newtonsoft.Json.Utilities
}
else
{
generator.Emit(OpCodes.Ldarg, argsIndex);
generator.Emit(OpCodes.Ldc_I4, i);
generator.Emit(OpCodes.Ldelem_Ref);
generator.PushArrayInstance(argsIndex, i);
generator.UnboxIfNeeded(parameterType);
}
@@ -41,6 +41,13 @@ namespace Newtonsoft.Json.Utilities
generator.Emit(OpCodes.Castclass, type);
}
public static void PushArrayInstance(this ILGenerator generator, int argsIndex, int arrayIndex)
{
generator.Emit(OpCodes.Ldarg, argsIndex);
generator.Emit(OpCodes.Ldc_I4, arrayIndex);
generator.Emit(OpCodes.Ldelem_Ref);
}
public static void BoxIfNeeded(this ILGenerator generator, Type type)
{
if (type.IsValueType())