ASP.NET MVC returning 302 (Found) HTTP status code on unauthorized Ajax calls instead of 401(Unauthorized) like classic ASP.NET

Classic ASP.NET

On classic ASP.NET when calling a [WebMethod] with Ajax in an unauthorized context (most likely in the case where the session expired) the response http status code is 401. You can handle this in the “error” handler (provided by most Ajax frameworks) and redirect to login page. For example I use this code with jQuery:


public static MyModel GetStuff()
    return new MyModel();


    type: "POST",
    url: "Default.aspx/GetStuff",
    data: "{}",
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function(msg) {
        // do stuff
    error: function(xhr, status, ex) {
        if (xhr.status == 401) // unauthorized
            window.location = "Login.aspx?ReturnUrl=" + window.location.pathname;


To do the same in ASP.NET MVC I have this method in my controller:

public ActionResult GetStuff()
    return Json(new MyModel());

The ASP.NET MVC infrastructure doesn’t return 401 http status code on failed authorization but 302 http status code (actually the 401 status code is returned initially but later, in the same request, is intercepted by the infrastructure and replaced by 302 status code). XMLHttpRequest object handles this internally automatically following the redirect (no event is fired client side). The Ajax call will end in “success” but the message won’t be the expected JSON but the html of the login page.

The best (well, it’s a hack, if you a better way please tell me) way I found is to replace 302 status code by 401 status code on request end. I added the following code to Global.asax :

protected void Application_EndRequest()
    if (Context.Response.StatusCode == 302 &&
        Context.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
        Context.Response.StatusCode = 401;

And the client side code (using Ext JS this time) is:

Ext.Ajax.on('requestexception', function(conn, response, options) {
    if (response.status == 401) {
        window.location = '<%= Html.ActionUrl("Account", "LogOn") %>?ReturnUrl=' +
This entry was posted in AJAX, JavaScript. Bookmark the permalink.

3 Responses to ASP.NET MVC returning 302 (Found) HTTP status code on unauthorized Ajax calls instead of 401(Unauthorized) like classic ASP.NET

  1. Josh says:

    Funny, I am having this same issue, in a custom handler I am working on. Your solution won’t work in my case as sometimes we will want the 302 error for other paths in the application.

  2. Brian says:

    Hi Ben,

    Thanks for posting this up, I am currently trying to implement an MVC uploader and this post is a helpful starting point. One problem I am having with your code is that Im getting a 302 HTTP error every time I post to my controler. Any ideas on why this should be?

    Thanks again,


  3. Brian says:

    Sorry … posted to wrong blog :(

Leave a Reply

Your email address will not be published. Required fields are marked *


You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>