【问题标题】:Migrating .NET Core 2 to .NET Core 3: HttpContent does not contain a definition for "ReadAsAsync"将 .NET Core 2 迁移到 .NET Core 3:HttpContent 不包含“ReadAsAsync”的定义
【发布时间】:2019-11-20 14:19:55
【问题描述】:

我正在按照本指南 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 指令或程序集引用?)

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

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

任何想法为什么会发生这种情况?

【问题讨论】:

    标签: asp.net-core-3.0 .net-core-3.0


    【解决方案1】:

    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());
    }
    

    【讨论】:

    • 要作为库代码重用,请使用ConfigureAwait(false) public static class HttpContentExtensions { public static async Task&lt;T&gt; ReadAsAsync&lt;T&gt;(this HttpContent content) =&gt; await JsonSerializer.DeserializeAsync&lt;T&gt;(await content.ReadAsStreamAsync().ConfigureAwait(false)).ConfigureAwait(false); }
    • @Lars 在 .NET Core 中不是过时的 ConfigureAwait(false) 吗?
    • @jspinella 是的,在 Asp.Net Core 中不需要它。因此我写道,如果它是库中可重用的代码,它应该使用ConfigureAwait,因为你不知道是谁在调用它。在 WPF .Net Core 中它仍然是相关的。
    • 它并没有过时。只是不需要,至少对于 ASP.NET Core,因为 ASP.NET Core 没有 SynchronizationContext。但是,.NET Core 的其他部分可以,当然 .NET Core 通常可以在非常需要 ConfigureAwait(false) 的应用程序中使用。因为在不需要的时候使用它并没有什么坏处,而且在你应该使用它的时候很容易忽略它,我总是建议继续将它添加到所有异步调用中,你不需要 SynchronizationContext。
    • 如果某些东西已经过时,它已被标记为最终删除。 ConfigureAwait 并没有过时,也不会被删除,因为同样有很多场景仍然需要它。任何库代码都应该在适当的情况下继续使用它,因为没有它,库代码就不能真正重用。我认为你误以为它不再是一件事了,而实际上它仍然是。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

      原代码:

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

      .NET Core 3 解决方案:

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-08-22
          • 1970-01-01
          • 2020-01-31
          • 1970-01-01
          • 2020-01-26
          相关资源
          最近更新 更多