为什么在发生异常时不从Mvc设置StatusCode

时间:2018-05-18 06:43:50

标签: c# asp.net-core

在一个简单的应用程序中:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.Use(async (context, next) =>
    {
        try
        {
            await next();
        }
        finally
        {
            var test = context.Response.StatusCode;
            //test=200 when exception is thrown from Mvc()
        }
    });
    app.UseMvc();
}

如果控制器抛出Response.StatusCode,为什么Exception未设置?这似乎相当令人惊讶和无证。它似乎与管道的概念不一致,例如。此时已设置 401 404 。这是一个错误还是这个设计?

2 个答案:

答案 0 :(得分:2)

错误处理不是MVC中间件的责任/关注点。异常只会冒泡,其他中间件(如开发人员异常页面或异常处理程序)应该处理此错误。

您可以在<{em> UseDeveloperExceptionPage()来电之前添加UseExceptionHandler()UseMvc() 来尝试此操作。例如:

public void Configure(IApplicationBuilder app)
{
    app.UseExceptionHandler("/path/to/error/page");
    app.UseMvc();
}

答案 1 :(得分:2)

在将异常返回给调用者之前,由ASP.NET中间件设置500状态代码。如果您使用Postman测试您的API,您将看到它报告状态代码500。

您在示例中没有看到它的原因是因为您的异步函数比检测到异常的代码更上行,并返回500状态代码。

在实验中,将UseDeveloperExceptionPage()代码添加到Configure

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.Use(async (context, next) =>
    {
        try
        {
            await next();
        }
        finally
        {
            var test = context.Response.StatusCode;
        }
    });

    app.UseMvc();
}

当您使用此代码运行时,StatusCode为500.但是,如果您将代码移至app.Use(...

之后
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.Use(async (context, next) =>
    {
        try
        {
            await next();
        }
        finally
        {
            var test = context.Response.StatusCode;
        }
    });

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseMvc();
}

在此代码中,您会发现StatusCode为500.因此,所有关于设置正确状态代码的中间件都是如此。它取决于您的代码在管道中的位置,以及它看到的状态代码。