我经常看到写到HttpContext.Response.Body
流是一个不好的做法(或者在HttpMessageResponse中使用PushStreamContent
或StreamContent
),这导致您无法更改HTTP状态代码,如果发生了什么事。
在操作出错的情况下,是否有任何变通办法可以实际执行async
到输出流的写入,同时能够更改HTTP状态代码?
答案 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