Skip to content

EN Message resolution

Vinícius Campos edited this page Aug 22, 2026 · 1 revision

Message resolution

Português · English home

The domain stores stable codes and interpolation arguments, not human text. IErrorMessageResolver turns those values into a message at the transport boundary. The built-in JSON implementation loads catalogs at startup; the Azure App Configuration adapter reads an IConfiguration hierarchy on each lookup.

flowchart TD
    Request[Requested culture, for example pt-BR] --> Exact{Code in pt-BR?}
    Exact -->|yes| Template[Use template]
    Exact -->|no| Parent{Code in parent pt?}
    Parent -->|yes| Template
    Parent -->|no| Default{Code in invariant or default catalog?}
    Default -->|yes| Template
    Default -->|no| Code[Return Error.Code]
    Template --> Interpolate[Replace known argument tokens]
    Interpolate --> Message[Resolved message]
Loading

Only one parent level is examined before the invariant/default catalog. Known {token} placeholders are replaced from Error.Arguments; unknown placeholders stay visible, which makes catalog drift diagnosable. If no catalog defines the code, the stable Error.Code itself is returned.

JSON catalogs

AddOffside uses an invariant catalog plus optional culture catalogs. An invariant/default catalog is required. Catalogs are parsed into memory, so changing their files after startup does not update an existing resolver. Registration can configure paths and catalogs as documented in Messages and cultures.

Azure App Configuration adapter

AddOffsideAzureAppConfiguration(services, configuration, ...) receives an IConfiguration that the host has already populated. It does not connect to Azure, select labels, install the provider or configure refresh. The resolver only queries the supplied configuration under Errors (or the configured section), using default for the invariant catalog. Because lookup happens on every call, values become visible after — and only after — the host's own configuration provider refreshes them.

Request culture

An explicit CultureInfo wins. Otherwise the ASP.NET adapter reads Accept-Language and uses the first language range only. It does not rank ranges by q weight or negotiate against a supported-culture list. Missing, wildcard or invalid first ranges fall back to CultureInfo.CurrentUICulture.

This makes host-side request-localization middleware useful when full negotiation is needed: select CurrentUICulture in the host or pass a culture explicitly, rather than expecting Offside to implement complete HTTP content negotiation.

Clone this wiki locally