2017-05-07 40 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