I am inheriting the HandleErrorAttribute
in my MVC application so I can log the error:
public class HandleAndLogErrorAttribute : HandleErrorAttribute { public override void OnException(ExceptionContext filterContext) { base.OnException(filterContext); if( filterContext.Exception != null ) { // log here } } }
I'm adding this as a global filter:
public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleAndLogErrorAttribute()); }
Is it possible to specify a custom view for specific exception types as well? For example:
if( filterContext.Exception is DivideByZeroException ) { // how do i specify that the view should be DivideByZero? }
Right-click on create method and add view. Add the CustomExceptionHandlerFilter class for creating a custom exception handler. Implements FilterAttribute and IExceptionFilter and overrides the OnException method. Open App_Start folder inside the App_start folder contains FilterConfig class.
Implement the OnException method and add your custom logic into the method. Hence, the code will look, as shown below. Apply the class name as an attribute on the controller class. Add an exception in the controller Index method.
HandleErrorAttribute
(or implements IExceptionFilter directly)filters.Add(new HandleError());
): Here is a filter that I've created that tries to find a view per specific HTTP status code:
public class MyErrorHandler : FilterAttribute, IExceptionFilter { public void OnException(ExceptionContext filterContext) { if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled) return; var statusCode = (int) HttpStatusCode.InternalServerError; if (filterContext.Exception is HttpException) { statusCode = filterContext.Exception.As<HttpException>().GetHttpCode(); } else if (filterContext.Exception is UnauthorizedAccessException) { //to prevent login prompt in IIS // which will appear when returning 401. statusCode = (int)HttpStatusCode.Forbidden; } _logger.Error("Uncaught exception", filterContext.Exception); var result = CreateActionResult(filterContext, statusCode); filterContext.Result = result; // Prepare the response code. filterContext.ExceptionHandled = true; filterContext.HttpContext.Response.Clear(); filterContext.HttpContext.Response.StatusCode = statusCode; filterContext.HttpContext.Response.TrySkipIisCustomErrors = true; } protected virtual ActionResult CreateActionResult(ExceptionContext filterContext, int statusCode) { var ctx = new ControllerContext(filterContext.RequestContext, filterContext.Controller); var statusCodeName = ((HttpStatusCode) statusCode).ToString(); var viewName = SelectFirstView(ctx, "~/Views/Error/{0}.cshtml".FormatWith(statusCodeName), "~/Views/Error/General.cshtml", statusCodeName, "Error"); var controllerName = (string) filterContext.RouteData.Values["controller"]; var actionName = (string) filterContext.RouteData.Values["action"]; var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName); var result = new ViewResult { ViewName = viewName, ViewData = new ViewDataDictionary<HandleErrorInfo>(model), }; result.ViewBag.StatusCode = statusCode; return result; } protected string SelectFirstView(ControllerContext ctx, params string[] viewNames) { return viewNames.First(view => ViewExists(ctx, view)); } protected bool ViewExists(ControllerContext ctx, string name) { var result = ViewEngines.Engines.FindView(ctx, name, null); return result.View != null; } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With