2015-04-02 105 views
2

我有这个代码从API链接检索Json字符串。 Json被反序列化并返回到一个文本框。c#反序列化JSON到列表

Additional information: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'GW2_tradingPost.RootObject' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.

To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.

做我的研究,这是因为没有地方存放JSON的,因为它不是一个列表:只要有只有1 Json的价值,正在返回多个值也与此错误崩溃完美的作品。

我已经试过这段代码和各种类似的代码。

List<RootObject> list = JsonConvert.DeserializeObject<List<RootObject>>(jsonReader.ToString()); 
return list; 

这将返回错误:

Error 1 Cannot implicitly convert type 'System.Collections.Generic.List' to 'GW2_tradingPost.RootObject' e:\mega\gw2_tradingpost\gw2_tradingpost\api_request.cs 34

,我不完全明白这意味着什么。

这是我的完整代码。

api_Request.cs

public class api_Request 
    { 
     public RootObject GetApi(string url) 
     { 

      HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); 

      try 
      { 
       WebResponse response = request.GetResponse(); 
       using (Stream responseStream = response.GetResponseStream()) 
       { 
       StreamReader reader = new StreamReader(responseStream, Encoding.UTF8); 
       var jsonReader = new JsonTextReader(reader); 
       var serializer = new JsonSerializer(); 
       return serializer.Deserialize<RootObject>(jsonReader); 
      } 
      } 
      catch (WebException ex) 
      { 
       WebResponse errorResponse = ex.Response; 
       using (Stream responseStream = errorResponse.GetResponseStream()) 
       { 
        StreamReader reader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8")); 
        String errorText = reader.ReadToEnd(); 
        // log errorText 
       } 
       throw; 
      } 
     } 

    } 


    public class Buy 
    { 
     public int listings { get; set; } 
     public int unit_price { get; set; } 
     public int quantity { get; set; } 
    } 

    public class Sell 
    { 
     public int listings { get; set; } 
     public int unit_price { get; set; } 
     public int quantity { get; set; } 
    } 

    public class RootObject 
    { 
     public int id { get; set; } 
     public List<Buy> buys { get; set; } 
     public List<Sell> sells { get; set; } 
    } 

Form1.cs的

private void button1_Click(object sender, EventArgs e) 
     { 
      RootObject RootObject = new RootObject(); 
      api_Request api_Request = new api_Request(); 
      richTextBox1.Text = api_Request.GetApi("https://api.guildwars2.com/v2/commerce/listings").id.ToString(); 
     } 

在此JSON是一个单一的ID,所以这个工作正常。 https://api.guildwars2.com/v2/commerce/listings/19684

但是,当检索多个ID像这里,它打破。 https://api.guildwars2.com/v2/commerce/listings

+0

我们可以看到你正在试图解析JSON的例子上市?当你试图反序列化到一个根对象列表,但在根对象级别,它试图解析一个列表,所以我的想法是,你有嵌套列表 – 2015-04-02 15:04:01

+0

@DavidWatts我已编辑帖子,在底部有2个Api链接会告诉你Json的样子。 – 2015-04-02 15:08:11

+1

他们返回完全不同的东西。多个ID的链接返回一个整数的数组,我猜测是单个列表的ID。看起来您必须查询所有列表,然后为每个列表运行另一个列表以获取实际对象。尝试一下,如果它有效,我会提出一个答案,否则,我会继续尝试和帮助 – 2015-04-02 15:10:11

回答

1

这里有一个简单的解决方案,使所有的ID,将时间的实际量虽然要经过所有这些

List<RootObject> rootobject = new List<RootObject>(); 
    using (var webclient = new WebClient()) 
    { 
     var Ids = webclient.DownloadString(" https://api.guildwars2.com/v2/commerce/listings"); 
     foreach (var id in Ids.Substring(1, s.Length-2).Split(',')) 
     { 
      string url = string.Format("{0}/{1}","https://api.guildwars2.com/v2/commerce/listings",id); 
      var res = webclient.DownloadString(url); 
      var jsonObject = JsonConvert.DeserializeObject<RootObject>(res); 
      rootobject.Add(jsonObject); 
     } 


    } 
0

您为多个ID提供的链接返回一个整数数组。我建议解析这是这样:

var ids = JsonConvert.DeserializeObject<int[]>(jsonReader.ToString()) 

正如你所说,你的代码适用于单个项目,这样你就可以使用现有的代码,这不是打https://api.guildwars2.com/v2/commerce/listings,将被打https://api.guildwars2.com/v2/commerce/listings/{id}每个单独的请求,其您可以使用string.Format()添加需要的地方。

认真考虑在int[]中你实际上想要获取根对象的ID有多少,因为从我看到它返回的结果来看,你将会发出很多请求。