json newtonsoft : Deserialize Object containing a list of string

42,219

Solution 1

There doesn't seem to be any apparent problem wit hyour code as this working example illustrates:

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
public class myClass
{
    public string ID { get; set; }
    public string KEY1 { get; set; } 
    public List<string> CATEG { get; set; } 
}
public class ESObject1
{
    [JsonProperty("EVT")]
    public List<myClass> EVT { get; set; }
}
public class ESObject0
{
    [JsonProperty("EVTS")]
    public ESObject1 EVTS { get; set; }
}
class Program
{
    static void Main()
    {
        string json = 
        @"{
            ""EVTS"": {
                ""EVT"": [
                    {
                        ""ID"": ""123456"",
                        ""KEY1"": ""somekey"",
                        ""CATEG"": [
                            ""cat1"",
                            ""cat2"",
                            ""cat3""
                        ]
                    }
                ]
            }
        }";
        ESObject0 globalobject = JsonConvert.DeserializeObject<ESObject0>(json);
        foreach (string item in globalobject.EVTS.EVT[0].CATEG)
        {
            Console.WriteLine(item);
        }
    }
}

Maybe you just fed a wrong json value to the deserializer which doesn't look like as the one shown in your question. By the way, the one shown i nyour question is invalid JSON as you are missing a , after KEY1 property declaration.


UPDATE:

Now that you have shown your real JSON (coming from http://donnees.ville.quebec.qc.ca/Handler.ashx?id=69&f=JSON) it appears that there's a row where CATEG is not an array of strings but a simple string:

""CATEG"": ""Conférence""

Now that's a pretty bad design because they are mixing arrays and simple properties. I am afraid that in order to deal with this situation you will need to use JObjects and extract the information you need by testing the actual underlying type.

For example:

var obj = JObject.Parse(json);
var events = (JArray)obj["EVTS"]["EVT"];
foreach (JObject evt in events)
{
    var categories = evt["CATEG"];
    if (categories is JArray)
    {
        // you've got a list of strings so you can loop through them
        string[] cats = ((JArray)categories)
            .Select(x => x.Value<string>())
            .ToArray();
    }
    else
    {
        // you've got a simple string
        string cat = categories.Value<string>();
    }
}

Solution 2

I have done this many times with many many headaches. My advice is take the json output and use a tool similar to this to write your class for you (http://json2csharp.com/).

Then go over any nullable variables and add nullable type (ex. using int? for int) where needed.

Share:
42,219

Related videos on Youtube

dafriskymonkey
Author by

dafriskymonkey

Updated on March 23, 2020

Comments

  • dafriskymonkey
    dafriskymonkey almost 3 years

    I have the following issue with this json :

    {
    "EVTS": {
    "EVT": [
      { "ID": "123456",
        "KEY1" : "somekey",
        "CATEG": [
          "cat1",
          "cat2",
          "cat3"
        ]
      }
      ]}
      }
    

    and this c# class:

    public class myClass{
        public string ID { get; set; }
        public string KEY1 { get; set; } 
        public list<string> CATEG { get; set; } 
    }
    public class ESObject1
    {
        [JsonProperty("EVT")]
        public List<myClass> EVT { get; set; }
    }
    public class ESObject0
    {
        [JsonProperty("EVTS")]
        public ESObject1 EVTS { get; set; }
    }
    

    }

    here i call the deserializer :

    ESObject0 globalobject = JsonConvert.DeserializeObject<ESObject0>(json);
    

    But this last code doesnt work, i throws this exception : System.ArgumentException: Could not cast or convert from System.String to System.Collections.Generic.List1[System.String].`

    Instead of list<string> i used string [] and only string nothing seems to work.

    how can i deserialize this object correctly please.

    Thank you.

  • dafriskymonkey
    dafriskymonkey almost 9 years
    I have simplified the json to post the question.
  • Darin Dimitrov
    Darin Dimitrov almost 9 years
    Well, you have simplified it and I showed a working example with it. If your actual JSON is different, I am afraid that I cannot be reading your mind and knowing how it looks like and even less be able to help without actually knowing what the problem is.
  • dafriskymonkey
    dafriskymonkey almost 9 years
    In reality i take the json from an external url like this HttpResponseMessage response = await client.GetAsync("http://donnees.ville.quebec.qc.ca/Handler.a‌​shx?id=69&f=JSON"); then i put it into a string string json = await response.Content.ReadAsStringAsync(); And when i comment the CATEG in my class it works !!!
  • dafriskymonkey
    dafriskymonkey almost 9 years
    sorry for that !! but u r right i know where is my probleme. some of the CATEG r not arrays, they r simple strings :( i dont know how to do it but ill mark ur answer.
  • Darin Dimitrov
    Darin Dimitrov almost 9 years
    I have updated my answer to illustrate how you could use a weakly typed JObject to achieve that.
  • Brian Rogers
    Brian Rogers almost 9 years
    @dafriskymonkey Note that you could also use a JsonConverter to handle this situation. See this answer for an example (different JSON, but same idea).
  • Brian Rogers
    Brian Rogers almost 9 years
    @dafriskymonkey Glad to help.

Related