来自 API 的 ResponseStream 在反序列化时产生空值

ResponseStream from API results in empty values on deserializing

从我的 API 返回数据并在客户端控制器中反序列化它,内容似乎是空的。我已验证 API 正在返回有效数据,并且响应中的“计数”是准确的。但是,序列化时的数据好像没有初始化。

不太确定在哪里寻找导致问题的原因。我最好的理论是数据在由于异步而具体化之前被反序列化,但这并不能解释为什么计数是正确的(2 条记录)。

public async Task<IActionResult> Index()
{
  var httpClient = _httpClientFactory.CreateClient("APIClient");

  var request = new HttpRequestMessage(HttpMethod.Get, "/api/AppUsers");
        
  var response = await httpClient.SendAsync(request).ConfigureAwait(false);

  if (response.IsSuccessStatusCode)
  { 
    using (var responseStream = await response.Content.ReadAsStreamAsync())        
    {
      var users = await JsonSerializer.DeserializeAsync<IList<AppUser>>(responseStream);

      return View(new IndexViewModel(users));
    }
  }
  else if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized ||
          response.StatusCode == System.Net.HttpStatusCode.Forbidden) 
  {
    return RedirectToAction("AccessDenied", "Authorization");
  }
  throw new Exception("Problem accessing the API");
  
}

API 调用的方法

[HttpGet]
public IActionResult GetAppUsers()
{
  var users = _appUserService.ListAppUsers();
  return Ok(users);
}

调用API方法直接显示如预期返回的2行

经过一些调试,我注意到从 API 返回的 json 结构的 属性 名称中的第一个字母是小写的,但是 AppUser class 有首字母大写。不知道为什么会这样,但这就是反序列化失败的原因。

尝试反序列化为 List 而不是 IList:

var users = await JsonSerializer.DeserializeAsync<List<AppUser>>(responseStream);

我认为您应该删除 ConfigureAwait(false) 以便您可以保持在相同的同步上下文中。

有关更多信息,请查看此 link:https://devblogs.microsoft.com/dotnet/configureawait-faq/

注意到 JSON 对象的属性从大写变为小写后,解决方案是将 JSON 强制为 PascalCase,因为现在默认为驼峰式

https://codeopinion.com/asp-net-core-mvc-json-output-camelcase-pascalcase/

或者我需要考虑反序列化时的驼峰命名法。

这个问题偷走了我几个小时的生活:/ 希望这个 post 可以为其他人节省一些时间。

一种解决方案是禁用默认设置

builder.Services.AddControllers(options =>
{
  options.ReturnHttpNotAcceptable = true;
})
  .AddXmlSerializerFormatters()
  .AddJsonOptions(options =>
 {
   options.JsonSerializerOptions.PropertyNamingPolicy = null; //to avoid defaulting to camelCase
 });