0% found this document useful (0 votes)
4 views16 pages

Filters in Core

Uploaded by

Niranjan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views16 pages

Filters in Core

Uploaded by

Niranjan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 16

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.

You might also like