2017-05-07 41 views
0

我试图从防暴API数据解析到C#对象 https://developer.riotgames.com/api-methods/#lol-static-data-v1.2/GET_getChampionList分析动态的Json数据结构到对象C#/ dotnet的核心

 HttpClient client = new HttpClient(); 
     client.DefaultRequestHeaders.Accept.Clear(); 
     client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 
     HttpResponseMessage response = await client.GetAsync("https://global.api.riotgames.com/api/lol/static-data/EUW/v1.2/champion?champData=allytips%2Cenemytips%2Cimage%2Ctags&dataById=true&api_key=###################"); 

     if (response.IsSuccessStatusCode) 
     { 
      var streamTask = response.Content.ReadAsStreamAsync(); 
      var stringJson = await response.Content.ReadAsStringAsync(); 
      var serializer = new DataContractJsonSerializer(typeof(ChampionWrapper)); 
      var champions = serializer.ReadObject(await streamTask) as ChampionWrapper; 
     } 

到目前为止,我只得到转换的类型和版本。
数据结构看起来如下:

{ 
    "type": "champion", 
    "version": "7.9.1", 
    "data": { 
    "89": { 
     "id": 89, 
     "key": "Leona", 
     "name": "Leona", 
     "title": "the Radiant Dawn", 
     "image": { 
     "full": "Leona.png", 
     "sprite": "champion2.png", 
     "group": "champion", 
     "x": 0, 
     "y": 0, 
     "w": 48, 
     "h": 48 
     }, 
     "allytips": [ 
     "Lead the charge and mark your foes with Sunlight before your allies deal damage.", 
     "Shield of Daybreak and Zenith Blade form a powerful offensive combo.", 
     "You can absorb a huge amount of damage using Eclipse, but you must stay near enemies to gain the bonus duration." 
     ], 
     "enemytips": [ 
     "When Leona activates Eclipse, you have three seconds to get away from her before she deals damage.", 
     "Only foes in the center of Solar Flare get stunned, so you can often avoid this if you're quick." 
     ], 
     "tags": [ 
     "Tank", 
     "Support" 
     ] 
    }, 
    "110": { 
     "id": 110, 
     "key": "Varus", 
     "name": "Varus", 
     "title": "the Arrow of Retribution", 
     "image": { 
     "full": "Varus.png", 
     "sprite": "champion3.png", 
     "group": "champion", 
     "x": 336, 
     "y": 96, 
     "w": 48, 
     "h": 48 
     }, 

到目前为止,我有一个ChampionWrapper:是没有得到填充

public class ChampionWrapper 
{ 
    public string type { get; set; } 
    public string version { get; set; } 
    public List<ChampionData> data { get; set; } 

    public ChampionWrapper() 
    { 

    } 
} 

列表ChampionData。版本和类型正在工作。

public List<string> id {get;set;} 
    public List<Champion> id { get; set; } 
    public ChampionData() 
    { 

    } 

这里是冠军对象

public string Id { get; set; } 
    public string Name { get; set; } 
    public string Title { get; set; } 
    public List<string> AllyTips { get; set; } 
    public List<string> EnemyTips { get; set; } 
    public List<string> Tags { get; set; } 

    public Champion() 
    { 

    } 

我的主要问题是动态datastruce

"data": { 
    "89": { .... } 
    "110": { .... } 

数是冠军的只是ID。

回答

0

找到解决方案:

  DataContractJsonSerializerSettings settings = new DataContractJsonSerializerSettings(); 
      settings.UseSimpleDictionaryFormat = true; 

整个事情:

 HttpClient client = new HttpClient(); 
     client.DefaultRequestHeaders.Accept.Clear(); 
     client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 
     HttpResponseMessage response = await client.GetAsync("https://global.api.riotgames.com/api/lol/static-data/EUW/v1.2/champion?champData=allytips%2Cenemytips%2Cimage%2Ctags&dataById=true&api_key=###########"); 

     if (response.IsSuccessStatusCode) 
     { 
      DataContractJsonSerializerSettings settings = new DataContractJsonSerializerSettings(); 
      settings.UseSimpleDictionaryFormat = true; 

      var streamTask = response.Content.ReadAsStreamAsync(); 
      var stringJson = await response.Content.ReadAsStringAsync(); 
      var serializer = new DataContractJsonSerializer(typeof(ChampionWrapper), settings); 
      var champions = serializer.ReadObject(await streamTask) as ChampionWrapper; 
     } 

而且ofcourse改变列表来解释:

public class ChampionWrapper 
{ 
    public string type { get; set; } 
    public string version { get; set; } 
    public Dictionary<string, Champion> data { get; set; } 
} 
1

您没有使用正确的类来反序列化您的对象。在你的JSON的data属性不是List,而更像是Dictionary

public class ChampionWrapper 
{ 
    public string type { get; set; } 
    public string version { get; set; } 
    public Dictionary<string, Champion> data { get; set; } 
} 

[编辑]

我相信你是反序列化从Json的响应方式复杂化,而不是,反序列化使用手动DataContractSerializer你应该使用ReadAsAsync<T>扩展方法的响应,以获得您的类的对象:

if(response.IsSuccessStatusCode) 
{ 
    var champions = await response.Content.ReadAsAsync<ChampionWrapper>(); 
} 

此扩展方法位于Microsoft.AspNet.WebApi.Client nuget package内部,请记住在使用它之前添加它。

+0

嗨。它仍然无法正常工作,即使当改成Dictionary Kiksen

+0

@Kiksen更新了答案,包括一个更好的方式来反序列化你的回应 –

+0

- >我发现了这个。问题是我正在使用DotNetCore,它不支持ReadAsAsync。 – Kiksen