Звоните и получайте ответ от web api в приложении winform c # - PullRequest
2 голосов
/ 08 июня 2019

Я делаю простое приложение WinForm в Windows и хочу получить некоторые данные о курсах валют.Поэтому я решил вызвать API от Oanda.Я пробовал несколько вещей, но ничего не получалось.Он дает ответ в формате CSV, а также в формате JSON.Я не знаю, с чем будет легче обращаться.

Также для этого типа ответа я не могу создать его класс модели.Ответ:

JSON:

{
  "meta": {
    "effective_params": {
      "data_set": "OANDA",
      "base_currencies": [
        "EUR"
      ],
      "quote_currencies": [
        "USD"
      ]
    },
    "endpoint": "spot",
    "request_time": "2019-06-08T12:05:23+00:00",
    "skipped_currency_pairs": []
  },
  "quotes": [
    {
      "base_currency": "EUR",
      "quote_currency": "USD",
      "bid": "1.13287",
      "ask": "1.13384",
      "midpoint": "1.13336"
    }
  ]
}

CSV:

base_currency,quote_currency,bid,ask,midpoint
EUR,USD,1.13287,1.13384,1.13336

Мне просто нужны эти три числа, какой метод будет полезен и как.

Этот код, который я уже пробовал:

var client = new HttpClient();
client.BaseAddress = new Uri("https://www1.oanda.com/rates/api/v2/rates/");
HttpResponseMessage response = await client.GetAsync("spot.csv?api_key=<myapikey>&base=EUR&quote=USD");
string result = await response.Content.ReadAsStringAsync();
textBox1.Text = result;

Редактировать: мне нужен результат этого вызова для дальнейшей обработки, поэтому мне нужен этот метод для завершения его выполнения, прежде чем продолжить

Ответы [ 2 ]

2 голосов
/ 08 июня 2019

Первое создание модели от Json:

  1. используйте онлайн-генератор моделей, такой как Json2C # , для Json, который вы разместили, ниже генерируется модель:

    public class EffectiveParams
    {
      public string data_set { get; set; }
      public List<string> base_currencies { get; set; }
      public List<string> quote_currencies { get; set; }
    }
    
    public class Meta
    {
      public EffectiveParams effective_params { get; set; }
      public string endpoint { get; set; }
      public DateTime request_time { get; set; }
      public List<object> skipped_currency_pairs { get; set; }
    }
    
    public class Quote
    {
      public string base_currency { get; set; }
      public string quote_currency { get; set; }
      public string bid { get; set; }
      public string ask { get; set; }
      public string midpoint { get; set; }
    }
    
    public class RootObject
    {
      public Meta meta { get; set; }
      public List<Quote> quotes { get; set; }
    }
    
  2. Теперь, подключаясь к WebAPI с помощью HttpClient, который может возвращать Json и CSV, я бы предпочел, чтобы JSON был стандартным, который также может легко потребляться разнообразием клиентов, используйте следующие простые универсальные методы:

Предполагая, что это только вызов GET, просто предоставьте сведения о хосте и API для общего метода Process под:

public async Task<TResponse> Process<TResponse>(string host,string api)
{
   // Execute Api call Async
   var httpResponseMessage = await MakeApiCall(host,api);

   // Process Json string result to fetch final deserialized model
   return await FetchResult<TResponse>(httpResponseMessage);
} 

public async Task<HttpResponseMessage> MakeApiCall(string host,string api)

{   
    // Create HttpClient
    var client = new HttpClient(new HttpClientHandler { UseDefaultCredentials = true }) { BaseAddress = new Uri(host) };
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    // Make an API call and receive HttpResponseMessage
    HttpResponseMessage responseMessage = await client.GetAsync(api, HttpCompletionOption.ResponseContentRead);

    return responseMessage;
}

public async Task<T> FetchResult<T>(HttpResponseMessage result)
{
    if (result.IsSuccessStatusCode)
    {
        // Convert the HttpResponseMessage to string
        var resultArray = await result.Content.ReadAsStringAsync();

        // Json.Net Deserialization
        var final = JsonConvert.DeserializeObject<T>(resultArray);

        return final;
    }
    return default(T);
}

Как использовать:

  • Просто позвоните:

    var rootObj = await Process<RootObject>("https://www1.oanda.com/rates/", "api/v2/rates/");
    
  • Вы получаете десериализованный RootObject, как показано на модели выше

  • Для любой более сложной обработки, такой как отправка ввода в вызов с телом http, вышеприведенный общий код нуждается в дальнейшей модификации, в настоящее время он соответствует только вашему требованию

Редактировать 1: (синхронизация входного вызова)

  • Чтобы сделать общий вызов синхронным, используйте GetAwaiter().GetResult() на самом верхнем уровне, метод Main будет преобразован в, остальные все останутся такими же, как в примере (асинхронные методы)

      void Main()
      {
         var rootObj =  Process<RootObject>("https://www1.oanda.com/rates/", "api/v2/rates/").GetAwaiter().GetResult();
      }
    

Редактировать 2: (Создание полного кода синхронным)

void Main()
{
    var rootObj = Process<RootObject>("https://www1.oanda.com/rates/", "api/v2/rates/");
}


public TResponse Process<TResponse>(string host, string api)
{
    // Execute Api call
    var httpResponseMessage = MakeApiCall(host, api);

    // Process Json string result to fetch final deserialized model
    return FetchResult<TResponse>(httpResponseMessage);
}

public HttpResponseMessage MakeApiCall(string host, string api)

{
    // Create HttpClient
    var client = new HttpClient(new HttpClientHandler { UseDefaultCredentials = true }) { BaseAddress = new Uri(host) };
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    // Make an API call and receive HttpResponseMessage
    HttpResponseMessage responseMessage = client.GetAsync(api, HttpCompletionOption.ResponseContentRead).GetAwaiter().GetResult();

    return responseMessage;
}

public T FetchResult<T>(HttpResponseMessage result)
{
    if (result.IsSuccessStatusCode)
    {
        // Convert the HttpResponseMessage to string
        var resultArray = result.Content.ReadAsStringAsync().GetAwaiter().GetResult();

        // Json.Net Deserialization
        var final = JsonConvert.DeserializeObject<T>(resultArray);

        return final;
    }
    return default(T);
}
1 голос
/ 08 июня 2019

Вы можете использовать онлайн-сервис, такой как json2csharp , чтобы получить модель json, и Json.Net , чтобы сериализовать и десериализовать строку json.Следующие модели вашего json.

public class EffectiveParams
{
    public string data_set { get; set; }
    public List<string> base_currencies { get; set; }
    public List<string> quote_currencies { get; set; }
}

public class Meta
{
    public EffectiveParams effective_params { get; set; }
    public string endpoint { get; set; }
    public DateTime request_time { get; set; }
    public List<object> skipped_currency_pairs { get; set; }
}

public class Quote
{
    public string base_currency { get; set; }
    public string quote_currency { get; set; }
    public string bid { get; set; }
    public string ask { get; set; }
    public string midpoint { get; set; }
}

public class RootObject
{
    public Meta meta { get; set; }
    public List<Quote> quotes { get; set; }
}

Обратите внимание, что вы можете изменить RootOject на более описательное имя.

Так, например, чтобы получить значение bid, ask и midpoint для каждого quotes, вы можете просто сделать это:

RootObject rootObj=JsonConvert.DeserializeObject(jsonString);

//Get the required values.
foreach(var quote in rootObj.quotes)
{
Console.WriteLine($"Bid : {quote.bid} Ask: {quote.ask} MidPoint: {quote.midpoint}");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...