控制器 JsonResult 方法始终 return 状态代码 200(确定)

Controller JsonResult method always return status code 200 (OK)

我有这样一个代码块:

public class AccountController : Controller
{
    [HttpPost]
    public JsonResult Check(LoginModel model){
        ...
        Response.StatusCode = (int)HttpStatusCode.Unauthorized;
        return Json( new { ErrorMessage = "..." } );
    }
}

这个逻辑我要将状态码401回传给客户端

在我的前端中,我使用 jquery ajax 方法来调用此方法。

$.ajax({
  ...
  success: function(data, textStatus, xhr){
  ...
  },
  error: function(xhr, textStatus, error){
  ...
  }
});

但是,错误回调始终无法到达。

我用postman调试了一下,发现无论怎样总是收到200(OK)。

你们知道这里发生了什么吗?

遗憾的是,这是默认行为。每当您获得未经授权的访问 (401) 时,MVC 就会启动并将您重定向到登录页面,您的 200(OK) 来自该页面,这就是为什么您永远不会得到您想要的响应 - 401。 为了能够 return 401 代码,您必须像这样显式抑制响应的身份验证重定向:

HttpContext.Response.SuppressFormsAuthenticationRedirect = true;

那么你得到的是:

public class AccountController : Controller
{
    [HttpPost]
    public JsonResult Check(LoginModel model)
    {
        ...
        Response.StatusCode = (int)HttpStatusCode.Unauthorized;
        Response.SuppressFormsAuthenticationRedirect = true;
        return Json( new { ErrorMessage = "..." } );
    }
}

我在 ASP.Net MVC 5 应用程序中也遇到过这个问题。在我的例子中,我使用带有 ASP.Net Identity v 2.0 的 OWIN 中间件来对用户进行身份验证。奇怪的是,Katana 项目的默认行为是将 HTTP 代码从 401 覆盖到 200,并将您的原始代码 401 和相关消息放入 header,称为

*X-Responded-JSON*, like this:
*X-Responded-JSON: {"status":401,"headers":{"location":"http:\/\/localhost:59540\/Account\/Login?ReturnUrl=%2Fapi%2FTestBasic"}}*

为了抑制默认行为,您需要更新 StartUp class。你可以在这里找到更多: http://kevin-junghans.blogspot.in/2013/12/returning-401-http-status-code-on.html

这是基于此 post 的解决方案: https://brockallen.com/2013/10/27/using-cookie-authentication-middleware-with-web-api-and-401-response-codes/