Description
Consider the following test:
[Fact]
public static void CanEnableDeserializationOnAlwaysIgnoreProperty()
{
var options = new JsonSerializerOptions
{
TypeInfoResolver = new DefaultJsonTypeInfoResolver
{
Modifiers =
{
jsonTypeInfo =>
{
if (jsonTypeInfo.Type != typeof(ClassWithJsonIgnoreAlwaysProperty))
{
return;
}
JsonPropertyInfo jsonPropertyInfo = jsonTypeInfo.Properties[0];
jsonPropertyInfo.Set = (obj, value) => ((ClassWithJsonIgnoreAlwaysProperty)obj).Value = (int)value;
}
}
}
};
ClassWithJsonIgnoreAlwaysProperty value = JsonSerializer.Deserialize<ClassWithJsonIgnoreAlwaysProperty>("""{"Value":42}""", options);
Assert.Equal(42, value.Value);
}
public class ClassWithJsonIgnoreAlwaysProperty
{
[JsonIgnore]
public int Value { get; set; }
}
This happens because the DetermineSerializationCapabilities
method will mark the property as non-serializable/deserializable based on the initial value of JsonIgnoreCondition
. JsonIgnoreCondition
is not user-settable so no user modification on the contract model can prevent this.
I would recommend we change this so that all logic in DetermineSerializationCapabilities
is done at initialization time and can be modified by users. Additionally, I propose we introduce a ShouldDeserialize
method to JsonPropertyInfo
:
public partial class JsonPropertyInfo
{
public Func<object, object?, bool> ShouldSerialize { get; set; }
+ public Func<object, object?, bool> ShouldDeserialize { get; set; }
}
The two delegates would allow mapping all possible JsonIgnoreCondition
configurations to these two delegates and not require nulling out the Get
and Set
delegates as we currently do for JsonIgnoreCondition.Always
. Contract customization in Json.NET also includes a ShouldDeserialize
delegate complementing ShouldSerialize
so we should be following a similar approach in System.Text.Json
.