Skip to content

Commit

Permalink
Make parameter matching for custom properties map property Name with …
Browse files Browse the repository at this point in the history
…parameter (#16)
  • Loading branch information
krwq authored Jun 22, 2022
1 parent 01119a8 commit 91bdc9e
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,8 @@ public JsonPropertyInfo CreateJsonPropertyInfo(Type propertyType, string name)

internal void CacheMember(JsonPropertyInfo jsonPropertyInfo, JsonPropertyDictionary<JsonPropertyInfo>? propertyCache, ref Dictionary<string, JsonPropertyInfo>? ignoredMembers)
{
string memberName = jsonPropertyInfo.ClrName!;
Debug.Assert(jsonPropertyInfo.ClrName != null, "ClrName can be null in custom JsonPropertyInfo instances and should never be passed in this method");
string memberName = jsonPropertyInfo.ClrName;

// The JsonPropertyNameAttribute or naming policy resulted in a collision.
if (!propertyCache!.TryAdd(jsonPropertyInfo.Name, jsonPropertyInfo))
Expand Down Expand Up @@ -545,7 +546,7 @@ internal void InitializeConstructorParameters(JsonParameterInfoValues[] jsonPara
foreach (KeyValuePair<string, JsonPropertyInfo?> kvp in PropertyCache.List)
{
JsonPropertyInfo jsonProperty = kvp.Value!;
string propertyName = jsonProperty.ClrName!;
string propertyName = jsonProperty.ClrName ?? jsonProperty.Name;

ParameterLookupKey key = new(propertyName, jsonProperty.PropertyType);
ParameterLookupValue value = new(jsonProperty);
Expand Down Expand Up @@ -584,7 +585,8 @@ internal void InitializeConstructorParameters(JsonParameterInfoValues[] jsonPara
else if (DataExtensionProperty != null &&
StringComparer.OrdinalIgnoreCase.Equals(paramToCheck.Name, DataExtensionProperty.Name))
{
ThrowHelper.ThrowInvalidOperationException_ExtensionDataCannotBindToCtorParam(DataExtensionProperty);
Debug.Assert(DataExtensionProperty.ClrName != null, "Custom property info cannot be data extension property");
ThrowHelper.ThrowInvalidOperationException_ExtensionDataCannotBindToCtorParam(DataExtensionProperty.ClrName, DataExtensionProperty);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@ internal void AddPropertiesUsingSourceGenInfo()
{
if (hasJsonInclude)
{
ThrowHelper.ThrowInvalidOperationException_JsonIncludeOnNonPublicInvalid(jsonPropertyInfo.ClrName!, jsonPropertyInfo.DeclaringType);
Debug.Assert(jsonPropertyInfo.ClrName != null, "ClrName is not set by source gen");
ThrowHelper.ThrowInvalidOperationException_JsonIncludeOnNonPublicInvalid(jsonPropertyInfo.ClrName, jsonPropertyInfo.DeclaringType);
}

continue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,9 +228,9 @@ public static void ThrowInvalidOperationException_ConstructorParameterIncomplete
}

[DoesNotReturn]
public static void ThrowInvalidOperationException_ExtensionDataCannotBindToCtorParam(JsonPropertyInfo jsonPropertyInfo)
public static void ThrowInvalidOperationException_ExtensionDataCannotBindToCtorParam(string propertyName, JsonPropertyInfo jsonPropertyInfo)
{
throw new InvalidOperationException(SR.Format(SR.ExtensionDataCannotBindToCtorParam, jsonPropertyInfo.ClrName, jsonPropertyInfo.DeclaringType));
throw new InvalidOperationException(SR.Format(SR.ExtensionDataCannotBindToCtorParam, propertyName, jsonPropertyInfo.DeclaringType));
}

[DoesNotReturn]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,70 @@ public ClassWithParametrizedConstructorAndWritableProperties(int a, string b)
}
}

[Fact]
public static void SerializingTypeWithCustomNonSerializablePropertyAndJsonConstructorWorksCorrectly()
{
var resolver = new DefaultJsonTypeInfoResolver { Modifiers = { ContractModifier } };
var options = new JsonSerializerOptions { TypeInfoResolver = resolver };
string json = JsonSerializer.Serialize(new PocoWithConstructor("str"), options);
Assert.Equal("{}", json);

static void ContractModifier(JsonTypeInfo jti)
{
if (jti.Type == typeof(PocoWithConstructor))
{
jti.Properties.Add(jti.CreateJsonPropertyInfo(typeof(string), "someOtherName"));
}
}
}

[Fact]
public static void SerializingTypeWithCustomSerializablePropertyAndJsonConstructorWorksCorrectly()
{
var resolver = new DefaultJsonTypeInfoResolver { Modifiers = { ContractModifier } };
var options = new JsonSerializerOptions { TypeInfoResolver = resolver };
string json = JsonSerializer.Serialize(new PocoWithConstructor("str"), options);
Assert.Equal("""{"test":"asd"}""", json);

static void ContractModifier(JsonTypeInfo jti)
{
if (jti.Type == typeof(PocoWithConstructor))
{
JsonPropertyInfo pi = jti.CreateJsonPropertyInfo(typeof(string), "test");
pi.Get = (o) => "asd";
jti.Properties.Add(pi);
}
}
}

[Fact]
public static void SerializingTypeWithCustomPropertyAndJsonConstructorBindsParameter()
{
var resolver = new DefaultJsonTypeInfoResolver { Modifiers = { ContractModifier } };
var options = new JsonSerializerOptions { TypeInfoResolver = resolver };
string json = """{"parameter":"asd"}""";
PocoWithConstructor deserialized = JsonSerializer.Deserialize<PocoWithConstructor>(json, options);
Assert.Equal("asd", deserialized.ParameterValue);

static void ContractModifier(JsonTypeInfo jti)
{
if (jti.Type == typeof(PocoWithConstructor))
{
jti.Properties.Add(jti.CreateJsonPropertyInfo(typeof(string), "parameter"));
}
}
}

private class PocoWithConstructor
{
internal string ParameterValue { get; set; }

public PocoWithConstructor(string parameter)
{
ParameterValue = parameter;
}
}

[Fact]
public static void JsonConstructorAttributeIsOverridenAndPropertiesAreSetWhenCreateObjectIsSet_LargeConstructor()
{
Expand Down

0 comments on commit 91bdc9e

Please sign in to comment.