首页 > 解决方案 > Json.Net反序列化没有属性名称的字典

问题描述

我已经查看了许多其他具有相同问题的问题,但从未找到真正适合我的明确解决方案。我尝试使用 JsonExtensionData 属性,但它不起作用,因为我无法将其他数据类转换为对象并且它会引发Invalid extension data attribute on 'NAMESPACE'. Member 'Sols' type must implement IDictionary<string, JToken>.错误。

我当前的数据模型类看起来像这样

public partial class Mars
{
    public Dictionary<string, Sol> Sols { get; set; }

    [JsonProperty("sol_keys")]
    public List<long> SolKeys { get; set; }
}

public partial class Sol
{
    [JsonProperty("AT")]
    public At At { get; set; }

    [JsonProperty("First_UTC")]
    public DateTimeOffset FirstUtc { get; set; }

    [JsonProperty("Last_UTC")]
    public DateTimeOffset LastUtc { get; set; }

    [JsonProperty("Season")]
    public string Season { get; set; }
}

public partial class At
{
    [JsonProperty("av")]
    public double Av { get; set; }

    [JsonProperty("ct")]
    public long Ct { get; set; }

    [JsonProperty("mn")]
    public double Mn { get; set; }

    [JsonProperty("mx")]
    public double Mx { get; set; }
}

json数据看起来像这样

{
    "651": 
    {
        "AT": 
        {
            "av": -61.957,
            "ct": 302204,
            "mn": -96.733,
            "mx": -15.877
        },
        "First_UTC": "2020-09-25T02:42:14Z",
        "Last_UTC": "2020-09-26T03:21:49Z",
        "Season": "summer"
    },
    "652": {
        "AT": {
            "av": -65.002,
            "ct": 278608,
            "mn": -96.111,
            "mx": -15.653
        },
        "First_UTC": "2020-09-26T03:21:50Z",
        "Last_UTC": "2020-09-27T04:01:24Z",
        "Season": "summer"
    },
    "sol_keys": [
        "646",
        "647",
        "648",
        "649",
        "650",
        "651",
        "652"
    ]
}

我无法真正修改 json 数据,因为我是从 api 获取的。我基本上只想选择其中一个数字,然后获取该对象的 Sol 数据。

任何帮助,将不胜感激。

标签: c#json.net.net-corejson.net

解决方案


JSON 不适合 C# 类型系统。但是,您仍然可以使用 Json.Net 对其进行解析。你只需要介绍一些额外的步骤。

第一步是将 JSON 解析为JObject

var jObject = JsonConvert.DeserializeObject<JObject>(json);

然后你可以提取sol_keys

var solKeys = jObject.GetValue("sol_keys").ToObject<long[]>();

现在它变得有点棘手。如果您sol_keys从 JSON(在本例中为已解析的 JSON)中删除 ,则它具有Sol您能够解析的对象字典的结构:

jObject.Remove("sol_keys");
var mars = jObject.ToObject<Dictionary<long, Sol>>();

现在你已经拥有solKeysmars从 JSON 中解析出来了。此外,solKeys字典中的 和 键共享相同的类型(long)。


推荐阅读