Asp.net mvc override OnException in base controller keeps propagating to Application_Error
The following should work:
protected override void OnException(ExceptionContext filterContext)
{
if (filterContext.ExceptionHandled)
{
return;
}
filterContext.Result = new ViewResult
{
ViewName = "~/Views/Shared/Error.aspx"
};
filterContext.ExceptionHandled = true;
}
Also make sure that no exception is thrown in this method or it will propagate to Application_Error
.
Haroon
Web Developer/Software Developer, C#, ASP.NET, SQL, Javascript, CSS, (X)HTML
Updated on July 14, 2020Comments
-
Haroon almost 4 years
I am trying to return a view not issue a redirect to the user based on certain errors that could occur from my application, I want to handle the errors + log them inside my base controller, I do not want the error to propagate up to my Global.asax - Application_Error() method as I want this method to handle any other errors inside my app e.g. user enters a bogus URL, has anyone found a way around this?
NOTE: I have left my commented code as I had a workaround for some issues, this also shows I have multiple exceptions to possible handle...
EDIT: If I issue a RedirectToAction within this OnException override everything works as expected, but I only want to return the view and no redirection...
My base controller method is:
protected override void OnException(ExceptionContext filterContext) { //dont interfere if the exception is already handled if (filterContext.ExceptionHandled) return; //let the next request know what went wrong filterContext.Controller.TempData["exception"] = filterContext.Exception; //log exception _logging.Error(User.Identity.Name, ExceptionHelper.BuildWebExceptionMessage(filterContext.Exception)); //set up redirect to my global error handler //if (filterContext.Exception.GetType() == typeof(NoAccessException)) // filterContext.Result = View(new RouteValueDictionary // (new { area = "", controller = "Error", action = "PublicError" })); //else { //Only return view, no need for redirection filterContext.Result = View(new RouteValueDictionary (new { area = "", controller = "Error", action = "NoAccess" })); //} //advise subsequent exception filters not to interfere and stop // asp.net from showing yellow screen of death filterContext.ExceptionHandled = true; //erase any output already generated filterContext.HttpContext.Response.Clear(); //base.OnException(filterContext); }
This method should handle any other errors that could appear in my app, I do not want the errors above being handled inside my Application_Error()
protected void Application_Error() { Exception exception = Server.GetLastError(); // Log the exception. var logger = Container.Get<ILoggingService>(); logger.Error(User.Identity.Name, ExceptionHelper.BuildWebExceptionMessage(exception)); Response.Clear(); HttpException httpException = exception as HttpException; RouteData routeData = new RouteData(); routeData.Values.Add("controller", "Error"); //if (httpException == null) //{ routeData.Values.Add("action", "PublicError"); //} //else //It's an Http Exception, Let's handle it. //{ // switch (httpException.GetHttpCode()) // { // case 404: // // Page not found. // routeData.Values.Add("action", "HttpError404"); // break; // case 500: // // Server error. // routeData.Values.Add("action", "HttpError500"); // break; // // Here you can handle Views to other error codes. // // I choose a General error template // default: // routeData.Values.Add("action", "General"); // break; // } //} // Pass exception details to the target error View. routeData.Values.Add("error", exception); // Clear the error on server. Server.ClearError(); // Avoid IIS7 getting in the middle Response.TrySkipIisCustomErrors = true; // Call target Controller and pass the routeData. IController errorController = new ErrorController(); errorController.Execute(new RequestContext( new HttpContextWrapper(Context), routeData)); }