Back to: ASP.NET Core Tutorials For Beginners and Professionals
TypeFilter vs ServiceFilter in ASP.NET Core MVC
In this article, I will discuss TypeFilter vs ServiceFilter, i.e., the Difference Between TypeFilter and ServiceFilter in ASP.NET Core MVC Applications with Examples. Please read our previous article discussing Action Filters in ASP.NET Core MVC Applications.
TypeFilter vs ServiceFilter in ASP.NET Core MVC
In ASP.NET Core, filters are used to execute custom pre- and post-processing logic before and after the action method execution. They can be used for various purposes, such as Authentication, Authorization, Caching, Exception Handling, Result Modifying, etc. There are different kinds of filters (like Authorization, Action, Exception, and Result filters) and different ways to apply filters to controllers and actions, such as applying at the action method level, at the controller level, or globally.
In ASP.NET Core, TypeFilter and ServiceFilter are built-in attributes that apply custom filters to controller actions or controllers. However, they have different purposes and are used in different scenarios. Now, let us proceed and try to understand the TypeFilter and ServiceFilter, what are the differences between them, and when to use which one:
TypeFilter Attribute in ASP.NET Core MVC:
- TypeFilter is a Built-in Attribute in ASP.NET Core that specifies a filter type (typically a Custom Filter Class) for a specific action method or controller. That means this built-in TypeFilter attribute allows us to apply a Custom Filter to a single action or controller (apply to all actions of that controller).
- We must provide the filter type (Custom Filter Class name) as a parameter to the TypeFilter attribute.
- It is useful when we want to apply a Custom Filter Class to a specific action or controller and don’t need to configure it globally or inject additional services.
Example to Understand TypeFilter Attribute:
Let us see an example to understand TypeFilter Attribute in ASP.NET Core MVC Application. The point that you need to remember is that you need to use the TypeFilter or Service Filter Attribute only when your Custom Filter class requires some services and you want to inject such services using the Dependency Injection Container.
So, let us first create the services consumed by the Custom Filter Classes. So, create a class file named ILoggerService.cs and copy and paste the following code. Here, you can see that the ILoggerService interface defines one method called Log, and the LoggerService class implements the ILoggerService interface and provides the implementation for the Log method.
namespace FiltersDemo.Models { public interface ILoggerService { public void Log(string methodName, string message); } public class LoggerService : ILoggerService { public void Log(string methodName, string message) { string filePath = Path.Combine(Directory.GetCurrentDirectory(), "Log", "Log.txt"); //saving the data in a text file called Log.txt File.AppendAllText(filePath, message); } } }
Creating Custom Action Filter:
Next, create a class file named CustomLoggingFilter.cs and then copy and paste the following code. As you can see, this class implements the IActionFilter interface and provides implementations for the OnActionExecuting and OnActionExecuted methods. Further, we have injected the LoggerService instance through constructor dependency injection.
using Microsoft.AspNetCore.Mvc.Filters; namespace FiltersDemo.Models { public class CustomLoggingFilter : IActionFilter { private readonly ILoggerService _LoggerService; public CustomLoggingFilter(ILoggerService LoggerService) { _LoggerService = LoggerService; } public void OnActionExecuting(ActionExecutingContext context) { var controllerName = context.RouteData.Values["controller"]; var actionName = context.RouteData.Values["action"]; string message = " Controller:" + controllerName + " Action:" + actionName + " Date: " + DateTime.Now.ToString() + Environment.NewLine; // Log the information before the action executes. _LoggerService.Log("OnActionExecuting", message); } public void OnActionExecuted(ActionExecutedContext context) { var controllerName = context.RouteData.Values["controller"]; var actionName = context.RouteData.Values["action"]; string message = " Controller:" + controllerName + " Action:" + actionName + " Date: " + DateTime.Now.ToString() + Environment.NewLine; // Log the information after the action executes. _LoggerService.Log("OnActionExecuted", message); } } }
Registering the Services to the Dependency Injection Container:
Next, we must register the Services to the Dependency Injection Container within the Program class so that the MVC Framework injects the service. So, add the following line in the Program class. Here, it is not required to register the Filter into the dependency injection container.
builder.Services.AddScoped<ILoggerService, LoggerService>();
Apply Filter as a Service:
To apply the filter as a service, we can use TypeFilter Attribute. A TypeFilterAttribute is used to create an instance of a Custom Filter Class using dependency injection. You can pass arguments to its constructor, which allows more flexibility if the filter has dependencies that need to be resolved. The type filter instantiates the filter type each time the filter is applied. So, modify the Home Controller as follows:
using FiltersDemo.Models; using Microsoft.AspNetCore.Mvc; namespace FiltersDemo.Controllers { public class HomeController : Controller { [TypeFilter(typeof(CustomLoggingFilter))] public ActionResult Index() { return View(); } } }
With the above changes, run the application and verify the generated Log.txt file.
ServiceFilter Attribute in ASP.NET Core MVC:
- ServiceFilter is also a Built-in Attribute in ASP.NET Core that applies a filter registered as a service with the dependency injection container.
- It is useful when we want to reuse the same Custom Filter Instance across multiple actions or controllers and configure it globally through dependency injection.
Example to Understand ServiceFilter Attribute:
A ServiceFilterAttribute is used when registering our filter as a service in the ASP.NET Core DI container. It requires the filter to be registered in the dependency injection container. Unlike TypeFilter, it doesn’t create a new instance but retrieves it from the DI container. We are going to work with the same example. So, modify the Home Controller as follows to use ServiceFilter Attribute.
using FiltersDemo.Models; using Microsoft.AspNetCore.Mvc; namespace FiltersDemo.Controllers { public class HomeController : Controller { [ServiceFilter(typeof(CustomLoggingFilter))] public ActionResult Index() { return View(); } } }
Registering The Filter:
- With TypeFilter, we need to specify the filter type directly within the TypeFilter constructor, and we don’t need to register it as a service in the Program.cs class file.
- With ServiceFilter, we must register the Custom Filter as a service in the Program.cs class file before using it with the ServiceFilter attribute.
So, we need to register the Services and Filters to the Dependency Injection Container within the Program class as follows.
builder.Services.AddScoped<ILoggerService, LoggerService>(); builder.Services.AddScoped<CustomLoggingFilter>();
With the above changes, run the application and verify the generated Log.txt file.
Differences Between TypeFilter and ServiceFilter in ASP.NET Core:
Instantiation:
- TypeFilter creates a new instance of the filter type on each request.
- ServiceFilter retrieves the instance from the DI container, which could be a singleton, scoped, or transient instance, depending on how it’s registered.
Dependencies:
- TypeFilter can directly accept constructor arguments for the filter.
- ServiceFilter uses the services registered in the DI container.
Flexibility:
- TypeFilter is more flexible since it can instantiate types that aren’t registered in the DI container.
- ServiceFilter is stricter and requires the type to be registered in the DI container.
So, choose TypeFilter if you need to inject dependencies that aren’t registered in the container or if you need to pass parameters directly. Choose ServiceFilter if your filter is already registered as a service in the container and you want to leverage the container’s lifetime management for your filter instances.
So, TypeFilter is suitable for applying filters to specific actions or controllers without global configuration. At the same time, ServiceFilter is more suitable when you want to reuse filters across multiple actions or controllers and configure them globally through dependency injection.
In the next article, I will discuss Cross-Site Request Forgery and Antiforgery Tokens in ASP.NET Core MVC. In this article, I explain the difference between TypeFilter and ServiceFilter in ASP.NET Core Applications with examples. I hope you enjoy this Difference Between TypeFilter and ServiceFilter in the ASP.NET Core article.
About the Author: Pranaya Rout
Pranaya Rout has published more than 3,000 articles in his 11-year career. Pranaya Rout has very good experience with Microsoft Technologies, Including C#, VB, ASP.NET MVC, ASP.NET Web API, EF, EF Core, ADO.NET, LINQ, SQL Server, MYSQL, Oracle, ASP.NET Core, Cloud Computing, Microservices, Design Patterns and still learning new technologies.