如何获取正确JSON格式流并通过System.Text.Json反序列化实体类?
问题:请求API返回HTML而非JSON,无法反序列化为League实体类
尝试将API响应流转换为League实体类时,始终收到HTML格式的内容而非JSON,清理浏览器缓存也无法解决。通过string res = await httpResponseMessage.Content.ReadAsStringAsync();确认返回内容是HTML,导致反序列化异常,需要获取JSON格式响应来完成反序列化和数据库存储。
控制器代码
using Microsoft.AspNetCore.Mvc; using Model; using System.Text.Json; namespace Web.Controllers.HttpControllers { public class LeagueClientController : ControllerBase { private readonly Uri _leagueRequest; private readonly BetDBContext _dbContext; private readonly HttpClient _httpClient; public LeagueClientController(IHttpClientFactory factory, BetDBContext dbContext) { _leagueRequest = new Uri("https://www.api-football.com/leagues"); _dbContext = dbContext; _httpClient = factory.CreateClient("BetHttpClient"); } [HttpGet] [Route("[controller]")] public async Task<League> GetLeagues() { try { var leagueResponse = await _httpClient.GetAsync(_leagueRequest)??throw new NullReferenceException(); if (leagueResponse.IsSuccessStatusCode) { Stream stream = await leagueResponse.Content.ReadAsStreamAsync(); if (stream != null) { var league = await JsonSerializer.DeserializeAsync<League>(stream)??throw new ArgumentNullException(); await _dbContext.AddAsync(league); await _dbContext.SaveChangesAsync(); } } } catch (ArgumentNullException e) { Console.WriteLine($"{e.Message} - can not connect to remote source"); } return new League(); } } }
HttpClient配置代码
builder.Services.AddHttpClient("BetHttpClient", httpClient => { httpClient.BaseAddress = new Uri("https://v3.football.api-sports.io/"); httpClient.DefaultRequestHeaders.Add("x-apisports-key", "it is secret"); httpClient.DefaultRequestHeaders.Add("x-rapidapi-host", "v3.football.api-sports.io"); httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); });
解决方案
1. 修正API请求地址
当前使用的https://www.api-football.com/leagues是旧版官网地址,并非实际API端点。结合HttpClient配置的BaseAddresshttps://v3.football.api-sports.io/,正确的联赛API端点应为相对路径/leagues。修改控制器中的请求地址:
// 替换原完整URI,改用相对路径 _leagueRequest = new Uri("/leagues", UriKind.Relative); // 或者直接在GetAsync中传入相对路径 var leagueResponse = await _httpClient.GetAsync("/leagues") ?? throw new NullReferenceException();
2. 排查响应错误细节
HTML响应通常对应4xx/5xx错误(如404未找到、401未授权),建议在代码中打印状态码和响应内容,定位具体问题:
var leagueResponse = await _httpClient.GetAsync("/leagues"); Console.WriteLine($"Status Code: {leagueResponse.StatusCode}"); var responseContent = await leagueResponse.Content.ReadAsStringAsync(); Console.WriteLine($"Response Content: {responseContent}"); if (leagueResponse.IsSuccessStatusCode) { // 原反序列化逻辑 } else { Console.WriteLine($"Request failed with status code: {leagueResponse.StatusCode}"); }
3. 验证API密钥有效性
确认x-apisports-key的密钥是否有效,过期或无效的密钥会导致API返回错误HTML页面。可通过Postman等工具直接测试API端点,验证密钥能否正常返回JSON。
4. 移除冗余请求头
x-rapidapi-host头在api-sports.io V3版本中无需配置,移除该头避免请求异常:
// 删除此行配置 // httpClient.DefaultRequestHeaders.Add("x-rapidapi-host", "v3.football.api-sports.io");
内容的提问来源于stack exchange,提问作者Maciej Ambroziak
相关产品推荐
相关产品推荐

