我正在尝试在我的MVC 5应用程序中实现全局异常处理。 为了实现这一点,我在Global.asax.cs中为Application_Error事件添加了一个处理程序。
在我的处理程序中,我从Server 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
}
注意:设置和阅读Cookie适用于其他任何地方。 我认为问题与重定向有关?
答案 0 :(得分:1)
//清除回复。
Response.Clear();