#c# #.net-5 #kestrel-http-server #identitymodel
Вопрос:
Я пытался понять, почему мое консольное приложение выходит из строя в тот момент, когда я представляю новый пакет. Использование IdentityModel.OidcClient
и Microsoft.AspNetCore.Server.Kestrel
только работает, но при добавлении Microsoft.Extensions.Configuration.Json
оно вызывает исключение. Я также не ссылаюсь на новый пакет в коде, я просто добавляю его в проект.
Шаги по воспроизведению:
- Клонировать https://github.com/IdentityModel/IdentityModel.ОидкКлиент.Образцы.мерзавец
- Обновите NetCoreConsoleClient до .NET 5 (пакеты обновлений).
- Удалите Serilog.Умывальники.Грамотный устаревший пакет.
- Удалите вызов
.WriteTo.LiterateConsole
для SeriLog в Program.cs и добавьтеusing IdentityModel.Client
. - Добавьте
CancellationToken cancellationToken = new CancellationToken()
параметр дляInvokeAsync
метода вSystemBrowser
классе. ПодписьIBrowser
интерфейса изменилась, новый метод должен выглядеть следующим образом:public async Task<BrowserResult> InvokeAsync(BrowserOptions options, CancellationToken cancellationToken = new CancellationToken())
- Запустите приложение и войдите в систему с помощью alice/Алиса. Приобретение токена прошло успешно.
- Добавьте пакет
Microsoft.Extensions.Configuration.Json
. - Запустите приложение. Теперь он создает исключение
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);
}
...
У меня уже есть два комментария.
WriteAsync
является асинхронной/задачей. Вам нужно дождаться этого.- ваш блок «поймать» там также будет выброшен в этом случае…… у вас нет «улова» для этого…
В любом случае, я думаю, что проблема в том, что вы добавляете версию .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