Преобразовать строку API в объект JSON с помощью NewtonSoft.Json - PullRequest
0 голосов
/ 31 декабря 2018

Я читал многочисленные темы, задавая похожие вопросы, но не смог связать все это вместе.

У меня есть API, подающий строку здесь: https://apiv2.bitcoinaverage.com/constants/exchangerates/local

Я хотел бы сделать эту строку пригодной для использования и доступной.Например, получение курса USD к CAD.

Я использую RestSharp и Newtonsoft JSON в своем коде.

using Newtonsoft.Json;
using RestSharp;

Сначала я использовал http://json2csharp.com/ для создания класса (классы?) соответствующие строки.РЕДАКТИРОВАТЬ: я теперь решил это, и мне пришлось правильно вкладывать классы, как в пересмотренном коде;

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; }
        }
    }
}

Затем я вызвал API и сохранил ответ в строке;

    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;

Я считаю, что осталось 1 или 2 шага, но я не могу понять это.Как мне теперь преобразовать эту строку во что-то пригодное для использования?

Любая помощь приветствуется!

Ответы [ 2 ]

0 голосов
/ 31 декабря 2018

Во-первых, измените модель данных так, чтобы она выглядела следующим образом:

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; }
}

Затем введите следующий метод расширения:

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;
    }
}

Теперь вы можете выполнить типизированный запрос какследующим образом.Напечатанный запрос автоматически десериализует ответ в желаемую модель данных:

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;

и вычислит перевод из USD в CAD следующим образом:

// 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);
}

На моем компьютере это выдает

Преобразование из USD в CAD = 1.36245

Что в настоящее время кажется правильным числом, подтвержденным поиском Google :

1 доллар США равен 1,36 канадского доллара

Примечания:

  • Поскольку этот API может в будущем возвращать разные валюты, но с той жеДля каждого из данных я определил rates как Dictionary<string, Rate> rates.Словарь фиксирует все возвращенные курсы валют.

    Ваш код должен знать ожидаемые названия валют, но я считаю, что они являются стандартными.

  • Поскольку здесь мы проводим конвертацию валют, я определил rate длябыть decimal, а не string.Сериализатор автоматически десериализует строковое значение для "rate" в десятичное число.

  • Чтобы убедиться, что ваш запрос был успешным, см. Как идиоматически обрабатывать коды ошибок HTTP при использованииRestSharp? .

    В качестве альтернативы вы можете проверить response.ErrorException, как показано на странице документации Рекомендуемое использование .

  • Если вам нужно сделать async запросов, см. Как мне реализовать ExecuteAsync с RestSharp на Windows Phone 7? .

  • RestSharp имеет встроенный сериализатор JSON , но вы можете использовать Json.NET, если хотите.Просто получите строку response.Content и выполните десериализацию, выполнив:

    // 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);
    
0 голосов
/ 31 декабря 2018

Должен быть слишком корневым объектом.

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