HttpStatusCodeResult(401)返回"200 OK"

Ada*_*abo 9 c# asp.net asp.net-mvc http-status-codes asp.net-mvc-5

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

但问题是,当我尝试返回401时,它总是返回"200:OK".MVC 5 RC1给出了"302:Found"而不是401,所以我可以使用一种解决方法(HttpStatusCodeResult(401)返回"302 Found").但现在我从MVC 5 RC1转移到MVC 5,这种行为发生了变化.现在它总是"200:OK".所以我的解决方法毫无用处,当然我不能用其他任何东西替换200.

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

   // ... other code ...
}
Run Code Online (Sandbox Code Playgroud)

怎么解决这个?

Dam*_*een 5

MVC 5+ Pipeline 修改了 401 响应代码。

选项 1 使用 .net 4.5

你可以设置 HttpContext.Response.SuppressFormsAuthenticationRedirect为true。

例如在您的自定义 AuthoriseAttribute.cs 中

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsAjaxRequest())
        {
            filterContext.Result = new JsonResult
            {
                Data = "_Logon_",
                JsonRequestBehavior = JsonRequestBehavior.AllowGet
            };
            filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized; 
            filterContext.HttpContext.Response.SuppressFormsAuthenticationRedirect = true;
        }
Run Code Online (Sandbox Code Playgroud)

选项 2. 如果不使用 .net 4.5

  public class SuppressFormsAuthenticationRedirectModule : IHttpModule
{
    private static readonly object SuppressAuthenticationKey = new object();

    public static void Register()
    {
        DynamicModuleUtility.RegisterModule(
            typeof(SuppressFormsAuthenticationRedirectModule));
    }

    public static void SuppressAuthenticationRedirect(HttpContext context)
    {
        context.Items[SuppressAuthenticationKey] = true;
    }

    public static void SuppressAuthenticationRedirect(HttpContextBase context)
    {
        context.Items[SuppressAuthenticationKey] = true;
    }

    public void Init(HttpApplication context)
    {
        context.PostReleaseRequestState += OnPostReleaseRequestState;
        context.EndRequest += OnEndRequest;
    }

    public void Dispose()
    {
    }

    private void OnPostReleaseRequestState(object source, EventArgs args)
    {
        var context = (HttpApplication)source;
        var response = context.Response;
        var request = context.Request;

        if (response.StatusCode == 401 && request.Headers["X-Requested-With"] == "XMLHttpRequest")
        {
            SuppressAuthenticationRedirect(context.Context);
        }
    }

    private void OnEndRequest(object source, EventArgs args)
    {
        var context = (HttpApplication)source;
        var response = context.Response;

        if (context.Context.Items.Contains(SuppressAuthenticationKey))
        {
            response.TrySkipIisCustomErrors = true;
            response.ClearContent();
            response.StatusCode = 401;
            response.RedirectLocation = null;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

并在 web.config

 <modules>
  <add name="SuppressFormsAuthenticationRedirectModule" type="SuppressFormsAuthenticationRedirectModule"/>
</modules>
Run Code Online (Sandbox Code Playgroud)

在这里查看更多信息


Kas*_*sen 1

我使用返回 404 的模拟器代码。您的代码可能是:

public ActionResult My()
{
  if (User.Identity.IsAuthenticated == false)
  {
    return new HttpUnauthorizedResult();
  }
  // ... other code ...
}
Run Code Online (Sandbox Code Playgroud)