Overview
Cuemon.AspNetCore provides the foundational building blocks for writing ASP.NET Core pipeline components. It covers three broad areas: a hierarchy of structured HTTP exceptions that carry a typed status code, reason phrase, and response headers; an abstract configurable middleware base class family that integrates the options pattern with up to five DI-injected parameters; and a set of ready-to-use middleware for common cross-cutting concerns including correlation IDs, request IDs, User-Agent enforcement, server timing, response caching validation, cache-busting version management, API key enforcement, and rate limiting.
The package also defines the fault descriptor pipeline consumed by companion packages such as Cuemon.Extensions.AspNetCore. FaultDescriptorOptions holds a prioritized list of HttpFaultResolver instances, each mapping exception predicates to an HttpExceptionDescriptor. That descriptor extends ExceptionDescriptor from Cuemon.Diagnostics with HTTP-specific fields: StatusCode, Instance, RequestId, CorrelationId, and TraceId. Exception-handling middleware in sibling packages resolves this chain to produce structured fault responses in either FaultDetails or ProblemDetails format.
Key APIs
ConfigurableMiddleware<TOptions> is the abstract base class for building options-pattern middleware. It inherits from ConfigurableMiddlewareCore<TOptions>, exposes the resolved Options property, and requires overriding InvokeAsync(HttpContext context). Generic overloads up to ConfigurableMiddleware<T1, T2, T3, T4, T5, TOptions> let the runtime inject up to five services directly into InvokeAsync through ASP.NET Core's middleware DI convention, avoiding constructor injection for per-request services. Both IOptions<TOptions> and Action<TOptions> constructor overloads are provided so that middleware can be registered with or without the options infrastructure.
HttpStatusCodeException is the abstract base for the package's typed HTTP exception hierarchy. Each subclass hard-codes its status code and a default message, and inherits StatusCode, ReasonPhrase, and a mutable Headers dictionary for additional response headers. The 15 concrete subtypes cover the most common 4xx and 5xx conditions: BadRequestException, UnauthorizedException, ForbiddenException, NotFoundException, MethodNotAllowedException, NotAcceptableException, ConflictException, GoneException, PreconditionFailedException, PayloadTooLargeException, UnsupportedMediaTypeException, PreconditionRequiredException, TooManyRequestsException, InternalServerErrorException, and ThrottlingException.
FaultDescriptorOptions configures the fault descriptor pipeline. Its ExceptionDescriptorHandlers list is pre-populated with an HttpFaultResolver that maps common framework exceptions to appropriate status codes. The FaultDescriptor property (PreferredFaultDescriptor enum, either FaultDetails or ProblemDetails) controls the serialization shape. ExceptionCallback and RequestFilter accept delegates for custom side effects or request-scoped exclusions, and UseBaseException controls whether the innermost exception is used when resolving the descriptor.
IServerTiming and its concrete implementation ServerTiming support the W3C Server-Timing response header. AddServerTiming(name), AddServerTiming(name, duration), and AddServerTiming(name, duration, description) accumulate ServerTimingMetric entries; ServerTimingMiddleware writes the accumulated metrics as a Server-Timing header and optionally measures the downstream pipeline duration using TimeMeasure.
CorrelationIdentifierMiddleware and RequestIdentifierMiddleware propagate per-request identifiers through configurable HTTP headers. CorrelationIdentifierMiddleware reads or generates a correlation ID from the header named by CorrelationIdentifierOptions.HeaderName (default X-Correlation-ID) and stores it in HttpContext.Items under a well-known key constant. RequestIdentifierMiddleware generates a unique request ID per request via RequestIdentifierOptions.Token and echoes it in the response header named by RequestIdentifierOptions.HeaderName (default X-Request-ID).
ThrottlingSentinelMiddleware provides middleware-level rate limiting. It takes a DI-injected IThrottlingCache and ThrottlingSentinelOptions containing a ThrottleQuota. ThrottleQuota accepts a rate limit and a window expressed as either a TimeSpan or a double/TimeUnit pair. When a request exceeds the quota, the middleware throws ThrottlingException, which extends TooManyRequestsException and carries RateLimit, Delta, and Reset properties for Retry-After header construction.
CacheBusting and DynamicCacheBusting implement ICacheBusting for cache-busting version strings. ICacheBusting exposes a single Version string. DynamicCacheBusting rotates the version on a configurable TimeToLive interval defined by DynamicCacheBustingOptions, making it suitable for tag helper scenarios where asset URLs must change periodically without an application restart.
Basic usage
using Codebelt.Extensions.Xunit;
using Cuemon.AspNetCore.Http;
using Microsoft.AspNetCore.Http;
using Xunit;
namespace MyProject.Tests;
public class HttpStatusCodeExceptionTest : Test
{
public HttpStatusCodeExceptionTest(ITestOutputHelper output) : base(output)
{
}
[Fact]
public void TryParse_ShouldCreateTypedExceptionForRetryableFailures()
{
var responseHeaders = new HeaderDictionary
{
["Retry-After"] = "120"
};
var success = HttpStatusCodeException.TryParse(
StatusCodes.Status429TooManyRequests,
"Too many requests for this tenant.",
out var exception);
Assert.True(success);
exception.Headers["Retry-After"] = responseHeaders["Retry-After"];
TestOutput.WriteLine($"{exception.ReasonPhrase} ({exception.StatusCode})");
Assert.IsType<TooManyRequestsException>(exception);
Assert.Equal("120", exception.Headers["Retry-After"].ToString());
}
}
Use this pattern when your ASP.NET Core code needs to turn a raw status code into a typed exception that still carries response metadata such as retry headers. It matters because downstream handlers can branch on the concrete exception type while preserving the HTTP status and header contract that should reach the client.
Installation
dotnet add package Cuemon.AspNetCore
Usage guidance
Adopt Cuemon.AspNetCore when building ASP.NET Core middleware components that need a consistent options pattern, structured HTTP exception types, server timing headers, per-request correlation or request identifiers, or configurable rate limiting. Pair it with Cuemon.Extensions.AspNetCore to activate the fault descriptor exception handler and the extension methods that wire these types into the IApplicationBuilder and IServiceCollection pipelines. If you only need a typed HTTP exception without the rest of the plumbing, the standalone exception classes work without hosting infrastructure, but if you need full content-negotiated fault responses or MVC filters, the sibling packages in the ASP.NET Core stack are a better starting point.
Family packages
- 🏭Cuemon.AspNetCore.App
- 🌐Cuemon.AspNetCore.Authentication
- 🌐Cuemon.AspNetCore.Mvc
- 🌐Cuemon.AspNetCore.Razor.TagHelpers
- 📦Cuemon.Core
- 🏭Cuemon.Core.App
- 🗄️Cuemon.Data
- 🗄️Cuemon.Data.Integrity
- 🗄️Cuemon.Data.SqlClient
- 🩺Cuemon.Diagnostics
- 🌐Cuemon.Extensions.AspNetCore
- 🌐Cuemon.Extensions.AspNetCore.Authentication
- 🌐Cuemon.Extensions.AspNetCore.Mvc
- 🌐Cuemon.Extensions.AspNetCore.Mvc.Formatters.Text.Json
- 🌐Cuemon.Extensions.AspNetCore.Mvc.Formatters.Xml
- 🌐Cuemon.Extensions.AspNetCore.Mvc.RazorPages
- 🌐Cuemon.Extensions.AspNetCore.Text.Json
- 🌐Cuemon.Extensions.AspNetCore.Xml
- 📦Cuemon.Extensions.Collections.Generic
- 📦Cuemon.Extensions.Collections.Specialized
- 📦Cuemon.Extensions.Core
- 🗄️Cuemon.Extensions.Data
- 🗄️Cuemon.Extensions.Data.Integrity
- 📦Cuemon.Extensions.DependencyInjection
- 🩺Cuemon.Extensions.Diagnostics
- 🏗️Cuemon.Extensions.Hosting
- 📦Cuemon.Extensions.IO
- 📦Cuemon.Extensions.Net
- 📦Cuemon.Extensions.Reflection
- 📦Cuemon.Extensions.Runtime.Caching
- 📝Cuemon.Extensions.Text
- 📝Cuemon.Extensions.Text.Json
- 📦Cuemon.Extensions.Threading
- 📦Cuemon.Extensions.Xml
- 📦Cuemon.IO
- ⚙️Cuemon.Kernel
- 📦Cuemon.Net
- 📦Cuemon.Resilience
- 📦Cuemon.Runtime.Caching
- 🔐Cuemon.Security.Cryptography
- 📦Cuemon.Threading
- 📦Cuemon.Xml