.NET Core中如何调用OData协议API并解决无效请求问题
问题描述
尝试调用一个公开端点获取JSON格式的对象列表,但调用时始终返回无效请求,怀疑是调用方式有误,需要修改代码中的哪些部分才能正确调用该API?
现有代码
接口方法
[HttpGet] public async Task<List<TaxaSelic>> ObterTaxaSelic() { List<TaxaSelic> taxasSelic = new List<TaxaSelic>(); string apiResponse = string.Empty; Uri uri = new Uri("https://api.bcb.gov.br/dados/serie/bcdata.sgs.4390/dados/ultimos/10/"); using (HttpClient httpClient = new HttpClient()) { using (HttpResponseMessage response = await httpClient.GetAsync(uri)) { if (response.IsSuccessStatusCode) apiResponse = await response.Content.ReadAsStringAsync(); taxasSelic = JsonConvert.DeserializeObject<List<TaxaSelic>>(apiResponse); } } return taxasSelic; }
实体类
public class TaxaSelic : Entity { [JsonProperty("data")] public string Data { get; set; } [JsonProperty("valor")] public string Valor { get; set; } }
修正方案
首先明确:这个巴西央行的API并非OData协议,它是SGS(时间序列管理系统)的REST API,返回无效请求的核心原因是缺少正确请求头及代码存在潜在问题,具体修改点如下:
添加
Accept请求头
该API需要明确指定接受JSON格式响应,否则可能返回默认非JSON格式(如XML),导致反序列化失败或请求被拒绝。在初始化HttpClient后添加:httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));复用HttpClient实例
每次用using创建新HttpClient会造成套接字资源泄漏,建议将HttpClient注册为单例或静态实例,比如在类中声明静态成员:private static readonly HttpClient _httpClient = new HttpClient(); static YourControllerName() { _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); }之后在方法中直接使用
_httpClient即可,无需每次创建新实例。完善错误处理
原代码在请求失败时仍会尝试反序列化空字符串,必然抛出异常。建议在请求失败时直接抛出HTTP错误异常:response.EnsureSuccessStatusCode(); // 触发HTTP错误时直接抛出异常 apiResponse = await response.Content.ReadAsStringAsync();修正URI末尾斜杠(可选)
虽然该API兼容末尾斜杠,但规范的URI可以去掉末尾的/,避免不必要的重定向:Uri uri = new Uri("https://api.bcb.gov.br/dados/serie/bcdata.sgs.4390/dados/ultimos/10");
修正后的完整代码示例
接口方法
private static readonly HttpClient _httpClient = new HttpClient(); static YourControllerName() { _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); } [HttpGet] public async Task<List<TaxaSelic>> ObterTaxaSelic() { var uri = new Uri("https://api.bcb.gov.br/dados/serie/bcdata.sgs.4390/dados/ultimos/10"); var response = await _httpClient.GetAsync(uri); response.EnsureSuccessStatusCode(); var apiResponse = await response.Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject<List<TaxaSelic>>(apiResponse); }
实体类
实体类无需修改,保持原定义即可。
内容的提问来源于stack exchange,提问作者Victor Moraes
相关产品推荐
相关产品推荐

