在Winform C#应用程序中从Web api调用并获取响应

时间:2019-06-08 12:20:21

标签: c# .net winforms rest api

我正在Windows中制作一个简单的WinForm应用程序,我想获取一些有关汇率的数据。因此,我决定从Oanda调用API。我尝试了几件事,但是没有任何效果。它以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 个答案:

答案 0 :(得分:2)

  

首先从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,它可以选择同时返回JsonCSV,我希望JSON被标准,也可以由各种客户端轻松使用,使用以下简单的通用方法:

  

假设它仅是GET调用,只需将Host和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 :(得分:1)

您可以使用诸如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更改为更具描述性的名称。

例如,要获取每个quotes bid,ask和midpoint 值,您只需执行以下操作:

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