Invariant Culture
Arc provides a .UseInvariantCulture() extension method that configures your application to use invariant culture throughout, ensuring consistent and predictable behavior regardless of the host machine's regional settings.
Why Invariant Culture?
Modern distributed applications run across different machines, containers, and cloud regions—each potentially configured with different regional settings. Without explicit culture configuration, operations like number parsing, date formatting, or string comparisons may produce inconsistent results depending on where the code runs.
Using invariant culture guarantees:
- DateTime formatting and parsing behaves identically everywhere
- Number formatting and parsing produces consistent results (e.g., decimal separator is always
.) - String comparisons and sorting are culture-independent
- Serialization and deserialization never depends on machine locale
Configuration
Call UseInvariantCulture() on the WebApplicationBuilder before building the application, and on the resulting WebApplication to activate the request localization middleware:
var builder = WebApplication.CreateBuilder(args);
builder.UseInvariantCulture();
builder.AddCratisArc();
var app = builder.Build();
app.UseInvariantCulture();
app.UseCratisArc();
await app.RunAsync();
Important: Call
app.UseInvariantCulture()before any middleware that processes request data to ensure invariant culture is applied to all incoming requests.
What Gets Configured
Calling UseInvariantCulture() on the builder:
- Sets
CultureInfo.DefaultThreadCurrentCulturetoCultureInfo.InvariantCulture - Sets
CultureInfo.DefaultThreadCurrentUICulturetoCultureInfo.InvariantCulture - Configures
RequestLocalizationOptionsto use onlyInvariantCulture - Removes all request culture providers, preventing clients from overriding the culture via
Accept-Languageheaders or query strings
Calling UseInvariantCulture() on the application:
- Registers the ASP.NET Core request localization middleware with the invariant culture settings
Practical Example
Consider an API that accepts a price value. Without invariant culture, "1,5" might parse as 1.5 on a European machine but fail on an English-locale machine. With invariant culture, parsing is always based on the standard "1.5" format:
var builder = WebApplication.CreateBuilder(args);
builder.UseInvariantCulture();
builder.AddCratisArc();
var app = builder.Build();
app.UseInvariantCulture();
app.MapPost("/products", (ProductRequest request) =>
{
// Price is always parsed using invariant culture rules
return Results.Ok(new { Price = request.Price });
});
await app.RunAsync();
record ProductRequest(decimal Price, DateOnly ExpiryDate);
When to Use
Invariant culture is recommended for:
- APIs and services that exchange data between systems
- Applications deployed in multiple regions or cloud environments
- Data processing pipelines where consistency is critical
- Any scenario where culture-sensitive behavior could lead to bugs or data inconsistencies
It is generally safe to apply invariant culture in back-end services, as the locale-specific formatting should be handled on the client side (e.g., a frontend application) rather than in the API itself.