Asp.Net Web Api Custom Exception Filters Complete Guide

 Last Update:2025-06-23T00:00:00     .NET School AI Teacher - SELECT ANY TEXT TO EXPLANATION.    7 mins read      Difficulty-Level: beginner

Understanding the Core Concepts of ASP.NET Web API Custom Exception Filters

ASP.NET Web API Custom Exception Filters

In the realm of ASP.NET Web API development, robust error handling is crucial for maintaining a reliable and maintainable application. One of the powerful mechanisms provided by ASP.NET Web API for handling exceptions is Custom Exception Filters. These filters allow developers to intercept exceptions thrown by actions in the Web API and handle them in a custom manner, making the response more informative and user-friendly.

Understanding Exception Filters

Exception filters are a type of action filter in ASP.NET Web API that execute after an action method completes, but only if an exception occurred. They enable you to execute error handling logic such as logging exceptions, sending notifications, or modifying the response to the client. There are two types of exception filters:

  1. Global Filters: Applied to all actions in the API across all controllers.
  2. Per-Controller Filters: Applied only to specific controllers.
  3. Per-Action Filters: Applied only to specific actions within a controller.

Building a Custom Exception Filter

Creating a custom exception filter involves implementing the IExceptionFilter interface or inheriting from the ExceptionFilterAttribute class. Below is a step-by-step guide to building a custom exception filter.

Implementing the IExceptionFilter Interface

To create a custom exception filter, implement the IExceptionFilter interface, which has a single method, ExecuteExceptionFilterAsync.

using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http.Filters;

public class CustomExceptionFilter : IExceptionFilter
{
    public async Task ExecuteExceptionFilterAsync(HttpActionExecutedContext context, CancellationToken cancellationToken)
    {
        // Log the exception details
        // Alternatively, use a logging framework like NLog, log4net, etc.
        string message = context.Exception.Message;
        string stackTrace = context.Exception.StackTrace;

        // Customize the response to the client
        var response = context.Request.CreateResponse(HttpStatusCode.InternalServerError, new
        {
            Error = "An unexpected error occurred.",
            Message = message,
            StackTrace = stackTrace // In a production environment, you might not want to expose stack traces.
        });

        context.Response = response;

        // Continue with the next exception filter if necessary
        await Task.CompletedTask;
    }
}
Using ExceptionFilterAttribute

Alternatively, you can inherit from ExceptionFilterAttribute and override the OnException method, which is a more straightforward approach if you don't need asynchronous behavior.

using System.Net;
using System.Net.Http;
using System.Web.Http.Filters;

public class CustomExceptionFilterAttribute : ExceptionFilterAttribute
{
    public override void OnException(HttpActionExecutedContext context)
    {
        // Log the exception details
        string message = context.Exception.Message;
        string stackTrace = context.Exception.StackTrace;

        // Customize the response to the client
        var response = context.Request.CreateResponse(HttpStatusCode.InternalServerError, new
        {
            Error = "An unexpected error occurred.",
            Message = message,
            StackTrace = stackTrace // Avoid exposing stack traces in a production environment.
        });

        context.Response = response;
    }
}

Registering the Exception Filter

To apply the custom exception filter globally, you need to register it in the WebApiConfig class.

using System.Web.Http;

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Other configuration settings...

        // Register the custom exception filter globally
        config.Filters.Add(new CustomExceptionFilterAttribute());
    }
}

For per-controller or per-action registration, simply use the [CustomExceptionFilter] attribute on the controller or action method, respectively.

[CustomExceptionFilter]
public class SampleController : ApiController
{
    public IHttpActionResult Get()
    {
        // Action method logic...
        throw new InvalidOperationException("This is a test exception.");
    }
}

Handling Specific Exceptions

Custom exception filters can be enhanced to handle specific exceptions differently. For example, you might want to return a 400 Bad Request for validation errors and a 500 Internal Server Error for other exceptions.

Online Code run

🔔 Note: Select your programming language to check or run code at

💻 Run Code Compiler

Step-by-Step Guide: How to Implement ASP.NET Web API Custom Exception Filters

Step 1: Create a New ASP.NET Web API Project

  1. Open Visual Studio: Start Visual Studio and create a new project.

  2. Create ASP.NET Web API Project:

    • Go to File -> New -> Project.
    • Select ASP.NET Web Application (.NET Framework).
    • Name your project (e.g., WebApiCustomExceptionFilters) and click Create.
    • Select Web API template and click Create.

Step 2: Create a Custom Exception Filter

  1. Add a New Class:

    • Right-click on the Filters folder in the Solution Explorer.
    • Select Add -> Class, and name it CustomExceptionFilter.cs.
  2. Implement the Exception Filter:

    • Open CustomExceptionFilter.cs and implement the IExceptionFilter interface.
using System;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http.Filters;

namespace WebApiCustomExceptionFilters.Filters
{
    public class CustomExceptionFilter : ExceptionFilterAttribute
    {
        public override void OnException(HttpActionExecutedContext context)
        {
            // Log the exception
            var message = string.Format("{0} occurred: {1}", 
                context.Exception.GetType().Name, 
                context.Exception.Message);
            // You can log the exception to a file, database, etc.
            System.Diagnostics.Debug.WriteLine(message);
            
            // Create a response object
            var response = new HttpResponseMessage(HttpStatusCode.InternalServerError)
            {
                Content = new StringContent("An error occurred. Please try again later."),
                ReasonPhrase = "Internal Server Error"
            };

            // Set the response to the context
            context.Response = response;
        }
    }
}

Step 3: Register the Custom Exception Filter Globally

  1. Open WebApiConfig.cs:

    • This file is located in the App_Start folder.
  2. Register the Filter:

    • Add the custom filter to the global configuration in WebApiConfig.cs.
using System.Web.Http;

namespace WebApiCustomExceptionFilters
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services

            // Register custom exception filter globally
            config.Filters.Add(new CustomExceptionFilter());

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }
}

Step 4: Create a Test Controller to Trigger the Exception

  1. Add a New Controller:

    • Right-click on the Controllers folder.
    • Select Add -> Controller, and choose Empty API Controller.
    • Name it TestController.
  2. Implement a Method to Throw an Exception:

    • Open TestController.cs and add a method that throws an exception.
using System.Web.Http;

namespace WebApiCustomExceptionFilters.Controllers
{
    public class TestController : ApiController
    {
        [HttpGet]
        public IHttpActionResult ThrowException()
        {
            // Throw an exception to test the custom exception filter
            throw new InvalidOperationException("This is a test exception");
        }
    }
}

Step 5: Test the Custom Exception Filter

  1. Run the Application:

    • Press F5 to run the application.
    • Open a browser or use a tool like Postman.
  2. Navigate to the Test Endpoint:

    • Go to http://localhost:<port>/api/test/throwexception.
    • You should see a response with the message "An error occurred. Please try again later." instead of the default error response.

Conclusion

You have now successfully implemented a custom exception filter in ASP.NET Web API. This filter intercepts exceptions thrown by your controllers and handles them in a consistent and controlled manner, improving the robustness of your application.

Top 10 Interview Questions & Answers on ASP.NET Web API Custom Exception Filters

1. What is an Exception Filter in ASP.NET Web API?

Answer: Exception filters in ASP.NET Web API are interfaces or attributes that allow you to handle exceptions that occur during the execution of an action method. They are part of the action filter pipeline and can be used to provide a more graceful error handling mechanism, log exceptions, and return custom error responses.

2. Why Should I Use a Custom Exception Filter?

Answer: Custom exception filters allow for centralized error handling, making it easier to manage exceptions across multiple action methods. They help in logging errors, returning appropriate error responses to clients, and maintaining a clean separation of concerns by keeping error handling logic out of the action methods.

3. How Do I Implement a Custom Exception Filter in ASP.NET Web API?

Answer: To implement a custom exception filter, you need to create a class that implements the IExceptionFilter interface or inherit from the ExceptionFilterAttribute class. Here is an example:

public class CustomExceptionFilterAttribute : ExceptionFilterAttribute
{
    public override void OnException(HttpActionExecutedContext context)
    {
        // Log the exception
        var exception = context.Exception;
        Trace.TraceError(exception.Message);

        // Customize the response
        context.Response = context.Request.CreateResponse(HttpStatusCode.BadRequest,
            new
            {
                Message = "An error occurred while processing your request.",
                ExceptionMessage = exception.Message
            });
    }
}

4. Can I Use Dependency Injection with Custom Exception Filters?

Answer: Yes, you can use dependency injection with custom exception filters in ASP.NET Web API. You need to configure the Web API to use a dependency resolver that supports DI. Here's how you might do it:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        var container = new UnityContainer();
        config.DependencyResolver = new UnityResolver(container);

        // Register your services here
    }
}

Then, modify your exception filter to include dependencies:

public class CustomExceptionFilterAttribute : ExceptionFilterAttribute
{
    private readonly ILogger _logger;

    public CustomExceptionFilter(ILogger logger)
    {
        _logger = logger;
    }

    public override void OnException(HttpActionExecutedContext context)
    {
        _logger.Log(LogLevel.Error, context.Exception.Message);

        context.Response = context.Request.CreateResponse(HttpStatusCode.InternalServerError,
            new { Message = "An error occurred while processing your request." });
    }
}

5. How Can I Handle Specific Types of Exceptions with Custom Exception Filters?

Answer: You can handle specific types of exceptions by checking the exception type within the OnException method. For example:

public class CustomExceptionFilterAttribute : ExceptionFilterAttribute
{
    public override void OnException(HttpActionExecutedContext context)
    {
        if (context.Exception is UnauthorizedAccessException)
        {
            context.Response = context.Request.CreateResponse(HttpStatusCode.Forbidden,
                new { Message = "You are not authorized to access this resource." });
        }
        else if (context.Exception is ArgumentException)
        {
            context.Response = context.Request.CreateResponse(HttpStatusCode.BadRequest,
                new { Message = "Invalid argument provided." });
        }
        else
        {
            context.Response = context.Request.CreateResponse(HttpStatusCode.InternalServerError,
                new { Message = "An error occurred while processing your request." });
        }
    }
}

6. How Do I Log Exceptions in a Custom Exception Filter?

Answer: You can log exceptions by using logging frameworks such as NLog, log4net, or the built-in logging in ASP.NET Core. Here’s an example using NLog:

public class CustomExceptionFilterAttribute : ExceptionFilterAttribute
{
    private readonly ILogger _logger;

    public CustomExceptionFilterAttribute(ILogger logger)
    {
        _logger = logger;
    }

    public override void OnException(HttpActionExecutedContext context)
    {
        var exception = context.Exception;
        _logger.Error(exception, "An error occurred while processing the request.");

        context.Response = context.Request.CreateResponse(HttpStatusCode.InternalServerError,
            new { Message = "An error occurred while processing your request." });
    }
}

7. Can I Apply a Custom Exception Filter Globally?

Answer: Yes, you can apply a custom exception filter globally by registering it in the HttpConfiguration in WebApiConfig.cs:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Filters.Add(new CustomExceptionFilterAttribute());
    }
}

8. How Do I Ensure That My Custom Exception Filter Does Not Mask Real Errors During Development?

Answer: During development, it’s a good practice to enable the IncludeErrorDetailPolicy to include more details about the exception in the response. However, disable it in production for security reasons:

public class CustomExceptionFilterAttribute : ExceptionFilterAttribute
{
    public override void OnException(HttpActionExecutedContext context)
    {
        if (context.Request.Properties.ContainsKey("MS_IsDebuggingEnabled") &&
            (bool)context.Request.Properties["MS_IsDebuggingEnabled"])
        {
            context.Response = context.Request.CreateResponse(HttpStatusCode.InternalServerError,
                new
                {
                    Message = context.Exception.Message,
                    StackTrace = context.Exception.StackTrace
                });
        }
        else
        {
            context.Response = context.Request.CreateResponse(HttpStatusCode.InternalServerError,
                new { Message = "An error occurred while processing your request." });
        }
    }
}

9. Can I Use Custom Exception Filters in ASP.NET Core MVC?

Answer: The concept of exception filters is similar in ASP.NET Core MVC, but the implementation is slightly different. You can create a custom exception filter by implementing the IExceptionFilter interface or inheriting from ExceptionFilterAttribute as follows:

public class CustomExceptionFilter : ExceptionFilterAttribute
{
    public override void OnException(ExceptionContext context)
    {
        context.Result = new ObjectResult(new { Message = "An error occurred." })
        {
            StatusCode = StatusCodes.Status500InternalServerError
        };
    }
}

10. What Are the Best Practices for Using Custom Exception Filters?

Answer:

  • Centralize exception handling.
  • Use logging extensively to capture errors.
  • Customize error messages carefully to avoid exposing sensitive information.
  • Handle different types of exceptions appropriately.
  • Apply exception filters globally or on specific controller actions as needed.
  • Consider using middleware in ASP.NET Core for broader error handling across multiple layers.

You May Like This Related .NET Topic

Login to post a comment.