json newtonsoft:反序列化包含字符串列表的Object

时间:2014-03-22 16:15:41

标签: c# asp.net .net json.net json-deserialization

我对这个json有以下问题:

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

和这个c#类:

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

}

这里我称之为解串器:

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

但是这最后一段代码不起作用,我抛出了这个异常:System.ArgumentException: Could not cast or convert from System.String to System.Collections.Generic.List 1 [System.String] .`

而不是list<string>我使用string []而只使用string似乎没有任何效果。

请如何正确反序列化此对象。

谢谢。

2 个答案:

答案 0 :(得分:13)

这个工作示例说明了:hyour代码似乎没有任何明显的问题:

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

也许你刚刚给反序列化器输入了一个错误的json值,它看起来不像你问题中显示的那样。顺便说一句,我在你的问题中显示的是无效的JSON,因为你在,属性声明之后缺少KEY1


更新:

现在您已经显示了真正的JSON(来自http://donnees.ville.quebec.qc.ca/Handler.ashx?id=69&f=JSON),似乎有一行CATEG不是字符串数组而是一个简单的字符串:

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

现在这是一个非常糟糕的设计,因为它们混合了数组和简单的属性。我担心为了处理这种情况,您需要使用JObject并通过测试实际的基础类型来提取所需的信息。

例如:

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

答案 1 :(得分:4)

我做了很多次这很多次头痛。我的建议是使用json输出并使用类似于此的工具为您编写类(http://json2csharp.com/)。

然后查看任何可以为空的变量,并在需要的地方添加可空类型(例如使用int?for int)。