将 .NET Core 2 迁移到 .NET Core 3:HttpContent 不包含 "ReadAsAsync" 的定义

Migrating .NET Core 2 to .NET Core 3: HttpContent does not contain a definition for "ReadAsAsync"

我正在按照本指南https://docs.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-3.0&tabs=visual-studio迁移到 .NET Core 3。

我收到编译错误:

错误 CS1061 'HttpContent' 不包含 'ReadAsAsync' 的定义,并且找不到接受类型 'HttpContent' 的第一个参数的可访问扩展方法 'ReadAsAsync'(您是缺少 using 指令或程序集引用?)

该项目是一个 class 库,我更新了它的 csproj,删除了对 Microsoft.AspNetCore.App 的包引用并添加了一个框架引用:

  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>

知道为什么会这样吗?

ReadAsAsync 从 .NET Core 3.0 开始作为 .NET Core 的一部分被弃用,但是您可以从 NuGet 包中包含它 Microsoft.AspNet.WebApi.Client,您将能够再次使用 ReadAsAsync。将 Web 应用程序从 .NET Core 2.0 更新到 .NET Core 3.0 时,我遇到了同样的问题。

ReadAsAsync 是一个 .NET Standard 扩展,实际上在 ASP.NET Core 和 ASP.NET Web Api 之间共享(通过 NuGet 库)。但是,它使用 JSON.NET 进行反序列化,并且从 .NET Core 3.0 开始,ASP.NET Core 现在使用 System.Text.Json。因此,此库(及其包含的扩展)未包含在 .NET Core 3.0 框架中,因为这样做除了 System.Text.Json.

之外还需要包含 JSON.NET 库

虽然您可以手动添加 Microsoft.AspNet.WebApi.Client(以及 Newtonsoft.Json),但您应该在没有它的情况下继续前进。无论如何,它不会为你节省太多,因为你可以通过以下方式完成同样的事情:

await JsonSerializer.DeserializeAsync<MyType>(await response.Content.ReadAsStreamAsync());

如果您愿意,可以将自己的扩展添加到 HttpContent 以将其包装在 ReadAsAsync 方法中:

public static class HttpContentExtensions
{
    public static async Task<T> ReadAsAsync<T>(this HttpContent content) =>
        await JsonSerializer.DeserializeAsync<T>(await content.ReadAsStreamAsync());
}

由于 System.Text.Json 不支持“允许字符串属性的非字符串 JSON 值”并且我无法找到或编写自己的可靠JsonConverter 完成这个,继续使用 Newtonsoft.Json 在我的情况下节省了很多。

在我的解决方案中,Microsoft.AspNet.WebApi.Client 不是必需的,只需 Newtonsoft.Json

原码:

return await response.Content.ReadAsAsync<MyClass>();

.NET Core 3 解决方案:

return JsonConvert.DeserializeObject<MyClass>(await response.Content.ReadAsStringAsync());

从 NuGet 安装包 System.Net.Http.Formatting.Extension。如果不存在,有时您还必须安装 Newtonsoft.Json