Добавление нового пакета нарушает работу приложения .NET 5

#c# #.net-5 #kestrel-http-server #identitymodel

Вопрос:

Я пытался понять, почему мое консольное приложение выходит из строя в тот момент, когда я представляю новый пакет. Использование IdentityModel.OidcClient и Microsoft.AspNetCore.Server.Kestrel только работает, но при добавлении Microsoft.Extensions.Configuration.Json оно вызывает исключение. Я также не ссылаюсь на новый пакет в коде, я просто добавляю его в проект.

Шаги по воспроизведению:

  1. Клонировать https://github.com/IdentityModel/IdentityModel.ОидкКлиент.Образцы.мерзавец
  2. Обновите NetCoreConsoleClient до .NET 5 (пакеты обновлений).
  3. Удалите Serilog.Умывальники.Грамотный устаревший пакет.
  4. Удалите вызов .WriteTo.LiterateConsole для SeriLog в Program.cs и добавьте using IdentityModel.Client .
  5. Добавьте CancellationToken cancellationToken = new CancellationToken() параметр для InvokeAsync метода в SystemBrowser классе. Подпись IBrowser интерфейса изменилась, новый метод должен выглядеть следующим образом: public async Task<BrowserResult> InvokeAsync(BrowserOptions options, CancellationToken cancellationToken = new CancellationToken())
  6. Запустите приложение и войдите в систему с помощью alice/Алиса. Приобретение токена прошло успешно.
  7. Добавьте пакет Microsoft.Extensions.Configuration.Json .
  8. Запустите приложение. Теперь он создает исключение Object reference not set to an instance of an object при записи в http-ответ.

Исключение возникает LoopbackHttpListener.SetResult при записи в ответ: ctx.Response.WriteAsync("<h1>You can now return to the application.</h1>");

Почему добавление только пакета оказывает такое влияние на среду выполнения?

Файл проекта:

 <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>
 

Полное исключение:

 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:UsersstefaSourceReposIdentityModel.OidcClient.SamplesNetCoreConsoleClientsrcNetCoreConsoleClientSystemBrowser.cs:line 172
 

Решение

Избавьтесь от Microsoft.AspNetCore.Server.Kestrel и Microsoft.Extensions.Configuration.Json , измените SDK на Microsoft.NET.Sdk.Web и все работает. Спасибо @JHBonarius за то, что указал мне правильное направление.

Комментарии:

1. Пожалуйста, дайте более подробную информацию о шаге 5. Похоже, вы объявляете локальную переменную, но говорите, что добавляете параметр… И что именно бросает?

2. Обратите внимание, что причиной может быть простое обновление основных версий пакетов И обновление ядра 2.0 до 5.0 И удаление пакетов без внесения изменений в код. Это серьезный риск для нестабильного поведения.

3. Требуются дополнительные модификации. Нужно добавить using IdentityModel.Client; в Program.cs и нужно удалить .WriteTo.LiterateConsole(outputTemplate:... из Program.cs.

4. @JHBonarius, я добавил еще немного контекста, и я также попробовал это без обновления репозитория, но запустив новый проект и просто скопировав соответствующий код. Используя правильные пакеты.

5. Пожалуйста, добавьте возникшее исключение.

Ответ №1:

Исключение создается в

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

У меня уже есть два комментария.

  1. WriteAsync является асинхронной/задачей. Вам нужно дождаться этого.
  2. ваш блок «поймать» там также будет выброшен в этом случае…… у вас нет «улова» для этого…

В любом случае, я думаю, что проблема в том, что вы добавляете версию .NET 5.0 нового пакета (и помните, что пакеты часто используют другие пакеты, на которые они полагаются) в довольно старый проект. Особенно с ASP.net все не так просто. Интерфейсы изменились. Методы создания экземпляров изменились. Вам часто приходится прилагать больше усилий.

Измените версию Microsoft.Extentions.Configuration.Json обратно на v3.1.13, и проблема, похоже, исчезнет…

Комментарии:

1. Код клонирован из репозитория IdentityModel, я добавил async/await в свой исходный код. Мне интересно, почему простое добавление пакета может оказать такое влияние на другие сборки. У меня сложилось впечатление, что .NET 5 адресован DLL-аду, ранее испытанному в .Net Framework. Я более подробно рассмотрю фактические файлы в папке bin.

2. @Винсент нет, это уже связано с .NET Core. И «DLL-ад» — это нечто другое, чем то, что вы делаете. Вы обновляетесь с . NET core 2.0 для .NET 5.0: это не тривиальная задача. Многое меняется с таким серьезным обновлением версии. Вещи * могут * работать, но они могут сломаться в любое время. (В моей компании мы также пытаемся обновить проекты до .NET 5.0, но на это уходят недели и недели работы.)

3. я был уверен, что NetStandard достаточен для совместимости с net 5. Я попробую переписать.

Ответ №2:

У меня была похожая проблема с моим ASP.NET Основной проект 2.2. Убедившись, что у меня нет никакого Microsoft.Расширения.Пакеты X, превышающие 3.1.X, исправили проблему для меня.

Комментарии:

1. Это может быть, но на самом деле это не отвечает на вопрос, поскольку речь идет конкретно о .NET 5.0. Очевидно, что удаление современных версий библиотек не решит эту проблему для них.

Ответ №3:

У меня была точно такая же проблема.

  ctx.Response.StatusCode = 200;
 ctx.Response.ContentType = "text/html";
 ctx.Response.Headers.Add("Date", new DateTimeOffset.UtcNow.ToString());
 await ctx.Response.WriteAsync(content);
 await ctx.Response.Body.FlushAsync();
 

Установка заголовка даты решила эту проблему 4 меня, так как это то, что не работает в Kestrel.Core