Custom error redirection page does not work with ELMAH

admin

Administrator
Staff member
I have implemented ELMAH logging in my application, <strong>everything is working fine, except custom page redirection.</strong>

I have added following lines in
Code:
web.config

Code:
&lt;customErrors mode="On" defaultRedirect="/Bug/ViewBug"&gt;
    &lt;error statusCode="401" redirect="/Bug/AccessDenied"/&gt;
    &lt;error statusCode="403" redirect="/Bug/AccessDenied"/&gt;
     &lt;error statusCode="404" redirect="/Bug/PageNotFound" /&gt;
    &lt;error statusCode="500" redirect="/Bug/InternalServerError" /&gt;
&lt;/customErrors&gt;

following lines in
Code:
Controllers\BugController.cs

Code:
public class BugController : Controller
    {
        public ActionResult ViewBug()
        {
            return View();
        }
        public ActionResult AccessDenied()
        {
            return View();
        }
        public ActionResult PageNotFound()
        {
            return View();
        }
        public ActionResult InternalServerError()
        {
            return View();
        }
    }

and as per controller I have also created view for same.

I have <strong>implemented ELMAH logging using <a href="http://dotnetdarren.wordpress.com/2010/07/27/logging-on-mvc-part-1/" rel="nofollow">this tutorial</a></strong>

<strong>HandleErrorActionInvoker.cs</strong>

Code:
 public class HandleErrorActionInvoker : ControllerActionInvoker
    {
        private readonly IExceptionFilter filter;
        public HandleErrorActionInvoker(IExceptionFilter filter)
        {
            if (filter == null)
            {
                throw new ArgumentNullException("filter");
            }
            this.filter = filter;
        }

        protected override FilterInfo GetFilters(
        ControllerContext controllerContext,
        ActionDescriptor actionDescriptor)
        {
            var filterInfo =
            base.GetFilters(controllerContext,
            actionDescriptor);
            filterInfo.ExceptionFilters.Add(this.filter);
            return filterInfo;
        }
    }

<strong>HandleErrorAttribute.cs</strong>

Code:
 public class HandleErrorAttribute : System.Web.Mvc.HandleErrorAttribute
    {
        public override void OnException(ExceptionContext context)
        {
            base.OnException(context);
            var e = context.Exception;
            // if unhandled, will be logged anyhow | // prefer signaling, if possible | // filtered?
            if (!context.ExceptionHandled || RaiseErrorSignal(e) || IsFiltered(context)) return;
            LogException(e);
        }
        private static bool RaiseErrorSignal(Exception e)
        {
            var context = HttpContext.Current;
            if (context == null) return false;
            var signal = ErrorSignal.FromContext(context);
            if (signal == null) return false;
            signal.Raise(e, context);
            return true;
        }
        private static bool IsFiltered(ExceptionContext context)
        {
            var config = context.HttpContext.GetSection("elmah/errorFilter") as ErrorFilterConfiguration;
            if (config == null) return false;
            var testContext = new ErrorFilterModule.AssertionHelperContext(context.Exception, HttpContext.Current);
            return config.Assertion.Test(testContext);
        }
        private static void LogException(Exception e)
        {
            var context = HttpContext.Current;
            ErrorLog.GetDefault(context).Log(new Error(e, context));
        }
    }

<strong>HandleErrorControllerFactory.cs</strong>

Code:
public class HandleErrorControllerFactory : DefaultControllerFactory
    {
        public override IController CreateController(RequestContext requestContext, string controllerName)
        {
            var controller = base.CreateController(requestContext, controllerName);
            var c = controller as Controller;
            if (c != null)
            {
                c.ActionInvoker = new HandleErrorActionInvoker(new HandleErrorAttribute());
            }
            return controller;
        }
    }

<strong>Gereating test error</strong>

Code:
public ActionResult Index()
{
    // Throw a test error so that we can see that it is handled by Elmah
    // To test go to the ~/elmah.axd page to see if the error is being logged correctly
    throw new Exception("A test exception for ELMAH");
    return View();
}

<strong>Problem:-</strong>

This will display error page
Code:
Shared\Error.cshtml
instead of
Code:
Bug\ViewBug
.

<em>What should I have to change for working with customErrors in web.config?</em>