提问人:vbond007 提问时间:8/28/2022 更新时间:8/29/2022 访问量:487
.Net 6 控制台应用中的 Kestrel - 调用 HttpContext.Response.WriteAsync() 时出现 NullReferenceException
Kestrel in .Net 6 console App - NullReferenceException when calling HttpContext.Response.WriteAsync()
问:
我正在使用 .Net 6 编写 Windows 服务器,我需要侦听内部网络 http 请求。
我决定使用红隼。
当我发送 http 请求时,一切都很好,Kestrel 接受该请求,我可以用代码管理它。
但是当我想通过 发送答案时,会启动 NullReferenceException。
堆栈跟踪如下:HttpContext.Response.WriteAsync()
在 Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.CreateResponseHeader(Boolean appCompleted) 在 Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.InitializeResponseAsync(Int32 firstWriteByteCount) 在 Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.WriteAsync(ReadOnlyMemory'1 data, CancellationToken cancellationToken) 在 Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpResponseStream.WriteAsync(Byte[] 缓冲区、 Int32 偏移量、 Int32 计数、 CancellationToken cancellationToken) 在 Microsoft.AspNetCore.Http.HttpResponseWritingExtensions.WriteAsync(HttpResponse response、字符串文本、编码编码、CancellationToken cancellationToken) 在 Microsoft.AspNetCore.Http.HttpResponseWritingExtensions.WriteAsync(HttpResponse response, 字符串文本, CancellationToken cancellationToken)
我的代码非常简单。 首先,注册服务:
IPAddress address = settings.BindAddress == null ? IPAddress.Any : IPAddress.Parse(settings.BindAddress);
services.Configure<KestrelServerOptions>(options =>
{
options.Listen(address, settings.ListeningPort);
});
services.AddSingleton<IServer, KestrelServer>();
services.AddSingleton<ITransportFactory, SocketTransportFactory>();
services.AddSingleton<IApplicationLifetime, ApplicationLifetime>();
services.AddTransient<IHttpContextFactory, HttpContextFactory>();
然后,服务器在实现 IHttpApplication 的类中启动,并且可以管理请求:
public class HttpController : IHttpApplication<HttpContext>
{
private readonly IServer _server;
private readonly ILogger<HttpController> _logger;
public HttpController(IServer server, IHttpContextFactory httpContextFactory, ILogger<HttpController> logger)
{
_server = server;
_httpContextFactory = httpContextFactory;
_logger = logger;
}
public async Task StartAsync(CancellationToken cancellationToken)
{
await Task.Yield();
_server.StartAsync(this, cancellationToken);
}
public HttpContext CreateContext(IFeatureCollection contextFeatures)
{
return _httpContextFactory.Create(contextFeatures);
}
public void DisposeContext(HttpContext context, Exception exception)
{
_httpContextFactory.Dispose(context);
}
public async Task ProcessRequestAsync(HttpContext context)
{
_logger.LogInformation("{Method} Http request received: {Path}", context.Request.Method, context.Request.Path);
try
{
if (context.Request.Path.StartsWithSegments("/hello"))
{
var resp = "Hello World!";
await context.Response.WriteAsync(resp);
}
}
catch(Exception ex)
{
_logger.LogError("Error while managing HTTP {Method} request to {Path} : {message}", context.Request.Method, context.Request.Path, ex.Message);
}
}
}
知道为什么要启动这个 NullReferenceException 吗?
谢谢。context.Response.WriteAsync()
答:
最后,经过 2 天的调查,我找到了解决方法。 我不得不使用包 Microsoft.AspNetCore.App。 然后我不得不添加这样的服务:
services.AddSingleton<IServer, KestrelServer>();
services.AddSingleton<IConnectionListenerFactory, SocketTransportFactory>();
services.AddTransient<IHttpContextFactory, DefaultHttpContextFactory>();
这意味着我必须删除该行。它由添加的包进行管理。
我不得不用 替换,我用 替换了......ApplicationLifeTime
ITransportFactory
IConnectionListenerFactory
HttpContextFactory
DefaultHttpContextFactory
部分答案在这里找到: https://github.com/dotnet/aspnetcore/issues/28112
评论