- Home
- .NET tutorials
- Use ASP.NET Core feature management to toggle flags on & off
Use ASP.NET Core feature management to toggle flags on & off
Published: Monday 5 August 2024
ASP.NET Core gives you the ability to toggle features and off with feature management.
This means that you can show certain features to certain users. This could be based on their location, the current date and time, or it could be totally random. The possibilities are endless!
C# coding challenges
It's supported in ASP.NET Core applications and be used in controllers as well as MVC views.
The first step is to ensure that you install the Microsoft.FeatureManagement.AspNetCore
NuGet package into your application. Afterwards, you can start to add features to the configuration through appsettings.json
.
Add feature flags to ASP.NET Core
By default, the FeatureManagement
key is used in appsettings.json
to add features.
Each feature is a key/value pair where the key is the name of the feature and the value is either true
or false
, depending on whether the feature is enabled.
There is an exception to this rule if you use a filter. You can specify the EnabledFor
key and specify the name of the filter. One of the built-in feature flag filters is Percentage
where you can enable a feature for a particular percentage of users.
Here's an example of how it can look in appsettings.json
. We have enabled the NewDesign
feature, disabled the ShowOffer
feature, and enabled the DiscountBanner
feature to 20% of the users.
"FeatureManagement": {
"NewDesign": true,
"ShowOffer": false,
"DiscountBanner": {
"EnabledFor": [
{
"Name": "Percentage",
"Parameters": {
"Value": 20
}
}
]
}
}
To ensure that ASP.NET Core can read your feature flags, you need to add the AddFeatureManagement
extension method in the IServiceCollection
instance in Program.cs
.
// Program.cs
builder.Services.AddFeatureManagement();
To change the name of the config key used in appsettings.json
, you can specify the configuration section as a parameter in the AddFeatureManagement
extension method.
In this example, we've changed it from FeatureManagement
to Features
.
"Features": {
"NewDesign": true,
"ShowOffer": false,
"DiscountBanner": {
"EnabledFor": [
{
"Name": "Percentage",
"Parameters": {
"Value": 20
}
}
]
}
}
// Program.cs
builder.Services.AddFeatureManagement(builder.Configuration.GetSection("Features"));
Use the feature manager in controllers
To use the feature manager in controllers, you need to inject the IFeatureManager
instance into it.
From there, you can use the IsEnabledAsync
method, passing in the feature flag name as the parameter.
For example, if you want to know if the NewDesign
feature is enabled, you would add that into the parameter.
// FeatureController.cs
[Route("api/[controller]")]
[ApiController]
public class FeatureController : ControllerBase
{
private readonly IFeatureManager _featureManager;
public FeatureController(IFeatureManager featureManager)
{
_featureManager = featureManager;
}
[HttpGet]
public async Task<IActionResult> Features()
{
return Ok(new
{
NewDesign = await _featureManager.IsEnabledAsync("NewDesign"),
ShowOffer = await _featureManager.IsEnabledAsync("ShowOffer"),
DiscountBanner = await _featureManager.IsEnabledAsync("DiscountBanner")
});
}
}
It can also be used in a controller as an attribute. By using the FeatureGateAttribute
, the controller's endpoint will only be run if that particular feature is enabled.
If it's not, it will return a 404 not found error.
In this example, the ShowDiscountBanner
is only invoked if the DiscountBanner
feature is enabled.
// FeatureController.cs
public class FeatureController : ControllerBase
{
[HttpGet("show-discount-banner"), FeatureGate("DiscountBanner")]
public IActionResult ShowDiscountBanner()
{
return NoContent();
}
}
Creating custom filters
You can write your own custom filter for feature management. To do that, you need to implement the IFeatureFilter
interface and add a FilterAlias
attribute to the class specifying the name.
The IFeatureFilter
includes an EvaluateAsync
method where you can return whether a feature is enabled or not. This method passes in a FeatureFilterEvaluationContext
instance which gets parameters that can be set in appsettings.json
.
In this instance, we've created a TimeOfDay
filter where it's enabled if the time of day is greater than the value specified in the parameter.
// TimeOfDayFilter.cs
[FilterAlias("TimeOfDay")]
public class TimeOfDayFilter : IFeatureFilter
{
public Task<bool> EvaluateAsync(FeatureFilterEvaluationContext context)
{
return Task.FromResult(DateTime.UtcNow.TimeOfDay >= context.Parameters.GetValue<TimeSpan>("Value"));
}
}
The filter needs to be added to Program.cs
to use it. This can be done by adding the AddFeatureFilter
extension method, with the filter type as its generic type.
// Program.cs
builder.Services.AddFeatureManagement()
.AddFeatureFilter<TimeOfDayFilter>();
We can set the parameter for a feature in appsettings.json
. For this instance, the feature flag is called TimedBanner
and it's enabled using the TimeOfDay
filter when the Value
parameter is 12:00 (UTC)
or later.
{
"FeatureManagement": {
...,
"TimedBanner": {
"EnabledFor": [
{
"Name": "TimeOfDay",
"Parameters": {
"Value": "12:00:00"
}
}
]
}
}
}
Use feature flags in MVC views
As well as controllers, feature flags can be used in MVC views.
To enable it, the @addTagHelper
needs to be added to the view where you are using it. It can also be added to _ViewImports
so it's used throughout the application.
@addTagHelper *, Microsoft.FeatureManagement.AspNetCore
From there, you can use the feature
tag helper alongside the name of the feature flag as a parameter. Depending on whether the feature flag is enabled depends on whether the content inside the feature
tag helper is shown.
You can also use the negate
parameter to show content if the feature flag is disabled.
<!-- Index.cshtml -->
<feature name="DiscountBanner">
<p>Show the banner.</p>
</feature>
<feature name="DiscountBanner" negate="true">
<p>Don't show the banner.</p>
</feature>
There is also the option to specify multiple feature flags in the name
parameter. For this, the requirement
parameter can be set with either All
or Any
.
If set to Any
, any of the feature flags can be enabled to show the content. If it's set to All
, all feature flags have to be enabled for the content to display.
<!-- Index.cshtml -->
<feature name="NewDesign, DiscountBanner" requirement="All">
<p>Show the new design and discount banner.</p>
</feature>
<feature name="NewDesign, DiscountBanner" requirement="Any">
<p>Show any of the new design or discount banner.</p>
</feature>
Watch the video
Watch our video where we add feature management to an ASP.NET Core application, and show you how to add it to controllers and views.
We'll also demonstrate feature flags working by running the application and showing what happens when the features are enabled and disabled.