首页 > 解决方案 > 未传递自定义中间件异常处理程序响应内容

问题描述

我在使用 ASP.Net Core 自定义中间件时遇到了一个奇怪的问题。

我有一个异常处理程序,我正在尝试记录异常,然后向调用者发送一条通用消息,而没有默认情况下似乎发送的异常详细信息。

问题是响应是在没有正文的情况下发送的。

我的代码:

public async Task Invoke(HttpContext context)
{
    try
    {
        await next.Invoke(context);
    }
    catch (Exception e)
    {
        logger.LogError(e, "Request threw an exception");

        context.Response.StatusCode = 500;

        using (var writer = new StreamWriter(context.Response.Body))
        {
            await writer.WriteAsync($"Error on server processing request");
            await writer.FlushAsync();
        }
    }
}

我正在使用 .Net 5。这个项目是一个 Web API 项目,以防万一。

我正在通过 swagger UI 调用我的 API,并且还使用 Edge(Chromium 版本)中的开发工具检查响应,以确保 swagger 没有隐藏正文。

响应似乎没有正文,它只是一个带有 500 代码的空响应。

在调试器中运行表明它正在执行代码,如果我将响应代码更改为 566,则 SwaggerUI 接收到响应代码,因此它正在执行某些操作。

注意:在我添加FlushAsync()调用之前,我收到一个异常发送给 Swagger,说在刷新时 dispose 正在使用同步写入,所以这似乎是必要的。

更新:管道配置,根据要求:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment() || env.IsTesting())
    {
        app.UseDeveloperExceptionPage();
        app.UseSwagger();
        app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Clients v1"));
    }

    app.UseRequestLoggingMiddleware(); // My custom middleware

    app.UseHttpsRedirection();

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

无论环境如何(开发、测试、登台或生产),行为都是相同的

标签: c#asp.net-coreasp.net-core-middleware

解决方案


我不确定为什么 usingcontext.Response.Body不起作用,但我所做的是直接使用这些方法context.Response

context.Response.StatusCode = 500;
await context.Response.WriteAsync($"Error on server processing request");

更新:鉴于您的中间件管道开始于app.UseDeveloperExceptionPage()我怀疑这就是覆盖响应的原因 - 至少如果您使用开发或测试作为环境运行。这是一个中间件,它实际上公开了您所说的要避免的完整异常详细信息。在 ASP.NET Core 项目样板/模板中,仅当不在生产环境中运行时才有意添加。

因此,也许您的问题可以通过将ASPNETCORE_ENVIRONMENT环境变量更改为Developmentor以外的其他值来解决Test。或者,如果您仍然想要自己的中间件,您可能应该删除app.UseDeveloperExceptionPage()甚至将自己的中间件app.UseRequestLoggingMiddleware()作为第一行Configure(尽管我不认为 Swagger 的东西应该干扰 - 但我不承诺:))


推荐阅读