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

问题描述 投票:0回答:2

我正在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;

编辑:我需要此调用的结果进行进一步处理,因此我必须需要此方法来完成其执行,然后再继续进行

c# .net winforms rest
2个回答
3
投票

首先从 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 调用,只需向下面的通用 Process 方法提供主机和 API 详细信息即可:

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

2
投票

您可以使用在线服务(例如 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}");
}
© www.soinside.com 2019 - 2024. All rights reserved.