IronAlpine.Framework.Web
3.0.6
See the version list below for details.
dotnet add package IronAlpine.Framework.Web --version 3.0.6
NuGet\Install-Package IronAlpine.Framework.Web -Version 3.0.6
<PackageReference Include="IronAlpine.Framework.Web" Version="3.0.6" />
<PackageVersion Include="IronAlpine.Framework.Web" Version="3.0.6" />
<PackageReference Include="IronAlpine.Framework.Web" />
paket add IronAlpine.Framework.Web --version 3.0.6
#r "nuget: IronAlpine.Framework.Web, 3.0.6"
#:package IronAlpine.Framework.Web@3.0.6
#addin nuget:?package=IronAlpine.Framework.Web&version=3.0.6
#tool nuget:?package=IronAlpine.Framework.Web&version=3.0.6
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.0.6,net10.0) - Depends on: Kernel, Observability, Swashbuckle 10,
Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer5.1, Yarp.ReverseProxy 2.3
Installation
<PackageReference Include="IronAlpine.Framework.Web" Version="3.0.6" />
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), appliesserviceNameandconfigure; in Development, when no origins are configured, allowshttp://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'VVVand version substitution; - adds Swagger generation: one document per API version (title from
ServiceName), aBearersecurity 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:
UseCors(CorsPolicyName)EventMetadataMiddlewareGlobalExceptionHandlingMiddleware- Swagger + Swagger UI - only when
EnableSwaggerand 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(taglive) - always healthy;/health/live.ironalpine-ready(tagready) -/health/ready. Checks:- every
DbContextservice type registered beforeAddIronAlpineHealthChecks(Database.CanConnectAsync); - Redis, when an
IConnectionMultiplexeris registered (detected at probe time, so registration order does not matter): the multiplexer must be connected and answerPING; - Kafka, when the IronAlpine event bus (
AddIronAlpineEventBusKafka) or ConfluentIProducer<,>/IConsumer<,>services are registered: event bus topology/transport state, broker metadata and the presence of every topology topic. Settings come from the boundEventBusKafkaOptions(including code overrides;Enabled = falseskips the Kafka check). Without the event bus they are read fromIronAlpine:EventBus:Kafka, and only when that section is absent from the legacyIronAlpine:Messaging:Kafkasection. The metadata timeout isProvisioning:MetadataWaitTimeoutSeconds(default 20 s).
- every
- Other checks tagged
ready, for example the event bus checkia-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-readynever 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.
DbContexttypes are captured whenAddIronAlpineHealthChecksruns: register it after the data packages.- Outside Development an empty
AllowedOriginsstops the host at start-up. - Running production workloads with
ASPNETCORE_ENVIRONMENT=Developmentenables Swagger, the development CORS origins and exception details in error responses. - The API versioning package is
Microsoft.AspNetCore.Mvc.Versioning(legacy line);[ApiVersion]comes fromMicrosoft.AspNetCore.Mvc. IronAlpine.Web.Runtime.AsyncLocalEventMetadataAccessorandDefaultExecutionModeDetectorare[Obsolete](3.0.5) and duplicate the types inIronAlpine.Observability.Runtime; prefer the Observability ones.
| Product | Versions 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. |
-
net10.0
- IronAlpine.Framework.Kernel (>= 3.0.6)
- IronAlpine.Framework.Observability (>= 3.0.6)
- Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer (>= 5.1.0)
- Microsoft.EntityFrameworkCore (>= 10.0.10)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Diagnostics.HealthChecks (>= 10.0.10)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 10.0.10)
- Swashbuckle.AspNetCore (>= 10.2.3)
- Yarp.ReverseProxy (>= 2.3.0)
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 |
IronAlpine framework release. See the package README and repository documentation for details.