JSON Deserealizing问题

时间:2018-07-25 07:27:31

标签: c# json deserialization

我尝试了堆栈和其他存储库上其他工程师的已发布答案。但没有成功。

[{
"cdr": "1461920017104140-1000",
"main_cdr": {
    "AcctId": "a",
    "accountcode": "b"
},
"sub_cdr_1": {
    "AcctId": "1",
    "accountcode": "xx"
},
"sub_cdr_2": {
    "AcctId": "2",
    "accountcode": "xxx"
}
}]

这是我从客户端获得的json,它是有效的,我的问题是在C#中将其反义化时,我找不到如何处理动态数的方式 “ sub_cdr”。

使用下面的代码,我试图将其反现实化。

var items = JsonConvert.DeserializeObject<List<CDRRootObject>>(json);
public class MainCdr
{
    public string AcctId { get; set; }
    public string accountcode { get; set; }
}

public class CDRRootObject
{
    public string cdr { get; set; }
    public MainCdr main_cdr { get; set; }
    public List<MainCdr> sub_cdrs { get; set; }
}

在json上方,它最多为“ sub_cdr_2”,但最多为n。我的代码使我成功达到了main_cdr,而不是之后。

3 个答案:

答案 0 :(得分:0)

您是否考虑过将动态对象用作反序列化结果?

var result = JsonConvert.DeserializeObject<dynamic>(your_json_string);

无论您的json中有多少sub_cdr_xxx,这都将起作用。

或者您可以按以下方式使用JArray:

        var result = JsonConvert.DeserializeObject<JArray>(your_json_string);

        var item = result.Children().First();
        var itemProperties = item.Children<JProperty>();
        foreach (var itemProperty in itemProperties.Where(x => x.Name.Contains("sub_cdr")))
        {
            Console.WriteLine(itemProperty.Name);

            MainCdr data = itemProperty.Value.ToObject<MainCdr>();
            Console.WriteLine(data.AcctId);
            Console.WriteLine(data.accountcode);
        }

答案 1 :(得分:0)

这对你有帮助

var jsonString = "[{\"cdr\": \"1461920017104140-1000\",\"main_cdr\":{\"AcctId\": \"a\",\"accountcode\": \"b\"},\"sub_cdr_1\": {\"AcctId\": \"1\",\"accountcode\": \"xx\"},\"sub_cdr_2\": {\"AcctId\": \"2\",\"accountcode\": \"xxx\"}}]";
                var value = JsonConvert.DeserializeObject<JArray>(jsonString);
                JObject jobj = JObject.Parse(value.First.ToString());
                jobj.Remove("cdr");
                var js = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string,string>>>(jobj.ToString());

答案 2 :(得分:0)

正如其他人提到的那样,无法用任意数量的属性定义属性名称中带有一些索引号的方法。

首选解决方案是让您的客户端将“ sub_cdr_xxx”属性更改为数组。

如果这不可能,那么(从类型的角度来看)您可以假设所有对象都是一个数组。因此,如果您使用Json.Net,则可以将其反序列化为IEnumerable<JObject>,然后处理JObject以获得所需的输出:

var result = JsonConvert.DeserializeObject<IEnumerable<JObject>>(json)
    .Select(jobj =>
    {
        var cdr = jobj.TryGetValue("cdr", out var token) ? token.ToObject<string>() : null;
        var mainCdr = jobj.TryGetValue("main_cdr", out token) ? token.ToObject<Cdr>() : null;
        var subCdrs = new List<Cdr>();
        for (var i = 1; jobj.TryGetValue("sub_cdr_" + i, out token); i++)
            subCdrs.Add(token.ToObject<Cdr>());

        return new
        {
            Cdr = cdr, // string
            MainCdr = mainCdr, // Cdr
            SubCdrs = subCdrs // List<Cdr>
        };
    })
    .ToList();

,其中Cdr定义为

class Cdr
{
    [JsonProperty("AcctId")]
    public string AccountId { get; set; }

    [JsonProperty("accountcode")]
    public string AccountCode { get; set; }
}

我个人比较喜欢dynamic