Question

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.

Was it helpful?

Solution

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>();
    }
}

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top