Exception Handling in ASP.NET MVC
Here you will learn how to handle exceptions in ASP.NET MVC application.
You may handle all possible exceptions in the action methods using try-catch blocks. However, there can be some unhandled exceptions that you want to log and display custom error messages or custom error pages to users.
When you create an MVC application in Visual Studio, it does not implement any exception handling technique out of the box. It will display an error page when an exception occurred.
For example, consider the following action method that throws an exception.
namespace ExceptionHandlingDemo.Controllers
{
public class HomeController : Controller
{
public ActionResult Contact()
{
string msg = null;
ViewBag.Message = msg.Length; // this will throw an exception
return View();
}
}
Navigating to /home/contact
in the browser, and you will see the following yellow page (also known as the Yellow Screen of Death) that shows exception details such as exception type, line number and file name where the exception occurred, and stack trace.
ASP.NET provides the following ways to handle exceptions:
- Using
<customErrors>
element in web.config - Using
HandleErrorAttribute
- Overriding
Controller.OnException
method - Using
Application_Error
event ofHttpApplication
<customErrors> Element in web.config
The <customErrors>
element under system.web
in web.config is used to configure error code to a custom page. It can be used to configure custom pages for any error code 4xx or 5xx. However, it cannot be used to log exception or perform any other action on exception.
Enable the <customErrors>
in web.config, as shown below.
<system.web>
<customErrors mode="On"></customErrors>
</system.web>
You also need to add HandleErrorAttribute
filter in the FilterConfig.cs
file.
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
}
After enabling the customErrors mode to On, an ASP.NET MVC application will show the default custom error page, as shown below.
The above view is Error.cshtml in the Shared folder. It will be displayed on the 500 error code.
The HandleErrorAttribute
filter set the Error.cshtml as the default view to display on an error occurred.
Learn more about handling exceptions using web.config customErrors in ASP.NET MVC.
HandleErrorAttribute
The HandleErrorAttribute is an attribute that can be used to handle exceptions thrown by an action method or a controller. You can use it to display a custom view on a specific exception occurred in an action method or in an entire controller.
The HandleErrorAttribute attribute can only be used to handle the exception with status code 500. Also, it does not provide a way to log exceptions.
In order to use this attribute, you must add HandleErrorAttribute
filter in the FilterConfig.RegisterGlobalFilters()
method and also, set the mode attribute to On <customErrors mode="On">
in web.config, as we did for the customErrors
section above.
Now, let's apply [HandleError]
attribute to the action method, as shown below.
public class HomeController : Controller
{
[HandleError]
public ActionResult Contact()
{
string msg = null;
ViewBag.Message = msg.Length;
return View();
}
}
Above, we configured [HandleError]
attribute on the Contact()
action method. It will display Error.cshtml view from the Shared folder when an exception occurs. The [HandleError]
set the Error.cshtml view as default view for any exceptions.
the [HandleError]
can also be used to configure different pages for different types of exceptions, as shown below.
public class HomeController : Controller
{
[HandleError]
[HandleError(ExceptionType =typeof(NullReferenceException), View ="~/Views/Error/NullReference.cshtml")]
public ActionResult Contact()
{
string msg = null;
ViewBag.Message = msg.Length;
return View();
}
}
Now, the above example will show NullReference.cshtml because it throws NullReferenceException
.
The [HandleError]
attribute has a limited scope and not recommended to use in most cases.
Overriding Controller.OnException Method
Another way to handle controller level exceptions is by overriding the OnException()
method in the controller class. This method handles all your unhandled errors with error code 500.
It allows you to log an exception and redirect to the specific view. It does not require to enable the <customErrors>
config in web.config.
public class HomeController : Controller
{
public ActionResult Contact()
{
string msg = null;
ViewBag.Message = msg.Length;
return View();
}
protected override void OnException(ExceptionContext filterContext)
{
filterContext.ExceptionHandled = true;
//Log the error!!
//Redirect to action
filterContext.Result = RedirectToAction("Error", "InternalError");
// OR return specific view
filterContext.Result = new ViewResult
{
ViewName = "~/Views/Error/InternalError.cshtml"
};
}
}
Using Application_Error event of HttpApplication
The ideal way to log exception occurred in any part of your MVC application is to handle it in the Application_Error event in the global.asax file.
public class MvcApplication : System.Web.HttpApplication
{
//other code removed for clarity
protected void Application_Error()
{
var ex = Server.GetLastError();
//log an exception
}
}
The Application_Error
event is fired on any type of exception and error codes. So, handle it carefully.
Recommendation
In most web applications, you should ideally log the exceptions and also show appropriate error messages or pages to the users. So, it is recommended to use the global Application_Error
event to log all the exceptions along with <customErrors>
element in web.config to redirect it to appropriate pages.
The above exception handling techniques will return the response with 200 status code. If you are concern to return specific error code in response then you have to use <httpErrors>
element in web.config. Learn how to display a custom error page with the appropriate error code in ASP.NET.