I'm trying to deserialize json that is sometimes array and some times objects (look on "Craftable"):
Dont look at the codes here i made a runable version to make that easier to understand the problem, please scroll down, tnx anyway :-)
Sometime this is an objects:
"prices": {
    "5": {
        "Tradable": {
            "Craftable": {
                "10": {
                    "currency": "earbuds",
                    "value": 4.5,
                    "last_update": 1404866151,
                    "difference": 76.95,
                    "value_high": 5
                },
                "11": {
                    "currency": "earbuds",
                    "difference": 7.0965,
                    "last_update": 1400430312,
                    "value": 1.8,
                    "value_high": 2.1
                }
and sometimes it's an array with one cell:
"A Distinctive Lack of Hue": {
    "defindex": [
        5040
    ],
    "prices": {
        "6": {
            "Tradable": {
                "Craftable": [
                    {
                        "currency": "keys",
                        "value": 2,
                        "last_update": 1393465587,
                        "difference": 0.35275
                    }
              ]
I'm try to shove it into these classes:
public class Tradable
{
    [JsonProperty("Craftable")]
    [JsonConverter(typeof(CategoryConverter))]
    public IDictionary<string, Craftable> Craftable { get; set; }
}
public class Craftable
{
    public IDictionary<string, Priceindex> Priceindex { get; set; }
}
But I'm getting this exception:
Error setting value to 'Craftable' on 'SteamTrade.PriceSchema+Tradable'.
(e.InnerException).Message:
Unable to cast object of type 'Craftable' to type 'System.Collections.Generic.IDictionary`2[System.String,SteamTrade.PriceSchema+Craftable]'.
This is my convertor:
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
    JToken token = JToken.Load(reader);
    if (token.Type == JTokenType.Object)
    {
        return token.ToObject<Craftable>();
    }
    else if (token.Type == JTokenType.Array)
    {
        return token.First.ToObject<Craftable>();
    }
    throw new JsonSerializationException("Unexpected token type: " + token.Type.ToString());
}
Other info which could help, the Priceindex class and the value inside the "token"when in side the convertor [I cant post the image cuz I don't have enough Rep, should i link it from outside website?]:
public class Priceindex
{
    [JsonProperty("currency")]
    public string currency { get; set; }
    [JsonProperty("value")]
    public decimal value { get; set; }
    [JsonProperty("value_old")]
    public Priceindex value_old { get; set; }
    [JsonProperty("value_high")]
    public string value_high { get; set; }
    //[JsonProperty("value_raw")]
    //public string currency { get; set; }
    [JsonProperty("last_update")]
    public int last_update { get; set; }
    [JsonProperty("difference")]
    public decimal difference { get; set; }
}
EDIT: To understande that scheme easier you can see "http://backpack.tf/api/prices"
RUNABLE CODE:
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using System.Net;
using System.IO;
using System.Threading;
using SteamTrade;
using Newtonsoft.Json.Linq;
namespace SteamTrade
{
    /// <summary>
    /// This class represents the TF2 Item prices schema from backpack.tf as deserialized from its
    /// JSON representation.
    /// </summary>
    public class PriceSchema
    {
        /// <summary>
        /// Fetches the Tf2 Item schema.
        /// </summary>
        /// <param name="apiKey">The API key.</param>
        /// <returns>A  deserialized instance of the Item Schema.</returns>
        /// <remarks>
        /// The schema will be cached for future use if it is updated.
        /// </remarks>
        [STAThread]
        public static void Main(string[] args)
        {
            // Convert the Json
            string result = File.ReadAllText("Json.txt");
            Data schemaResult = JsonConvert.DeserializeObject<Data>(result);
        }
        public class Data
        {
            [JsonProperty("response")]
            public Response response { get; set; }
        }
        public class Response
        {
            [JsonProperty("success")]
            public int success { get; set; }
            [JsonProperty("message ")]
            public string message { get; set; }
            [JsonProperty("current_time")]
            public string current_time { get; set; }
            [JsonProperty("raw_usd_value")]
            public string raw_usd_value { get; set; }
            [JsonProperty("usd_currency ")]
            public string usd_currency { get; set; }
            [JsonProperty("usd_currency_index")]
            public int usd_currency_index { get; set; }
            [JsonProperty("items")]
            public IDictionary<string, ItemName> items { get; set; }
            //public Items[] items { get; set; }
        }
        public class Items
        {
            public ItemName ItemName { get; set; }
        }
        public class ItemName
        {
            [JsonProperty("defindex")]
            public int[] Defindex { get; set; }
            [JsonProperty("prices")]
            public IDictionary<string, QualityInteger> Prices { get; set; }
        }
        public class Prices
        {
            public QualityInteger QualityInteger { get; set; }
        }
        public class QualityInteger
        {
            public Tradable Tradable { get; set; }
            public Untradable Untradable { get; set; }
        }
        public class Tradable
        {
            [JsonProperty("Craftable")]
            [JsonConverter(typeof(CategoryConverter))]
            public IDictionary<string, Craftable> Craftable { get; set; }
            //public List<Craftable> craftable { get; set; }
            [JsonProperty("Non-Craftable")]
            public List<Uncraftable> Uncraftable { get; set; }
        }
        public class Untradable
        {
            [JsonProperty("Craftable")]
            [JsonConverter(typeof(CategoryConverter))]
            public Craftable Craftable { get; set; }
            //public IDictionary<string, Craftable> Craftable { get; set; }
            //public List<Craftable> craftable { get; set; }
            [JsonProperty("Non-Craftable")]
            public List<Uncraftable> Uncraftable { get; set; }
        }
        #region Overrdie Reader
        class CategoryConverter : JsonConverter
        {
            public override bool CanConvert(Type objectType)
            {
                return (objectType == typeof(string[]));
            }
            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
            {
                JToken token = JToken.Load(reader);
                if (token.Type == JTokenType.Object)
                {
                    return token.ToObject<Craftable>();
                }
                else if (token.Type == JTokenType.Array)
                {
                    return token.First.ToObject<Craftable>();
                }
                throw new JsonSerializationException("Unexpected token type: " + token.Type.ToString());
            }
            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
            {
                throw new NotImplementedException();
            }
        }
        #endregion
        public class Craftable
        {
            //public List<Priceindex> Priceindex { get; set; }
            public IDictionary<string, Priceindex> Priceindex { get; set; }
            //public Priceindex Priceindex { get; set; }
        }
        public class Uncraftable
        {
            //public Priceindex Priceindex { get; set; }
            public IDictionary<string, Priceindex> Priceindex { get; set; }
            //public Priceindex Priceindex { get; set; }
        }
        public class Priceindex
        {
            [JsonProperty("currency")]
            public string currency { get; set; }
            [JsonProperty("value")]
            public decimal value { get; set; }
            [JsonProperty("value_old")]
            public Priceindex value_old { get; set; }
            [JsonProperty("value_high")]
            public string value_high { get; set; }
            //[JsonProperty("value_raw")]
            //public string currency { get; set; }
            [JsonProperty("last_update")]
            public int last_update { get; set; }
            [JsonProperty("difference")]
            public decimal difference { get; set; }
        }
    }
}
and the text file contains an example: from here V:
{
    "response": {
        "success": 1,
        "current_time": 1405635143,
        "raw_usd_value": 0.245,
        "usd_currency": "metal",
        "usd_currency_index": 5002,
        "items": {
            "A Brush with Death": {
                "defindex": [
                    30186
                ],
                "prices": {
                    "6": {
                        "Tradable": {
                            "Craftable": [
                                {
                                    "currency": "metal",
                                    "value": 3.66,
                                    "last_update": 1405098842,
                                    "difference": -0.34
                                }
                            ]
                        }
                    }
                }
            },
            "A Rather Festive Tree": {
                "defindex": [
                    341
                ],
                "prices": {
                    "5": {
                        "Tradable": {
                            "Craftable": {
                                "10": {
                                    "currency": "earbuds",
                                    "value": 4.5,
                                    "last_update": 1404866151,
                                    "difference": 76.95,
                                    "value_high": 5
                                },
                                "11": {
                                    "currency": "earbuds",
                                    "difference": 7.0965,
                                    "last_update": 1400430312,
                                    "value": 1.8,
                                    "value_high": 2.1
                                },
                            }
                        }
                    "6": {
                        "Tradable": {
                            "Craftable": [
                                {
                                    "currency": "metal",
                                    "value": 1.66,
                                    "last_update": 1400374538,
                                    "difference": -0.17
                                }
                            ],
                            "Non-Craftable": [
                                {
                                    "currency": "metal",
                                    "value": 1.33,
                                    "last_update": 1400368707,
                                    "difference": -0.22
                                }
                            ]
                        }
                    }
                }
            },
        }
    }
}
end of file here^