.net-5 - System.Text.Json.JsonSerializer.Deserialize() 的.net 5.0 签名更改
问题描述
我正在尝试从 .NET Core 3.1 到 .NET 5.0 的步骤,并在使用 .NET Core 时收到一堆可空性警告Deserialize<TValue>(String, JsonSerializerOptions)
。快速调查显示签名已从
public static TValue Deserialize<TValue> (string json, System.Text.Json.JsonSerializerOptions options = default);
(文档)在 .NET Core 3.1 到
public static TValue? Deserialize<TValue> (string json, System.Text.Json.JsonSerializerOptions? options = default);
(文档)在 .NET 5.0 中。
它看起来是一个合理的改变,但我无法让 null 实际返回,因为所有错误的输入/错误使用都会在我的实验中引发异常,并且文档没有描述为什么调用会返回据我所知,null。
如果反序列化失败将抛出而不是返回 null,那么在我们所有的使用中添加 null 返回检查似乎有点不必要。
我错过了什么?
解决方案
如原始 JSON 提案所示,文本null
是格式完美的 JSON:
值可以是双引号中的字符串、数字、 true 或 false 或null,或者对象或数组。这些结构可以嵌套。
RFC 8259: The JavaScript Object Notation (JSON) Data Interchange Format进一步阐明了这一点,它指出格式良好的 JSON 文本只需一个原始值,包括null
:
JSON 文本是一系列标记。标记集包括六个结构字符、字符串、数字和三个文字名称 [false、true 和 null]。
JSON 文本是一个序列化的值。请注意,某些先前的 JSON 规范将 JSON 文本限制为对象或数组。仅生成需要 JSON 文本的对象或数组的实现将是可互操作的,因为所有实现都将接受这些作为符合标准的 JSON 文本。
由于null
是根据这个最新的 JSON RFC 格式良好的 JSON 文本,JsonSerializer
在将其反序列化为引用类型或可为空值类型时不会抛出,而是只返回一个空值:
object? obj1 = JsonSerializer.Deserialize<object>("null"); // Does not throw; explicitly typed for clarity.
Assert.IsNull(obj1); // Passes
var array = JsonSerializer.Deserialize<int []>("null"); // Does not throw;
Assert.IsNull(array); // Passes
var nullable = JsonSerializer.Deserialize<int?>("null"); // Does not throw;
Assert.IsNull(nullable); // Passes
相反,以下会生成编译器警告:
#nullable enable
object obj2 = JsonSerializer.Deserialize<object>("null"); // Compiler warning: Converting null literal or possible value to non-nullable type;
并且以下抛出,因为 anint
是不可分配的不可空值null
类型:
var i = JsonSerializer.Deserialize<int>("null"); // Throws, since int is a non-nullable value type.
如果要在反序列化 JSON 文本时抛出异常null
,可以添加以下扩展方法:
public static class ObjectExtensions
{
public static T ThrowOnNull<T>(this T? value) where T : class => value ?? throw new ArgumentNullException();
}
并做:
var value = JsonSerializer.Deserialize<TValue>(json).ThrowOnNull();
演示小提琴在这里。
推荐阅读
- python-3.x - 绘制数字日志:typeerror: only size -1 arrays
- postgresql - 关闭 trgm 索引中的重新检查
- python - 我想在 python 中创建一个阶乘函数,使其返回 N
- reactjs - 非空检查后对象属性仍未定义
- c - 将编译器默认包含路径获取到生成文件中
- python - 如何将 Tweepy Bot 与 Alexa Skill 一起使用
- reactjs - 与 redux-thunk 同步操作
- asp.net-core - 在我的示例(blazor)中,为什么绑定不适用于数组和 for 循环?
- unit-testing - 当 PartialEq 的实现不合适时,如何断言两个变量相等?
- arrays - GLSL 动态数组索引