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!
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);
应该是太根对象。
var beers = JsonConvert.DeserializeObject<RootObject>(response.Content);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.