如何使用 System.Text.Json 处理可为空的引用类型?

lan*_*gen 17 json nullable-reference-types .net-core-3.0 system.text.json

我已将我的项目升级到 netcore 3.0,我正在重构一个项目以使用新的可为空引用类型功能,但由于以下问题而很快陷入困境。

假设我使用了一个 REST api,它返回以下 JSON:

{
  "Name": "Volvo 240",
  "Year": 1989
}
Run Code Online (Sandbox Code Playgroud)

此 api 始终返回名称/年份,因此它们不可为空。

我会使用这个简单的类进行反序列化:

{
  "Name": "Volvo 240",
  "Year": 1989
}
Run Code Online (Sandbox Code Playgroud)

我会Car使用新的将其反序列化为一个实例System.Text.Json

public class Car
{
    public string Name {get; set;}
    public int Year {get; set;}
}
Run Code Online (Sandbox Code Playgroud)

这一切都有效,但是当启用可为空引用类型时,我在声明为不可空但可以为空的Car类中收到警告Name。我明白为什么我会得到这个,因为可以在不初始化Name属性的情况下实例化这个对象。

所以理想情况下Car应该是这样的:

var car = JsonSerializer.Deserialize<Car>(json);
Run Code Online (Sandbox Code Playgroud)

但这不起作用,因为System.Text.Json序列化程序不支持带参数的构造函数。

所以我的问题是:我如何声明CarName是不可为空的并让它在System.Text.Json没有“不可为空”警告的情况下工作?`

我不想让它可以为空,因为在启用可为空引用类型时,我必须对基本上所有内容进行空检查,并且因为我的示例中的 REST API 说它们总是被提供,它们不应该为空。

lan*_*gen 6

更新

System.Text.Json for .NET 5 现在支持参数化构造函数,所以这不再是一个问题。

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

下面的旧答案

阅读msdocs 后,我发现了如何解决这个问题。

因此,直到System.Text.Json无法在其构造函数中使用参数实例化类,Car该类将必须如下所示:

public class Car
{
    public string Name { get; set; } = default!;
    public int Year { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

  • 就我个人而言,我宁愿使用 `= "";`,否则你基本上是在说(在我看来)“这个属性永远不会为空(**只是开玩笑**)”。 (5认同)
  • @MattJacobi `System.Text.Json` 很乐意将 `null` 反序列化为不可为空的字符串属性;至少默认情况下,无论反序列化类的“#nullable”状态如何(我刚刚尝试过) - 是否有一些选项可以触发这种更严格的“我真的是指可空性”模式? (3认同)
  • (对于 System.Text.Json,默认情况下,由属性省略导致的显式 null 和隐式 null 都不是可空性错误) (2认同)