HttpStatusCodeResult(401) returns "302 Found"

本文关键字:quot Found returns HttpStatusCodeResult | 更新日期: 2023-09-27 18:30:48

使用 ASP.NET MVC 5,我想为不同的场景返回适当的HTTP状态代码(401表示用户未经过身份验证,403表示用户无权使用某些资源等),而不是在jQuery中处理它们。

但问题是,当我尝试返回 401 时,它总是返回"302:已找到"。自定义状态代码的诀窍是什么,为什么这不起作用?

public ActionResult My()
{
    if (User.Identity.IsAuthenticated == false)
    {
        return new HttpStatusCodeResult(401, "User is not authenticated."); 
            // Returns "302: Found"
    }
   // ... other code ...
}

编辑1:有趣的一点:

如果我像这样用 401 替换 404:

return new HttpNotFoundResult("User is not authenticated.");

然后它确实给出了一个404,jQuery可以抓住问题。但是,这不是一个优雅的解决方案,因为错误代码不同。

编辑 2:302 对我不好,因为结果将在 jQuery.get().fail() 中使用,但 302 不会使fail()

HttpStatusCodeResult(401) returns "302 Found"

哈哈,这是一个很棒的问题

身份验证在 MVC 中的工作方式是,当您未登录并尝试访问安全页面时,它会引发 401 异常。然后,MVC 捕获此异常并将用户重定向到登录页面(即您看到的 302)

我想你可以做一些事情来修复它:

  • 忽略它,无论如何它可能是你想要的行为
  • 禁用登录页面重定向(phil haack 在这里有一篇很好的文章:http://haacked.com/archive/2011/10/04/prevent-forms-authentication-login-page-redirect-when-you-donrsquot-want.aspx)

编辑

根据您的评论,以下代码将在通过 ajax 请求时将所有重定向转换为 401。这是避免所列问题的一种方法

public class MvcApplication : HttpApplication {
    protected void Application_EndRequest() {
        var context = new HttpContextWrapper(Context);
        // If we're an ajax request, and doing a 302, then we actually need to do a 401
        if (Context.Response.StatusCode == 302 && context.Request.IsAjaxRequest()) {
            Context.Response.Clear();
            Context.Response.StatusCode = 401;
        }
    }
}