HttpStatusCodeResult (401) возвращает "302 Найдено"

Используя 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 может уловить проблему. Однако это не изящное решение, поскольку код ошибки отличается.

EDIT 2: 302 не подходит для меня, так как результат будет использоваться в jQuery.get().fail(), но 302 не будет triger fail()

Ответ 1

Lol это удивительная проблема

Способ auth в MVC заключается в том, что, когда вы не вошли в систему и не пытаетесь получить доступ к защищенной странице, это исключает 401 исключение. MVC затем перехватывает это исключение и перенаправляет пользователя на страницу входа (это 302, которую вы видите)

Я предполагаю, что вы можете сделать несколько действий, чтобы исправить это:

ИЗМЕНИТЬ

В соответствии с вашими комментариями следующий код превратит все переадресации в 401s по запросу через ajax. Это один из способов избежать перечисленных проблем.

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;
        }
    }
}