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

问题描述 投票:0回答:2

我经常发现写入

HttpContext.Response.Body
流是一种不好的做法(或者使用
PushStreamContent
StreamContent
作为 HttpMessageResponse 的一部分),因为如果发生错误,您将无法更改 HTTP 状态代码。

是否有任何解决方法可以实际执行

async
写入输出流,同时能够更改HTTP状态代码以防操作出错?

c# .net .net-core streaming asp.net-core-webapi
2个回答
3
投票

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

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
,然后在中间件中捕获并调用与异常相关的您自己的逻辑。


2
投票

接下来不要打电话。将响应发送到客户端后调用。响应开始后对 HttpResponse 进行更改,引发异常。

例如,设置标头和状态代码等更改会引发异常。调用 next 后写入响应正文可能会导致协议违规,即写入的内容超出 Content-Length 标头中指定的内容。

它可能会破坏正文格式,就像将 HTML 页脚写入 CSS 文件一样。

HasStarted
是一个有用的提示,指示是否已发送标头或是否已写入正文。

检查 ASP.NET Core 中间件

© www.soinside.com 2019 - 2024. All rights reserved.