Roll out features to targeted audiences in an ASP.NET Core application
In this guide, you'll use the targeting filter to roll out a feature to targeted audiences for your ASP.NET Core application. For more information about the targeting filter, see Roll out features to targeted audiences.
Prerequisites
- An Azure account with an active subscription. Create one for free.
- An App Configuration store. Create a store.
- A feature flag with targeting filter. Create the feature flag.
- .NET SDK 6.0 or later.
Create a web application with a feature flag
In this section, you create a web application that allows users to sign in and use the Beta feature flag you created before.
Create a web application that authenticates against a local database using the following command.
dotnet new webapp --auth Individual -o TestFeatureFlags
Navigate to the newly created TestFeatureFlags directory and add references to the following NuGet packages.
dotnet add package Microsoft.Azure.AppConfiguration.AspNetCore dotnet add package Microsoft.FeatureManagement.AspNetCore dotnet add package Azure.Identity
Create a user secret for the application by running the following commands.
The command uses Secret Manager to store a secret named
Endpoints:AppConfiguration
, which stores the endpoint for your App Configuration store. Replace the<your-App-Configuration-endpoint>
placeholder with your App Configuration store's endpoint. You can find the endpoint in your App Configuration store's Overview blade in the Azure portal.dotnet user-secrets init dotnet user-secrets set Endpoints:AppConfiguration "<your-App-Configuration-endpoint>"
Add Azure App Configuration and feature management to your application.
You use the
DefaultAzureCredential
to authenticate to your App Configuration store. Follow the instructions to assign your credential the App Configuration Data Reader role. Be sure to allow sufficient time for the permission to propagate before running your application.Update the Program.cs file with the following code.
// Existing code in Program.cs // ... ... using Azure.Identity; var builder = WebApplication.CreateBuilder(args); // Retrieve the endpoint string endpoint = builder.Configuration.GetValue<string>("Endpoints:AppConfiguration") ?? throw new InvalidOperationException("The setting `Endpoints:AppConfiguration` was not found."); // Connect to Azure App Configuration and load all feature flags with no label builder.Configuration.AddAzureAppConfiguration(options => { options.Connect(new Uri(endpoint), new DefaultAzureCredential()) .UseFeatureFlags(); }); // Add Azure App Configuration middleware to the container of services builder.Services.AddAzureAppConfiguration(); // Add feature management to the container of services builder.Services.AddFeatureManagement(); // The rest of existing code in Program.cs // ... ...
Enable configuration and feature flag refresh from Azure App Configuration with the App Configuration middleware.
Update Program.cs withe the following code.
// Existing code in Program.cs // ... ... var app = builder.Build(); // Use Azure App Configuration middleware for dynamic configuration refresh app.UseAzureAppConfiguration(); // The rest of existing code in Program.cs // ... ...
Add a new empty Razor page named Beta under the Pages directory. It includes two files Beta.cshtml and Beta.cshtml.cs.
@page @model TestFeatureFlags.Pages.BetaModel @{ ViewData["Title"] = "Beta Page"; } <h1>This is the beta website.</h1>
Open Beta.cshtml.cs, and add the
FeatureGate
attribute to theBetaModel
class.using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.FeatureManagement.Mvc; namespace TestFeatureFlags.Pages { [FeatureGate("Beta")] public class BetaModel : PageModel { public void OnGet() { } } }
Open Pages/_ViewImports.cshtml, and register the feature manager Tag Helper using an
@addTagHelper
directive.@addTagHelper *, Microsoft.FeatureManagement.AspNetCore
Open _Layout.cshtml in the Pages/Shared directory. Insert a new
<feature>
tag in between the Home and Privacy navbar items, as shown in the highlighted lines below.<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3"> <div class="container"> <a class="navbar-brand" asp-area="" asp-page="/Index">TestAppConfigNet3</a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse"> <ul class="navbar-nav flex-grow-1"> <li class="nav-item"> <a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a> </li> <feature name="Beta"> <li class="nav-item"> <a class="nav-link text-dark" asp-area="" asp-page="/Beta">Beta</a> </li> </feature> <li class="nav-item"> <a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a> </li> </ul> </div> </div> </nav>
Enable targeting for the web application
The targeting filter evaluates a user's feature state based on the user's targeting context, which comprises the user ID and the groups the user belongs to. In this example, you use the signed-in user's email address as the user ID and the domain name of the email address as the group.
Add an ExampleTargetingContextAccessor.cs file with the following code. You implement the
ITargetingContextAccessor
interface to provide the targeting context for the signed-in user of the current request.using Microsoft.FeatureManagement.FeatureFilters; namespace TestFeatureFlags { public class ExampleTargetingContextAccessor : ITargetingContextAccessor { private const string TargetingContextLookup = "ExampleTargetingContextAccessor.TargetingContext"; private readonly IHttpContextAccessor _httpContextAccessor; public ExampleTargetingContextAccessor(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); } } }
Open the Program.cs file and enable the targeting filter by calling the
WithTargeting
method. You pass in the typeExampleTargetingContextAccessor
that the targeting filter will use to get the targeting context during feature flag evaluation. AddHttpContextAccessor
to the service collection to allowExampleTargetingContextAccessor
to access the signed-in user information from theHttpContext
.// Existing code in Program.cs // ... ... // Add feature management to the container of services builder.Services.AddFeatureManagement() .WithTargeting<ExampleTargetingContextAccessor>(); // Add HttpContextAccessor to the container of services. builder.Services.AddHttpContextAccessor(); // The rest of existing code in Program.cs // ... ...
Note
For Blazor applications, see instructions for enabling feature management as scoped services.
Targeting filter in action
Build and run the application. Initially, the Beta item doesn't appear on the toolbar, because the Default percentage option is set to 0.
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.Sign in as
test@contoso.com
, using the password you set when registering the account.The Beta item now appears on the toolbar, because
test@contoso.com
is specified as a targeted user.Now sign in as
testuser@contoso.com
, using the password you set when registering the account. The Beta item doesn't appear on the toolbar, becausetestuser@contoso.com
is specified as an excluded user.You can create more users with
@contoso.com
and@contoso-xyz.com
email addresses to see the behavior of the group settings.Users with
contoso-xyz.com
email addresses won't see the Beta item. While 50% of users with@contoso.com
email addresses will see the Beta item, the other 50% won't see the Beta item.
Next steps
To learn more about the feature filters, continue to the following documents.
For the full feature rundown of the .NET feature management library, continue to the following document.