Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HandleErrorAttribute not working

I have started an MVC 3 template project in VS10 and modified global.asax.cs as such:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute { ExceptionType = typeof(DivideByZeroException), View = "DivideByZeroException", Order = 1 });
    filters.Add(new HandleErrorAttribute { View = "AllOtherExceptions", Order = 2 });
}

To web.config I added:

<customErrors mode="On">

Then created the corresponding views and finally added a DivideByZero-throw to one of the actions.

The result: The view AllOtherExceptions is rendered.

like image 748
Martin Avatar asked Jan 24 '12 09:01

Martin


2 Answers

Much though I hate to disagree with anything Darin says, he is wrong on this one.

There is no problem with setting the properties (that's the way you are supposed to do it).

The only reason your original code didn't work as expected is because you have the Order set wrong.

See MSDN:

The OnActionExecuting(ActionExecutingContext), OnResultExecuting(ResultExecutingContext), and OnAuthorization(AuthorizationContext) filters run in forward order. The OnActionExecuted(ActionExecutedContext), OnResultExecuting(ResultExecutingContext), and OnException(ExceptionContext) filters run in reverse order.

So your generic AllOtherExceptions filter needs to be the lowest Order number, not the highest.

Hopefully that helps for next time.

like image 91
fearofawhackplanet Avatar answered Sep 19 '22 08:09

fearofawhackplanet


You shouldn't set properties when registering a global action filter. You could write a custom handle error filter:

public class MyHandleErrorAttribute : FilterAttribute, IExceptionFilter
{
    public void OnException(ExceptionContext filterContext)
    {
        if (!filterContext.IsChildAction && (!filterContext.ExceptionHandled && filterContext.HttpContext.IsCustomErrorEnabled))
        {
            Exception innerException = filterContext.Exception;
            if ((new HttpException(null, innerException).GetHttpCode() == 500))
            {
                var viewName = "AllOtherExceptions";
                if (typeof(DivideByZeroException).IsInstanceOfType(innerException))
                {
                    viewName = "DivideByZeroException";
                }

                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 = viewName,
                    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;
            }
        }
    }
}

and then register it:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new MyHandleErrorAttribute());
}
like image 26
Darin Dimitrov Avatar answered Sep 21 '22 08:09

Darin Dimitrov