无法将此JSON数据存储在c#中



我试图从一个名为backpack.tf.的站点创建一个使用API的应用程序

我面临一个问题,我有一个存储数据的文件:

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; }
}

现在我的问题是数据没有在第二个API调用中检索,如果我删除第二个foreach循环,它将输出包含JSON数据的变量Test。但是,如果我保留第二个foreach循环,则它将不打印任何内容。。

提前表示感谢,并对措辞不当等表示歉意。背包.tf API文档

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,因为我认为两者都必须处理。还应注意文件中的以下资格:

每个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;
        }
    }

相关内容

  • 没有找到相关文章

最新更新