razki
razki

Reputation: 1229

Cannot convert type 'Newtonsoft.Json.Linq.JProperty' to 'Newtonsoft.Json.Linq.JObject'

Currently trying to work with the fixer.io API to create a currency conversion in C#.

I've used a similar method to below whilst parsing the JSON from a twitter API and that worked without any problems, I'm not entirely sure whats going on here.

Example of the JSON returned from the API:

 {
    "base": "EUR",
    "date": "2016-05-05",
    "rates": {
        "AUD": 1.5266,
        "BGN": 1.9558,
        "BRL": 4.0282,
        "CAD": 1.4665,
        "CHF": 1.1018,
        "CNY": 7.441,
        "CZK": 27.028,
        "DKK": 7.4401,
        "GBP": 0.7886,
        "HKD": 8.8775,
        "HRK": 7.515,
        "HUF": 312.84,
        "IDR": 15260.95,
        "ILS": 4.3221,
        "INR": 76.0745,
        "JPY": 122.51,
        "KRW": 1333.95,
        "MXN": 20.2155,
        "MYR": 4.5819,
        "NOK": 9.2985,
        "NZD": 1.6577,
        "PHP": 54.171,
        "PLN": 4.4234,
        "RON": 4.5035,
        "RUB": 75.0559,
        "SEK": 9.2575,
        "SGD": 1.5531,
        "THB": 40.191,
        "TRY": 3.3166,
        "USD": 1.1439,
        "ZAR": 17.0751
    }
}

And here is the code that I'm currently working with:

        List<string> exchangeRate = new List<string>();
        string BSE = "USD";
        string URL = "http://api.fixer.io/latest?base=" + BSE;

        using (var webClient = new System.Net.WebClient())
        {
            var json = webClient.DownloadString(URL);
            dynamic stuff = JsonConvert.DeserializeObject(json);

            foreach (JObject item in stuff)
            {
                exchangeRate.Add(item["rates"].ToString());

                foreach (var rates in exchangeRate)
                {
                    Console.WriteLine(rates);
                }
            }
        }

Now the error that I receive is:

Cannot convert type 'Newtonsoft.Json.Linq.JProperty' to 'Newtonsoft.Json.Linq.JObject'

This occurs at the "JObject item"

Upvotes: 5

Views: 21783

Answers (3)

Brian Rogers
Brian Rogers

Reputation: 129677

In your code, JsonConvert.DeserializeObject() is returning a JObject into the dynamic variable stuff. When you use foreach to iterate over a JObject, the items being enumerated are always JProperty instances, not JObject instances. Since JProperty is not a subclass of JObject, you cannot assign it to a JObject variable, and that is why you are getting this error.

If you are simply trying to print out all the currency exchange rates to the console, you can do it like this:

JObject stuff = JObject.Parse(json);

foreach (JProperty rate in stuff["rates"])
{
    Console.WriteLine(rate.Name + ": " + rate.Value);
}

Fiddle: https://dotnetfiddle.net/fpS9CM

Upvotes: 4

BRAHIM Kamel
BRAHIM Kamel

Reputation: 13755

You can try something like this:

foreach (JProperty item in stuff)
{
    if (item.Name == "rates")
    {
        exchangeRate.AddRange(from rate in item from xch in rate select xch.ToString());
        foreach (var value in exchangeRate)
        {
            Console.WriteLine(value);
        }
    }
}

A JToken is a generic representation of a JSON value of any kind. It could be a string, object, array, property, etc.

A JProperty is a single JToken value paired with a name. It can only be added to a JObject, and its value cannot be another JProperty.

A JObject is a collection of JProperties. It cannot hold any other kind of JToken directly.

Upvotes: 3

Scott Hannen
Scott Hannen

Reputation: 29207

If you use a strongly-typed object that matches your Json then you'll find it easier to work with what you've deserialized. Try this:

public class ConversionRates
{
    public string @base { get; set; }
    public string date { get; set; }
    public Dictionary<string, decimal> rates { get; set; }
}

Then deserialize to that.

var obj = JsonConvert.DeserializeObject<ConversionRates>(yourJson);

Upvotes: 3

Related Questions