使用NewtonSoft.Json

时间:2018-12-31 18:53:38

标签: c# json restsharp

我读过许多询问类似问题的主题,但无法将它们结合在一起。

我有一个API在这里提供字符串:https://apiv2.bitcoinaverage.com/constants/exchangerates/local

我想使此字符串可用和可访问。例如,将USD转换为CAD汇率。

我在代码中使用RestSharp和Newtonsoft JSON。

using Newtonsoft.Json;
using RestSharp;

首先,我使用http://json2csharp.com/创建了一个与字符串匹配的类(classes?)。编辑:我现在已经解决了这个问题,并且必须按照修订后的代码正确嵌套类;

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步,但我不太清楚。现在如何将该字符串转换为可用的字符串?

感谢您的帮助!

3 个答案:

答案 0 :(得分:1)

首先,将数据模型修改为如下所示:

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;

并按如下方式计算从美元到加元的转换:

// 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 search确认的当前似乎是正确的数字:

  

1美元等于1.36加元

注意:

  • 由于该API将来可能会返回不同的货币,但是每种货币具有相同的数据,因此我将rates定义为Dictionary<string, Rate> rates。该词典将捕获所有返回的货币汇率。

    您的代码将需要知道期望的货币名称,但是我相信这些是标准的。

  • 由于我们在这里进行货币换算,因此我将rate定义为decimal,而不是string。序列化程序将自动将"rate"的字符串值反序列化为十进制。

  • 要确保您的请求成功,请参见 How to idiomatically handle HTTP error codes when using RestSharp?

    或者,您也可以按照Recommended Usage文档页面中所示检查response.ErrorException

  • 如果您需要发出async请求,请参见 How should I implement ExecuteAsync with RestSharp on Windows Phone 7?

  • RestSharp有一个built-in JSON serializer,但您可以根据需要使用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);
    

答案 1 :(得分:0)

应该是根对象。

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

答案 2 :(得分:-1)

您可以使用Newtonsoft转换器将JSON反序列化到您的类中。

using (var client = new HttpClient())
{
    var response = await client.GetAsync(getPath);
    if (response.IsSuccessStatusCode)
    {
        var responseContentString = await response.Content.ReadAsStringAsync();
        var beersFromApi = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Beer>>(responseContentString);
    }
    return beersFromApi;
}