Skip to content

Default values for init-only properties are lost with generated JsonTypeInfo #84484

@Sergio0694

Description

@Sergio0694

Description

Note: related to #58770

With the 8.0.0 release, System.Text.Json will support required and init-only properties. This is something we'd like to leverage in the Microsoft Store, as moving away from records to instead use normal classes with required init-only properties can help reduce code size (due to no longer having all the record fluff), while still keeping things "well defined" (ie. not having nullable properties you need to suppress warnings for, etc.). But, I've noticed that default values don't really seem to work.

Consider this example:

Foo? foo = JsonSerializer.Deserialize("{}", MyJsonContext.Default.Foo);

Console.WriteLine(foo);

[JsonSerializable(typeof(Foo))]
public partial class MyJsonContext : JsonSerializerContext
{
}

public record Foo(string Name = "DefaultName", int Number = 42);

This will print "Foo { Name = DefaultName, Number = 42 }". That is, those default values are correctly used.

Consider the same thing, but changing that record to a class like this:

public class Foo
{
    public string Name { get; init; } = "DefaultName";

    public int Number { get; init; } = 42;
}

This will cause those default values to be completely lost instead. The same code above will deserialize an instance that just has the values of each property set to default. This is not really intuitive - I would've expected the default value from those property initializers to be preserved, whereas the generated code is just always assigning something to every single property, even if the value isn't present in the JSON, which will just cause default to be assigned instead.

Shouldn't the generated code for the object initializer only assign init-only, non-required properties when they're actually present in the JSON? If not, is there some way to preserve the "default value" behavior for properties in some way? Eg. I've tried to see if there was already some [JsonDefaultValue] attribute or something, but it doesn't seem to be a thing. Should it?

cc. @eiriktsarpalis @layomia

Metadata

Metadata

Labels

area-System.Text.JsonenhancementProduct code improvement that does NOT require public API changes/additionsin-prThere is an active PR which will close this issue when it is merged

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions