Exception Handling In ASP.NET MVC

In this article, we will be discussing various ways of handling an exception in ASP.NET MVC.

Below are the different ways -

  • Try-Catch
  • Override onException from Controller class
  • HandleError Attribute
  • CustomException by HandleErrorAttribute

Now, let’s elaborate one by one.

Try-Catch

This is the default way of handling exceptions where we write our source code into the try block and catch the exceptions in the catch block. However, you can have multiple catch blocks for a try block. Even you can have Try-Catch blocks inside a Try block.

  • try
    A Try block is used to encapsulate a code. If any code throws an exception within that Try block, the exception will be handled by the corresponding Catch.

  • catch
    When an exception occurs, the Catch block of code gets it. This is the place where we are able to handle the exceptions.

Below is the example for the same.

  1. public IActionResult Index()  
  2. {  
  3.     try  
  4.     {  
  5.         int i = 10;  
  6.         i = i / 0;  
  7.         return View();  
  8.     }  
  9.     catch (Exception Ex)  
  10.     {  
  11.         return View("Error");  
  12.     }  
  13. }  

In the above example, we are handling an exception by using Try-Catch. In Try block, we have written the code that needs to be executed, however, if an error occurs, the catch bock handles the error and redirects it to View.

Note

In a Catch block, you can log the error either in a file or in a database.

Override onException from Controller class

You can override OnException(ExceptionContext filterContext), which belongs to Controller class. And you can pass this to the base Exception, as shown below.

  1. public class HomeController : Controller  
  2. {  
  3.     protected overridevoid OnException(ExceptionContext filterContext)  
  4.     {  
  5.         base.OnException(filterContext);  
  6.     }  
  7.   
  8.     public ActionResult Index()  
  9.     {  
  10.         return View();  
  11.     }  
  12. }  

In the above sample, we are overriding onException() and passing the exception to a base method.

Now, you will be redirected to the default exception page. To overcome this, i.e., to show custom view, use the below example.

  1. protected override  void OnException(ExceptionContext filterContext)  
  2. {  
  3.     ViewResult view = new ViewResult();  
  4.     view.ViewName = "Error";  
  5.     filterContext.Result = view;  
  6.     filterContext.ExceptionHandled = true;  
  7. }  

In the above example, we are creating a view result and passing the view name to it. And after that, we are passing that view to filtercontext.

Note

In this case, we must intimate the filtercontext that we have handled the error. For this, we need to write the below line of code.

filterContext.ExceptionHandled = true;

Now, in the above scenarios, we will have to handle the exception in every controller. To overcome this, we create a BaseController class which will implement the Controller class and our all controllers will implement Base Contoller class. See below.

Add BaseController Class which implements a Controller class.

  1. public class BaseController: Controller  
  2. {  
  3.     protected override void OnException(ExceptionContext filterContext)  
  4.     {  
  5.         //base.OnException(filterContext);  
  6.         ViewResult view = new ViewResult();  
  7.         view.ViewName = "Error";  
  8.         filterContext.Result = view;  
  9.         filterContext.ExceptionHandled = true;  
  10.     }  
  11. }   

Now, implement BaseController to every Controller like HomeController.

  1. public class HomeController : BaseController  
  2. {  
  3.     public ActionResult Index()  
  4.     {  
  5.         int i = 10;  
  6.         i = i / 0;  
  7.         return View();  
  8.     }  
  9. }  

HandleError Attribute

ASP.NET MVC HandleError attribute provides a built-in exception filter. It can be applied on a specific action method or at controller. However, we can add it at the global level for handling exception in controller and action level. While creating our application, it is automatically included within the Global.asax.cs and registered in FilterConfig.cs, as shown below.

  1. public static void RegisterGlobalFilters(GlobalFilterCollection filters)  
  2. {  
  3.     filters.Add(new HandleErrorAttribute());  
  4. }  

Now, we need to set the mode to on status for customErrors node of system.web section of web.config file.

  1. <customErrors mode="On"></customErrors>  

Now, we can use HanldeError attribute at any of the action methods like Index.

  1. public class HomeController : Controller  
  2. {  
  3.     [HandleError()]  
  4.     public ActionResult Index()  
  5.     {  
  6.         int i = 10;  
  7.         i = i / 0;  
  8.         return View();  
  9.     }  
  10. }  

Even you can add it at controller level so that it will be applicable to all the action methods present in the controller.

  1. [HandleError()]  
  2. public class HomeController : Controller  
  3. {  
  4.           
  5.     public ActionResult Index()  
  6.     {  
  7.         int i = 10;  
  8.         i = i / 0;  
  9.         return View();  
  10.     }  
  11.   
  12.     public ActionResult About()  
  13.     {  
  14.         ViewBag.Message = "Your application description page.";  
  15.   
  16.         return View();  
  17.     }  
  18. }  

HandleError attribute has some properties as explained below.

  • ExceptionType
    It specifies the Type of exception to be caught. If it is not specified, then the HandleError filter handles all exceptions.

  • View
    View name for displaying the exception information.

  • Master
    Master View for displaying the exception.

  • Order
    The order in which the action filters are executed. The Order property has an integer value and it specifies the priority from 1 to any positive integer value. Highest priority is 1 and the greater the value of the integer is, the lower is the priority of the filter.

  • AllowMultiple
    It indicates whether more than one instances of the error filter attribute can be specified.

Below are some of the examples.

  1. public class HomeController : Controller  
  2. {  
  3.     [HandleError(View = "NullError", ExceptionType = typeof(NullReferenceException))]  
  4.     [HandleError(Order = 2, View = "Error", ExceptionType = typeof(DivideByZeroException))]  
  5.     public ActionResult Index()  
  6.     {  
  7.         int i = 10;  
  8.         i = i / 0;  
  9.         return View();  
  10.     }  
  11. }  

CustomeException by HandleErrorAttribute

Now, we can achieve custom exception handling by implementing the  HandleError attribute which has on ExceptionContext exceptionContext. Below is the detailed description of the same.

  • We will be adding CustomErrorHandling.cs which inherits HandleErrorAttribute in the "Utilities" folder in nSights UI application.
  • Now, we need to add Error.cshtml  in “~/Views/Shared “.
  • Now, add the below attribute on top of every action method, like below.

[CustomErrorHandling]
public ActionResult GetRoles()

Below is the implementation for the same.

  1. public override void OnException(ExceptionContext exceptionContext)  
  2. {  
  3.     if (!exceptionContext.ExceptionHandled)  
  4.     {  
  5.         string controllerName = (string)exceptionContext.RouteData.Values["controller"];  
  6.         string actionName = (string)exceptionContext.RouteData.Values["action"];  
  7.   
  8.         Exception custException = new Exception("There is some error");  
  9.   
  10.         Log.Error(exceptionContext.Exception.Message+ " in " + controllerName);  
  11.   
  12.         var model = new HandleErrorInfo(custException, controllerName, actionName);  
  13.   
  14.         exceptionContext.Result = new ViewResult  
  15.         {  
  16.             ViewName = "~/Views/Shared/Error.cshtml",  
  17.             ViewData = new ViewDataDictionary<HandleErrorInfo>(model),  
  18.             TempData = exceptionContext.Controller.TempData  
  19.         };  
  20.   
  21.         exceptionContext.ExceptionHandled = true;  
  22.   
  23.     }  

Below is the sample of Error.cshtml.

  1. <!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4.     <meta name="viewport" content="width=device-width" />  
  5.     <title>Error</title>  
  6. </head>  
  7. <body>  
  8.     <hgroup>  
  9.         <h1>Error.</h1>  
  10.   
  11.         @model System.Web.Mvc.HandleErrorInfo  
  12.   
  13.         @if (Model != null)  
  14.         {  
  15.             <div>  
  16.                 <h2>  
  17.                     @Model.Exception.Message  in @Model.ControllerName  
  18.                 </h2>  
  19.   
  20.             </div>  
  21.         }  
  22.   
  23.     </hgroup>  
  24. </body>  
  25. </html>