Moyni
Moyni

Reputation: 13

Accessing child value of JSON in C#

public static void apiCall2()
{
    WebClient c = new WebClient();
    var data = c.DownloadString(baseURL + endPoint + "?access_key=" + accessKey + "&currencies=TWD&source=USD&format=1");
    //Console.WriteLine(data);
    JObject api = JObject.Parse(data);

    string conversion = "";

    foreach (var result in api["quotes"])
    {
        System.Console.WriteLine(result);
        conversion = (string)result["USDTWD"];
        System.Console.WriteLine(conversion);
    }
}

When ever I run this simple JSON API call code I receive an error of

Cannot access child value on Newtonsoft.Json.Linq.JProperty.

The USDTWD (the only section inside of [quotes] is supposed to call a double which returns the exchange rate from USD to TWD, and even trying to call it in as a string does not seem to help.

Upvotes: 1

Views: 16648

Answers (3)

Jason Boyd
Jason Boyd

Reputation: 7029

When you call foreach (var result in api["quotes"]) you are looping over the child objects of the 'quotes' JObject one of which is the JProperty with property name 'USDTWD'. You then put that JProperty in the result variable. Then here:

conversion = (string)result["USDTWD"]

you are trying to access the USDTWD property of result but result does not have a USDTWD property because it is the USDTWD property. Hence the exception.

If you just need the value of the USDTWD property you can replace your foreach loop with this:

conversion = api["quotes"]["USDTWD"].ToString();

Upvotes: 2

Bruno Garcia
Bruno Garcia

Reputation: 6408

Easy way is:

Change: JObject api = JObject.Parse(data); To:

dynamic api = JObject.Parse(data);
var quote = api.quotes.USDTWD;

Upvotes: 2

Ilya Chernomordik
Ilya Chernomordik

Reputation: 30385

I have a suggestion that might help you fix the issue by using a class with a structure rather than "raw" JObject. If you create a class like that:

public class ResponseModel
{
    public bool Success {get;set;}
    ....

    public List<Quote> Quotes {get;set;}
}

public class QuoteModel
{
    public decimal USDTWD {get;set;}
}

Then you can convert to that object like that:

var response = api.ToObject<ResponseModel>();

I am not sure if this is acceptable for you (e.g. you might not have all the different quotes, or they are not all listed). But it is usually a more convenient way of working with responses than using JObject directly in my opinion.

P.S. Maybe you can even have a List as Quotes property to not hardcode it all, but I am not sure on how it is supported.

Upvotes: 1

Related Questions