C# JSON反序列化问题

C# JSON反序列化问题,c#,json,deserialization,C#,Json,Deserialization,我试着在stack和其他存储库中使用其他工程师发布的答案。但是没有成功 [{ "cdr": "1461920017104140-1000", "main_cdr": { "AcctId": "a", "accountcode": "b" }, "sub_cdr_1": { "AcctId": "1", "accountcode": "xx" }, "sub_cdr_2": { "AcctId": "2", "accountcode": "xxx"

我试着在stack和其他存储库中使用其他工程师发布的答案。但是没有成功

[{
"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#中反实现相同的json时,我找不到如何处理动态数量的json “副指挥官”

使用下面的代码,我试图反序列化它

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; }
}
var items=JsonConvert.DeserializeObject(json);
公共类MainCdr
{
公共字符串AcctId{get;set;}
公共字符串accountcode{get;set;}
}
公共类cdrootobject
{
公共字符串cdr{get;set;}
公共MainCdr main_cdr{get;set;}
公共列表子目录{get;set;}
}

在上面的json中,它最多为“sub_cdr_2”,但最多为n。我的代码在main_cdr之前成功,而不是之后成功。

您考虑过使用动态对象作为反序列化结果吗

var result = JsonConvert.DeserializeObject<dynamic>(your_json_string);
var result=JsonConvert.DeserializeObject(您的\u json\u字符串);
无论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);
        }
var result=JsonConvert.DeserializeObject(您的\u json\u字符串);
var item=result.Children().First();
var itemProperties=item.Children();
foreach(itemProperties.Where(x=>x.Name.Contains(“sub_cdr”))中的var itemProperty)
{
Console.WriteLine(itemProperty.Name);
MainCdr data=itemProperty.Value.ToObject();
Console.WriteLine(data.AcctId);
Console.WriteLine(data.accountcode);
}
这一个对你有帮助

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());
var jsonString=“[{\'cdr\”:\'14611920017104140-1000\”,\'main'u cdr\“:{\'AcctId\”:“a\”,“accountcode\”:“b\”,“sub\u cdr\u 1\”:{\'AcctId\”:“1\”,“accountcode\”:“xx\”,“sub\u cdr\u 2\:{\'AcctId\”,“accountcode\”:“xxx\”;
var value=JsonConvert.DeserializeObject(jsonString);
JObject jobj=JObject.Parse(value.First.ToString());
jobj.移除(“cdr”);
var js=JsonConvert.DeserializeObject(jobj.ToString());

正如其他人所提到的,没有办法用任意数量的属性定义属性名称中的索引号

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

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

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'
main\u cdr
sub_cdr
etc,但内容不同。第一个是字符串,其余的是字典本身。这意味着您不能创建一个类来轻松地反序列化它,您必须处理每个元素。或者,您可以反序列化为
动态
变量,并尝试在没有编译器帮助的情况下访问属性,因为它在语法上是有效的json,但并不意味着它在语义上是有效的json。@PepitoSh确实sub_cdr_是尖叫数组…使用动态是资源密集型的。@IteratioN7T不是真的,DLR经过了很好的优化。在本例中,要么处理单独的JSON元素,这是资源密集型的<代码>动态
是不安全的,尽管在运行时之前您无法检测拼写错误和模式更改,但我认为静态将代替
class Cdr
{
    [JsonProperty("AcctId")]
    public string AccountId { get; set; }

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