首页 新闻 会员 周边

httpErrors、customErrors错误处理不同

0
悬赏园豆:40 [已解决问题] 解决于 2016-03-29 18:22

想实现:

404错误跳转到404.html没有小尾巴,500错误跳转到/View/Shared/Error,并且显示错误信息

现状:

使用httpErrors时,filterContext.HttpContext.IsCustomErrorEnabled为false,自带的HandleErrorAttribute将不满足条件不能执行。

自定义了一个ErrorExceptionAttribute,重写了OnException方法,ErrorExceptionAttribute将返回一次Result。

但是同时又会跳转到httpErrors里的500配置的路径,造成ErrorExceptionAttribute返回的Result被覆盖。

这样第一次Result里的错误信息就被第二次覆盖,而第二次没有错误信息

如果httpErrors和customErrors都配置,<customErrors mode="On"></customErrors>会造成filterContext.ExceptionHandled直接变成已处理

customErrors没有此问题,但是404错误会有小尾巴,状态码为200

问题:

1、为何HandleErrorAttribute只支持customErrors

2、如何在配置httpErrors时,只返回一次Result

愿景:

有没有办法不重写,直接使用HandleErrorAttribute

 

public override void OnException(ExceptionContext filterContext)
        {
            /*
                自带异常处理只支持web.config中customErrors mode="On"的情况,不支持httpErrors,
                所以下面重写,去掉了filterContext.HttpContext.IsCustomErrorEnabled检查
            */
            //base.OnException(filterContext);

            filterContext.CheckNull(nameof(filterContext));

            if (!filterContext.IsChildAction && !filterContext.ExceptionHandled)
            {
                Exception innerException = filterContext.Exception;
                if ((new HttpException(null, innerException).GetHttpCode() == 500) && this.ExceptionType.IsInstanceOfType(innerException))
                {
                    string controllerName = (string)filterContext.RouteData.Values["controller"];
                    string actionName = (string)filterContext.RouteData.Values["action"];
                    HandleErrorInfo model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
                    ViewResult result = new ViewResult
                    {
                        ViewName = this.View,
                        MasterName = this.Master,
                        ViewData = new ViewDataDictionary<HandleErrorInfo>(model),
                        TempData = filterContext.Controller.TempData
                    };
                    filterContext.Result = result;
                    filterContext.ExceptionHandled = true;
                    filterContext.HttpContext.Response.Clear();
                    filterContext.HttpContext.Response.StatusCode = 500;
                    filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
                }
            }

            // ajax请求出现的异常返回json,否则上一步自带异常处理将跳转web.config指定的500错误页
            if ((new HttpException(null, filterContext.Exception).GetHttpCode() == 500)
                && filterContext.HttpContext.Request.IsAjaxRequest())
            {
                filterContext.Result = new JsonResult
                {
                    JsonRequestBehavior = JsonRequestBehavior.AllowGet,
                    Data = new Result(StateCode.Fail, "Oops!服务器出现了内部错误。")
                };
            }
        }
    <httpErrors errorMode="Custom" existingResponse="Replace">
      <clear />
      <error statusCode="404" path="404.html" />
      <error statusCode="500" responseMode="ExecuteURL" path="/Error" />
    </httpErrors>

 

    public class ErrorController : Controller
    {
        public ActionResult Index()
        {
            return View("Error");
        }

        [ActionName("404")]
        public ActionResult NotFound()
        {
            return new HttpStatusCodeResult(HttpStatusCode.NotFound);
        }
    }

 

            GlobalFilters.Filters.Add(new ErrorExceptionAttribute());
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
问题补充:

测试发现

filterContext.HttpContext.Response.StatusCode = 500;

这个会将页面转向配置文件里指定的500错误页,拿掉就不会,这样就可以显示错误信息

Mango_的主页 Mango_ | 初学一级 | 园豆:5
提问于:2015-12-21 18:53
< >
分享
最佳答案
0

测试发现

filterContext.HttpContext.Response.StatusCode = 500;

这个会将页面转向配置文件里指定的500错误页,拿掉就不会,这样就可以显示错误信息

Mango_ | 初学一级 |园豆:5 | 2016-03-29 18:21
其他回答(1)
0

这里有几点需要配置:

1.服务器端是否将错误呈现给客户端 

<customErrors mode="On"></customErrors>

On        指定启用自定义错误。如果未指定 defaultRedirect,用户将看到一般性错误。

Off        指定禁用自定义错误。这允许显示标准的详细错误。

RemoteOnly  指定仅向远程客户端显示自定义错误并且向本地主机显示 ASP.NET 错误。这是默认值。

默认值为 RemoteOnly。

2.iis是否显示 服务器端的错误信息

http://www.cnblogs.com/GISerYang/archive/2012/09/10/2679340.html

 

只有这2个都设置为可显示  那么浏览器才有可能显示错误信息

 

其次有关 StatusCode:

这个是http 返回码 自己可以在网上查找 200代表什么 300代表什么 400代表什么 500代表什么

改成200 可以完成功能 但是并不是一个良好的返回值 因为 这意味着 你将 一个本来错误的东西 以正确的输出进行返回了

收获园豆:40
小眼睛老鼠 | 园豆:2731 (老鸟四级) | 2016-01-22 16:08
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册