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

4

44

I am following this guide https://learn.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-3.0&tabs=visual-studio to migrate to .NET Core 3.

I am getting the compilation error:

Error CS1061 'HttpContent' does not contain a definition for 'ReadAsAsync' and no accessible extension method 'ReadAsAsync' accepting a first argument of type 'HttpContent' could be found (are you missing a using directive or an assembly reference?)

The project is a class library, I have updated its csproj removing a package reference to Microsoft.AspNetCore.App and adding a framework reference instead:

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

Any ideas why this is happening?

Menorca answered 20/11, 2019 at 14:19 Comment(0)
S
82

ReadAsAsync is a .NET Standard extension that's actually shared between ASP.NET Core and ASP.NET Web Api (via a NuGet library). However, it uses JSON.NET to do the deserialization, and as of .NET Core 3.0, ASP.NET Core now uses System.Text.Json instead. As such, this library (and the extension it contains) is not included in the .NET Core 3.0 framework because doing so would require including the JSON.NET library in addition to System.Text.Json.

While you can manually add the Microsoft.AspNet.WebApi.Client (and Newtonsoft.Json along with it), you should just move on without it. It doesn't save you much anyways, as you can accomplish the same via just:

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

If you like, you can add your own extension to HttpContent to wrap this up in a ReadAsAsync method:

public static class HttpContentExtensions
{
    public static async Task<T> ReadAsAsync<T>(this HttpContent content) =>
        await JsonSerializer.DeserializeAsync<T>(await content.ReadAsStreamAsync());
}
Simms answered 20/11, 2019 at 16:8 Comment(6)
For reuse as library code, use ConfigureAwait(false) public static class HttpContentExtensions { public static async Task<T> ReadAsAsync<T>(this HttpContent content) => await JsonSerializer.DeserializeAsync<T>(await content.ReadAsStreamAsync().ConfigureAwait(false)).ConfigureAwait(false); }Cello
@Cello isn't ConfigureAwait(false) obsolete in .NET Core?Caster
@Caster Yes, in Asp.Net Core it's not needed. Therefore I wrote, if it's reusable code in a library, it should use ConfigureAwait, since you don't know, who is calling it. In WPF .Net Core it's still relevant.Cello
It's not obsolete. Just not needed, at least with ASP.NET Core, since ASP.NET Core doesn't have a SynchronizationContext. However, other parts of .NET Core do, and of course .NET Core, in general, can be used in applications where ConfigureAwait(false) is very much needed. Since it doesn't hurt to use it when it's not needed, and it's far too easy to neglect to use it when you should, I always recommend continuing to add it to all async calls, where you don't need a SynchronizationContext.Simms
TIL "obsolete" and "not needed" are two different things :) To me, it does hurt because you have all this .ConfigureAwait(false) littering your code base. It's one of those things where some devs will agree and some will disagree.Caster
If something is obsolete, it has been marked for eventual removal. ConfigureAwait is not obsolete, and will not be removed, because, again, there's plenty of scenarios where it's still necessary. Any library code should continue to use it where appropriate, because that library code is not truly reusable without it. I think you're under the mistaken impression that it's not a thing any more, when it very much still is.Simms
S
17

ReadAsAsync is deprecated as being part of .NET Core as of .NET Core 3.0 however you can include it as from the NuGet package Microsoft.AspNet.WebApi.Client and you'll be able to use ReadAsAsync again. When updating web application from .NET Core 2.0 to .NET Core 3.0 I experienced the same issue.

Simoniac answered 20/11, 2019 at 14:24 Comment(0)
Y
6

Since System.Text.Json does not support "Allow non-string JSON values for string properties" and I was unable to find or write my own reliable JsonConverter to accomplish this, continuing to use Newtonsoft.Json saved a lot in my case.

In my solution, Microsoft.AspNet.WebApi.Client isn't necessary, just Newtonsoft.Json.

Original Code:

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

.NET Core 3 Solution:

return JsonConvert.DeserializeObject<MyClass>(await response.Content.ReadAsStringAsync());
Yolande answered 30/12, 2020 at 15:7 Comment(0)
M
0

Install package System.Net.Http.Formatting.Extension from NuGet. You'll sometimes have to Install Newtonsoft.Json as well, if not existing.

Massie answered 24/1, 2022 at 6:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.