How to disable standard ASP.NET handling of 401 response code (redirecting to login page) for AJAX/JSON requests?
For web-pages it's okay, but for AJAX I need to get right 401 error code instead of good looking 302/200 for login page.
How to disable standard ASP.NET handling of 401 response code (redirecting to login page) for AJAX/JSON requests?
For web-pages it's okay, but for AJAX I need to get right 401 error code instead of good looking 302/200 for login page.
You could choose to create a custom FilterAttribute
implementing the IAuthorizationFilter
interface.
In this attribute you add logic to determine if the request are supposed to return JSON. If so, you can return an empty JSON result (or do whatever you like) given the user isn't signed in. For other responses you would just redirect the user as always.
Even better, you could just override the OnAuthorization
of the AuthorizeAttribute
class so you don't have to reinvent the wheel. Add the logic I mentioned above and intercept if the filterContext.Cancel
is true (the filterContext.Result
will be set to an instance of the HttpUnauthorizedResult
class.
Read more about "Filters in ASP.NET MVC CodePlex Preview 4" on Phil Haacks blog. It also applies to the latest preview.
The ASP.NET runtime is developed so that it always will redirect the user if the HttpResponse.StatusCode
is set to 401, but only if the <authentication />
section of the Web.config is found.
Removing the authentication section will require you to implement the redirection to the login page in your attribute, but this shouldn't be a big deal.
You could also use the Global.asax to interrupt this process with something like this:
protected void Application_PreSendRequestHeaders(object sender, EventArgs e) {
if (Response.StatusCode == 401) {
Response.Clear();
Response.Redirect(Response.ApplyAppPathModifier("~/Login.aspx"));
return;
}
}
In classic ASP.NET you get a 401 http response code when calling a WebMethod with Ajax. I hope they'll change it in future versions of ASP.NET MVC. Right now I'm using this hack:
protected void Application_EndRequest()
{
if (Context.Response.StatusCode == 302 && Context.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
{
Context.Response.Clear();
Context.Response.StatusCode = 401;
}
}