How to Add License Key Validation to Your .NET Application
Whether you're building an ASP.NET Core web API, a WPF desktop application, or a .NET MAUI mobile app, license key validation is critical for monetization. This guide shows you how to integrate Traffic Orchestrator into any .NET application using the REST API.
Why License Keys in .NET?
The .NET ecosystem powers enterprise software across every platform. License keys help you:
- Monetize desktop applications with per-seat licensing
- Control API access with subscription-based keys
- Enforce domain binding for web deployments
- Support offline scenarios with cryptographic verification
Step 1: Create a License Client
Create a reusable HTTP client class for license validation:
// Services/LicenseClient.cs
using System.Net.Http.Json;
public class LicenseClient { private readonly HttpClient _http; private readonly string _baseUrl;
public LicenseClient(string baseUrl = "https://api.trafficorchestrator.com/api/v1") { _http = new HttpClient(); _baseUrl = baseUrl; }
public async Task<LicenseResult> ValidateAsync(string key, string domain) { var response = await _http.PostAsJsonAsync( $"{_baseUrl}/validate", new { key, domain } );
response.EnsureSuccessStatusCode(); return await response.Content.ReadFromJsonAsync<LicenseResult>(); } }
public record LicenseResult( bool Valid, string Key, string[] Features, string Error, string Plan ); ```
Step 2: ASP.NET Core Middleware
Protect your web API with middleware:
// Middleware/LicenseMiddleware.cs
public class LicenseMiddleware
{
private readonly RequestDelegate _next;
private readonly LicenseClient _client;
public LicenseMiddleware(RequestDelegate next, LicenseClient client) { _next = next; _client = client; }
public async Task InvokeAsync(HttpContext context) { var licenseKey = context.Request.Headers["X-License-Key"].FirstOrDefault();
if (string.IsNullOrEmpty(licenseKey)) { context.Response.StatusCode = 401; await context.Response.WriteAsJsonAsync(new { error = "License key required" }); return; }
var result = await _client.ValidateAsync(licenseKey, context.Request.Host.Value);
if (!result.Valid) { context.Response.StatusCode = 403; await context.Response.WriteAsJsonAsync(new { error = "Invalid license", reason = result.Error }); return; }
context.Items["License"] = result; await _next(context); } }
// Register in Program.cs // app.UseMiddleware<LicenseMiddleware>(); ```
Step 3: Attribute-Based Authorization
Create a custom authorization attribute for controller actions:
// Attributes/RequireLicenseAttribute.cs
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class RequireLicenseAttribute : Attribute, IAsyncActionFilter
{
private readonly string _feature;
public RequireLicenseAttribute(string feature = null) { _feature = feature; }
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { var license = context.HttpContext.Items["License"] as LicenseResult;
if (license == null || !license.Valid) { context.Result = new UnauthorizedObjectResult(new { error = "Valid license required" }); return; }
if (_feature != null && !license.Features.Contains(_feature)) { context.Result = new ObjectResult(new { error = $"Feature '{_feature}' not included" }) { StatusCode = 403 }; return; }
await next(); } } ```
Use it on controllers:
[ApiController]
[Route("api/[controller]")]
public class AnalyticsController : ControllerBase
{
[HttpGet]
[RequireLicense("analytics")]
public IActionResult GetAnalytics()
{
var license = HttpContext.Items["License"] as LicenseResult;
return Ok(new { analytics = "data", plan = license?.Plan });
}
}
Step 4: Desktop Application (WPF / WinForms)
For desktop apps, validate on startup and cache the result:
// Desktop license validation
var client = new LicenseClient();
// Generate a machine fingerprint var machineId = Convert.ToHexString( System.Security.Cryptography.SHA256.HashData( System.Text.Encoding.UTF8.GetBytes(Environment.MachineName + Environment.UserName) ) )[..32];
var result = await client.ValidateAsync(licenseKey, machineId);
if (result.Valid) { // License is active — enable features EnableFeatures(result.Features); } else { // Show activation dialog ShowActivationDialog(result.Error); } ```
Step 5: Dependency Injection Setup
Register the license client in your DI container:
// Program.cs
builder.Services.AddSingleton<LicenseClient>();
builder.Services.AddScoped<LicenseMiddleware>();
var app = builder.Build(); app.UseMiddleware<LicenseMiddleware>(); ```
Next Steps
- Browse the REST API documentation for all available endpoints
- Set up webhook integration for real-time events
- Learn about domain binding for web app protection
- Explore offline verification with Ed25519 signatures
Traffic Orchestrator's REST API works with any .NET HTTP client, giving you full control over license validation in ASP.NET Core, WPF, MAUI, and console applications.
Ship licensing in your next release
5 licenses, 500 validations/month, full API access. Set up in under 5 minutes — no credit card required.