asp.net-core - 类型未知时反序列化 JSON - .NET Core
问题描述
我试图了解反序列化来自 REST API 的 Json 数据的最佳方法。
我正在使用的 API 上的端点之一将返回一个User
对象或一个ApiException
对象。
所以我必须做
var user = JsonConverter.Deserialize<User>(json);
if(user.UserId == 0)
{
var error = JsonConverter.Deserialize<ApiException>(json);
}
或者
if(!json.Contains("error"))
{
var user = JsonConverter.Deserialize<User>(json);
}
else
{
var error = JsonConverter.Deserialize<ApiException>(json);
}
有没有更清洁的方法来实现这一点?
编辑:我想另一种方法是如果 api 返回一个包装类,该包装类包含包含类型的响应,但由于某种原因这仍然感觉很笨重。
解决方案
一个想法是使用 System.Text.Json 中的JsonDocument类在反序列化为任何一种可能的类型之前查看原始数据。例如,如果“userId”键的存在是识别为用户对象的可靠方法,您可以在 JsonDocument 中以高性能方式对此进行测试,而无需对错误类型进行不必要的反序列化。它看起来像:
using JsonDocument document = JsonDocument.Parse(json);
if (document.RootElement.TryGetProperty("userId", out _))
{
var user = JsonSerializer.Deserialize<User>(json);
// Do stuff with user
}
else
{
var error = JsonSerializer.Deserialize<ApiException>(json);
// Do stuff with error
}
要知道这实际上是否比两种类型的盲目反序列化更好,我会将其放入基准测试中,看看哪种情况会胜出。我使用从 UTF8 字节数组中解析的相对较小的“用户”进行了快速测试。我的基准测试结果:
| Method | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
|----------------- |---------:|----------:|----------:|-------:|------:|------:|----------:|
| JSONDocument | 2.500 us | 0.0193 us | 0.0181 us | 0.1297 | - | - | 824 B |
| StringParse | 1.360 us | 0.0096 us | 0.0090 us | 0.2460 | - | - | 1544 B |
| BlindDeserialize | 2.084 us | 0.0132 us | 0.0123 us | 0.1335 | - | - | 840 B |
在此示例中,搜索“UserId:”的原始字符串似乎比使用 JSONDocument 更快,但会消耗更多内存。“BlindDeserialize”正在反序列化两者并检查结果。当然,这至少不科学,但给人一种替代品的味道。
推荐阅读
- c - 在c linux中的套接字编程中连接被拒绝
- javascript - 使用应用脚本的无限倒数计时器
- flutter - 为什么AppBar的automaticImplyLeading没有效果?
- javascript - 如何在双击时重命名列表但将图标保留在其旁边
- laravel - Windows 10 Apache 虚拟主机下的 Laravel 8 存储文件夹问题
- notepad++ - notepad ++ - 在每个单词中找到用户定义的语言“如果”
- pytorch - GAN 模型总结 Pytorch 使用 TensorBoard?
- r - 如何在不复制基础数据的情况下从 Eigen::Tensor 创建 Rcpp NumericVector
- python - XML解析Python(需要指定3个标签和1个属性时)
- github - 如何在 Github 中为 Pytorch 模型提供正确的路径?