响应正文写入后,在 CookieAuthenticationEvents.OnValidatePrincipal 中停止请求
Stop request in CookieAuthenticationEvents.OnValidatePrincipal after response body has been written to
在OnValidatePrincipal
中,我有以下代码:
async (context) =>
{
await context.HttpContext.SignOutAsync();
context.Principal = null;
context.Response.StatusCode = 452;
await context.Response.WriteAsJsonAsync(new { Description = "Sample description"});
await context.Response.Body.FlushAsync();
}
虽然出于某种原因,请求继续到它最初指向的位置,执行操作及其背后的代码。
我不确定这是否是错误,但响应已经写入 - 继续执行请求最初指向的 action/endpoint 似乎毫无意义。有办法阻止吗?
即使正在执行的操作 returns 不同的响应,ASP.NET 核心正确 returns 我在里面写的响应 OnValidatePrincipal
,可能是因为刷新了它, 锁定流以防止进一步写入?
我已经通过使用定制的中间件解决了这个问题:
/// <summary>
/// A middleware that short-circuits the request's pipeline, if a response has already been started.
/// </summary>
public class EnsureResponseNotStartedMiddleware
{
private readonly RequestDelegate _nextMiddleware;
public EnsureResponseNotStartedMiddleware(RequestDelegate nextMiddleware)
{
_nextMiddleware = nextMiddleware;
}
public Task InvokeAsync(HttpContext context)
{
if (!context.Response.HasStarted)
{
return _nextMiddleware(context);
}
return Task.CompletedTask;
}
}
在OnValidatePrincipal
中,我有以下代码:
async (context) =>
{
await context.HttpContext.SignOutAsync();
context.Principal = null;
context.Response.StatusCode = 452;
await context.Response.WriteAsJsonAsync(new { Description = "Sample description"});
await context.Response.Body.FlushAsync();
}
虽然出于某种原因,请求继续到它最初指向的位置,执行操作及其背后的代码。
我不确定这是否是错误,但响应已经写入 - 继续执行请求最初指向的 action/endpoint 似乎毫无意义。有办法阻止吗?
即使正在执行的操作 returns 不同的响应,ASP.NET 核心正确 returns 我在里面写的响应 OnValidatePrincipal
,可能是因为刷新了它, 锁定流以防止进一步写入?
我已经通过使用定制的中间件解决了这个问题:
/// <summary>
/// A middleware that short-circuits the request's pipeline, if a response has already been started.
/// </summary>
public class EnsureResponseNotStartedMiddleware
{
private readonly RequestDelegate _nextMiddleware;
public EnsureResponseNotStartedMiddleware(RequestDelegate nextMiddleware)
{
_nextMiddleware = nextMiddleware;
}
public Task InvokeAsync(HttpContext context)
{
if (!context.Response.HasStarted)
{
return _nextMiddleware(context);
}
return Task.CompletedTask;
}
}