ASP.Net MVC 5 - Cookie未存储

时间:2016-12-15 08:28:52

标签: c# asp.net asp.net-mvc cookies

我正在尝试在我的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适用于其他任何地方。 我认为问题与重定向有关?

1 个答案:

答案 0 :(得分:1)

//清除回复。

Response.Clear();