简体   繁体   English

使用动态密钥将JSON反序列化为Object

[英]Deserialize JSON with dynamic key into Object

I know there have been some questions already raised about this topic however I still struggle o understand it. 我知道已经对此主题提出了一些问题,但是我仍然很难理解。 I have quite a complex JSON object returning which has a dynamic key at the beginning. 我有一个返回的相当复杂的JSON对象,它在开始时有一个动态密钥。 I am trying to deserialize it into a C# object model but my problem is the dynamic key: 我正在尝试将其反序列化为C#对象模型,但是我的问题是动态键:

{
"ISBN:0903393972": {
    "bib_key": "ISBN:0903393972",
    "details": {
        "publishers": ["Sweet & Maxwell"],
        "physical_format": "Hardcover",
        "title": "Tanker Voyage Charter Parties",
        "created": {
            "type": "/type/datetime",
            "value": "2008-04-30T09:38:13.731961"
        },
        "authors": [{
            "name": "F.M. Ventris",
            "key": "/authors/OL3610236A"
        }],
}}}

My headache comes from the "ISBN:0903393972" part which is dynamic. 我的头痛来自动态的“ ISBN:0903393972”部分。 Below is also part of the model: 以下也是该模型的一部分:

[DataContract]
public class Created
{
    [DataMember]
    public string type { get; set; }
    [DataMember]
    public DateTime value { get; set; }
}

[DataContract]
public class Author
{
    [DataMember]
    public string name { get; set; }
    [DataMember]
    public string key { get; set; }
}

[DataContract]
public class Details
{
    [DataMember]
    public List<string> publishers { get; set; }
    [DataMember]
    public string physical_format { get; set; }
    [DataMember]
    public string title { get; set; }
    [DataMember]
    public Created created { get; set; }
    [DataMember]
    public List<Author> authors { get; set; }
}

[DataContract]
public class ISBN
{
    [DataMember]
    public string bib_key { get; set; }
    [DataMember]
    public Details details { get; set; }
}

[DataContract]
public class RootObject
{
    public Dictionary<string, ISBN> bookRoot { get; set; }
}

I am deserializing the JSON format with the below code (which works in case I hard code the "ISBN:0903393972" as the key of the object): 我正在使用以下代码反序列化JSON格式(在我将“ ISBN:0903393972”硬编码为对象的键的情况下可以使用):

        string json = new WebClient().DownloadString(URLAddress);
        JObject book = JObject.Parse(json) as JObject;

        // Copy to a static Album instance
        RootObject deserializedBook = book.ToObject<RootObject>();

        return deserializedBook;

I am sure that I'm missing something here but have been struggling he whole day already in trying to find a solution. 我确定我在这里遗漏了一些东西,但是他整天都在努力寻找解决方案。 Any help would be really appreciated! 任何帮助将非常感激!

You are close. 你近了

In your JSON, the dynamic keys are at the root level, and so that object needs to be represented by a Dictionary<string, ISBN> . 在您的JSON中,动态键位于根级别,因此该对象需要由Dictionary<string, ISBN> It seems you have realized this, however, in your model, you have added an outer class to contain the dictionary. 看来您已经意识到这一点,但是,在您的模型中,您添加了一个外部类来包含字典。 This doesn't line up with the JSON and is not needed here. 这与JSON不一致,这里不需要。 Instead, you should deserialize directly into the dictionary: 相反,您应该直接反序列化到字典中:

string json = new WebClient().DownloadString(URLAddress);
var bookRoot = JsonConvert.DeserializeObject<Dictionary<string, ISBN>>(json);

From there, you can loop over the Values collection on the dictionary to access the books without having to know the key(s) in advance: 从那里,您可以在字典上遍历Values集合以访问书籍,而无需事先知道键:

foreach (var isbn in bookRoot.Values)
{
    // ...
}

Or, if you're expecting only one book, you can get it from the dictionary like this: 或者,如果您只希望读一本书,则可以从字典中获取,如下所示:

var isbn = bookRoot.Values.First();

Here is a working demo: https://dotnetfiddle.net/csgSKp 这是一个有效的演示: https : //dotnetfiddle.net/csgSKp

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM