微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

添加新包会破坏 .NET 5 应用程序

如何解决添加新包会破坏 .NET 5 应用程序

我一直在试图弄清楚为什么我的控制台应用程序在我引入一个新包的那一刻就失败了。使用 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. CancellationToken cancellationToken = new CancellationToken() 类中的 InvokeAsync 方法添加 Systembrowser 参数。 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 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 为我指明了正确的方向。

解决方法

异常被抛出

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. 你的“catch”块在这种情况下也会抛出......你没有'catch'......

无论如何,我认为问题在于您将新包的 .NET 5.0 版本(并记住包经常引入它们所依赖的其他包)到一个相当老的项目。尤其是对于 ASP.net,它并不是那么简单。接口已经改变。实例化方法已经改变。你经常需要投入更多的工作。

Microsoft.Extentions.Configuration.Json的版本改回v3.1.13,问题好像没有了...

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。