How to deal with nullable reference types with System.Text.Json?

Update If you're on net5, use the parameterized constructor support now offer as @langen points out. Else below can still be useful.

Original Slightly alternative approach. System.Text.Json appears to have no problems using a private parameterless constructor. So you can at least do the following:

public class Car
{
    public string Name { get; set; }
    public int Year { get; set; }

    // For System.Text.Json deserialization only
    #pragma warning disable CS8618 // Non-nullable field is uninitialized.
    private Car() { }
    #pragma warning restore CS8618

    public Car(string name, int year)
    {
        Name = name
            ?? throw new ArgumentNullException(nameof(name));
        Year = year;
    }
}

Benefits being:

  • Init of the object from your own code must be through the public ctor.
  • You don't need to do = null!; on each property.

Remaining downside with S.T.Json and nullable reference types:

  • S.T.Json still requires setters on the properties to actually set the values during deserialization. I tried with private ones and it's a no go, so we still can't get an immutable object...

UPDATE

System.Text.Json for .NET 5 now supports parameterized constructors, so this should not be a problem anymore.

See https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-immutability?pivots=dotnet-5-0

Old answer below

After reading the msdocs I found out how I could solve this issue.

So until System.Text.Json cannot instantiate classes with parameters in their constructor, the Car class will have to look like this:

public class Car
{
    public string Name { get; set; } = default!;
    public int Year { get; set; }
}