In ASP.NET Core 8.
0, filters are a powerful feature that allow you to run code before or
after specific stages in the request processing pipeline, especially in MVC and Razor Pages
applications. They're commonly used for cross-cutting concerns like logging, error
handling, authorization, or caching.
Types of Filters in .NET 8.0
Filter Type Description
Authorization Filter Runs before anything else, checks if user is authorized.
Action Filter Runs before and after the action method executes.
Exception Filter Runs if an exception is thrown during action or result execution.
Result Filter Runs before and after the action result (e.g., a View) is executed.
Real-time example of an AuthorizationFilter in .NET 8.0 MVC — like checking whether a
user has access to a particular admin panel or feature based on roles or claims.
You have a controller called AdminController and only users with a role of "Admin" should
be allowed to access it. We'll create a custom AuthorizationFilter for this.
Create the Custom AuthorizationFilter:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
public class AdminOnlyAuthorizationFilter : IAuthorizationFilter
{
public void OnAuthorization(AuthorizationFilterContext context)
{
// Simulate retrieving a user (in real apps, you'd get this from session or claims)
var isAdmin = context.HttpContext.Request.Headers["IsAdmin"] == "true";
if (!isAdmin)
{
context.Result = new RedirectToActionResult("AccessDenied", "Home", null);
}
}
}
Register the Filter Globally in Program.cs
If you want this filter only on certain controllers, skip this and use [ServiceFilter] instead.
builder.Services.AddControllersWithViews(options =>
{
options.Filters.Add<AdminOnlyAuthorizationFilter>();
});
If using only for certain controllers/actions:
builder.Services.AddScoped<AdminOnlyAuthorizationFilter>();
3. Create AdminController.cs:
[ServiceFilter(typeof(AdminAuthorizationFilter))]
public class AdminController : Controller
{
public IActionResult Dashboard()
{
return View();
}
}
4. Create HomeController.cs
using Microsoft.AspNetCore.Mvc;
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
public IActionResult AccessDenied()
{
return View();
}
}
5. Views
📁 Views/Home/Index.cshtml
@{
ViewData["Title"] = "Home";
}
<h2>Welcome to the site</h2>
<p>This is the public area.</p>
<a href="/Admin/Dashboard" class="btn btn-primary">Go to Admin Dashboard</a>
Views/Home/AccessDenied.cshtml:
@{
ViewData["Title"] = "Access Denied";
}
<h2>Access Denied</h2>
<p>You are not authorized to view this page.</p>
<a href="/" class="btn btn-secondary">Back to Home</a>
Views/Admin/Dashboard.cshtml:
@{
ViewData["Title"] = "Admin Dashboard";
}
<h2>Admin Dashboard</h2>
<p>Only users with admin access can view this page.</p>
Testing the Authorization
✅ Simulate Admin Access
Use a tool like Postman, or modify a test request using browser extensions like
"ModHeader", and add:
Header: IsAdmin = true
You’ll be allowed into /Admin/Dashboard
❌ Without Header or with IsAdmin=false
Redirects to /Home/AccessDenied
ActtionFilter with example in .net 8.0
What is an Action Filter?
An ActionFilter lets you run logic before and after an action method executes. It’s useful for:
Logging
Timing execution
Validating model state
Modifying input/output
Real-Time Example: Logging Action Execution Time
You want to log how long each controller action takes to execute.
Step 1: Create the Custom ActionFilter
using Microsoft.AspNetCore.Mvc.Filters;
using System.Diagnostics;
public class ExecutionTimeLoggerFilter : IActionFilter
{
private Stopwatch _stopwatch;
public void OnActionExecuting(ActionExecutingContext context)
{
_stopwatch = Stopwatch.StartNew();
Console.WriteLine($"[START] Action: {context.ActionDescriptor.DisplayName}");
}
public void OnActionExecuted(ActionExecutedContext context)
{
_stopwatch.Stop();
var elapsed = _stopwatch.ElapsedMilliseconds;
Console.WriteLine($"[END] Action: {context.ActionDescriptor.DisplayName} took
{elapsed} ms");
}
}
Step 2: Register the Filter in Program.cs
builder.Services.AddControllersWithViews(options =>
{
options.Filters.Add<ExecutionTimeLoggerFilter>(); // Register globally
});
// If you want to use [ServiceFilter], register it as a service
builder.Services.AddScoped<ExecutionTimeLoggerFilter>();
Step 3: Use it on a Controller or Action (Optional)
If not registering globally:
[ServiceFilter(typeof(ExecutionTimeLoggerFilter))]
public class HomeController : Controller
{
public IActionResult Index()
{
// Simulate some delay
System.Threading.Thread.Sleep(500);
return View();
}
}
Output in Console
When you hit Home/Index, the console logs will show:
[START] Action: HomeController.Index (YourAppName)
[END] Action: HomeController.Index (YourAppName) took 503 ms
Exception Filter for E-commerce Checkout Error Handling
🔸 Scenario
You're building an e-commerce website. During the checkout process, exceptions may occur
such as:
InventoryServiceException (e.g., item out of stock)
PaymentGatewayException (e.g., payment failure)
GeneralException (anything unexpected)
Create Custom Exceptions:
public class InventoryServiceException : Exception
{
public InventoryServiceException(string message) : base(message) { }
}
public class PaymentGatewayException : Exception
{
public PaymentGatewayException(string message) : base(message) { }
}
Create the Custom Exception Filter:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
public class CheckoutExceptionFilter : IExceptionFilter
{
private readonly ILogger<CheckoutExceptionFilter> _logger;
public CheckoutExceptionFilter(ILogger<CheckoutExceptionFilter> logger)
{
_logger = logger;
}
public void OnException(ExceptionContext context)
{
var exception = context.Exception;
if (exception is InventoryServiceException)
{
_logger.LogWarning(exception, "Inventory error during checkout.");
context.Result = new ViewResult { ViewName = "InventoryError" };
}
else if (exception is PaymentGatewayException)
{
_logger.LogError(exception, "Payment processing failed.");
context.Result = new ViewResult { ViewName = "PaymentError" };
}
else
{
_logger.LogCritical(exception, "Unexpected error during checkout.");
context.Result = new ViewResult { ViewName = "GeneralError" };
}
context.ExceptionHandled = true;
}
}
3. Register the Filter in Program.cs
builder.Services.AddControllersWithViews(options =>
{
options.Filters.Add<CheckoutExceptionFilter>();
});
builder.Services.AddScoped<CheckoutExceptionFilter>();
4. Controller Usage
public class CheckoutController : Controller
{
public IActionResult CompleteOrder()
{
// Simulate an error
throw new PaymentGatewayException("Transaction failed. Card declined.");
}
}
Create Views
Create the following Razor views under Views/Checkout/:
InventoryError.cshtml
PaymentError.cshtml
GeneralError.cshtml
Views/Checkout/InventoryError.cshtml
@{
ViewData["Title"] = "Item Out of Stock";
}
<h1>Item Not Available</h1>
<p>Sorry, one or more items in your cart are no longer available.</p>
<p>Please review your cart and try again.</p>
<a href="/Cart" class="btn btn-primary">Go to Cart</a>
Views/Checkout/PaymentError.cshtml
@{
ViewData["Title"] = "Payment Failed";
}
<h1>Payment Failed</h1>
<p>There was an issue processing your payment. Please check your card details or try
another method.</p>
<a href="/Checkout/Payment" class="btn btn-warning">Retry Payment</a>
<a href="/Home" class="btn btn-secondary">Return to Home</a>
Views/Checkout/GeneralError.cshtml
@{
ViewData["Title"] = "Error";
}
<h1>Oops! Something went wrong.</h1>
<p>An unexpected error occurred during checkout. We are looking into it.</p>
<a href="/Home" class="btn btn-outline-dark">Go to Home</a>
How to Use Them
Place all views under: Views/Checkout/
Ensure your controller method throws different custom exceptions like this:
public IActionResult CompleteOrder()
{
// Simulate exceptions
// throw new InventoryServiceException("Item not in stock.");
// throw new PaymentGatewayException("Payment failed.");
// throw new Exception("Unexpected error.");
return View("Success");
}
Result Filter:
Real-time Result Filter example in .NET 8.0 MVC, including:
✅ Controller
✅ Views
✅ Result Filter
✅ Registration in Program.cs
1. BrandingResultFilter.cs
Create this in your Filters folder (or root if no folder yet):
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Diagnostics;
using Microsoft.Extensions.Logging;
public class BrandingResultFilter : IResultFilter
{
private readonly ILogger<BrandingResultFilter> _logger;
private Stopwatch _stopwatch;
public BrandingResultFilter(ILogger<BrandingResultFilter> logger)
{
_logger = logger;
}
public void OnResultExecuting(ResultExecutingContext context)
{
// Inject branding info
if (context.Result is ViewResult viewResult)
{
viewResult.ViewData["CompanyName"] = "TechMart";
viewResult.ViewData["CompanyLogoUrl"] = "/images/logo.png";
}
// Start the stopwatch
_stopwatch = Stopwatch.StartNew();
}
public void OnResultExecuted(ResultExecutedContext context)
{
_stopwatch?.Stop();
var elapsed = _stopwatch?.ElapsedMilliseconds ?? 0;
var controller = context.RouteData.Values["controller"];
var action = context.RouteData.Values["action"];
_logger.LogInformation($"View for {controller}/{action} rendered in {elapsed} ms.");
}
}
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
public class BrandingResultFilter : IResultFilter
{
public void OnResultExecuting(ResultExecutingContext context)
{
if (context.Result is ViewResult viewResult)
{
viewResult.ViewData["CompanyName"] = "TechMart";
viewResult.ViewData["CompanyLogoUrl"] = "/images/logo.png";
}
}
public void OnResultExecuted(ResultExecutedContext context)
{
// Nothing needed after result execution
}
}
3. HomeController.cs
Create in Controllers folder:
using Microsoft.AspNetCore.Mvc;
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
public IActionResult About()
{
return View();
}
}
4. Views
Create the following Razor views:
Views/Home/Index.cshtml
@{
ViewData["Title"] = "Home";
}
<div style="text-align:center">
<img src="@ViewData["CompanyLogoUrl"]" width="150" />
<h1>Welcome to @ViewData["CompanyName"]!</h1>
<p>This is the homepage of our e-commerce platform.</p>
</div>
Views/Home/About.cshtml:
@{
ViewData["Title"] = "About";
}
<div style="text-align:center">
<img src="@ViewData["CompanyLogoUrl"]" width="150" />
<h1>About @ViewData["CompanyName"]</h1>
<p>We are a leading e-commerce company offering top-quality products worldwide.</p>
</div>
Output (in Console or Logs):
info: BrandingResultFilter[0]
View for Home/Index rendered in 45 ms.