How to handle all errors (caught and uncaught) in ASP.Net MVC?

There is a great app ASP.Net MVC, to-ROE drew a bunch of services. The behavior of the services is not always stable, so in code with many try/catch blocks.
There is need to handle all exception: to search the database and, depending on the search results, to implement future actions.
Question: how to apply the treatment on all errors (caught and uncaught) in ASP.Net MVC? There is some mechanism or to write a new method in each catch block?
July 9th 19 at 10:09
2 answers
July 9th 19 at 10:11
I prefer the following approach:

1. Create a controller ErrorControllerlike this:

public class ErrorController
{
 public virtual ActionResult BadRequest()
{
 return View();
}

 public virtual ActionResult Forbidden()
{
 return View();
}

 public virtual ActionResult Index()
{
 return View();
}

 public virtual ActionResult NotFound()
{
 return View();
}
}


2. Add view function

3. Create your extended HandleErrorAttributelike this:

public class ExtHandleErrorAttribute : HandleErrorAttribute
{
 //private readonly ILogger logger;

 public ExtHandleErrorAttribute(/*ILogger logger*/)
{
 //this.logger = logger;
}

 public override void OnException(ExceptionContext filterContext)
{
 if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
{
return;
}

 if (new HttpException(null, filterContext.Exception).GetHttpCode() != 500)
{
return;
}

 if (!ExceptionType.IsInstanceOfType(filterContext.Exception))
{
return;
}

 if (filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
{
 filterContext.Result = new JsonResult
{
 JsonRequestBehavior = JsonRequestBehavior.AllowGet,
 Data = new
{
 error = true,
 message = filterContext.Exception.Message
}
};
}
else
{
 var controllerName = (string)filterContext.RouteData.Values["controller"];
 var actionName = (string)filterContext.RouteData.Values["action"];
 var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);

 filterContext.Result = new ViewResult
{
 ViewName = View,
 MasterName = Master,
 ViewData = new ViewDataDictionary<handleerrorinfo>(model),
 In TempData = filterContext.Controller.In TempData
};
}

 //var e = filterContext.Exception;
 //logger.Error(e, e.Message);

 filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.Clear();
 filterContext.HttpContext.Response.StatusCode = 500;
 filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
}
}</handleerrorinfo>


4. Register a global filter:
public class FilterConfig
{
 public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
 var extHandleErrorAttribute = DependencyResolver.Current.GetService<exthandleerrorattribute>();// new ExtHandleErrorAttribute();
filters.Add(extHandleErrorAttribute);
}
}</exthandleerrorattribute>


5. In Global.asax.cs add a method Application_Error:

protected void Application_Error(object sender, EventArgs e)
{
 var httpContext = ((MvcApplication)sender).Context;

 var currentRouteData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext));
 var currentController = " ";
 var currentAction = " ";

 if (currentRouteData != null)
{
 if (currentRouteData.Values["controller"] != null && !String.IsNullOrEmpty(currentRouteData.Values["controller"].ToString()))
{
 currentController = currentRouteData.Values["controller"].ToString();
}

 if (currentRouteData.Values["action"] != null && !String.IsNullOrEmpty(currentRouteData.Values["action"].ToString()))
{
 currentAction = currentRouteData.Values["action"].ToString();
}
}

 var ex = Server.GetLastError();

 var controller = new ErrorController();
 var routeData = new RouteData();
 var action = "Index";

 if (ex is HttpException)
{
 var httpEx = ex as HttpException;

 switch (httpEx.GetHttpCode())
{
 case 404:
 action = "NotFound";
break;

 case 403:
 action = "Forbidden";
break;

 case 400:
 action = "BadRequest";
break;

default:
 action = "Index";
 //var logger = DependencyResolver.Current.GetService<ilogger>();
 //logger.Error(ex, ex.Message);
break;
}
}

httpContext.ClearError();
httpContext.Response.Clear();
 httpContext.Response.StatusCode = ex is HttpException ? ((HttpException)ex).GetHttpCode() : 500;
 httpContext.Response.TrySkipIisCustomErrors = true;
 routeData.Values["controller"] = "Error";
 routeData.Values["action"] = action;

 controller.ViewData.Model = new HandleErrorInfo(ex, currentController, currentAction);
 ((IController)controller).Execute(new RequestContext(new HttpContextWrapper(httpContext), routeData));
}</ilogger>


6. In the web.config added to the system.web
<customerrors mode="On"></customerrors>

also in the system.webServer , you can add:

<httperrors>
 <remove statuscode="400" substatuscode="-1">
 <remove statuscode="403" substatuscode="-1">
 <remove statuscode="502" substatuscode="-1">
 <remove statuscode="501" substatuscode="-1">
 <remove statuscode="500" substatuscode="-1">
 <remove statuscode="404" substatuscode="-1">
 <error statuscode="400" prefixlanguagefilepath path="/Error/BadRequest" responsemode="ExecuteURL">
 <error statuscode="404" prefixlanguagefilepath path="/Error/NotFound" responsemode="ExecuteURL">
 <error statuscode="500" prefixlanguagefilepath path="/Error" responsemode="ExecuteURL">
 <error statuscode="501" prefixlanguagefilepath path="/Error" responsemode="ExecuteURL">
 <error statuscode="502" prefixlanguagefilepath path="/Error" responsemode="ExecuteURL">
 <error statuscode="403" prefixlanguagefilepath path="/Error/Forbidden" responsemode="ExecuteURL">
</error></error></error></error></error></error></remove></remove></remove></remove></remove></remove></httperrors>
July 9th 19 at 10:13

Find more questions by tags ASP.NETC#Exceptions