Когда мое приложение встречает исключение типа UnauthorizedAccessException
во время запроса AJAX, я хочу обработать поведение самостоятельно и вернуть пользовательский ответ JSON.
Итак, я переопределил метод OnException
в базовом контроллере, от которого наследуются все мои контроллеры, вот так:
protected override void OnException(ExceptionContext filterContext)
{
var exception = filterContext.Exception;
if (exception is UnauthorizedAccessException)
{
filterContext.ExceptionHandled = true;
if (filterContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.HttpContext.Response.StatusCode = (int)System.Net.HttpStatusCode.Unauthorized;
filterContext.HttpContext.Response.ContentType = "application/json";
JavaScriptSerializer serializer = new JavaScriptSerializer();
string json = serializer.Serialize(new { IsUnauthenticated = true });
filterContext.HttpContext.Response.Write(json);
filterContext.HttpContext.Response.End();
}
else
{
filterContext.Result = RedirectToAction("LogOut", "Account");
}
}
else
{
// Allow the exception to be processed as normal.
base.OnException(filterContext);
}
}
Теперь это в значительной степени делает то, что я хочу. Если во время запроса AJAX возникнет исключение, мой JavaScript вернет правильный объект JSON, как требуется.
Однако проблема заключается в том, что приложение затем получает внутреннюю HttpException
с сообщением:
Невозможно перенаправить после отправки заголовков HTTP.
И трассировка стека из исключения:
в System.Web.HttpResponse.Redirect (URL-адрес строки, логический конец-ответ, логический перманент)
в System.Web.Security.FormsAuthenticationModule.OnLeave (Источник объекта, EventArgs eventArgs)
в System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute ()
в System.Web.HttpApplication.ExecuteStepImpl (шаг IExecutionStep)
в System.Web.HttpApplication.ExecuteStep (шаг IExecutionStep, логическое и завершено синхронно)
Я получаю эту информацию об исключении при добавлении точки останова к методу Application_Error
MvcApplication
, например:
protected void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
LogError(ex);
}
Итак, хотя мое приложение дает результат именно так, как я хочу с точки зрения пользовательского опыта. У меня есть это «закулисное» исключение, которого я действительно не хочу, чтобы это произошло.
Что здесь не так? И что я могу сделать, чтобы исключение не произошло?