Table of Contents

Class TrellisAspOptions

Namespace
Trellis.Asp
Assembly
Trellis.Asp.dll

Configuration options for Trellis ASP.NET Core integration. Controls error-to-status-code mapping and host-local pagination route policies.

public sealed class TrellisAspOptions
Inheritance
TrellisAspOptions
Inherited Members
Extension Methods

Examples

Zero-config — uses defaults:

builder.Services.AddTrellisAsp();

Override specific mappings:

builder.Services.AddTrellisAsp(options =>
{
    options.MapError<DomainError>(StatusCodes.Status400BadRequest);
});

Remarks

By default, all standard error types are mapped to conventional HTTP status codes:

Error TypeDefault HTTP Status
Error.InvalidInput422 Unprocessable Entity
Error.InvariantViolation422 Unprocessable Entity
Error.AuthenticationRequired401 Unauthorized
Error.Forbidden403 Forbidden
Error.NotFound404 Not Found
Error.Conflict409 Conflict
Error.Gone410 Gone
Error.TransportFaultWrapped HttpError cases map by inner HTTP fault (405/406/412/413/415/416/428).
Error.RateLimited429 Too Many Requests
Error.Unexpected500 Internal Server Error
Error.Unavailable503 Service Unavailable

Use MapError<TError>(int) to override any mapping. Unmapped error types fall back to 500 Internal Server Error.

Properties

FailFastOnSilentVersionInjection

When true, calls to .WithVersionedRoute() (or its pinned overload) that would silently skip api-version injection because the target endpoint has no ApiVersionMetadata attached throw InvalidOperationException on every offending request instead of logging a single warning per endpoint. Defaults to false (warn-once-per-endpoint).

public bool FailFastOnSilentVersionInjection { get; set; }

Property Value

bool

Examples

builder.Services.AddTrellisAsp(o => o.FailFastOnSilentVersionInjection = builder.Environment.IsDevelopment());

Remarks

The framework's .WithVersionedRoute() resolver silently no-ops on hosts that never call services.AddApiVersioning(...) so the helper composes cleanly in unversioned hosts. Mid-migration — when AddApiVersioning(...) has been removed but legacy .WithVersionedRoute() chains remain — that silent skip can hide a downstream contract regression (clients stop receiving api-version in Location headers). Set this option to true in non-Production environments to surface the misconfiguration immediately rather than at the next client integration test.

When false (default) the framework logs a single warning per (endpoint, AppDomain) pair via the "Trellis.Asp.ApiVersioning" ILogger category. When true, every silent-skip occurrence throws; de-duplication does not apply because the request fails fast and never reaches the consumer.

PageUrlRouteResolver

Optional host-local policy that selects a pagination destination and enriches its cloned route values. Null uses ordinary named routing without API-version handling.

public Func<PageUrlRouteContext, Endpoint>? PageUrlRouteResolver { get; set; }

Property Value

Func<PageUrlRouteContext, Endpoint>

Remarks

Configure through AddTrellisAsp or UseAsp. The resolver must return a candidate or the link-enabled active endpoint with the same route name; it must not return null. A per-builder resolver overrides this policy.

ProblemContentLanguage

The language tag emitted as Content-Language on problem responses, or null (the default) to emit no such header.

public string? ProblemContentLanguage { get; set; }

Property Value

string

Examples

builder.Services.AddTrellisAsp(options => options.ProblemContentLanguage = "en");

Remarks

Every Trellis problem response ships prose in title and detail. Setting this declares what language that prose is in, e.g. "en".

The default is deliberately unset: detail is frequently application-supplied, so the framework cannot know its language, and emitting Content-Language: en unconditionally would assert something it has not checked as well as silently changing behaviour for every existing application.

This is a single static value, not server-side negotiation. Nothing reads Accept-Language, and no Vary header is emitted, because the response does not in fact vary by it. This composes with rather than competes against the reason-code and arguments mechanism: detail is negotiated prose where negotiation exists, while codes and arguments let the client hold the catalog, which is the only option when the server has no translations at all.

SynthesizeProblemDetailsInstanceFromResourceRef

When true (default), Trellis.Asp.ResponseFailureWriter synthesises ProblemDetails.Instance from the error's ResourceRef when the request URL does not already identify the failing resource (for example, a POST /orders whose body references a missing customer becomes Instance = "/customers/abc-123" instead of "/orders"). The original request URL is preserved under ProblemDetails.Extensions["request"].

public bool SynthesizeProblemDetailsInstanceFromResourceRef { get; set; }

Property Value

bool

Remarks

Default-on because the synthesised URI is strictly more informative than the request URL when synthesis applies; when it does not (no ResourceRef, no id, or the id already appears in the URL) the original request URL is left in place and no extension is added.

Set to false only when strict backward compatibility with the previous behaviour (always emit Instance = path+query) is required.

Methods

MapError<TError>(int)

Maps an error type to an HTTP status code. Overrides the default mapping if one exists.

public TrellisAspOptions MapError<TError>(int statusCode) where TError : Error

Parameters

statusCode int

The HTTP status code to return for this error type.

Returns

TrellisAspOptions

The options instance for fluent chaining.

Type Parameters

TError

The error type to map. Must derive from Error.

Examples

options.MapError<Error.Conflict>(StatusCodes.Status400BadRequest)
       .MapError<Error.InvalidInput>(StatusCodes.Status422UnprocessableEntity);

Exceptions

ArgumentOutOfRangeException

Thrown when statusCode is outside 100–599.