Exception ASP.NET Core上的HttpStatus代码不正确

Exception ASP.NET Core上的HttpStatus代码不正确,exception,asp.net-core,middleware,Exception,Asp.net Core,Middleware,我在ASP.NET核心应用程序上有一个异常中间件,可以执行以下操作: try { await _next(httpContext); } catch (MyException exception) { httpContext.Response.ContentType = "application/json"; httpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden; await httpCo

我在ASP.NET核心应用程序上有一个异常中间件,可以执行以下操作:

try
{
    await _next(httpContext);
}
catch (MyException exception)
{
    httpContext.Response.ContentType = "application/json";
    httpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;

    await httpContext.Response.WriteAsync(exception.Message);
}

在这个例子中,我们发送禁止403HTTP状态码,但我总是收到500。我在Swagger和Google Chrome上检查了这一点,我不明白原因。

您可能在管道中的错误位置注册了中间件。在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();
}
现在,我们已经将处理程序注册为在请求的内置异常处理程序之后,但更重要的是,在响应的内置异常处理程序之前。因此,在这种情况下,当控制器抛出异常时,我们的处理程序将捕获它,处理它,并将状态代码更改为我们想要的。其他异常处理程序将不会看到异常,除非另一个中间件处理程序在我们之后抛出异常