【问题标题】:Newtonsoft parse Json array using class data structureNewtonsoft 使用类数据结构解析 Json 数组
【发布时间】:2014-11-30 19:10:52
【问题描述】:

我一直在解析 JSon,无法弄清楚。它在 IDictionary 的数组中给了我 NULL。这是我所拥有的:

 {
 "response" : {
  "method" : "my.current.method",
  "result" : {
     "current_calls" : {
        "current_call" : [
           {
              "provider" : "ABC",
              "start_time" : "2014-11-30 02:24:52",
              "duration" : "5",
              "to_caller_id_number" : "800",
              "state" : "ivr",
              "from_caller_id_name" : "<unknown>",
              "to_caller_id_name" : "Main Answer Queue",
              "format" : "ulaw",
              "from_caller_id_number" : "1234567890",
              "id" : "SIP/1234567890-08682a00"
           },
           {
              "provider" : "ThinkTel",
              "start_time" : "2014-11-30 02:24:50",
              "duration" : "7",
              "to_caller_id_number" : "800",
              "state" : "ivr",
              "from_caller_id_name" : "<unknown>",
              "to_caller_id_name" : "Main Answer Queue",
              "format" : "ulaw",
              "from_caller_id_number" : "0123456789",
              "id" : "SIP/0123456789-08681350"
           }
        ],
        "total_items" : "2"
     }
  }
 }
}

然后我的 C# 代码中有以下内容:

    public class Data
    {
        public Response response { get; set; }
    }

    public class Response
    {
        public string method { get; set; }
        public Result result { get; set; }

    }

    public class Result
    {
        public CurrentCalls current_calls { get; set; }
    }

    public class CurrentCalls
    {
        public List<IDictionary<string, Current_call>> current_calls { get; set; }
        public int total_items { get; set; }
    }

    public class  Current_call
    {
        public string provider { get; set; }
        public DateTime start_time { get; set; }
        public int duration { get; set; }
        public string to_caller_id_number { get; set; }
        public string state { get; set; }
        public string from_caller_id_name { get; set; }
        public string to_caller_id_name { get; set; }
        public string format { get; set; }
        public string from_caller_id_number { get; set; }
        public string id { get; set; }
    }

    public class Data
    {
        public Response response { get; set; }
    }

    public class Response
    {
        public string method { get; set; }
        public Result result { get; set; }

    }

    public class Result
    {
        public CurrentCalls current_calls { get; set; }
    }

    public class CurrentCalls
    {
        public List<IDictionary<string, Current_call>> current_calls { get; set; }
        public int total_items { get; set; }
    }

    public class  Current_call
    {
        public string provider { get; set; }
        public DateTime start_time { get; set; }
        public int duration { get; set; }
        public string to_caller_id_number { get; set; }
        public string state { get; set; }
        public string from_caller_id_name { get; set; }
        public string to_caller_id_name { get; set; }
        public string format { get; set; }
        public string from_caller_id_number { get; set; }
        public string id { get; set; }
    }    

我像这样反序列化它:

   allCalls = JsonConvert.DeserializeObject<Data>(json);

然后我尝试在以下情况下使用它:

        if (parser.allCalls.response.result.current_calls.current_calls != null)
        {
            foreach (var defindex in parser.allCalls.response.result.current_calls.current_calls)
            {
                foreach (var call in defindex) { 
                        System.IO.StreamWriter file = new System.IO.StreamWriter("c:\\A\\Testing\\test" + i + ".txt");
                        file.WriteLine("Current call:" );
                        file.WriteLine("\t Provider: " + call.Value.provider);
                        file.WriteLine("\t Start Tine: " + call.Value.start_time);
                        file.WriteLine("\t Duration: " + call.Value.duration);
                        file.WriteLine("\t To Caller: " + call.Value.to_caller_id_number);
                        file.WriteLine("\t State: " + call.Value.state);
                        file.WriteLine("\t From: " + call.Value.from_caller_id_name);
                        file.WriteLine("\t To Name: " + call.Value.to_caller_id_name);
                        file.WriteLine("\t Format: " + call.Value.format);
                        file.WriteLine("\t From Caller ID: " + call.Value.from_caller_id_number);
                        file.WriteLine("\t ID: " + call.Value.id);
                        file.Close();
                }
            }
        }

所以 Total Items 的值为 2 ok。我似乎无法计算 IDictionary 的数组。它是空的。 请帮忙。 (顺便说一句,这是使用 Newtonsoft)

【问题讨论】:

  • 抱歉,刚刚意识到我粘贴了我的 Data 类两次
  • 所以我设法使用 json2csharp.com 创建了正确的结构,但现在在这段代码中出现异常: var json = SwitchvoxGetCalls("{\"request\": {\"method\": \" switchvox.currentCalls.getList\", \"参数\": {}}}"); this.allCalls = JsonConvert.DeserializeObject(json);返回这个;这会抛出无法将当前 JSON 数组(例如 [1,2,3])反序列化为具有复杂和嵌套对象的类型

标签: c# arrays json json.net idictionary


【解决方案1】:

这是一个有效的 dotNetFiddle:https://dotnetfiddle.net/3UpWwO

加载小提琴页面后等待几秒钟,然后查看底部的控制台输出窗格。

这是解决方案的完整代码。

using System;               
using System.Collections.Generic;
using System.Linq;
    
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
                    
public class Program
{
    // Solution to SO Question: http://stackoverflow.com/q/27217095/325521
    // This Answer: http://stackoverflow.com/a/27238215/325521
    // Author: Shiva Manjunath
    // SO Profile: http://stackoverflow.com/users/325521/shiva
    public static void Main()
    {       
       string jsonString = @"{
                             ""response"" : {
                              ""method"" : ""my.current.method"",
                              ""result"" : {
                                 ""current_calls"" : {
                                    ""current_call"" : [
                                       {
                                          ""provider"" : ""ABC"",
                                          ""start_time"" : ""2014-11-30 02:24:52"",
                                          ""duration"" : ""5"",
                                          ""to_caller_id_number"" : ""800"",
                                          ""state"" : ""ivr"",
                                          ""from_caller_id_name"" : ""<unknown>"",
                                          ""to_caller_id_name"" : ""Main Answer Queue"",
                                          ""format"" : ""ulaw"",
                                          ""from_caller_id_number"" : ""1234567890"",
                                          ""id"" : ""SIP/1234567890-08682a00""
                                       },
                                       {
                                          ""provider"" : ""ThinkTel"",
                                          ""start_time"" : ""2014-11-30 02:24:50"",
                                          ""duration"" : ""7"",
                                          ""to_caller_id_number"" : ""800"",
                                          ""state"" : ""ivr"",
                                          ""from_caller_id_name"" : ""<unknown>"",
                                          ""to_caller_id_name"" : ""Main Answer Queue"",
                                          ""format"" : ""ulaw"",
                                          ""from_caller_id_number"" : ""0123456789"",
                                          ""id"" : ""SIP/0123456789-08681350""
                                       }
                                    ],
                                    ""total_items"" : ""2""
                                 }
                                }
                              }
                            }";
        
        Console.WriteLine("BEGIN JSON Deserialization\n");
        var callData = Newtonsoft.Json.JsonConvert.DeserializeObject<CallData>(jsonString);
            // extract the current list of calls in the response
        var callsList = callData.response.result.current_calls.current_call;
            // check if there are any calls
        if (callsList.Any())
        {
            Console.WriteLine("    Number of Call Records Received via JSON = {0}\n", callsList.Count());
            int i = 1;
                // print out call details for each call.
            foreach(var oneCall in callsList)
            {
                Console.WriteLine("    Call #" + i);
                Console.WriteLine("      provider: " + oneCall.provider);
                Console.WriteLine("      start_time: " + oneCall.start_time);
                Console.WriteLine("      duration: " + oneCall.duration);
                Console.WriteLine("      to_caller_id_number: " + oneCall.to_caller_id_number);
                Console.WriteLine("      state: " + oneCall.state);
                Console.WriteLine("      from_caller_id_name: " + oneCall.from_caller_id_name);
                Console.WriteLine("      to_caller_id_name: " + oneCall.to_caller_id_name);
                Console.WriteLine("      format: " + oneCall.format);
                Console.WriteLine("      from_caller_id_number: " + oneCall.from_caller_id_number);
                Console.WriteLine("      id: {0}\n", oneCall.id);
                i++;
            }           
        }
        Console.WriteLine("\nEND JSON Deserialization");
    }
}

public class CurrentCall
{
    public string provider { get; set; }
    public string start_time { get; set; }
    public string duration { get; set; }
    public string to_caller_id_number { get; set; }
    public string state { get; set; }
    public string from_caller_id_name { get; set; }
    public string to_caller_id_name { get; set; }
    public string format { get; set; }
    public string from_caller_id_number { get; set; }
    public string id { get; set; }
}

public class CurrentCalls
{
    public List<CurrentCall> current_call { get; set; }
    public string total_items { get; set; }
}

public class Result
{
    public CurrentCalls current_calls { get; set; }
}

public class Response
{
    public string method { get; set; }
    public Result result { get; set; }
}

public class CallData
{
    public Response response { get; set; }
}

请注意,您可以在 POCO 上使用 JsonProperty,以便在 C# 类中摆脱 _ 下划线和小写等。

例如:

public class Result
{
    [JsonProperty(PropertyName = "current_calls")]
    public CurrentCalls Calls { get; set; }
}

【讨论】:

  • 谢谢@Shiva。使用我最初的解决方案,这整个事情实际上是一个从交换机服务器读取动态 Json 的服务。小问题是反序列化器会在有 1 次调用或 0 次调用的情况下抛出错误。当有 1 次调用时,Json 中的内部数组不存在。当 0 - current_calls 消失时。这就是: current_calls 有时是一个数组,有时是一个数组。我找到了一个很好的方法here 来解决这个“有时”的问题。
  • 我明白了。但是你在这里描述的是一个单独的问题/问题。我已经回答了您最初的问题,即没有在数组中获取任何通话记录。
  • 谢谢,这行得通。这也很清楚。我很感激你在这方面的时间!我在实施您的建议后遇到的问题确实是原始问题的扩展,我也确实单独找到了合适的解决方案。
猜你喜欢
  • 2014-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 2020-06-12
  • 2016-06-16
相关资源
最近更新 更多