Skip to main content

Entity Context

Target features based on domain objects on the page (orders, products) in addition to user rules. See Entity & page context for the shared model.

Register a context kind​

In Program.cs or Startup.cs, register each entity type your app evaluates:

using Toggly.FeatureManagement.Configuration;

builder.Services.AddTogglyEntityContext<Order>(
kind: "Order",
keySelector: p => p.Id.ToString(),
configure: builder => builder
.KeyProperty("Id")
.Property("Status", "string")
.Property("Total", "number")
.MapAttributes(p => new Dictionary<string, object?>
{
["Status"] = p.Status,
["Total"] = p.Total,
}));
  • kind — matches the context kind selected in the Toggly dashboard for Context Property filters.
  • keySelector — stable instance id for usage stats (user|Order|7).
  • Property / MapAttributes — schema for dashboard catalog sync; explicit MapAttributes overrides reflection.

Repeat for Order, Product, or any other kind you target.

Startup catalog registration​

By default, registered kinds are sent to Toggly at startup so they appear on the dashboard Contexts page:

"Toggly": {
"AppKey": "your-app-key",
"Environment": "Production",
"RegisterContextsOnStartup": true
}

Set RegisterContextsOnStartup to false when you do not want the SDK to call PUT sdk/{appKey}/contexts. Evaluation still works; the dashboard catalog may be stale until updated elsewhere.

Failures are logged as warnings and do not prevent the app from starting.

Razor views​

Import feature tag helpers in _ViewImports.cshtml:

@addTagHelper *, Toggly.FeatureManagement.Web
@removeTagHelper Microsoft.FeatureManagement.Mvc.TagHelpers.FeatureTagHelper, Microsoft.FeatureManagement.AspNetCore

The remove is required when the project also references Microsoft.FeatureManagement.AspNetCore. Microsoft's helper targets <feature> and ignores context, so entity rules would never run.

Conditionally render UI for a specific order on the detail page:

@model OrderDetailViewModel

<feature name="OrderBadge" context="@Model.Order">
<span class="badge">Featured order</span>
</feature>

Multiple features with requirement="All":

<feature names="NewCheckout,ExpressShipping" requirement="All" context="@Model.Order">
<partial name="_ExpressCheckout" model="Model.Order" />
</feature>

When context is omitted but the feature has Context Property filters, evaluation fails closed (content hidden).

Controllers and services​

Use IFeatureManager.IsEnabledAsync with the entity instance:

public class PuppiesController : Controller
{
private readonly IFeatureManager _featureManager;

public PuppiesController(IFeatureManager featureManager)
{
_featureManager = featureManager;
}

public async Task<IActionResult> Details(int id)
{
var order = await _repository.GetAsync(id);
ViewBag.ShowBadge = await _featureManager.IsEnabledAsync("OrderBadge", order);
return View(order);
}
}

Use IFeatureManager when the same feature is checked against different Orders. IFeatureManagerSnapshot caches Boolean results by feature for the request and can reuse the first Order's result.

List actions — evaluate per row in memory (no extra Toggly HTTP per item when using cached definitions on server):

foreach (var order in orders)
{
order.ShowExpress = await _featureManager.IsEnabledAsync("ExpressCheckout", order);
}

User rules AND entity rules​

Server evaluation applies user filters first (from HttpContext / ambient user context), then entity filters against the passed instance. Percentage rollouts apply to the user only.

If user targeting fails, the feature is off regardless of entity attributes.

Fail closed​

SituationResult
Feature has entity filters, call without contextfalse
context type not registered via AddTogglyEntityContextfalse
Resolver cannot map attributesfalse

Working example​

Explore the .NET SDK Sample. Its guided sections include the first flag, request identity, Order VIP targeting, filter presets, named variants, Hangfire, health checks, and OpenAPI filtering. The README maps each section to its source files and includes a manual walkthrough.