【问题标题】:Incorrect HttpStatus code on ASP.NET CoreASP.NET Core 上的 HttpStatus 代码不正确
【发布时间】:2018-07-13 10:21:38
【问题描述】:
我在 ASP.NET Core 应用程序上有一个异常中间件,可以执行此操作:
try
{
await _next(httpContext);
}
catch (MyException exception)
{
httpContext.Response.ContentType = "application/json";
httpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
await httpContext.Response.WriteAsync(exception.Message);
}
在本例中,我们发送“Forbidden”(403 http 状态代码),但我总是收到 500。我在 Swagger 和 Google Chrome 上对此进行了检查,但我不明白原因。
【问题讨论】:
标签:
exception
asp.net-core
middleware
【解决方案1】:
您可能在管道中的错误位置注册了中间件。您在startup.cs 中放置中间件的顺序会有所不同。例如:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.Use(async (context, next) =>
{
try
{
await next();
}
catch (Exception ex)
{
context.Response.StatusCode = StatusCodes.Status403Forbidden;
await context.Response.WriteAsync(ex.Message);
}
});
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMvc();
}
在上面的代码中,我在管道开始时注册了与您的类似的中间件。 ASP.NET Core 将按照您放置请求的顺序处理任何请求,因此我的自定义中间件将首先运行请求。但是,响应是从底部向上处理的。因此,在示例中,当控制器(或任何地方)抛出异常时,UseDeveloperExceptionPage 或 UseExceptionHandler 将首先接收任何异常,对其进行处理并将状态代码更改为 500。
如果我们把顺序改成这样:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.Use(async (context, next) =>
{
try
{
await next();
}
catch (Exception ex)
{
context.Response.StatusCode = StatusCodes.Status403Forbidden;
await context.Response.WriteAsync(ex.Message);
}
});
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMvc();
}
现在我们已经将我们的处理程序注册在请求的内置异常处理程序之后,但更重要的是,在它们之前进行响应。因此,在这种情况下,当控制器抛出异常时,我们的处理程序将捕获它、处理它并将状态代码更改为我们想要的。其他异常处理程序不会看到该异常(除非另一个中间件处理程序在我们之后抛出异常)。