c# - 在 winform c# 应用程序中调用并从 web 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"e=USD");
string result = await response.Content.ReadAsStringAsync();
textBox1.Text = result;
编辑:我需要此调用的结果以进行进一步处理,因此我必须需要此方法才能完成其执行,然后再继续
解决方案
首先从 Json 创建模型:
使用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; } }
现在连接到
WebAPI
usingHttpClient
,它可以选择返回Json
和CSV
,我更喜欢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);
}
推荐阅读
- javascript - Django HTML & CSS 渲染为 pdf
- python - 用熊猫有条件地替换
- python - Python单面KS-Test
- azure - Azure Functions App 从共享路径访问文件
- memory - AnyLogic 简单进程内存爆炸
- python - 使用 findall() 时如何从输出中删除空格?
- java - 如何使用Android Studio一一填充三个EditText?
- firebase - 是否可以通过 firebase 功能访问 firebase 托管的文件系统?
- c - Eclipse C/C++ 调试变量默认格式为十六进制
- html - VBA HTML将输入元素添加到Span