Adding new package breaks the .NET 5 application

1

I've been trying to figure out why my console application fails the instant I introduce a new package. Using IdentityModel.OidcClient and Microsoft.AspNetCore.Server.Kestrel only works, but when adding Microsoft.Extensions.Configuration.Json it throws exception. I don't reference the new package in code either, I just add it to the project.

Steps to reproduce:

  1. Clone https://github.com/IdentityModel/IdentityModel.OidcClient.Samples.git

  2. Upgrade NetCoreConsoleClient to .NET 5 (update packages).

  3. Remove Serilog.Sinks.Literate obsolete package.

  4. Remove call to .WriteTo.LiterateConsole for SeriLog in Program.cs and add using IdentityModel.Client.

  5. Add CancellationToken cancellationToken = new CancellationToken() parameter for InvokeAsync method in SystemBrowser class. The signature for the IBrowser interface has changed, the new method should look like this: public async Task<BrowserResult> InvokeAsync(BrowserOptions options, CancellationToken cancellationToken = new CancellationToken())

  6. Run application and login with alice/alice. Acquiring token is successful.

  7. Add package Microsoft.Extensions.Configuration.Json.

  8. Run application. It now throws exception Object reference not set to an instance of an object when writing to the http response.

The exception occurs in LoopbackHttpListener.SetResult when writing to the response: ctx.Response.WriteAsync("<h1>You can now return to the application.</h1>");

Why does adding a package only, have such an impact to the runtime?

Project file:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
    <AssemblyName>NetCoreConsoleClient</AssemblyName>
    <OutputType>Exe</OutputType>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="5.0.0" />
    <PackageReference Include="Serilog.Extensions.Logging" Version="3.0.1" />
    <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.2.0" />
    <PackageReference Include="IdentityModel.OidcClient" Version="3.1.2" />
  </ItemGroup>

</Project>

Complete exception:

System.NullReferenceException
  HResult=0x80004003
  Message=Object reference not set to an instance of an object.
  Source=Microsoft.AspNetCore.Server.Kestrel.Core
  StackTrace:
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.CreateResponseHeader(Boolean appCompleted)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProduceStart(Boolean appCompleted)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.InitializeResponseAsync(Int32 firstWriteByteCount)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.WriteAsync(ReadOnlyMemory`1 data, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpResponseStream.WriteAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Http.HttpResponseWritingExtensions.WriteAsync(HttpResponse response, String text, Encoding encoding, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Http.HttpResponseWritingExtensions.WriteAsync(HttpResponse response, String text, CancellationToken cancellationToken)
   at ConsoleClientWithBrowser.LoopbackHttpListener.SetResult(String value, HttpContext ctx) in C:\Users\stefa\Source\Repos\IdentityModel.OidcClient.Samples\NetCoreConsoleClient\src\NetCoreConsoleClient\SystemBrowser.cs:line 172

Solution

Get rid of Microsoft.AspNetCore.Server.Kestrel and Microsoft.Extensions.Configuration.Json, change the SDK to Microsoft.NET.Sdk.Web and everything works. Thanks to @JHBonarius for pointing me in the right direction.

c#
.net-5
kestrel-http-server
identitymodel
asked on Stack Overflow Mar 27, 2021 by Vincent • edited Mar 27, 2021 by Vincent

1 Answer

1

The exception is thrown in

private void SetResult(string value, HttpContext ctx)
{
    try
    {
        ctx.Response.StatusCode = 200;
        ctx.Response.ContentType = "text/html";
        // below
        ctx.Response.WriteAsync("<h1>You can now return to the application.</h1>"); <--- here
        // ^^
        ctx.Response.Body.Flush();

        _source.TrySetResult(value);
    }
...

I have two comments already.

  1. WriteAsync is an async/Task. You need to await it.
  2. your 'catch' block there will also throw in this case...... you have no 'catch' for that...

Anyhow, I think the problem is you adding a .NET 5.0 version of the new package (and remember that packages often pull in other packages which they rely on) to a quite old project. Especially with ASP.net it's not that simple. Interfaces have changed. Instantiation methods have changed. You often need to put in more work.

Change the version of Microsoft.Extentions.Configuration.Json back to v3.1.13 and the problem seems to be gone...

answered on Stack Overflow Mar 27, 2021 by JHBonarius

User contributions licensed under CC BY-SA 3.0