如何在开始写入 ASP.NET Core 中的 HttpContext.Response.Body 流后更改 http 状态代码?

How to change the http status code after starting writing to the HttpContext.Response.Body stream in ASP.NET Core?

我经常看到写入 HttpContext.Response.Body 流是一种不好的做法(或使用 PushStreamContentStreamContent 作为 HttpMessageResponse 的一部分),因为这样您就无法更改 HTTP 状态如果发生错误,请输入代码。

是否有任何解决方法来实际执行 async 写入输出流,同时能够更改 HTTP 状态代码以防操作出错?

是的。最佳实践是编写中间件。例如:

public class ErrorWrappingMiddleware
{
    private readonly RequestDelegate next;

    public ErrorWrappingMiddleware(RequestDelegate next)
    {
        this.next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        try
        {
            await next.Invoke(context);
        }
        catch (Exception exception)
        {
            context.Response.StatusCode = 500;
            await context.Response.WriteAsync(...); // change you response body if needed
        }
    }
}

并将它们注入您的管道

public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider serviceProvider)
{
...
app.UseMiddleware<ErrorWrappingMiddleware>();
...
}

当然,您可以根据需要更改中间件中的逻辑,包括根据需要更改响应代码。此外,您可以抛出您自己的异常类型,例如 MyOwnException,然后在中间件中捕获并调用您自己的与您的异常相关的逻辑。

下次不要打电话。在将响应发送到客户端后调用。响应开始后对 HttpResponse 的更改,抛出异常。

例如,设置 headers 和状态代码等更改会引发异常。在调用 next 后写入响应 body 可能会导致违反协议,即写入超过 Content-Length header.

中指定的内容

它可能会破坏 body 格式,例如将 HTML 页脚写入 CSS 文件。

HasStarted 是一个有用的提示,指示是否已发送 header 或是否已写入 body。

勾选this