c# - 继承 Newtonsoft JSON.NET 的反序列化无法正常工作

标签 c# json postgresql json.net jsonb

(使用 Newtonsoft JSON.NET)

您好我在反序列化事件列表时遇到问题,其中事件是基本类型,例如ResourceEvent 是一个子类。如果我只是进行序列化然后反序列化,一切正常并且列表包含 ResourceEvents - 但是我将使用 EF7 的那些存储到 postgres 的 jsonb 列中。

当我从 postgres 获取 JSON 负载时,它已重新排序(但 JSON 合法)属性。当我尝试使用 Newtonsoft JSON.net 进行反序列化时,它只给我一个包含基本类型 Event 而不是子类 ResourceEvent 的列表。

我添加了两个高度剥离的示例,不同之处在于“Type”属性位于不同的位置。其他属性的顺序也已在类中被打乱。我根本没有关于这些类的注释。

此负载成功反序列化:

json
{
    "$type": "System.Collections.Generic.List`1[[Event, Tests]], mscorlib",
    "$values": [
        {
            "$type": "ResourceConfigurationEvent, Tests",
            /* Properties */
            "Resources": {
                /* Properties */                
            },
            "Type": 1            
        }
    ]
}

此负载反序列化失败:

json
{
    "$type": "System.Collections.Generic.List`1[[Event, Tests]], mscorlib",
    "$values": [
        {
            "Type": 1,            
            "$type": "ResourceConfigurationEvent, Tests",
            /* Properties */
            "Resources": {
                /* Properties */                
            },
        }
    ]
}

最佳答案

Json.Net 通常希望 $type 元数据成为每个对象的第一个属性,以实现反序列化的最佳效率。如果 $type 没有首先出现,则 Json.Net 假定它不存在。这就是为什么在重新排序属性时会得到不同结果的原因。

幸运的是,Json.Net 提供了一个 MetadataPropertyHandling设置以使其能够应对这种情况。如果将 MetadataPropertyHandling 设置为 ReadAhead,它应该可以解决您的问题。请注意,这会对性能产生影响。

这是一个code sample来自文档。

string json = @"{
  'Name': 'James',
  'Password': 'Password1',
  '$type': 'MyNamespace.User, MyAssembly'
}";

object o = JsonConvert.DeserializeObject(json, new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.All,
    // $type no longer needs to be first
    MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead
});

User u = (User)o;

Console.WriteLine(u.Name);
// James

关于c# - 继承 Newtonsoft JSON.NET 的反序列化无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37563603/

相关文章:

c# 通用接口(interface)不可能实现

c# - 如何获取周中的日期,同时也适用于 53 周的年份? C#

json - 如何使用 try.zorba.io 从 JSON 运行 JSONiq

c# - JSON 解析问题 - 'S' 是 JSON 中无效的可转义字符

arrays - 使用 Rails 4+ 和 PostgreSQL 数组检查非空数组

sql - 插入多行时重复项会发生什么情况?

C# - 如何缩小 SHA512 的大小

json - 循环通过 loadFromJSON() 加载的对象时,fabric.util.loadImage() 的奇怪行为

sql - regexp_matches() 返回 $ 的两个匹配项(字符串结尾)

c# - msbuild 使用了错误的程序集名称