Controller JsonResult method always return status code 200 (OK)

时间:2016-04-07 10:30:20

标签: asp.net-mvc asp.net-mvc-4 asp.net-ajax

I have a code block like this:

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

This logic I want to send status code 401 back to the client.

In my frontend, I use the jquery ajax method to call this method.

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

However, the error callback can never be reached.

I used postman to debug, and I found that no matter what I always receive 200(OK).

Do you guys have any idea what's going on here?

2 个答案:

答案 0 :(得分:3)

遗憾的是,这是默认行为。每当您获得未经授权的访问权限(401)时,MVC就会启动并重定向到登录页面,您的200(OK)来自此页面,这就是您无法获得所需响应的原因 - 401。 为了能够返回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 = "..." } );
    }
}

答案 1 :(得分:3)

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

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

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

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