简体   繁体   中英

Deserialize JSON to Dictionary<string, List<string>>

I am very new to JSON, so I may have missed something. But here's what I am attempting. I want to Deserialize the following type of JSON

{
  "Size": 
  {
    "Creature": 
    {
      "Dragon": 
      [
        "Huge",
        "Colossal",
        "Mountain-sized"
      ],

      "Wolf": 
      [
        "Pup",
        "Fully grown",
        "Giant"
      ]
    },

    "Building": 
    [
      "Small",
      "Medium",
      "Large"
    ]
  }
}

The core function of the JSON is intended so that I am not sure how nested it may become over time. With creature having subtypes depending on what kind of creature it is, and same for building and so on.

I've attempted with this code

using StreamReader r = new StreamReader("Storage.json");
string json = r.ReadToEnd();
CoreStorageDict = JsonConvert.DeserializeObject<Dictionary<string, List<string>>>(json);

I would like to Deserialize it into a dictionary as directly as possible, but I've yet to find a good way to do it and I think I am missing something fundamental about the whole system.

Is the JSON wrong or is my code wrong? Or both perhaps?

If you define the following classes:

public class Creature
{
    public IList<string> Dragon { get; set; }
    public IList<string> Wolf { get; set; }
}

public class Size
{
    public Creature Creature { get; set; }
    public IList<string> Building { get; set; }
}

public class Example
{
    public Size Size { get; set; }
}

and then try to deserialize your json you will make it. You can alter the name of classes as you want. For the names above you have just to do this:

var result = JsonConvert.DeserializeObject<Example>(json);

What is the problem with the approach you followed ?

The problem is that you have nested types. So you have to declare each and any type properly in order the deserialization work.

How you can find which classes are needed to be declared ?

There are may tools out there that do this job. The one I used is the following one JSON Utils . Provided that you have a valid json, these tools can auto generate the required classes. If I am correct, also Visual Studio, provides you with such a functionality.

Making classes is definitely a good way to do it and I agree with Christos.

However if you're doing a one-time thing and don't want to bother making classes you can hack it by deserializing the whole thing to dynamic and then re-serializing and deserializing the part you need, to your expected type, like this.

   var json = @"{
                    ""Size"": {
                      ""Creature"": {
                        ""Dragon"": [
                          ""Huge"",
                          ""Colossal"",
                          ""Mountain-sized""
                        ],
                        ""Wolf"": [
                          ""Pup"",
                          ""Fully grown"",
                          ""Giant""
                        ]
                      },
                      ""Building"": [
                        ""Small"",
                        ""Medium"",
                        ""Large""
                      ]
                    }
                  }";

            var deserialized = JsonConvert.DeserializeObject<dynamic>(json);

            var thePartYouWant = deserialized.Size.Creature;

            var dict = (Dictionary<string, List<string>>) JsonConvert
                .DeserializeObject<Dictionary<string, List<string>>>(
                    (JsonConvert.SerializeObject(thePartYouWant)));

            dict.Keys.ToList().ForEach(Console.WriteLine);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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