Я пытаюсь реализовать глобальную обработку исключений в моем приложении MVC 5. Для этого я добавил обработчик события Application_Error в Global.asax.cs.ASP.Net MVC 5 - Cookie не хранится
В моем обработчике я прочитал данные об ошибках с сервера GetLastError. Я сохраняю данные об ошибках в файле cookie и делаю перенаправление на контроллер ошибок, который считывает файл cookie и отображает данные об ошибках пользователю.
Cookie устанавливается правильно, но когда я пытаюсь прочитать его в контроллере ошибок, cookie не существует.
Это мой код:
protected void Application_Error(Object sender, EventArgs e)
{
const String route = "Default";
const String controller = "Errors";
const String area = "";
var action = "InternalServerError";
var errorCode = 500;
try
{
// Get the previous exception.
var exception = Server.GetLastError() ?? new HttpException((Int32) HttpStatusCode.InternalServerError, "Unknown internal server error occurred.");
// Clear the exception
Server.ClearError();
// Bypass IIS custom errors
Response.TrySkipIisCustomErrors = true;
// Check for HTTP code
var httpException = exception as HttpException;
if (httpException != null)
errorCode = httpException.GetHttpCode();
// ReSharper disable once SwitchStatementMissingSomeCases
switch (errorCode)
{
case 401:
case 403:
action = "Forbidden";
break;
case 404:
action = "NotFound";
break;
}
// Try to collect some error details
try
{
var details = new WebErrorDetails
{
Exception = exception,
ErrorSource = HttpContext.Current.Request.Url.ToString()
};
HttpContext.Current.Response.Cookies.Set(new HttpCookie(CommonConstants.ErrorDetails, JsonConvert.SerializeObject(details))
{
Expires = DateTime.Now.Add(2.ToMinutes()),
HttpOnly = true
});
}
catch
{
// ignore
}
Response.RedirectToRoute(route, new RouteValueDictionary(new { area, controller, action }));
}
catch
{
Response.RedirectToRoute(route, new RouteValueDictionary(new { area, controller, action = "InternalServerError" }));
}
}
public class ErrorsController : ControllerBase
{
#region Ctor
/// <summary>
/// Initialize a new instance of the <see cref="ErrorsController" /> class.
/// </summary>
/// <param name="loggerFactory">A <see cref="ILoggerFactory" />.</param>
public ErrorsController(ILoggerFactory loggerFactory)
: base(loggerFactory.CreateLogger(typeof(ErrorsController)))
{
Logger.Trace("Enter.");
}
#endregion
#region Private Members
[NotNull]
private WebErrorDetails PopErrorDetails()
{
try
{
// GetRequestCookie looks like this => HttpContext.Current.Request.Cookies[cookieName];
var cookie = HttpContextService.GetRequestCookie(CommonConstants.ErrorDetails);
if (cookie != null)
{
var errorDetails = JsonConvert.DeserializeObject<WebErrorDetails>(cookie.Value);
if (errorDetails != null)
return errorDetails;
}
}
catch (Exception ex)
{
Logger.Warn(ex, "Failed to pop error details.");
}
// Fall-back value
return new WebErrorDetails
{
Exception = new Exception("Exception details missing."),
ErrorSource = "-"
};
}
private void StoreErrorDetails(WebErrorDetails errorDetails)
{
try
{
HttpContextService.AddCookieToResponse(new HttpCookie(CommonConstants.ErrorDetails, JsonConvert.SerializeObject(errorDetails))
{
Expires = DateTime.Now.Add(2.ToMinutes()),
HttpOnly = true
});
}
catch (Exception ex)
{
Logger.Warn(ex, "Failed to store error details.");
}
}
#endregion
#region Action Methods
/// <summary>
/// Returns a error view for 500 internal server errors.
/// </summary>
/// <returns>Returns a error view for 500 internal server errors.</returns>
public async Task<ActionResult> InternalServerError()
{
Logger.Info("Enter error action method.");
WebErrorDetails errorDetails = null;
try
{
errorDetails = PopErrorDetails();
// Get the layout view model
var layoutVm = await PrepareLayoutViewModel();
// Build the view model
var vm = new LayoutApplicationErrorViewModel
{
Exception = errorDetails.Exception,
ErrorSource = errorDetails.ErrorSource,
ViewTitle = CommonResources.Common_Static_InternalServerError
};
HttpContextService.StatusCode = (Int32) HttpStatusCode.InternalServerError;
// Set the layout view model
SetLayoutData(layoutVm, vm);
return View("Error", vm);
}
catch (Exception ex)
{
try
{
Logger.Error(ex, "Unexpected exception occurred.");
if (errorDetails != null)
StoreErrorDetails(errorDetails);
else
StoreErrorDetails(new WebErrorDetails
{
ErrorSource = HttpContextService.RequestUrl.ToString(),
Exception = ex
});
}
catch
{
// ignore
}
return RedirectToAction("GeneralError", "Errors");
}
}
/// <summary>
/// Returns a general error view without any layout.
/// </summary>
/// <returns>Returns a general error view without any layout.</returns>
public ActionResult GeneralError()
{
Logger.Info("Enter general error action method.");
try
{
// Build the view model
var errorDetails = PopErrorDetails();
var vm = new LayoutApplicationErrorViewModel
{
Exception = errorDetails.Exception,
ErrorSource = errorDetails.ErrorSource,
ViewTitle = "Error"
};
HttpContextService.StatusCode = (Int32) HttpStatusCode.InternalServerError;
return View(vm);
}
catch (Exception ex)
{
Logger.Fatal(ex, "Could not display basic error view.");
}
}
#endregion
}
Примечание: Установка и чтение куки работает везде. Я предполагаю, что проблема связана с перенаправлением?
После устранения ответа он отлично работает. Спасибо за ответ. – musium