Ich versuche, eine globale Ausnahmebehandlung in meiner MVC 5-Anwendung zu implementieren. Um dies zu erreichen, habe ich dem Ereignis Application_Error in Global.asax.cs einen Handler hinzugefügt.ASP.Net MVC 5 - Cookie nicht gespeichert
In meinem Handler las ich die Fehlerdetails vom Server GetLastError. Ich speichere die Fehlerdetails in einem Cookie und führe eine Weiterleitung zu einem Fehlercontroller durch, der den Cookie liest und dem Benutzer die Fehlerdetails anzeigt.
Der Cookie wird korrekt gesetzt, aber wenn ich versuche, es in meinem Fehler-Controller zu lesen, existiert der Cookie nicht.
Dies ist mein Code:
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
}
Hinweis: Einstellung und Cookies arbeitet sonst überall lesen. Ich nehme an, das Problem hängt mit der Umleitung zusammen?
Nach dem Löschen der Antwort funktioniert es einwandfrei. Danke für die Antwort. – musium