IronAlpine.Framework.Web 3.1.1

dotnet add package IronAlpine.Framework.Web --version 3.1.1
                    
NuGet\Install-Package IronAlpine.Framework.Web -Version 3.1.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="IronAlpine.Framework.Web" Version="3.1.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="IronAlpine.Framework.Web" Version="3.1.1" />
                    
Directory.Packages.props
<PackageReference Include="IronAlpine.Framework.Web" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add IronAlpine.Framework.Web --version 3.1.1
                    
#r "nuget: IronAlpine.Framework.Web, 3.1.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package IronAlpine.Framework.Web@3.1.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=IronAlpine.Framework.Web&version=3.1.1
                    
Install as a Cake Addin
#tool nuget:?package=IronAlpine.Framework.Web&version=3.1.1
                    
Install as a Cake Tool

IronAlpine.Framework.Web

ASP.NET Core defaults for IronAlpine services: CORS, URL-segment API versioning, Swagger with a bearer scheme, correlation/trace metadata middleware, a global exception middleware, slugified routes, liveness/readiness health checks and a YARP transform for gateways.

  • Package id: IronAlpine.Framework.Web (3.1.1, net10.0)
  • Depends on: Kernel, Observability, Swashbuckle 10, Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer 5.1, Yarp.ReverseProxy 2.3

Installation

<PackageReference Include="IronAlpine.Framework.Web" Version="3.1.1" />

Quick start

using IronAlpine.Web.Extensions;

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddIronAlpineWebDefaults(builder.Configuration, "orders-service")
    .AddControllers()
    .AddIronAlpineSlugifiedRoutes();

builder.Services.AddIronAlpineHealthChecks();      // after DbContext / Redis registrations

var app = builder.Build();

app.UseIronAlpineWebDefaults();                    // CORS, metadata, exception handling, Swagger (Development)
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.MapIronAlpineHealthChecks();                   // /health/live, /health/ready
app.Run();

AddIronAlpineWebDefaults does not register Serilog, telemetry or health checks; combine it with the Observability package and AddIronAlpineHealthChecks.

Services

AddIronAlpineWebDefaults(configuration = null, serviceName = null, configure = null)

  • binds IronAlpine:Web:AspNetCore (IronAlpineWebOptions), applies serviceName and configure; in Development, when no origins are configured, allows http://localhost:4200, http://localhost:5173, http://localhost:5000;
  • calls AddIronAlpineWeb (below);
  • adds a CORS policy (CorsPolicyName) with the allowed origins, any header, any method and credentials;
  • adds API versioning: default 1.0, assumed when unspecified, reported in headers, read from the URL segment (UrlSegmentApiVersionReader); versioned API explorer with group name 'v'VVV and version substitution;
  • adds Swagger generation: one document per API version (title from ServiceName), a Bearer security scheme and requirement, operation ids = action method names.

Controllers therefore use routes such as:

[ApiController]
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/[controller]")]
public sealed class OrderLinesController : ControllerBase { }

AddIronAlpineWeb(configuration = null, configure = null)

Registers only the middleware pieces: IronAlpineWebOptions (validated on start), IHttpContextAccessor, HttpEventMetadataProvider as IEventMetadataAccessor / IEventMetadataProvider (replacing earlier registrations), EventMetadataMiddleware, GlobalExceptionHandlingMiddleware.

IMvcBuilder.AddIronAlpineSlugifiedRoutes()

Adds a route token transformer: [controller] / [action] tokens become kebab case (OrderLines → order-lines). Only lower-to-upper boundaries are split (GetV2Orders → get-v2orders).

Configuration

{
  "IronAlpine": {
    "Web": {
      "AspNetCore": {
        "ServiceName": "orders-service",
        "ErrorCodePrefix": "ORD",
        "CorsPolicyName": "IronAlpineDefaultCorsPolicy",
        "AllowedOrigins": [ "https://app.example.com" ],
        "EnableSwagger": true,
        "SwaggerRoutePrefix": ""
      }
    }
  }
}

Validation (on start): CorsPolicyName must be set; outside Development AllowedOrigins must contain at least one origin. "Development" is read from the ASPNETCORE_ENVIRONMENT / DOTNET_ENVIRONMENT environment variables.

Middleware

app.UseIronAlpineWebDefaults() runs, in this order:

  1. UseCors(CorsPolicyName)
  2. EventMetadataMiddleware
  3. GlobalExceptionHandlingMiddleware
  4. Swagger + Swagger UI - only when EnableSwagger and the environment is Development (one endpoint per API version, RoutePrefix = SwaggerRoutePrefix)

app.UseIronAlpineWeb() adds only steps 2 and 3. Call either before authentication/authorization and endpoint mapping, so exceptions from later middleware are handled.

Event metadata

For each request EventMetadataMiddleware builds an EventMetadataContext:

Field Source
TraceId Activity.Current.TraceId, else HttpContext.TraceIdentifier, else a new Guid
CorrelationId X-Correlation-ID header, else TraceId
CausationId, TenantId X-Causation-ID, X-Tenant-ID
TraceParent, TraceState, Baggage traceparent (else current activity id), tracestate, baggage

It stores the context in an async local (read through IEventMetadataProvider), tags the current activity (correlation.id, causation.id, tenant.id), sets HttpContext.TraceIdentifier to the trace id and returns X-Correlation-ID in the response. Serilog enrichment and the telemetry processor of the Observability package use the same provider.

Exception handling

Exception Status errorCode
DomainException 400 {PREFIX}-DOMAIN-0001
IronAlpine.Kernel.Exceptions.ApplicationException 400 {PREFIX}-APPLICATION-0001
InfrastructureException (incl. TransientException, NonRetryableException) 503 {PREFIX}-INFRASTRUCTURE-0001
PersistenceException 503 {PREFIX}-PERSISTENCE-0001
ApiException (IronAlpine.Web.Middleware) 400 {PREFIX}-API-0001
anything else 500 {PREFIX}-COMMON-UNKNOWN-0001

PREFIX is ErrorCodePrefix upper-cased (default IA). The response is JSON:

{ "errorCode": "ORD-DOMAIN-0001", "message": "Domain error", "traceId": "4bf92f3577b34da6a3ce929d0e0e4736", "detail": null }

detail contains exception.ToString() in Development only. The exception is logged at Error with trace and correlation ids. Nothing is written when the response has already started. BaseException.Code is not included in the response.

Health checks

builder.Services.AddIronAlpineHealthChecks();
app.MapIronAlpineHealthChecks();
  • ironalpine-live (tag live) - always healthy; /health/live.
  • ironalpine-ready (tag ready) - /health/ready. Checks:
    • every DbContext service type registered before AddIronAlpineHealthChecks (Database.CanConnectAsync);
    • Redis, when an IConnectionMultiplexer is registered (detected at probe time, so registration order does not matter): the multiplexer must be connected and answer PING;
    • Kafka, when the IronAlpine event bus (AddIronAlpineEventBusKafka) or Confluent IProducer<,> / IConsumer<,> services are registered: event bus topology/transport state, broker metadata and the presence of every topology topic. Settings come from the bound EventBusKafkaOptions (including code overrides; Enabled = false skips the Kafka check). Without the event bus they are read from IronAlpine:EventBus:Kafka, and only when that section is absent from the legacy IronAlpine:Messaging:Kafka section. The metadata timeout is Provisioning:MetadataWaitTimeoutSeconds (default 20 s).
  • Other checks tagged ready, for example the event bus check ia-eventbus-ready, are included in /health/ready.
  • Responses are JSON: status, totalDurationMs, entries (status, description, durationMs, data, exception).

Only checks tagged live / ready are mapped. Checks registered by other packages without these tags need their own endpoint.

Gateway transforms (YARP)

builder.Services.AddReverseProxy()
    .LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"))
    .AddIronAlpineGatewayTransforms();

For every proxied request: keeps a valid incoming traceparent (or creates one), sets X-Correlation-ID to the trace id, and forwards tracestate, baggage and X-Tenant-ID. A client-supplied X-Correlation-ID is replaced by the trace id when a valid traceparent is present.

Pitfalls

  • Up to 3.0.4 the Redis part of ironalpine-ready never found the multiplexer (always unhealthy when Redis was registered) and the Kafka part never ran with the IronAlpine event bus. Since 3.0.5 both are real checks: a service whose Redis or Kafka is unreachable, or whose topology topics are missing, is reported not ready.
  • The Kafka readiness check creates an admin client and requests broker metadata on every probe; when the broker is unreachable the probe takes up to the metadata timeout. Give the readiness probe a matching timeout.
  • DbContext types are captured when AddIronAlpineHealthChecks runs: register it after the data packages.
  • Outside Development an empty AllowedOrigins stops the host at start-up.
  • Running production workloads with ASPNETCORE_ENVIRONMENT=Development enables Swagger, the development CORS origins and exception details in error responses.
  • The API versioning package is Microsoft.AspNetCore.Mvc.Versioning (legacy line); [ApiVersion] comes from Microsoft.AspNetCore.Mvc.
  • IronAlpine.Web.Runtime.AsyncLocalEventMetadataAccessor and DefaultExecutionModeDetector are [Obsolete] (3.0.5) and duplicate the types in IronAlpine.Observability.Runtime; prefer the Observability ones.
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
3.1.1 193 10/21/2026
3.0.9 221 10/15/2026
3.0.8 117 10/13/2026
3.0.7 102 10/13/2026
3.0.6 110 10/9/2026
3.0.5 196 10/5/2026
3.0.4 199 10/2/2026
3.0.3 170 9/30/2026
3.0.2 1,079 7/22/2026
3.0.1 126 7/22/2026
3.0.0 322 7/20/2026
2.0.3 116 7/20/2026
2.0.2 159 7/13/2026
2.0.1 150 7/13/2026
2.0.0 149 7/13/2026
2.0.0-preview.2 75 7/13/2026
2.0.0-preview.1 80 7/6/2026
1.0.2 129 7/3/2026
1.0.1 127 7/3/2026
Loading failed

IronAlpine framework release. See the package README and repository documentation for details.