如何在响应重定向MVC后保留Server.GetLastError

mat*_*nik 4 model-view-controller asp.net-mvc response application-error global-asax

在我的Global.asax中,我定义了Application_error方法:

protected void Application_Error(object sender, EventArgs e)
{
    // Code that runs when an unhandled error occurs

    // Get the exception object.
    var exc                         = Server.GetLastError();

    //logics

    Response.Redirect(String.Format("~/ControllerName/MethodName?errorType={0}", errorAsInteger));
}
Run Code Online (Sandbox Code Playgroud)

并且exc变量确实保留了最后一个错误但是在响应方法(MethodName)中从响应重定向后,它Server.GetLastError()是null.我怎样才能保留它或将其传递给Response.Redirect(String.Format("~/ControllerName/MethodName?errorType={0}"我所以我可以将我的方法体中的异常作为对象?

Los*_*ter 14

我想建议您在出现错误时重定向,以便保留URL并设置正确的HTTP状态代码.

而是在里面执行你的控制器 Application_Error

protected void Application_Error(object sender, EventArgs e)
{
    var exception = Server.GetLastError();

    var httpContext = ((HttpApplication)sender).Context;
    httpContext.Response.Clear();
    httpContext.ClearError();
    ExecuteErrorController(httpContext, exception);
}

private void ExecuteErrorController(HttpContext httpContext, Exception exception)
{
    var routeData = new RouteData();
    routeData.Values["controller"] = "Error";
    routeData.Values["action"] = "Index";
    routeData.Values["errorType"] = 10; //this is your error code. Can this be retrieved from your error controller instead?
    routeData.Values["exception"] = exception;

    using (Controller controller = new ErrorController())
    {
        ((IController)controller).Execute(new RequestContext(new HttpContextWrapper(httpContext), routeData));
    }
}
Run Code Online (Sandbox Code Playgroud)

然后是ErrorController

public class ErrorController : Controller
{
    public ActionResult Index(Exception exception, int errorType)
    {
        Response.TrySkipIisCustomErrors = true;
        Response.StatusCode = GetStatusCode(exception);

        return View();
    }

    private int GetStatusCode(Exception exception)
    {
        var httpException = exception as HttpException;
        return httpException != null ? httpException.GetHttpCode() : (int)HttpStatusCode.InternalServerError;
    }
}
Run Code Online (Sandbox Code Playgroud)


Vol*_*hat 4

TempData 的值将一直存在,直到被读取或会话超时。以这种方式保留 TempData 可以实现重定向等方案,因为 TempData 中的值在单个请求之外即可使用。

Dictionary<string, object> tempDataDictionary = HttpContext.Current.Session["__ControllerTempData"] as Dictionary<string, object>;
            if (tempDataDictionary == null)
            {
                tempDataDictionary = new Dictionary<string, object>();
                HttpContext.Current.Session["__ControllerTempData"] = tempDataDictionary;
            }
            tempDataDictionary.Add("LastError", Server.GetLastError());
Run Code Online (Sandbox Code Playgroud)

然后在你的行动中你可以使用

var error = TempData["LastError"];
Run Code Online (Sandbox Code Playgroud)

但这是您可以在不重定向的情况下执行的其他解决方案

protected void Application_Error(object sender, EventArgs e)
        {
            Exception exception = Server.GetLastError();

            Response.Clear();
            var httpException = exception as HttpException;
            var routeData = new RouteData();
            routeData.Values.Add("controller", "Error");

            if (httpException == null)
            {
                routeData.Values.Add("action", "HttpError500");
            }
            else
            {
                switch (httpException.GetHttpCode())
                {
                    case 404:
                        routeData.Values.Add("action", "HttpError404");
                        break;
                    default:
                        routeData.Values.Add("action", "HttpError500");
                        break;
                }
            }

            routeData.Values.Add("error", exception);
            Server.ClearError();
            IController errorController = DependencyResolver.Current.GetService<ErrorController>();
            errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
        }
Run Code Online (Sandbox Code Playgroud)

然后在控制器中您可以添加操作

public ActionResult HttpError500(Exception error)
        {
            return View();
        }
Run Code Online (Sandbox Code Playgroud)