Introduction
The HandleError attribute is used to display user-friendly error pages to the end users when there is an unhandled exception.
Step 1
Open Visual Studio 2015 or a version of your choice and create a new project.
Step 2
Choose the web application type project and give an appropriate name to your project.
Step 3
Select the empty template, check on MVC checkbox below, and click OK.
Step 4
Right-click on the Controllers folder and add a Controller.
A window will appear. Choose MVC5 Controller-Empty and click "Add".
After clicking on "Add", another window will appear with DefaultController. Change the name to HomeController and click "Add". The HomeController will be added under the Controllers folder. Don’t change the Controller suffix for all controllers, change only the highlight, and instead of the default, just change Home.
The complete code for Home Controller
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.Mvc;
-
- namespace ExceptionalFilter_Demo.Controllers
- {
- public class HomeController : Controller
- {
-
- public ActionResult Index()
- {
- throw new Exception("Something went wrong...");
-
- }
- }
- }
Step 5
Right-click on the Index method in HomeController. The "Add View" window will appear with default index name checked (use a Layout page); click on "Add.
Step 6 - Built and run project ctrl+F5
The Index action method throws an exception. As this exception is not handled when we run the application, we will get the default yellow screen of death which does not make sense to the end user.
Step 7
Now, we will be replacing this yellow screen of death with a friendly error page.
Enable custom errors in the web.config file that is present in the root directory of MVC application. The “customErrors” element must be nested under “<system.web>“.
- <customErrors mode=”On”>
- </customErrors>
Step 8
Add Shared folder under Views folder if does not exist already. Add Error.cshtml View inside this folder if Error.cshtml does not exist. Write the following HTML in the Error.cshtml view.
Run the application and notice that you are redirected to the friendly Error view instead of the generic Yellow screen of death. We have not specified the error page (View) name anywhere, but still, in the response, we get error view whenever an error occurs.
Step 8
Create classFilterConfig if it does not exist under App_Start folder. Write the following code.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.Mvc;
-
- namespace ExceptionalFilter_Demo.App_Start
- {
- public class FilterConfig
- {
- public static void RegisterGlobalFilters(GlobalFilterCollection filters)
- {
- filters.Add(new HandleErrorAttribute());
- }
- }
- }
Step 9
In Global.asax file, in Applicaion_Start() method, RegisterGlobalFilters method is invoked, as shown below. Register FilterConfig in Global.asax file.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.Mvc;
- using System.Web.Routing;
- using ExceptionalFilter_Demo.App_Start;
-
- namespace ExceptionalFilter_Demo
- {
- public class MvcApplication : System.Web.HttpApplication
- {
- protected void Application_Start()
- {
- FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
- AreaRegistration.RegisterAllAreas();
- RouteConfig.RegisterRoutes(RouteTable.Routes);
- }
- }
- }
Step 10 - Displaying error detail in the Error view
We will make our error view strongly typed view of model System.Web.Mvc.HandleErrorInfo and then, as usual, using @Model keyword we can access the members. One of the members is the Exception object.
Replace error view with the following code.
- @{
- ViewBag.Title = "Error";
- }
-
- <h2 class="alert-danger">Error Occured</h2>
- <hgroup>
- <h5 class="text-danger">Controller Name:@Model.ControllerName</h5>
- <h5 class="text-danger">Action Name:@Model.ActionName</h5>
- <h5 class="text-danger">Controller Name:@Model.Exception</h5>
- </hgroup>
Step 11
Create different views for different exceptions under the shared folder where we created an error view.
Step 12
Create a NullReference error view.
- @{
- ViewBag.Title = "NullReference";
- }
-
- <h2 class="alert-danger">Error Occured</h2>
- <hgroup>
- <h5 class="text-danger">Controller Name:@Model.ControllerName</h5>
- <h5 class="text-danger">Action Name:@Model.ActionName</h5>
- <h5 class="text-danger">Controller Name:@Model.Exception</h5>
- </hgroup>
Step 13
Create DividedByZero error view under shared folder.
- @{
- ViewBag.Title = "DivideByZero";
- }
-
- <h2 class="alert-danger">Error Occured</h2>
- <hgroup>
- <h5 class="text-danger">Controller Name:@Model.ControllerName</h5>
- <h5 class="text-danger">Action Name:@Model.ActionName</h5>
- <h5 class="text-danger">Controller Name:@Model.Exception</h5>
- </hgroup>
Complete controller code
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.Mvc;
-
- namespace ExceptionalFilter_Demo.Controllers
- {
- public class HomeController : Controller
- {
- [HandleError(ExceptionType = typeof(NullReferenceException),View = "NullReference")]
- [HandleError(ExceptionType = typeof(DivideByZeroException),View = "DivideByZero")]
- [HandleError]
- public ActionResult Index()
- {
- throw new Exception("Something went wrong...");
-
- }
-
- public ActionResult TestMethodOne()
- {
- throw new NullReferenceException();
- }
-
- public ActionResult TestMethodTwo()
- {
- throw new DivideByZeroException();
- }
- }
- }
Some of the limitations of the HandleError attribute are -
- The error won’t get logged anywhere.
- Exceptions raised outside controllers will not be handled. Example- exception raised because of invalid URL won’t be handled.
- Exception Handling based on the scenario is not possible. Example – So one error page when the request comes via AJAX and a different one when comes via normal request.
http://localhost:60124/home/TestMethodOne
http://localhost:60124/home/TestMethodTwo