CSharpEssentials.AspNetCore
4.0.0
See the version list below for details.
dotnet add package CSharpEssentials.AspNetCore --version 4.0.0
NuGet\Install-Package CSharpEssentials.AspNetCore -Version 4.0.0
<PackageReference Include="CSharpEssentials.AspNetCore" Version="4.0.0" />
<PackageVersion Include="CSharpEssentials.AspNetCore" Version="4.0.0" />
<PackageReference Include="CSharpEssentials.AspNetCore" />
paket add CSharpEssentials.AspNetCore --version 4.0.0
#r "nuget: CSharpEssentials.AspNetCore, 4.0.0"
#:package CSharpEssentials.AspNetCore@4.0.0
#addin nuget:?package=CSharpEssentials.AspNetCore&version=4.0.0
#tool nuget:?package=CSharpEssentials.AspNetCore&version=4.0.0
CSharpEssentials.AspNetCore
Production-ready ASP.NET Core utilities: global exception handling, structured ProblemDetails, API versioning, Swagger setup, and Result endpoint filters.
Features
- Enhanced Problem Details — One configurable ProblemDetails pipeline for Minimal API, MVC, the exception handler and status code pages. It has secure defaults and the extension points
IProblemDetailsEnricher,IErrorStatusCodeMapperandIExceptionProblemMapper. - Global Exception Handler — Maps exceptions to ProblemDetails. Unknown exceptions return 500, and the exception message goes to the log, not to the response.
- Result Endpoint Filter — Converts
Result<T>return values to200 OKor a ProblemDetails response. - Enum Binding — Query and route values for
[StringEnum]enums accept the same spellings as JSON. Invalid values return 400. - API Versioning — Pre-configured URL segment and header-based versioning.
- Swagger — Easy setup with versioning support, enum schema filters, and custom schema IDs.
Installation
dotnet add package CSharpEssentials.AspNetCore
Usage
Problem Details
builder.Services.AddEnhancedProblemDetails(o =>
{
o.TraceId = TraceIdFormat.W3CTraceId; // default
o.ErrorFields = ProblemErrorFields.Codes | ProblemErrorFields.ValidationErrors; // default
o.ExposeExceptionDetails = builder.Environment.IsDevelopment();
});
builder.Services.AddExceptionHandler<GlobalExceptionHandler>();
// Optional extension points
builder.Services.AddProblemDetailsEnricher<TenantEnricher>(); // add fields to every problem response
builder.Services.AddErrorStatusCodeMapper<AuthAwareStatusMapper>(); // Error -> status code / title
builder.Services.AddExceptionProblemMapper<PaymentExceptionMapper>(); // Exception -> problem
var app = builder.Build();
app.UseEnhancedProblemDetails(); // UseExceptionHandler + UseStatusCodePages
| Option | Default | Notes |
|---|---|---|
TraceId |
W3CTraceId |
TraceparentHeader or None |
IncludeRequestId / IncludeUser / IncludeSpanIds |
false |
|
Instance |
Path |
MethodAndPath or None |
ErrorFields |
Codes \| ValidationErrors |
Messages, AllErrors, All, None |
ValidationErrorsFormat |
List |
Dictionary groups descriptions by code |
TypeUriResolver |
ProblemTypeUris.Rfc9110 |
ProblemTypeUris.Rfc7231 or a custom function |
ExposeExceptionDetails |
false |
Enable only in Development |
o.UseLegacyDefaults() restores the 3.x output. See the migration notes in the repository README.
With no W3C Activity (tracing disabled), W3CTraceId falls back to HttpContext.TraceIdentifier. errors lists only ErrorType.Validation errors; every code is in errorCodes.
services.ConfigureInvalidModelStateResponse() writes the automatic 400 of [ApiController] (invalid model state) through the same pipeline, with the model state key as the error code. It can be called before or after AddControllers(). It has no effect together with ConfigureModelValidatorResponse(), which turns the automatic 400 off (SuppressModelStateInvalidFilter = true); use one or the other.
errors.ToProblemResult() (Minimal API) and errors.ToActionResult(HttpContext) (MVC) read these options when they execute, so both produce the same JSON.
API Versioning
builder.Services.AddAndConfigureApiVersioning();
var app = builder.Build();
var usersGroup = app.CreateVersionedGroup("users", version: 1);
usersGroup.MapGet("/{id}", (int id) => Results.Ok(new { Id = id }));
Swagger with Versioning
builder.Services.AddSwagger<ConfigureSwaggerOptions>(securityScheme: SecuritySchemes.Bearer);
var app = builder.Build();
app.UseVersionableSwagger();
Result Endpoint Filter
builder.Services.AddScoped<IResultErrorMapper, DomainErrorMapper>(); // optional, any lifetime
app.MapGet("/users/{id}", (int id) => GetUser(id))
.AddEndpointFilter<ResultEndpointFilter>();
// Returns 200 with value on success; on failure the mapper's result (resolved per request),
// or a ProblemDetails response when no mapper is registered
Enum Query/Route Binding
builder.Services.AddEnumBinding(o => o.AllowIntegerValues = true); // optional
app.UseEnumBinding(); // after routing, UseAuthentication and UseAuthorization (otherwise a 400 hides the 401)
// [StringEnum] enum OrderStatus { InProgress, Done }
// ?status=in_progress, ?status=InProgress, ?status=inprogress, ?status=0 all bind to OrderStatus.InProgress
app.MapGet("/orders", (OrderStatus? status) => ...);
This works for Minimal API (including [AsParameters]) and MVC ([FromQuery], [FromRoute], and query DTO properties, nested up to 8 levels: ?filter.inner.status=…).
- Nullable, array,
List<T>and[Flags]parameters are supported. Flags values are a comma-separated list. - These values return a 400 ProblemDetails response:
- undefined numbers;
- unknown names;
- commas on enums without
[Flags]; - empty values for non-nullable parameters.
- The error code is the query/route key (
status,filter.status). Change the code or message witho.ErrorFactory = (key, enumType, names) => Error.Validation($"validation.{key}", ...). - Empty values of nullable or collection parameters are dropped, so they bind as
nullor are skipped. - Matched values are rewritten to the C# member name before binding. Link generation that reuses the current route values (ambient values, such as
CreatedAtRoutewithout explicit values) therefore emits the member name (/items/HttpStatus). Pass the value explicitly to get the JSON spelling.
Structured Error Response
{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
"title": "Bad Request",
"status": 400,
"detail": "Email format is incorrect.",
"instance": "/users",
"traceId": "0af7651916cd43dd8448eb211c80319c",
"errorCodes": ["User.InvalidEmail"],
"errors": [
{ "code": "User.InvalidEmail", "description": "Email format is incorrect." }
]
}
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. 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. net11.0 is compatible. |
-
net10.0
- Asp.Versioning.Abstractions (>= 8.1.0)
- Asp.Versioning.Http (>= 8.1.0)
- Asp.Versioning.Mvc (>= 8.1.0)
- Asp.Versioning.Mvc.ApiExplorer (>= 8.1.0)
- CSharpEssentials.Errors (>= 4.0.0)
- CSharpEssentials.Json (>= 4.0.0)
- CSharpEssentials.Results (>= 4.0.0)
- Swashbuckle.AspNetCore (>= 8.1.0 && < 10.0.0)
-
net11.0
- Asp.Versioning.Abstractions (>= 8.1.0)
- Asp.Versioning.Http (>= 8.1.0)
- Asp.Versioning.Mvc (>= 8.1.0)
- Asp.Versioning.Mvc.ApiExplorer (>= 8.1.0)
- CSharpEssentials.Errors (>= 4.0.0)
- CSharpEssentials.Json (>= 4.0.0)
- CSharpEssentials.Results (>= 4.0.0)
- Swashbuckle.AspNetCore (>= 8.1.0 && < 10.0.0)
-
net8.0
- Asp.Versioning.Abstractions (>= 8.1.0)
- Asp.Versioning.Http (>= 8.1.0)
- Asp.Versioning.Mvc (>= 8.1.0)
- Asp.Versioning.Mvc.ApiExplorer (>= 8.1.0)
- CSharpEssentials.Errors (>= 4.0.0)
- CSharpEssentials.Json (>= 4.0.0)
- CSharpEssentials.Results (>= 4.0.0)
- Swashbuckle.AspNetCore (>= 8.1.0 && < 10.0.0)
- System.Text.Json (>= 9.0.4)
-
net9.0
- Asp.Versioning.Abstractions (>= 8.1.0)
- Asp.Versioning.Http (>= 8.1.0)
- Asp.Versioning.Mvc (>= 8.1.0)
- Asp.Versioning.Mvc.ApiExplorer (>= 8.1.0)
- CSharpEssentials.Errors (>= 4.0.0)
- CSharpEssentials.Json (>= 4.0.0)
- CSharpEssentials.Results (>= 4.0.0)
- Swashbuckle.AspNetCore (>= 8.1.0 && < 10.0.0)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on CSharpEssentials.AspNetCore:
| Package | Downloads |
|---|---|
|
CSharpEssentials.AspNetCore.Swashbuckle
Swashbuckle (Swagger) integration for CSharpEssentials.AspNetCore: versioned Swagger setup, schema ids, security schemes and OpenAPI enum schemas that follow the CSharpEssentials enum conventions (wire names, numeric groups, flags and nullable properties). Use it instead of CSharpEssentials.AspNetCore.OpenApi, never together with it. |
|
|
CSharpEssentials.AspNetCore.OpenApi
Microsoft.AspNetCore.OpenApi integration for the CSharpEssentials enum conventions: enum schemas with wire names, numeric groups, flags, collections, defaults and nullable usages, for OpenAPI 3.0 and 3.1 documents. Use it instead of CSharpEssentials.AspNetCore.Swashbuckle, never together with it. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 6.5.0 | 0 | 10/9/2026 |
| 6.4.0 | 24 | 10/9/2026 |
| 6.3.0 | 35 | 10/8/2026 |
| 6.2.0 | 48 | 10/8/2026 |
| 6.1.0 | 43 | 10/7/2026 |
| 6.0.0 | 47 | 10/7/2026 |
| 5.2.1 | 47 | 10/7/2026 |
| 5.2.0 | 47 | 10/7/2026 |
| 5.1.0 | 43 | 10/7/2026 |
| 5.0.0 | 50 | 10/6/2026 |
| 4.1.0 | 46 | 10/6/2026 |
| 4.0.0 | 89 | 10/5/2026 |
| 3.2.3 | 161 | 5/31/2026 |
| 3.2.2 | 128 | 5/31/2026 |
| 3.2.1 | 119 | 5/31/2026 |
| 3.2.0 | 118 | 5/30/2026 |
| 3.1.0 | 124 | 5/27/2026 |
| 3.0.8 | 116 | 5/20/2026 |
| 3.0.7 | 120 | 5/20/2026 |
| 3.0.6 | 122 | 5/20/2026 |