本文介绍了如何在同一视图中显示例外?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

我寻求一种显示抛出异常的通用方法,而无需重定向到错误页面,而是在同一视图中显示它.我在下面尝试过这些:

I search for a generic way to display thrown exceptions without redirecting to an error page but displaying it in the same view. I tried these below:

1)我首先尝试通过在global.asax中添加自定义过滤器并在我的Attribute类中覆盖 public overlay void OnException(ExceptionContext filterContext)来处理它们,但是这样,我无法因为视图的旧模型无法访问,所以以我想要的方式填充filterContext.Result,所以我只能重定向到错误页面,但这不是我想要的.

1) I firstly tried to handle them by adding a custom filter in global.asax and overriding public override void OnException(ExceptionContext filterContext) in my Attribute class but in that way, I couldn't fill filterContext.Result in the way I want since the old model of the view is not reachable so I could only redirect to an error page but that's not what I want.

2)然后,我尝试在 BaseController 上捕获异常(我所有的控制器都继承自该异常).我再次在控制器中重写 public重写void OnException(ExceptionContext filterContext)并将异常详细信息等放入ViewBag中,并通过 filterContext.HttpContext.Response.Redirect(filterContext)将页面重定向到同一视图.RequestContext.HttpContext.Request.Path); ,但是ViewBag内容在重定向页面中丢失了,所以我想不出其他办法了?

2) Then I tried to catch the exceptions on my BaseController(All of my controllers inherits from it). I again override public override void OnException(ExceptionContext filterContext) in my controller and put exception details etc. in ViewBag and redirected the page to the same view by filterContext.HttpContext.Response.Redirect(filterContext.RequestContext.HttpContext.Request.Path ); but ViewBag contents are lost in the redirected page so I can't think any other way?

我该如何实现?我在 BaseController 中编写的代码示例如下:

How can I achieve that? Code Sample that I wrote in my BaseController is below:

protected override void OnException(ExceptionContext filterContext) {
    var controllerName = (string)filterContext.RouteData.Values["controller"];
    var actionName = (string)filterContext.RouteData.Values["action"];

    //filterContext.Result = new ViewResult
    //{
    //    ViewName = actionName,
    //    ViewData = new ViewDataDictionary<??>(??),
    //    TempData = filterContext.Controller.TempData,
    //};

    filterContext.ExceptionHandled = true;
    filterContext.HttpContext.Response.Clear();

    filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
    ModelState.AddModelError("Error", filterContext.Exception.Message);
    ViewBag.das = "dasd";
    filterContext.HttpContext.Response.Redirect(filterContext.RequestContext.HttpContext.Request.Path);
}

推荐答案

我不久前找到了解决方案,并添加了解决方案,以便对其他人有所帮助.我使用TempData和_Layout来显示错误:

I found the solution a while ago and add the solution so that it may help the others. I use TempData and _Layout to display errors:

public class ErrorHandlerAttribute : HandleErrorAttribute
{
    private ILog _logger;

    public ErrorHandlerAttribute()
    {
        _logger = Log4NetManager.GetLogger("MyLogger");
    }

    public override void OnException(ExceptionContext filterContext)
    {
        if (filterContext.ExceptionHandled)
        {
            return;
        }

        if (!ExceptionType.IsInstanceOfType(filterContext.Exception))
        {
            return;
        }

        // if the request is AJAX return JSON else view.
        if (filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
        {
            filterContext.Result = new JsonResult
            {
                JsonRequestBehavior = JsonRequestBehavior.AllowGet,
                Data = new
                {
                    error = true,
                    message = filterContext.Exception.Message
                }
            };
            filterContext.HttpContext.Response.StatusCode = 500;
        }

        // log the error using log4net.
        _logger.Error(filterContext.Exception.Message, filterContext.Exception);

        filterContext.ExceptionHandled = true;
        filterContext.HttpContext.Response.Clear();

        filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;

        if (filterContext.HttpContext.Request.Headers["X-Requested-With"] != "XMLHttpRequest")
        {
            if (filterContext.Controller.TempData["AppError"] != null)
            {
                //If there is a loop it will break here.
                filterContext.Controller.TempData["AppError"] = filterContext.Exception.Message;
                filterContext.HttpContext.Response.Redirect("/");
            }
            else
            {
                int httpCode = new HttpException(null, filterContext.Exception).GetHttpCode();

                switch (httpCode)
                {
                    case 401:
                        filterContext.Controller.TempData["AppError"] = "Not Authorized";
                        filterContext.HttpContext.Response.Redirect("/");
                        break;
                    case 404:
                        filterContext.Controller.TempData["AppError"] = "Not Found";
                        filterContext.HttpContext.Response.Redirect("/");
                        break;
                    default:
                        filterContext.Controller.TempData["AppError"] = filterContext.Exception.Message;
                        //Redirect to the same page again(If error occurs again, it will break above)
                        filterContext.HttpContext.Response.Redirect(filterContext.RequestContext.HttpContext.Request.RawUrl);
                        break;
                }
            }
        }
    }
}

在Global.asax中:

And in Global.asax:

    protected void Application_Error(object sender, EventArgs e)
    {
        var httpContext = ((MvcApplication)sender).Context;
        var ex = Server.GetLastError();

        httpContext.ClearError();
        httpContext.Response.Clear();
        httpContext.Response.StatusCode = ex is HttpException ? ((HttpException)ex).GetHttpCode() : 500;
        httpContext.Response.TrySkipIisCustomErrors = true;

        var routeData = new RouteData();
        routeData.Values["controller"] = "ControllerName";
        routeData.Values["action"] = "ActionName";
        routeData.Values["error"] = "404"; //Handle this url paramater in your action
        ((IController)new AccountController()).Execute(new RequestContext(new HttpContextWrapper(httpContext), routeData));
    }

这篇关于如何在同一视图中显示例外?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-09 00:35