【问题标题】:Adding new package breaks the .NET 5 application添加新包会破坏 .NET 5 应用程序
【发布时间】:2021-03-27 09:36:08
【问题描述】:

我一直试图弄清楚为什么我的控制台应用程序在我引入一个新包时会失败。使用 IdentityModel.OidcClientMicrosoft.AspNetCore.Server.Kestrel only 有效,但添加 Microsoft.Extensions.Configuration.Json 时会引发异常。我也没有在代码中引用新包,我只是将它添加到项目中。

重现步骤:

  1. 克隆https://github.com/IdentityModel/IdentityModel.OidcClient.Samples.git

  2. NetCoreConsoleClient 升级到 .NET 5(更新包)。

  3. 删除 Serilog.Sinks.Literate 过时的包。

  4. 删除 Program.cs 中对 SeriLog 的 .WriteTo.LiterateConsole 的调用并添加 using IdentityModel.Client

  5. SystemBrowser 类中为InvokeAsync 方法添加CancellationToken cancellationToken = new CancellationToken() 参数。 IBrowser 接口的签名已更改,新方法应如下所示:public async Task<BrowserResult> InvokeAsync(BrowserOptions options, CancellationToken cancellationToken = new CancellationToken())

  6. 运行应用程序并使用 alice/alice 登录。获取token成功。

  7. 添加包Microsoft.Extensions.Configuration.Json

  8. 运行应用程序。现在在写入 http 响应时会抛出异常 Object reference not set to an instance of an object

写入响应时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:\Users\stefa\Source\Repos\IdentityModel.OidcClient.Samples\NetCoreConsoleClient\src\NetCoreConsoleClient\SystemBrowser.cs:line 172

解决方案

摆脱Microsoft.AspNetCore.Server.KestrelMicrosoft.Extensions.Configuration.Json,将SDK更改为Microsoft.NET.Sdk.Web,一切正常。感谢@JHBonarius 为我指明了正确的方向。

【问题讨论】:

  • 请在第 5 步中提供更多详细信息。您似乎在声明一个局部变量,但您说您正在添加一个参数......究竟抛出了什么?
  • 请注意,仅升级软件包的主要版本并将核心 2.0 升级到 5.0 并删除软件包,而不修改代码,也可能是原因。这是不稳定行为的主要风险。
  • 需要更多修改。需要在 Program.cs 中添加using IdentityModel.Client; 并需要从 Program.cs 中删除.WriteTo.LiterateConsole(outputTemplate:...
  • @JHBonarius,我添加了更多上下文,我也尝试过不升级存储库,但通过启动一个新项目并复制相关代码。使用正确的包。
  • 请添加抛出的异常。

标签: c# .net-5 kestrel-http-server identitymodel


【解决方案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);
    }
...

我已经有两个 cmets。

  1. WriteAsync 是一个异步/任务。你需要等待它。
  2. 你的 'catch' 块也会在这种情况下抛出......你没有'catch' ......

无论如何,我认为问题在于您将新包的 .NET 5.0 版本(请记住,包通常会引入它们所依赖的其他包)到一个相当旧的项目中。特别是对于 ASP.net,它并不是那么简单。接口发生了变化。实例化方法发生了变化。你经常需要付出更多的努力。

Microsoft.Extentions.Configuration.Json的版本改回v3.1.13,问题似乎消失了……

【讨论】:

  • 代码是从 IdentityModel 存储库中克隆出来的,我已将 async/await 添加到我的原始代码中。我想知道为什么只是添加包会对其他程序集产生如此大的影响。我的印象是 .NET 5 解决了以前在 .Net Framework 中经历的 DLL 地狱。我将深入了解 bin 文件夹中的实际文件。
  • @Vincent 不,.NET Core 已经有了。而“DLL-hell”就是你正在做的事情。您正在从 .NET core 2.0 升级到 .NET 5.0:这不是一项简单的任务。随着这样的主要版本升级,许多事情都发生了变化。事情 * 可能 * 工作,但他们可能随时中断。 (在我的公司,我们也在尝试将项目升级到 .NET 5.0,但这需要数周和数周的工作。)
  • 我确信 NetStandard 足以兼容 net 5。我会尝试重写。
【解决方案2】:

我的 ASP.NET Core 2.2 项目也有类似的问题。确保我没有任何大于 3.1.X 的 Microsoft.Extensions.X 包为我解决了这个问题。

【讨论】:

  • 可能是这样,但它并没有真正回答这个问题,因为这是专门关于 .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 中的失败

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-17
    • 2015-09-21
    • 2014-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多