Mvc抛出异常时为何未设置Response.StatusCode?
为什么控制器抛异常时Response.StatusCode还是200?
这个问题其实是ASP.NET Core中间件管道的设计行为,不是Bug,我来给你捋清楚背后的逻辑:
首先看中间件的执行顺序:你注册的自定义中间件在
UseMvc()之前,当调用await next()时,控制权会传递给Mvc中间件。如果Mvc里的控制器抛出异常,这个异常会直接向上冒泡回你的自定义中间件,打断了Mvc原本的响应处理流程——Mvc还没来得及修改响应状态码,就因为异常终止了。HttpResponse的默认状态码就是200,在Mvc还没机会修改它的时候,异常就已经触发了finally块的执行,所以你拿到的自然是初始的200,而不是预期的错误状态码(比如500)。
那什么时候能拿到正确的错误状态码?如果你的管道里注册了异常处理中间件(比如
UseExceptionHandler),并且它在你的自定义中间件之前注册,那么当Mvc抛出异常时,异常会被异常处理中间件捕获,它会负责设置500这类错误状态码,此时你的finally块里就能拿到正确的状态值了。举个例子:
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { // 先注册异常处理中间件,确保能捕获并处理Mvc抛出的异常 app.UseExceptionHandler("/Home/Error"); app.Use(async (context, next) => { try { await next(); } finally { var test = context.Response.StatusCode; // 现在会返回500 } }); app.UseMvc(); }
简单来说,你遇到的情况是因为异常打断了Mvc的响应设置流程,加上你的中间件位置靠前,所以拿到的是默认状态码,这完全符合ASP.NET Core管道的设计逻辑,并非Bug。
内容的提问来源于stack exchange,提问作者Esben Skov Pedersen
相关产品推荐
相关产品推荐

