【问题标题】:How to populate a Generic List from a JSON string using C#.NET?如何使用 C#.NET 从 JSON 字符串填充通用列表?
【发布时间】:2013-12-25 12:58:48
【问题描述】:

我正在尝试在 C# 中填充一个列表,但值没有出现在数组中 - 尽管在我尝试使用数组索引设置变量之前它不会引发错误(因为它当然超出了范围) .

这是我在调试时看到的确切返回字符串strJSON

strJSON "{\"id\":34379899,\"name\":\"Revelation22\",\"profileIconId\":547,\"summonerLevel\":30,\"revisionDate\":1387913628000}"

为什么列表(数组)没有填充?

这是 KeyValue.cs 的代码(老实说我还不知道为什么它需要另一个类)

namespace LoLSummoner
{
    public class KeyValue
    {
        public int id {get; set;}
        public string name {get; set;}
        public int profileIconId {get; set;}
        public int summonerLevel {get; set;}
        public int revisionDate {get; set;}
    }
}

这是 Summoner.svc.cs 的代码

namespace LoLSummoner
{
    public class Summoner : ISummoner
    {

        public int GetSummonerID(string SummonerName)
        {
            int summonerId = 0;

            WebClient client = new WebClient();
            string strJSON = client.DownloadString("http://prod.api.pvp.net/api/lol/na/v1.2/summoner/by-name/" + SummonerName + "?api_key=xxxx");

            JavaScriptSerializer js = new JavaScriptSerializer();

            KeyValue[] arrJSON = js.Deserialize<List<KeyValue>>(strJSON).ToArray();

            summonerId = Convert.ToInt32(arrJSON.GetValue(0));

            return summonerId;
        }
    }
}

【问题讨论】:

    标签: c# json wcf


    【解决方案1】:

    您的 JSON 包含单个对象,而不是数组。
    所以只能反序列化为KeyValue

    【讨论】:

    • 那我应该用另一种方式解析吗?我不能只拆分字符串吗:
    • @JoJo:你没有名单,所以不要假装你有。 js.Deserialize&lt;KeyValue&gt;(strJSON)
    • 抱歉收到No parameterless constructor defined for type 我如何才能得到问题的答案?我应该再问一次吗?我需要研究什么才能知道出了什么问题?
    • 为哪种类型定义的?堆栈跟踪是什么?
    【解决方案2】:
    1. 您的RevisionDate 属性必须是long,因为1387913628000 是您尝试反序列化的值,超出了int 范围。

    2. 您的 JSON 仅包含一个 KeyValue 对象的信息,而不是那里的数组,因此您必须将其反序列化为 KeyValue,而不是 KeyValue[]

      KeyValue item = js.Deserialize<KeyValue>(strJSON);
      
    3. 拥有KeyValue 实例,您可以使用标准属性语法返回ID

      return item.id;
      

    我发现这段代码有效:

    public class KeyValue
    {
        public int id { get; set; }
        public string name { get; set; }
        public int profileIconId { get; set; }
        public int summonerLevel { get; set; }
        public long revisionDate { get; set; }
    }
    
    static void Main(string[] args)
    {
        var input = @"{""id"":34379899,""name"":""Revelation22"",""profileIconId"":547,""summonerLevel"":30,""revisionDate"":1387913628000}";
    
        JavaScriptSerializer js = new JavaScriptSerializer();
    
         var item = js.Deserialize<KeyValue>(input);
    
         var summonerId = item.id;
    }
    

    【讨论】:

      【解决方案3】:

      我还不知道为什么它需要另一个类

      你不需要那个类。它认为最简单的方法是将您的 json 直接反序列化为 Dictionary&lt;string, object&gt;

      var strJSON = "{\"id\":34379899,\"name\":\"Revelation22\",\"profileIconId\":547,\"summonerLevel\":30,\"revisionDate\":1387913628000}";
      
      var dict = new JavaScriptSerializer()
                 .Deserialize<Dictionary<string, object>>(strJSON);
      
      Console.WriteLine(dict["name"]);
      Console.WriteLine(ToDateTime((long)dict["revisionDate"]));
      

      DateTime ToDateTime(long l)
      {
          return  new DateTime(1970, 1, 1).AddMilliseconds(l);
      }
      

      【讨论】:

        【解决方案4】:

        如前所述,如果没有键入 long,revisionDate 将导致运行时绑定异常。

        public class KeyValue
        {
            public int id { get; set; }
            public string name { get; set; }
            public int profileIconId { get; set; }
            public int summonerLevel { get; set; }
            public long revisionDate { get; set; }
        }
        

        除此之外,您可能希望尝试进行简单的检测,以便将其反序列化为对象或对象数组(如果将来名称不再唯一)。

        public int GetSummonerID(string SummonerName)
        {
            int summonerId = 0;
        
            WebClient client = new WebClient();
            string strJSON = client.DownloadString("http://prod.api.pvp.net/api/lol/na/v1.2/summoner/by-name/" + SummonerName + "?api_key=xxxx");
        
            JavaScriptSerializer js = new JavaScriptSerializer();
        
            if(strJSON[0] == '[')
            {
                return js.Deserialize<KeyValue[]>(strJSON)[0].id;
            }
            else
            {
                return js.Deserialize<KeyValue>(strJSON).id;
            }
            return summonerId;
        }
        

        【讨论】:

          【解决方案5】:

          需要注意的是,您的 JSON 字符串仅包含一个 KeyValue,而不是它们的列表。另一个问题是修订日期太大,无法放入 32 位 int,因此请考虑使用 long。

          这里有一些示例代码,可以读取您的示例字符串并打印出一些值。

          public class KeyValue
          {
              public int id { get; set; }
              public string name { get; set; }
              public int profileIconId { get; set; }
              public int summonerLevel { get; set; }
              public long revisionDate { get; set; }
          }
          
          static void Main(string[] args)
          {
              var strJSON = "{\"id\":34379899,\"name\":\"Revelation22\",\"profileIconId\":547,\"summonerLevel\":30,\"revisionDate\":1387913628000}";
              var serializer = new JavaScriptSerializer();
          
              var keyValue = serializer.Deserialize<KeyValue>(strJSON);
              var id = keyValue.id;
              var name = keyValue.name;
              var level = keyValue.summonerLevel;
          
              Console.WriteLine("Summoner name:{0}, Id:{1}, Level:{2}", name, id, level);
              Console.Read();
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-08-02
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多