0

I've read numerous threads asking similar questions but have been unable to tie it all together.

I have an API feeding a string here: https://apiv2.bitcoinaverage.com/constants/exchangerates/local

I would like to make this string usable and accessible. For example getting the USD to CAD rate.

I'm using RestSharp and Newtonsoft JSON in my code.

using Newtonsoft.Json;
using RestSharp;

First I used http://json2csharp.com/ to create a class (classes?) matching the string. EDIT: I've now solved this, and had to nest the classes properly, as per revised code;

class Exrates
{
    public Rates rates { get; set; }
    public string time { get; set; }

    public class Rates
    {
        public MXN Mxn { get; set; }
        public ILS Ils { get; set; }
        public EUR Eur { get; set; }
        public BRL Brl { get; set; }
        public PLN Pln { get; set; }
        public MYR Myr { get; set; }
        public SEK Sek { get; set; }
        public AUD Aud { get; set; }
        public IDR Idr { get; set; }
        public TRY Try { get; set; }
        public RUB Rub { get; set; }
        public JPY Jpy { get; set; }
        public CAD Cad { get; set; }
        public USD Usd { get; set; }
        public GBP Gbp { get; set; }
        public NZD Nzd { get; set; }
        public CZK Czk { get; set; }
        public SGD Sgd { get; set; }

    public class MXN
        {
            public string name { get; set; }
            public string rate { get; set; }
        }

        public class ILS
        {
            public string name { get; set; }
            public string rate { get; set; }
        }

        public class EUR
        {
            public string name { get; set; }
            public string rate { get; set; }
        }

        public class BRL
        {
            public string name { get; set; }
            public string rate { get; set; }
        }

        public class PLN
        {
            public string name { get; set; }
            public string rate { get; set; }
        }

        public class MYR
        {
            public string name { get; set; }
            public string rate { get; set; }
        }

        public class SEK
        {
            public string name { get; set; }
            public string rate { get; set; }
        }

        public class AUD
        {
            public string name { get; set; }
            public string rate { get; set; }
        }

        public class IDR
        {
            public string name { get; set; }
            public string rate { get; set; }
        }

        public class TRY
        {
            public string name { get; set; }
            public string rate { get; set; }
        }

        public class RUB
        {
            public string name { get; set; }
            public string rate { get; set; }
        }

        public class JPY
        {
            public string name { get; set; }
            public string rate { get; set; }
        }

        public class CAD
        {
            public string name { get; set; }
            public string rate { get; set; }
        }

        public class USD
        {
            public string name { get; set; }
            public string rate { get; set; }
        }

        public class GBP
        {
            public string name { get; set; }
            public string rate { get; set; }
        }

        public class NZD
        {
            public string name { get; set; }
            public string rate { get; set; }
        }

        public class CZK
        {
            public string name { get; set; }
            public string rate { get; set; }
        }

        public class SGD
        {
            public string name { get; set; }
            public string rate { get; set; }
        }
    }
}

I then called the API and stored the response in a string;

    var btcAvgClient = new RestClient();
    btcAvgClient.BaseUrl = new Uri("https://apiv2.bitcoinaverage.com/constants/exchangerates/local");

    IRestResponse response;
    var request = new RestRequest();

    response = btcAvgClient.Execute(request);
    string btcAvg = response.Content;

I believe there are 1 or 2 steps remaining but I can't quite figure it out. How do I now convert this string to something usable?

Any help is appreciated!

1

2 Answers 2

1

Firstly, modify your data model to look like the following:

public class Rate
{
    public string name { get; set; }
    public decimal rate { get; set; }
}

public class RootObject
{
    public Dictionary<string, Rate> rates { get; set; }
    public string time { get; set; }
}

Next, introduce the following extension method:

public static partial class RateExtensions
{
    public static bool TryGetConversion(this Dictionary<string, Rate> rates, string from, string to, out decimal rate)
    {
        Rate fromRate;
        Rate toRate;

        if (rates == null || !rates.TryGetValue(from, out fromRate))
        {
            rate = 0;
            return false;
        }

        if (!rates.TryGetValue(to, out toRate))
        {
            rate = 0;
            return false;
        }

        rate = toRate.rate / fromRate.rate;
        return true;
    }
}

Now, you can execute a typed request as follows. The typed request will automatically deserialize the response into your desired data model:

var btcAvgClient = new RestClient("https://apiv2.bitcoinaverage.com/");
var request = new RestRequest("constants/exchangerates/local");

// Execute the request and get the typed response
var response = btcAvgClient.Execute<RootObject>(request);

// Get the root object from the response.
RootObject data = response.Data;

And compute the conversion from USD to CAD as follows:

// Compute the converson from (e.g.) USD to CAD
var fromName = "USD";
var toName = "CAD";

decimal rate;
if (data.rates.TryGetConversion(fromName, toName, out rate))
{
    Console.WriteLine("Conversion from {0} to {1} = {2}", fromName, toName, rate);
}
else
{
    Console.WriteLine("Cannot get conversion from {0} to {1}.", fromName, toName);
}

On my computer this outputs

Conversion from USD to CAD = 1.36245

Which currently seems to be the correct number as confirmed by a Google search:

1 United States Dollar equals 1.36 Canadian Dollar

Notes:

  • Since this API might possibly return different currencies in the future, but with the same data for each, I defined rates to be a Dictionary<string, Rate> rates. The dictionary will capture all returned currency rates.

    Your code will need to know the currency names to expect, but I believe these are standard.

  • Since we are doing currency conversions here I defined rate to be a decimal rather than a string. The serializer will automatically deserialize the string value for "rate" into a decimal.

  • To ensure your request was successful see How to idiomatically handle HTTP error codes when using RestSharp?.

    Alternatively you could check the response.ErrorException as shown in the Recommended Usage documentation page.

  • If you need to make async requests see How should I implement ExecuteAsync with RestSharp on Windows Phone 7?.

  • RestSharp has a built-in JSON serializer but you could use Json.NET if you prefer. Simply get the response.Content string and deserialize by doing:

    // Execute the request and get the untyped (string) response
    var response = btcAvgClient.Execute(request);
    
    // Get the root object from the response.
    RootObject data = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(response.Content);
    
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your help! I'm a beginner and am having problems understanding your code, but it's coming along nicely. I ended up solving the above, but will circle back to your code at some point to improve my own implementation. Once again I appreciate your help.
0

Should be too root object.

var beers = JsonConvert.DeserializeObject<RootObject>(response.Content);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.