2015-03-30 15 views
0

我試圖創建一個應用程序,該應用程序使用來自名爲backpack.tf的站點的API。不能存儲在C#中的這個JSON數據?

進出口面臨的一個問題,我對其中的數據將被存儲在文件:

class currencyData 
{ 
    public CurrencyResponse currencyResponse { get; set; } 
} 

public class CurrencyResponse 
{ 
    public int success { get; set; } 
    public int current_time { get; set; } 
    public int raw_usd_value { get; set; } 
    public int usd_currency { get; set; } 
    public int usd_currency_index { get; set; } 

    public Dictionary<string, CurrencyPrices> items { get; set; } 
} 

public class CurrencyPrices 
{ 
    public int currency { get; set; } 
    public int value { get; set; } 
    public int value_high { get; set; } 
    public int value_raw { get; set; } 
    public int value_high_raw { get; set; } 
    public int last_update { get; set; } 
    public int difference { get; set; } 
} 

,基本上我的努力來存儲JSON數據的代碼是這樣的:

//make call to the API and retrieve JSON data 
char[] array1 = { }; 
char[] array2 = { }; 
System.Net.WebClient client = new System.Net.WebClient(); 
System.Net.WebClient client2 = new System.Net.WebClient(); 
client.Headers.Add("key-price", "application/json"); 
client2.Headers.Add("item-data", "application/json"); 
//get the JSON data. 
string test = Encoding.ASCII.GetString(client.UploadData("http://backpack.tf/api/IGetCurrencies/v1/?key=54972a10b88d885f748b4956&appid=440&compress=1", "POST", Encoding.Default.GetBytes(array1))); 
string currencyJSON = Encoding.ASCII.GetString(client2.UploadData("http://backpack.tf/api/IGetPrices/v4/?key=54972a10b88d885f748b4956&appid=440&compress=1", "POST", Encoding.Default.GetBytes(array2))); 

//deserialize json data and store it in rootObject.cs 
rootObject obj = JsonConvert.DeserializeObject<rootObject>(test); 
//same as above but store itt in currencyData.cs 
currencyData currencyData = JsonConvert.DeserializeObject<currencyData>(currencyJSON); 

Response response = obj.response; 
CurrencyResponse currencyResponse = currencyData.currencyResponse; 
//check if the API responds, If not we can display an error message 
if (response.success == 1) { 
    foreach (KeyValuePair<string, Currency> kvp in response.currencies) 
    { 
     string currencyName = kvp.Key; 
     Currency currency = kvp.Value; 
    } 

    foreach (KeyValuePair<string, CurrencyPrices> currencyDataDict in currencyResponse.items) 
    { 
     string itemName = currencyDataDict.Key; 
     CurrencyPrices currencyPrices = currencyDataDict.Value; 
    } 

    Currency kek = new Currency(); 
    outputBox.Text = test; 
} 

rootObject :

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

public class Response 
{ 
    public int success { get; set; } 
    public int current_time { get; set; } 
    public Dictionary<string, Currency> currencies { get; set; } 
    public string name { get; set; } 
    public string url { get; set; } 
} 

public class Currency 
{ 
    public int quality { get; set; } 
    public int priceindex { get; set; } 
    public string single { get; set; } 
    public string plural { get; set; } 
    public int round { get; set; } 
    public string craftable { get; set; } 
    public string tradable { get; set; } 
    public int active { get; set; } 
    public int defindex { get; set; } 
} 

現在我的問題是數據isnt在第二個API調用中檢索,如果我刪除第二foreach循環它將輸出變量測試包含JSON數據,但是如果我保持第二foreach循環中,將事先打印什麼..

感謝,併爲不良用語等 Backpack.tf API doccumentation

+0

它認爲這是不壞的主意使用異步調用您的網絡請求,看看它是否工作。 – 2015-03-30 20:02:11

+0

「rootObject」類的結構是什麼? – 2015-03-30 20:10:15

+0

@persianDeveloper使用rootObject結構更新了我的文章。 – 2015-03-30 20:38:00

回答

3
對不起

有很多問題currencyData

  1. 的JSON返回不文檔(好工作Backpack.tf)所匹配:

    1.1。名爲"Untradable"的字段實際上被返回爲"Non-Tradable"

    1.2。名爲"Uncraftable"的字段實際上返回爲"Non-Craftable"

    1.3。 "Craftable"對象應該在數量字典中返回到價格數據。事實上,他們是有時返回一個陣列

     "Craftable": [ 
         { 
          "currency": "metal", 
          "value": 1.33, 
          "last_update": 1417451879, 
          "difference": -0.11 
         } 
         ] 
    
        But they are *sometimes* returned as a dictionary! 
    
         "Craftable": { 
         "10": { 
          "currency": "usd", 
          "value": 101.49, 
          "value_high": 124.04, 
          "last_update": 1362682641, 
          "difference": 34.719 
         }, 
         "11": { 
          "currency": "earbuds", 
          "value": 1.4, 
          "last_update": 1406474947, 
          "difference": 31.236, 
          "value_high": 1.8 
         }, 
    
  2. 你必須聲明爲int它可以有小數數據幾個領域。他們需要更改爲其他內容,例如decimal

  3. 您的數據模型與記錄的模型不匹配,它比您的數據層級更深。

下面的代碼和對象爲currencyData文檔中顯示兩個JSON和JSON實際上是由調用返回,因爲我想兩者都必須處理讀取。還請注意文檔中的以下qualification

對於每個API密鑰每分鐘只能對此API發出一個請求。此外,響應每隔10分鐘進行一次緩存和更新。

因此,請確保您沒有太頻繁地收到價格。

[DataContract] 
public class currencyData 
{ 
    [DataMember(Name="response")] 
    public CurrencyResponse response { get; set; } 
} 

[DataContract] 
public class CurrencyResponse 
{ 
    public CurrencyResponse() 
    { 
     this.items = new Dictionary<string,ItemPrices>(); 
    } 

    [DataMember] 
    public int success { get; set; } 
    [DataMember] 
    public long current_time { get; set; } 
    [DataMember] 
    public decimal raw_usd_value { get; set; } 
    [DataMember] 
    public string usd_currency { get; set; } 
    [DataMember] 
    public long usd_currency_index { get; set; } 

    [DataMember(EmitDefaultValue = false)] 
    public Dictionary<string, ItemPrices> items { get; set; } 
} 

[DataContract] 
public class ItemPrices 
{ 
    public ItemPrices() 
    { 
     this.prices = new Dictionary<long, ItemTradablePrices>(); 
    } 
    [DataMember(EmitDefaultValue = false)] 
    public Dictionary<long, ItemTradablePrices> prices { get; set; } 
} 

[DataContract] 
public class ItemTradablePrices 
{ 
    [DataMember(EmitDefaultValue = false)] 
    public ItemCraftablePrices Tradable { get; set; } 

    // Sometimes appears as "Non-Tradable", sometimes "Untradable". Handle both 
    [DataMember(EmitDefaultValue = false)] 
    public ItemCraftablePrices Untradable { get; set; } 

    [DataMember(Name = "Non-Tradable", EmitDefaultValue=false)] 
    ItemCraftablePrices NonTradable 
    { 
     get 
     { 
      return null; 
     } 
     set 
     { 
      Untradable = value; 
     } 
    } 
} 

[DataContract] 
public class ItemCraftablePrices 
{ 
    [DataMember(EmitDefaultValue = false)] 
    [JsonConverter(typeof(PrinceIndexDictionaryConverter))] 
    public Dictionary<long, PriceIndex> Craftable { get; set; } 

    // Sometimes appears as "Non-Craftable", sometimes "Uncraftable". Handle both 
    [DataMember(EmitDefaultValue=false)] 
    [JsonConverter(typeof(PrinceIndexDictionaryConverter))] 
    public Dictionary<long, PriceIndex> Uncraftable { get; set; } 

    [DataMember(Name="Non-Craftable", EmitDefaultValue=false)] 
    [JsonConverter(typeof(PrinceIndexDictionaryConverter))] 
    Dictionary<long, PriceIndex> NonCraftable 
    { 
     get 
     { 
      return null; 
     } 
     set 
     { 
      Uncraftable = value; 
     } 
    } 
} 

public class PrinceIndexDictionaryConverter : JsonConverter 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return objectType == typeof(Dictionary<long, PriceIndex>); 
    } 

    public override bool CanWrite 
    { 
     get 
     { 
      return false; 
     } 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     var dict = existingValue as Dictionary<long, PriceIndex>; 
     if (dict == null) 
      dict = new Dictionary<long, PriceIndex>(); 

     switch (reader.TokenType) 
     { 
      case JsonToken.StartArray: 
       List<PriceIndex> list = new List<PriceIndex>(); 
       serializer.Populate(reader, list); 
       for (int i = 0; i < list.Count; i++) 
        dict[i] = list[i]; 
       break; 

      case JsonToken.StartObject: 
       serializer.Populate(reader, dict); 
       break; 

      default: 
       Debug.WriteLine("Unexpected token type " + reader.TokenType.ToString()); 
       throw new InvalidOperationException(); 
     } 
     return dict; 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 
} 

public class PriceIndex 
{ 
    public string currency { get; set; } 
    public decimal value { get; set; } 
    public decimal value_high { get; set; } 
    public decimal value_raw { get; set; } 
    public decimal value_high_raw { get; set; } 
    public long last_update { get; set; } 
    public decimal difference { get; set; } 
} 

然後,你可以使用它像:

public currencyData SendCurrencyQuery() 
    { 
     //make call to the API and retrieve JSON data 
     char[] array2 = { }; 

     using (var client2 = new System.Net.WebClient()) 
     { 
      client2.Headers.Add("item-data", "application/json"); 
      //get the JSON data. 
      string currencyJSON = Encoding.UTF8.GetString(client2.UploadData("http://backpack.tf/api/IGetPrices/v4/?key=54972a10b88d885f748b4956&appid=440&compress=1", "POST", Encoding.UTF8.GetBytes(array2))); 

      //same as above but store itt in currencyData.cs 
      var currencyData = JsonConvert.DeserializeObject<currencyData>(currencyJSON); 

      return currencyData; 
     } 
    }