Asp.Net Mvc Global Error Handling Complete Guide
Understanding the Core Concepts of ASP.NET MVC Global Error Handling
ASP.NET MVC Global Error Handling
Key Concepts
Exception Filters: ASP.NET MVC provides exception filters like custom attributes that can intercept and handle exceptions when they occur in a controller action. The most commonly used one is
HandleErrorAttribute
.Application Level Error Handling: This involves setting up error handlers within the
Global.asax
file, which is the entry point for handling HTTP requests in MVC applications.Logging: Integrating logging mechanisms with your error handling setup is essential to track exceptions over time and analyze them for debugging purposes.
Custom Error Pages: Displaying user-friendly custom error pages instead of generic server errors enhances the usability and professionalism of your application.
Elmah (Error Logging Modules and Handlers): An open-source library that integrates seamlessly into MVC applications for comprehensive error logging and notification.
HTTP Error Codes: Properly setting HTTP error codes (e.g., 400 Bad Request, 404 Not Found, 500 Internal Server Error) ensures accurate communication between the client and server.
Model State Validation: Ensuring model state is valid before processing actions prevents exceptions derived from invalid data entry, providing an additional layer of error prevention.
Try-Catch Blocks: Localizing try-catch blocks within controller actions for specific exceptions can complement global error handling by targeting exceptional scenarios precisely.
Dependency Injection: Utilizing dependency injection for error handling can make your code more maintainable and testable.
Unit Testing: Writing unit tests for error handling ensures that your error management logic is reliable during the development phase.
Integration with External Services: Logging errors to external services or notifying developers via email/SMS can improve the response time to critical issues.
Implementation Details
Using HandleErrorAttribute
The HandleErrorAttribute
is an exception filter attribute that can be applied globally or on individual controllers/actions.
[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
throw new Exception("An example exception");
}
}
// Global usage in FilterConfig.cs
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
}
- This attribute handles exceptions by redirecting users to a predefined error view (
Error.cshtml
) based on settings. - Configure the attribute in
web.config
andFilterConfig.cs
to specify which types of exceptions it should handle.
Overriding OnException
Method
Alternatively, you can override the OnException
method in your base controller to provide custom exception handling behavior.
public class BaseController : Controller
{
protected override void OnException(ExceptionContext filterContext)
{
if (!filterContext.ExceptionHandled) // Check to see if already handled.
{
// Log the exception here using your logging mechanism.
// Redirect to a custom error view or page.
filterContext.Result = View("CustomErrorView");
filterContext.ExceptionHandled = true;
}
base.OnException(filterContext);
}
}
public class HomeController : BaseController
{
public ActionResult Index()
{
throw new Exception("An example exception");
}
}
- This approach offers more flexibility and control over how exceptions are managed compared to using attributes alone.
Using Application_Error in Global.asax
For global exception handling outside of specific controllers, you can use the Application_Error
method in Global.asax
.
void Application_Error(object sender, EventArgs e)
{
// Get the exception object.
Exception exception = Server.GetLastError();
switch (exception)
{
case HttpException httpException:
// Log the exception.
break;
default:
// Log the exception.
break;
}
// Respond to the error.
Server.ClearError(); // Clear the default error.
Response.Redirect("~/ErrorPage"); // Redirect to a custom error page.
}
- This method is triggered for unhandled exceptions anywhere in the MVC pipeline.
- Remember to clear the error after handling it to prevent the default error handlers from interfering.
Logging Exceptions Integrating logging into your error handling process is crucial for maintaining and debugging your application. There are several libraries available for logging, including Elmah, NLog, and Log4Net.
Elmah Example:
// Install Elmah using NuGet packages manager
ELMAH.ErrorSignal.FromCurrentContext().Raise(exception);
NLog Example:
using NLog;
var logger = LogManager.GetCurrentClassLogger();
logger.Error(exception);
Creating Custom Error Views Custom error views can be designed to provide a user-friendly interface when an error occurs.
- Use
Web.config
to specify custom error pages for different HTTP status codes.
<configuration>
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
</pages>
</system.web.webPages.razor>
<system.web>
<customErrors mode="On" defaultRedirect="~/Error">
<error statusCode="404" redirect="~/NotFound" />
<error statusCode="500" redirect="~/ServerError" />
</customErrors>
</system.web>
</configuration>
- Design views (
Error.cshtml
,NotFound.cshtml
,ServerError.cshtml
) to display appropriate messages and information.
Model State Validation Validate models and data entries to prevent invalid data from causing errors.
public ActionResult Create(MyModel model)
{
if (!ModelState.IsValid)
{
// Return the same view passing model.
return View(model);
}
try
{
// Perform your create operation here.
}
catch (Exception ex)
{
ModelState.AddModelError("",ex.Message);
return View(model);
}
return RedirectToAction("Index");
}
- Display validation summary or error messages to guide users in correcting their input.
Handling Specific Exceptions Localize try-catch blocks for specific exceptions within controller actions to offer fine-grained control.
public ActionResult Update(int id, MyModel model)
{
try
{
// Perform update operation
}
catch (NullReferenceException nre)
{
// Handle specifically
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, nre.Message);
}
catch (Exception ex)
{
// General exception handling
return View("Error", ex.Message);
}
return RedirectToAction("Index");
}
- Avoid catching all exceptions in a single try-catch block as this can obscure specific exceptional cases.
Testing Error Handling Ensure thorough testing of your error handling strategy by simulating potential exceptions and verifying that your application responds appropriately.
- Write unit tests for controller actions that have specific exception handling.
- Use integration tests to verify global error handling configurations.
Conclusion Global error handling in ASP.NET MVC should be a combination of attributes, controllers, and configuration, along with proper logging mechanisms. It ensures that your application remains resilient to unexpected issues, logs meaningful data for debugging, and presents user-friendly custom error views, significantly contributing to the quality and reliability of your web application. By following these best practices and integrating Elmah or similar logging tools, you can establish a robust error handling framework for your MVC application.
Important Info Summary
- HandleErrorAttribute: Applied on controllers/actions, redirects to a custom error view.
- Global.asax's
Application_Error
: Handles all uncaught exceptions in the application. - Elmah: An open-source library for detailed error logging and alerts.
- Logging: Essential for debugging and tracking issues, supports various logging levels.
- Custom Error Views: Provides user-friendly experiences during failures.
- Model State Validation: Prevents exceptions by validating input data before processing.
- Specific Exception Handling: Use try-catch blocks within actions for granular error management.
- Testing: Crucial to verify that the error handling works as expected under real conditions.
Online Code run
Step-by-Step Guide: How to Implement ASP.NET MVC Global Error Handling
Step 1: Create a New ASP.NET MVC Project
- Open Visual Studio.
- Click on Create a new project.
- Select ASP.NET Web Application (.NET Framework) and click Next.
- Provide a name for your project (e.g.,
MVCErrorHandling
) and click Create. - Choose MVC under the ASP.NET Framework Templates and click Create.
Step 2: Understand Basic Error Handling
In ASP.NET MVC, you can handle errors using the following methods:
- Action Level: Using attributes or the
try-catch
block within a controller action. - Controller Level: Using the
OnException
method within a controller. - Global Level: Using filters,
Application_Error
event, or middleware.
For global error handling, we will use Application_Error
in the Global.asax.cs
file and create a custom error controller.
Step 3: Create a Custom Error Controller
Add a new Controller:
- Right-click on the Controllers folder in Solution Explorer.
- Select Add → Controller.
- Choose MVC 5 Controller – Empty and click Add.
- Name the controller
ErrorController
.
Add Action Methods:
- Inside the
ErrorController
, add two action methods:General
andNotFound
.
- Inside the
using System.Web.Mvc;
namespace MVCErrorHandling.Controllers
{
public class ErrorController : Controller
{
// General Error Handler
public ActionResult General(Exception exception)
{
// Log exception
ViewBag.ExceptionMessage = exception.Message; // For demonstration purposes only
return View("General");
}
// 404 Not Found Error Handler
public ActionResult NotFound()
{
Response.StatusCode = 404;
return View();
}
}
}
- Create Views for Error Actions:
- Right-click on the view folder of
ErrorController
(e.g.,Views/Error
). - Select Add → View....
- Name the view
General
and click Add. - Repeat the process for the
NotFound
view.
- Right-click on the view folder of
General ViewModel
Here's a simple example for the General
view (Views/Error/General.cshtml
):
@{
ViewBag.Title = "Oops!";
}
<h2>An Error Occurred</h2>
<p>Something went wrong with our application.</p>
@if (ViewBag.ExceptionMessage != null)
{
<div>
<strong>Error Message:</strong>
@ViewBag.ExceptionMessage
</div>
}
NotFound ViewModel
Here's a simple example for the NotFound
view (Views/Error/NotFound.cshtml
):
@{
ViewBag.Title = "Not Found";
}
<h2>404 Not Found</h2>
<p>The page you are looking for does not exist.</p>
Step 4: Configure Route for Errors (Optional)
It might be helpful to define routes for the error pages in the RouteConfig.cs
. However, this can also be handled using IIS settings.
Define Routes in RouteConfig.cs
using System.Web.Mvc;
using System.Web.Routing;
namespace MVCErrorHandling
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "NotFound",
url: "Error/NotFound",
defaults: new { controller = "Error", action = "NotFound" }
);
routes.MapRoute(
name: "General",
url: "Error/General",
defaults: new { controller = "Error", action = "General" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
}
Step 5: Handle 404 Not Found Errors in Global.asax.cs
The Application_Error
method is triggered whenever there's an unhandled exception but it doesn't capture HTTP 404 errors by default. To capture 404 errors, you need to configure them in the web.config
as well.
- Modify the
web.config
:
<configuration>
<system.webServer>
<httpErrors mode="Custom" existingResponse="Replace">
<remove statusCode="404" />
<error statusCode="404" responseMode="ExecuteURL" path="/Error/NotFound" />
</httpErrors>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
</configuration>
- Handle Unhandled Exceptions in
Global.asax.cs
:
using System.Web;
using System.Web.Mvc;
using System;
using System.Web.Routing;
namespace MVCErrorHandling
{
public class MvcApplication : HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
protected void Application_Error(object sender, EventArgs e)
{
// Get the exception object
Exception exception = Server.GetLastError();
// Clear the error so that it doesn’t get propagated up to the server
// if it’s caught elsewhere or logged via other means
Server.ClearError();
// Handle HTTP 404 errors
if (exception is HttpException httpException && httpException.GetHttpCode() == 404)
{
var routeData = new RouteData();
routeData.Values.Add("controller", "Error");
routeData.Values.Add("action", "NotFound");
Response.StatusCode = 404;
// You can log the error here or in the NotFound action of ErrorController
IController controller = new ErrorController();
controller.Execute(new RequestContext(
new HttpContextWrapper(Context), routeData));
return;
}
// Else, handle general exceptions
var routeDataGeneral = new RouteData();
routeDataGeneral.Values.Add("controller", "Error");
routeDataGeneral.Values.Add("action", "General");
routeDataGeneral.Values.Add("exception", exception);
// Pass the exception information to the appropriate view
IController generalController = new ErrorController();
generalController.Execute(new RequestContext(
new HttpContextWrapper(Context), routeDataGeneral));
}
}
}
Step 6: Test Your Configuration
Run the Application:
- Press
F5
to start the debugging process.
- Press
Simulate a General Exception:
- Modify the
HomeController
Index Action to throw an exception:
- Modify the
public ActionResult Index()
{
throw new Exception("This is a test error.");
}
- Test 404 Not Found:
- Navigate to a non-existing URL like
http://localhost:xxxx/NonExistentController/Index
.
- Navigate to a non-existing URL like
You should see the relevant error page based on your configurations.
Conclusion
With these steps, you have implemented a basic global error handling mechanism in your ASP.NET MVC application. The Application_Error
event in Global.asax.cs
handles uncaught exceptions, and specific HTTP status codes are managed by routes and web.config
settings. Always ensure that sensitive error details are not exposed to end-users in production environments. Instead, consider logging these details to a file, database, or an external monitoring tool.
Top 10 Interview Questions & Answers on ASP.NET MVC Global Error Handling
1. What is global error handling in ASP.NET MVC?
Answer: Global error handling in ASP.NET MVC involves strategies to catch and manage exceptions that occur anywhere in your application at a centralized point. This ensures that users receive a consistent error page and helps in debugging and monitoring the application effectively.
2. How can I handle exceptions globally in ASP.NET MVC?
Answer: You can implement global exception handling in an ASP.NET MVC application using the following methods:
- Application_Error Method in Global.asax: Override this method to intercept unhandled exceptions.
- Custom Exception Filters: Create filters that apply globally to all controllers or specific actions.
- Logging Frameworks: Integrate logging frameworks like NLog or log4net for capturing errors.
3. Can you explain how to use the Application_Error method for global error handling?
Answer: To use the Application_Error
method, you need to open the Global.asax.cs
file and override the method. Here’s a basic example of implementing Application_Error
:
protected void Application_Error(object sender, EventArgs e)
{
var exception = Server.GetLastError();
if (exception != null)
{
// Log the exception
Logger.Error(exception);
// Route to a common error page
Response.Redirect("~/Error/InternalServerError");
// Clear the error from the server
Server.ClearError();
}
}
This method intercepts all exceptions not handled by any specific controller action. After logging the error, you redirect the user to a custom error page.
4. What is an Exception Filter in ASP.NET MVC?
Answer: An Exception Filter in ASP.NET MVC is a type of filter that allows you to execute custom logic when controller action methods throw unhandled exceptions. The most commonly used exception filter attribute is [HandleError]
.
5. How do I create a custom exception filter in ASP.NET MVC?
Answer: To create a custom exception filter, you need to define a class that inherits from FilterAttribute
and implements IExceptionFilter
. Here’s an example:
public class CustomExceptionFilterAttribute : FilterAttribute, IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
// Log the error using a preferred logger
Logger.Error(filterContext.Exception);
filterContext.ExceptionHandled = true;
filterContext.Result = new ViewResult()
{
ViewName = "~/Views/Error/GeneralErrorView.cshtml"
};
}
}
Then, register this custom filter in FilterConfig
:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new CustomExceptionFilterAttribute());
}
}
This filter will handle exceptions in your application, logging them and displaying a generic error view.
6. What is the best practice to handle exceptions across the entire application?
Answer: Best practices include combining Application_Error
and custom exception filters with logging mechanisms, ensuring detailed logs are captured. Use structured logging and error codes for easier troubleshooting.
7. How do I use custom attributes to handle different types of exceptions?
Answer: Define different exception filter attributes for various needs. For instance, one for validation errors, another for database exceptions, and generic ones for unforeseen errors. Then, apply these attributes where applicable, either globally or specifically on controllers/actions.
8. What are the benefits of using Elmah in ASP.NET MVC applications?
Answer: ELMAH (Error Logging Modules and Handlers) is an excellent tool for logging errors in ASP.NET MVC applications. Benefits include:
- Consistent Logging: Logs all unhandled exceptions without configuration changes.
- Easier Diagnostics: Provides comprehensive information about exceptions for quicker troubleshooting.
- Email Notifications: Sends emails automatically when critical errors occur, enhancing real-time monitoring.
To integrate it, add the ELMAH NuGet package and configure it in Web.config
.
9. How can I display friendly error messages to end-users while logging detailed error logs for developers?
Answer: Handle exceptions in both global Application_Error
and individual actions using custom exception filters. Log detailed information in the filters but return simple, user-friendly messages through the exception filters or result actions. Additionally, consider using a HandleError
attribute for displaying views with user-friendly messages.
10. What's the difference between Application_Error
, custom exception filters, and HTTP error handlers?
Answer: Each approach handles errors differently:
- Application_Error: Catches unhandled exceptions after all filters have been executed. Primarily used for logging and redirection or custom responses.
- Custom Exception Filters: Allows execution of custom code when exceptions are thrown. Applied at the controller or action level, providing more granular control over exceptions.
- HTTP Error Handlers: Used to handle HTTP status codes (like 404 or 500). Configured through
Web.config
or usingapp.UseStatusCodePagesWithReExecute()
in middleware, these are not related to code exceptions but more to HTTP errors.
Login to post a comment.