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

时间:2018-11-11 20:08:47

标签: c# .net .net-core streaming asp.net-core-webapi

我经常看到写到HttpContext.Response.Body流是一个不好的做法(或者在HttpMessageResponse中使用PushStreamContentStreamContent),这导致您无法更改HTTP状态代码,如果发生了什么事。

在操作出错的情况下,是否有任何变通办法可以实际执行async到输出流的写入,同时能够更改HTTP状态代码?

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

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

例如,诸如设置标题和状态代码之类的更改会引发异常。在下次调用之后写入响应正文可能会导致协议冲突,即,写入的内容超出了Content-Length标头中指定的内容。

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

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

选中this