Description
Description
The JsonIgnore
attribute is ignored for init-only properties in source generation mode.
A motivating example is when I have an outer record wrapping some inner record to perform some serialization transformation.
record MyRecord([property: JsonIgnore] MyOtherRecord MyOtherRecord)
{
[JsonConstructor]
public MyRecord(int foo) : this(new MyOtherRecord(foo, "Baz"))
{
}
[JsonPropertyName("foo")] public string Foo => MyOtherRecord.Foo.ToString();
}
record MyOtherRecord(int Foo, string Bar);
[JsonSerializable(typeof(MyRecord))]
partial class JsonContext : JsonSerializerContext;
In the example above, the object initializer for MyRecord
, generated by the json source generation machinery, would override the initialized value of the MyOtherRecord
property to null
-- despite having a JsonIgnore
applied to the property.
Reproduction Steps
Apply the JsonIgnore
attribute to an init-only property and observe that the init is invoked upon object construction. As illustrated below, the behavior seems to diverge from reflection mode.
var reflection = JsonSerializer.Deserialize<JsonClass>("""{"A":1}""");
Console.WriteLine($"Property: {reflection!.Property}"); // Property: 42
var sourceGenerated = JsonSerializer.Deserialize<JsonClass>("""{"A":1}""", JsonContext.Default.JsonClass);
Console.WriteLine($"Property: {sourceGenerated!.Property}"); // Property: 0
class JsonClass
{
[JsonIgnore(Condition = JsonIgnoreCondition.Always)]
public int Property { get; init; } = 42;
}
[JsonSerializable(typeof(JsonClass))]
partial class JsonContext : JsonSerializerContext;
Expected behavior
The JsonIgnore
attribute should, when applied to an init-only property, cause the property initializer to be omitted entirely from object construction.
From the docs:
[JsonIgnore] Prevents a property or field from being serialized or deserialized.
Actual behavior
The init-only property is effectively behaving as if the ignore condition is set to JsonIgnoreCondition.Never
, thus causing any value set in the constructor to subsequently be overridden.
Regression?
No response
Known Workarounds
Changing the accessor from init
to set
updates ObjectWithParameterizedConstructorCreator
from static args => new global::JsonClass(){ Property = (int)args[0] }
to static args => new global::JsonClass()
.
Configuration
.NET 8
SDK 8.0.204
Other information
No response