是否有可能在反序列化时以某种方式捕获与任何 POCO 属性不匹配的 JSON 数据的其余部分?

Posted

技术标签:

【中文标题】是否有可能在反序列化时以某种方式捕获与任何 POCO 属性不匹配的 JSON 数据的其余部分?【英文标题】:Is it possible to catch somehow the remainder of JSON data that didn't match any POCO properties while deserializing? 【发布时间】:2020-11-23 09:11:04 【问题描述】:

我正在从外部 API 获取一些 JSON 数据。我有数据反序列化到的 POCO 对象。我使用 System.Text.Json.JsonSerializer 进行反序列化。最近,我意识到我收到的 JSON 的结构发生了变化,我是在检查其他内容时偶然知道的。我的问题是,是否有可能以某种方式捕获未成功映射到任何 POCO 字段的 json 数据?

更准确地说,我的问题是一个 POCO 示例:

public class Car

    public string Name  get; set; 
    public int Age  get; set; 

我之前收到的 JSON:

"Name" : "PinkCar", "Age": 3

我现在收到的 JSON:

"Name" : "PinkCar", "Age": 3, "RogueField": "Loser"

我希望至少能够在不破坏反序列化过程的情况下以某种方式获得与任何 POCO 属性都不匹配的新“RogueField”的信息。

【问题讨论】:

如果您愿意,可以在 JSON.Net 中使用 JsonExtensionData。我在标准序列化类型中找不到任何建议您可以拥有“全部捕获”事件的内容,以便您可以处理未知或新属性。此处示例:newtonsoft.com/json/help/html/DeserializeExtensionData.htm 你是如何反序列化数据的?您是手动执行还是依赖 MVC 模型绑定?如果是 MVC,你使用的是哪个版本的 .NET Core? 我不知道有任何内置功能可以帮助您。我想我会创建一个简单的 JsonConverter,它可以记录目标对象上不存在的任何属性。 @DavidG 我手动输入:System.Text.Json.JsonSerializer.Deserialize<Car>(json);@Mono 我喜欢你的想法,但老实说,我不知道如何使用 JsonConverter 捕获这些数据。不是只有当 json 中有与属性名称匹配的数据时才会运行 json 转换器吗?我不确定你是否明白我的意思。 【参考方案1】:

额外的属性可以与您的对象一起保存在字典中。你可以操作这个目录,当你再次序列化你的对象时会用到它。

来自https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-how-to#handle-overflow-json:创建一个Dictionary<string, object>类型的属性,它可以有任何名称(通常这被命名为ExtensionData但可以是任何名称),并用[JsonExtensionData]属性装饰它,例如:

public class Car

    public string Name  get; set; 
    public int Age  get; set; 
    [JsonExtensionData]
    public Dictionary<string, object> ExtensionData  get; set; 

【讨论】:

【参考方案2】:

不幸的是,目前无法使用 .NET Core 中的 System.Text.Json 对象。 It is currently unsupported.

您可以使用 Newtonsoft JSON,例如:

var settings = new JsonSerializerSettings

    MissingMemberHandling = MissingMemberHandling.Error
;

var result = Newtonsoft.Json.JsonConvert.DeserializeObject<Car>(json, settings);

现在,当您的 POCO 遗漏任何字段时,它会抛出 JsonSerializationException

JsonSerializationException:在“Car”类型的对象上找不到成员“RogueField”。路径“RogueField”,第 1 行,位置 44。

【讨论】:

以上是关于是否有可能在反序列化时以某种方式捕获与任何 POCO 属性不匹配的 JSON 数据的其余部分?的主要内容,如果未能解决你的问题,请参考以下文章

指定从 Qt 应用程序复制的文本格式?粘贴时以某种方式使其他应用程序崩溃

fastjson 1.2.24-基于JdbcRowSetImpl的PoC构造与分析

在没有分隔符时以某种方式拆分行的问题

在反序列化期间获取任何深度的XMLElement

我可以让 XmlSerializer 在反序列化时忽略命名空间吗?

Protobuf-net r282 在反序列化使用 r249 序列化的对象时遇到问题