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; explicitMapAttributesoverrides 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
| Situation | Result |
|---|---|
Feature has entity filters, call without context | false |
context type not registered via AddTogglyEntityContext | false |
| Resolver cannot map attributes | false |
Related
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.