HttpStatusCodeResult(401) returns “200 OK”
asp.net, asp.net-mvc, asp.net-mvc-5, c#, http-status-codes
Solution
The MVC 5+ Pipeline modifies 401 response codes.
Option 1 With .net 4.5
you can set `HttpContext.Response.SuppressFormsAuthenticationRedirect` to true.
e.g. in your custom 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;
}
Option 2. If not using .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;
}
}
}
and in web.config
<modules>
<add name="SuppressFormsAuthenticationRedirectModule" type="SuppressFormsAuthenticationRedirectModule"/>
</modules>
See here for more info
Problem
Using ASP.NET MVC 5, I would like to return appropriate HTTP status code for different scenarios (401 for user is not authenticated, 403 when user has no right for some resource, etc.), then handle them in jQuery. But the problem is, when I try to return 401, it always returns "200: OK". MVC 5 RC1 was giving "302: Found" instead of 401, so I could use a workaround (HttpStatusCodeResult(401) returns "302 Found"). But now I moved from MVC 5 RC1 to MVC 5 and this behaviour changed. Now it is always "200: OK". So my workaround is useless, of course I can't replace 200 with anything else. ``` public ActionResult My() { if (User.Identity.IsAuthenticated == false) { return new HttpStatusCodeResult(401, "User is not authenticated."); // Returns "200: OK" } // ... other code ... } ``` How to solve this?