TinyHelpers.AspNetCore 4.2.12

dotnet add package TinyHelpers.AspNetCore --version 4.2.12
                    
NuGet\Install-Package TinyHelpers.AspNetCore -Version 4.2.12
                    
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="TinyHelpers.AspNetCore" Version="4.2.12" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="TinyHelpers.AspNetCore" Version="4.2.12" />
                    
Directory.Packages.props
<PackageReference Include="TinyHelpers.AspNetCore" />
                    
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 TinyHelpers.AspNetCore --version 4.2.12
                    
#r "nuget: TinyHelpers.AspNetCore, 4.2.12"
                    
#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 TinyHelpers.AspNetCore@4.2.12
                    
#: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=TinyHelpers.AspNetCore&version=4.2.12
                    
Install as a Cake Addin
#tool nuget:?package=TinyHelpers.AspNetCore&version=4.2.12
                    
Install as a Cake Tool

Tiny Helpers for ASP.NET Core

Lint Code Base CodeQL NuGet NuGet License: MIT

TinyHelpers.AspNetCore is a small collection of practical helpers for ASP.NET Core applications: claims handling, configuration binding, localization, middleware support, validation attributes, route helpers, OpenAPI helpers, and exception handling.

The package is designed to reduce code duplication and keep common behavior centralized in one place.

Upgrade from 3.x to 4.x Swashbuckle / Swagger support has been moved to the separate TinyHelpers.AspNetCore.Swashbuckle package. If you were using extensions such as AddAcceptLanguageHeader() and AddDefaultProblemDetailsResponse() together with AddSwaggerGen, you now need to install that package as well.

Compatibility

The package targets:

  • .NET 8
  • .NET 9
  • .NET 10

OpenAPI features are available when the consuming project targets .NET 9 or .NET 10. Some extensions are also framework-specific:

  • EnableEnumSupport() is available only on .NET 9+
  • UseStrictNumericSchemas() is available only on .NET 10+
  • WithResponseDescription() and WithLocationHeader() are available only on .NET 10+

Installation

Install the package from NuGet:

dotnet add package TinyHelpers.AspNetCore

Or search for TinyHelpers.AspNetCore in the Visual Studio Package Manager.

Contents

Claims handling

This area contains two groups of extensions:

  • helpers for IList<Claim> that modify the collection
  • helpers for ClaimsPrincipal that read values without repeating the same lookup logic

ClaimsExtensions

Method What it does When to use it
Update(string type, string value) Removes the first claim with that type and adds a new one with the specified value. When you want to replace an identity value without leaving logical duplicates.
Remove(string type) Removes the first claim with that type. When you want to remove a specific value from the list.

ClaimsPrincipalExtensions

Method What it does When to use it
GetClaimValues(string type) Returns all claim values as string?. When a claim can have multiple values.
GetClaimValues<T>(string type) Returns all values converted to type T. When you need typed conversion of claim values.
GetClaimValue(string type) Returns the first matching value as string?. When the claim is single-value.
GetClaimValue<T>(string type) Returns the first matching value converted to T?. When you want a typed value with default fallback.
HasClaim(string type) Checks whether at least one claim with that type exists. When you need a quick presence check.

Example

using System.Security.Claims;
using TinyHelpers.AspNetCore.Extensions;

var claims = new List<Claim>
{
    new(ClaimTypes.Name, "Marco"),
    new(ClaimTypes.Role, "Admin")
};

claims.Update(ClaimTypes.Name, "Mario");
claims.Remove(ClaimTypes.Role);

var principal = new ClaimsPrincipal(new ClaimsIdentity(claims));

var name = principal.GetClaimValue(ClaimTypes.Name);
var roles = principal.GetClaimValues(ClaimTypes.Role);
var hasName = principal.HasClaim(ClaimTypes.Name);

Configuration and options

IConfigurationExtensions

Method What it does When to use it
GetSection<T>(sectionName) Reads a configuration section and materializes it as object T. When you want a strongly typed object without registering it immediately in the container.

ServiceCollectionExtensions

Method What it does When to use it
ConfigureAndGet<T>(configuration, sectionName) Binds a section and also registers the options in the container, returning the created instance. When you want to configure and read the same options during startup.
Replace<TService, TImplementation>(lifetime) Replaces a registered service with another implementation. When you want to swap a service without rewriting the whole registration.
AddDefaultProblemDetails() Registers ProblemDetails with a consistent and centralized configuration. When you want uniform RFC 7807 responses across the app.
AddDefaultExceptionHandler() Registers the library's default IExceptionHandler and ensures ProblemDetails is available too. When you want unhandled exceptions to become a standard payload.
UseDefaults(ProblemDetailsContext context) Applies the library's default values to a ProblemDetailsContext. When you customize CustomizeProblemDetails but still want the same base behavior.
AddRequestLocalization(params string[] cultures) Registers localization using only the list of supported cultures. The first culture becomes the default. When you do not need to configure providers manually.
AddRequestLocalization(IEnumerable<string> cultures, Action<IList<IRequestCultureProvider>>? providersConfiguration) Registers localization and lets you customize the culture-provider chain. The first culture becomes the default. When you want to change the provider order or composition.

Example

var settings = builder.Services.ConfigureAndGet<MySettings>(builder.Configuration, "MySettings");

builder.Services.AddRequestLocalization("it-IT", "en-US");
builder.Services.AddDefaultProblemDetails();
builder.Services.AddDefaultExceptionHandler();

Localization and pipeline

Method What it does When to use it
TryGetQueryString<T>(key, out value) Reads a value from the current query string and tries to convert it to int, string, decimal, or bool. When you work in Blazor or components that need to read URL parameters.

ApplicationBuilderExtensions

Method What it does When to use it
UseRequestRewind() Enables request-body buffering so the body can be read more than once. When a middleware or filter must inspect the body without consuming it permanently.

EnableRequestRewindMiddleware

The internal middleware used by UseRequestRewind() calls Request.EnableBuffering() before passing control to the next middleware. It is useful for audit, validation, or request-signature scenarios.

Example

app.UseRequestRewind();

if (navManager.TryGetQueryString<int>("page", out var page))
{
    // use page
}

Validation and authorization attributes

AllowedExtensionsAttribute

Validates that an IFormFile uses one of the allowed file extensions.

  • Constructor: AllowedExtensionsAttribute(params string[] extensions)
  • FormatErrorMessage(string name): generates the error message with the allowed extensions

ContentTypeAttribute

Validates the Content-Type of an IFormFile.

  • ContentTypeAttribute(params string[] validContentTypes): uses an explicit MIME type list
  • ContentTypeAttribute(FileType fileType): uses a predefined group
  • FormatErrorMessage(string name): generates the error message with the allowed MIME types

FileType

Supporting enum for ContentTypeAttribute:

  • Image
  • Video
  • Audio

FileSizeAttribute

Validates that an IFormFile does not exceed a maximum size.

  • Constructor: FileSizeAttribute(int maxFileSizeInBytes)
  • FormatErrorMessage(string name): generates the error message with the limit in bytes

RoleAuthorizeAttribute

Automatically builds the Roles list of AuthorizeAttribute from one or more roles.

  • Constructor: RoleAuthorizeAttribute(params string[] roles)

Example

using TinyHelpers.AspNetCore.DataAnnotations;

public sealed class UploadModel
{
    [AllowedExtensions("jpg", "png")]
    [ContentType(FileType.Image)]
    [FileSize(2_000_000)]
    public IFormFile File { get; set; } = default!;
}

[RoleAuthorize("Admin", "Manager")]
public IActionResult SecretArea()
{
    return Ok();
}

Route and Minimal API helpers

RouteHandlerBuilderExtensions

Method What it does Availability
ProducesDefaultProblem(params int[] statusCodes) Adds ProblemDetails responses to the route metadata for the specified status codes. .NET 8+
WithResponseDescription(int statusCode, string description) Updates the description of an existing OpenAPI response. .NET 10+
WithLocationHeader(string description, int statusCode) Adds a Location header to the specified creation response. .NET 10+

These helpers keep Minimal API configuration close to the route instead of scattering OpenAPI metadata in separate places.

Example

app.MapPost("/orders", () => Results.Created("/orders/1", new { Id = 1 }))
   .ProducesDefaultProblem(StatusCodes.Status400BadRequest, StatusCodes.Status500InternalServerError);

.NET 10 example

app.MapPost("/orders", () => Results.Created("/orders/1", new { Id = 1 }))
   .WithResponseDescription(StatusCodes.Status201Created, "Order created successfully")
   .WithLocationHeader();

OpenAPI

The OpenAPI extensions are available when the consuming project uses the package on .NET 9 or .NET 10.

OpenApiExtensions

Method What it does Notes
AddOpenApiOperationParameters(setupAction) Registers reusable OpenAPI parameters inside OpenApiOperationOptions.Parameters. Lets you declare common parameters once.
AddAcceptLanguageHeader() Adds the Accept-Language header to documented operations. Useful when the app uses request localization.
AddDefaultProblemDetailsResponse() Adds a default error response based on ProblemDetails. In .NET 9 it also adds the document transformer.
AddOperationParameters() Adds the parameters configured through OpenApiOperationOptions. The bridge between the options bag and the generated document.
RemoveServerList() Removes the server list from the OpenAPI document. Useful when you want a more portable document across environments.
WriteNumberAsString() Aligns the schema with numbers serialized as strings. Useful when runtime JSON uses JsonNumberHandling.WriteAsString.
DescribeAllParametersInCamelCase() Converts query parameter names to camel case in the document. Keeps documentation consistent with JSON naming.
AddTimeExamples() Adds readable examples for TimeSpan and TimeOnly. Helps readers understand the expected format.
EnableEnumSupport() Improves enum representation in the document. .NET 9 only.
UseFullTypeNameSchemaIds() Uses the full type name for schema IDs. Prevents collisions between types with the same name.
UseStrictNumericSchemas() Removes the string fallback from numeric schemas. .NET 10 only.

OpenApiSchemaHelper

This utility creates ready-to-use schema fragments that can be reused in transformers or other OpenAPI customizations.

.NET 9
  • CreateStringSchema(string? defaultValue = null)
  • CreateSchema<TValue>(string type, string? format = null)
  • CreateSchema<TValue>(string type, string? format, TValue? defaultValue = null)
  • CreateSchema(IEnumerable<string> values, string? defaultValue = null)
  • CreateSchema<TEnum>(TEnum? defaultValue = null)
.NET 10
  • CreateStringSchema(string? defaultValue = null)
  • CreateSchema<TValue>(JsonSchemaType type, string? format = null)
  • CreateSchema<TValue>(JsonSchemaType type, string? format, TValue? defaultValue = null)
  • CreateSchema(IEnumerable<string> values, string? defaultValue = null)
  • CreateSchema<TEnum>(TEnum? defaultValue = null)

What they do in practice

  • CreateStringSchema() creates a simple string schema, optionally with a default.
  • CreateSchema(..., format) creates a schema with explicit type and format.
  • CreateSchema(..., defaultValue) also adds a default to the contract.
  • CreateSchema(IEnumerable<string> values, ...) turns a list of values into a string-based OpenAPI enum.
  • CreateSchema<TEnum>(...) builds an enum schema directly from a CLR enum.

Example

builder.Services.AddOpenApi(options =>
{
    options.AddAcceptLanguageHeader();
    options.AddDefaultProblemDetailsResponse();
    options.AddOperationParameters();
    options.RemoveServerList();
    options.WriteNumberAsString();
    options.DescribeAllParametersInCamelCase();
    options.AddTimeExamples();
    options.UseFullTypeNameSchemaIds();
#if NET9_0
    options.EnableEnumSupport();
#endif
#if NET10_0_OR_GREATER
    options.UseStrictNumericSchemas();
#endif
});

Example AddOpenApiOperationParameters()

builder.Services.AddOpenApiOperationParameters(parameters =>
{
    parameters.Parameters.Add(new OpenApiParameter
    {
        Name = "X-Correlation-Id",
        In = ParameterLocation.Header,
        Required = false,
        Description = "Identifier used to correlate requests"
    });
});

Example OpenApiSchemaHelper

var schema = OpenApiSchemaHelper.CreateStringSchema("it-IT");

Exception handling

DefaultExceptionHandler

TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken) converts unhandled exceptions into a consistent ProblemDetails response.

Main behavior:

  • uses the StatusCode from BadHttpRequestException when present
  • sets title, detail, instance, and traceId
  • adds innerException when an inner exception exists
  • includes stackTrace only in the Development environment

Example

builder.Services.AddDefaultExceptionHandler();
app.UseExceptionHandler();

If a route throws an exception, the response becomes predictable and easy for clients to document and consume.

Quick examples

Minimal API with ProblemDetails and OpenAPI

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddDefaultProblemDetails();
builder.Services.AddDefaultExceptionHandler();
builder.Services.AddRequestLocalization("it-IT", "en-US");

builder.Services.AddOpenApi(options =>
{
    options.AddAcceptLanguageHeader();
    options.AddDefaultProblemDetailsResponse();
    options.UseFullTypeNameSchemaIds();
});

var app = builder.Build();

app.UseExceptionHandler();
app.UseRequestRewind();

app.MapGet("/hello", () => Results.Ok(new { Message = "Hello" }))
   .ProducesDefaultProblem(StatusCodes.Status500InternalServerError);

app.Run();

Reading a configuration section

var appSettings = builder.Services.ConfigureAndGet<AppSettings>(builder.Configuration, "AppSettings");

Contribute

The project is continuously evolving. Contributions, issues, and pull requests are welcome.

Work on the develop branch, not on master. Pull requests should target develop.

Product 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. 
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 (3)

Showing the top 3 popular GitHub repositories that depend on TinyHelpers.AspNetCore:

Repository Stars
marcominerva/ChatGptNet
A ChatGPT integration library for .NET, supporting both OpenAI and Azure OpenAI Service
marcominerva/SqlDatabaseVectorSearch
A Blazor Web App and Minimal API for performing RAG (Retrieval Augmented Generation) and vector search using the native VECTOR type in Azure SQL Database and Azure OpenAI.
marcominerva/MinimalHelpers
A collection of helpers libraries for Minimal API projects.
Version Downloads Last Updated
4.2.12 174 6/11/2026
4.2.3 295 5/22/2026
4.1.21 725 4/15/2026
4.1.19 652 3/11/2026
4.1.18 492 2/19/2026
4.1.17 322 2/11/2026
4.1.15 1,237 1/14/2026
4.1.12 815 12/10/2025
4.1.10 816 11/13/2025
4.1.8 686 10/15/2025
4.1.6 2,529 9/10/2025
4.1.4 363 9/1/2025
4.1.3 490 7/30/2025
4.1.2 243 7/28/2025
Loading failed