Enable staged rollout of features for targeted audiences
Feature flags allow you to dynamically activate or deactivate functionality in your application. Feature filters determine the state of a feature flag each time it's evaluated. The Microsoft.FeatureManagement
library includes TargetingFilter
, which enables a feature flag for a specified list of users and groups, or for a specified percentage of users. TargetingFilter
is "sticky." This means that once an individual user receives a feature, they'll continue to see that feature on all future requests. You can use TargetingFilter
to enable a feature for a specific account during a demo, to progressively roll out new features to users in different groups or "rings," and much more.
In this article, you'll learn how to roll out a new feature in an ASP.NET Core web application to specified users and groups, using TargetingFilter
with Azure App Configuration.
Create a web application with feature flags and authentication
To roll out features based on users and groups, you'll need a web application that allows users to sign in.
Create a web application that authenticates against a local database using the following command:
dotnet new mvc --auth Individual -o TestFeatureFlags
Build and run, then select the Register link in the upper right corner to create a new user account. Use an email address of
test@contoso.com
. On the Register Confirmation screen, select Click here to confirm your account.Follow the instructions in Quickstart: Add feature flags to an ASP.NET Core app to add a feature flag to your new web application.
Toggle the feature flag in App Configuration. Validate that this action controls the visibility of the Beta item on the navigation bar.
Update the web application code to use TargetingFilter
At this point, you can use the feature flag to enable or disable the Beta
feature for all users. To enable the feature flag for some users while disabling it for others, update your code to use TargetingFilter
. In this example, you'll use the signed-in user's email address as the user ID, and the domain name portion of the email address as the group. You'll add the user and group to the TargetingContext
. The TargetingFilter
uses this context to determine the state of the feature flag for each request.
Update to the latest version of the
Microsoft.FeatureManagement.AspNetCore
package.dotnet add package Microsoft.FeatureManagement.AspNetCore
Add a TestTargetingContextAccessor.cs file:
using Microsoft.AspNetCore.Http; using Microsoft.FeatureManagement.FeatureFilters; using System; using System.Collections.Generic; using System.Threading.Tasks; namespace TestFeatureFlags { public class TestTargetingContextAccessor : ITargetingContextAccessor { private const string TargetingContextLookup = "TestTargetingContextAccessor.TargetingContext"; private readonly IHttpContextAccessor _httpContextAccessor; public TestTargetingContextAccessor(IHttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor)); } public ValueTask<TargetingContext> GetContextAsync() { HttpContext httpContext = _httpContextAccessor.HttpContext; if (httpContext.Items.TryGetValue(TargetingContextLookup, out object value)) { return new ValueTask<TargetingContext>((TargetingContext)value); } List<string> groups = new List<string>(); if (httpContext.User.Identity.Name != null) { groups.Add(httpContext.User.Identity.Name.Split("@", StringSplitOptions.None)[1]); } TargetingContext targetingContext = new TargetingContext { UserId = httpContext.User.Identity.Name, Groups = groups }; httpContext.Items[TargetingContextLookup] = targetingContext; return new ValueTask<TargetingContext>(targetingContext); } } }
In Startup.cs, add a reference to the Microsoft.FeatureManagement.FeatureFilters namespace:
using Microsoft.FeatureManagement.FeatureFilters;
Update the ConfigureServices method to register
TargetingFilter
, following the call toAddFeatureManagement()
:services.AddFeatureManagement() .AddFeatureFilter<TargetingFilter>();
Update the ConfigureServices method to add the
TestTargetingContextAccessor
created in the earlier step to the service collection. The TargetingFilter uses it to determine the targeting context every time that the feature flag is evaluated.services.AddSingleton<ITargetingContextAccessor, TestTargetingContextAccessor>();
The entire ConfigureServices method will look like this:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddControllersWithViews();
services.AddRazorPages();
// Add feature management, targeting filter, and ITargetingContextAccessor to service collection
services.AddFeatureManagement().AddFeatureFilter<TargetingFilter>();
services.AddSingleton<ITargetingContextAccessor, TestTargetingContextAccessor>();
}
Update the feature flag to use TargetingFilter
In the Azure portal, go to your App Configuration store and select Feature manager.
Select the context menu for the Beta feature flag that you created in the quickstart. Select Edit.
In the Edit screen, select the Enable feature flag checkbox if it isn't already selected. Then select the Use feature filter checkbox.
Select the Targeting radio button.
Select the following options:
- Default percentage: 0
- Groups: Enter a Name of contoso.com and a Percentage of 50
- Users:
test@contoso.com
The feature filter screen will look like this:
These settings result in the following behavior:
- The feature flag is always enabled for user
test@contoso.com
, becausetest@contoso.com
is listed in the Users section. - The feature flag is enabled for 50% of other users in the contoso.com group, because contoso.com is listed in the Groups section with a Percentage of 50.
- The feature is always disabled for all other users, because the Default percentage is set to 0.
Select Apply to save these settings and return to the Feature manager screen.
The Feature filter for the feature flag now appears as Targeting. This state indicates that the feature flag will be enabled or disabled on a per-request basis, based on the criteria enforced by the Targeting feature filter.
TargetingFilter in action
To see the effects of this feature flag, build and run the application. Initially, the Beta item doesn't appear on the toolbar, because the Default percentage option is set to 0.
Now sign in as test@contoso.com
, using the password you set when registering. The Beta item now appears on the toolbar, because test@contoso.com
is specified as a targeted user.
The following video shows this behavior in action.
You can create additional users with @contoso.com
email addresses to see the behavior of the group settings. 50% of these users will see the Beta item. The other 50% won't see the Beta item.
Next steps
Feedback
Submit and view feedback for