Allowing dynamic SupportedCultures in RequestLocalizationOptions
The documented usage of RequestLocalizationOptions in ASP.NET 5/Core is to assign a static list of SupportedCultures since ASP.NET is assuming you’ll know up-front what cultures your app is supporting. But what if you are creating a CMS or another web app that allows users to include cultures dynamically?
This isn’t documented anywhere but it’s certainly possible. RequestLocalizationOptions.SupportedCultures is a mutable IList which means that values can be added/removed at runtime if you really want.
Create a custom RequestCultureProvider
First thing you need is a custom RequestCultureProvider. The trick is to pass in the RequestLocalizationOptions into it’s ctor so you can dynamically modify the SupportedCultures when required.
public class MyCultureProvider : RequestCultureProvider
{
private readonly RequestLocalizationOptions _localizationOptions;
private readonly object _locker = new object();
// ctor with reference to the RequestLocalizationOptions
public MyCultureProvider(RequestLocalizationOptions localizationOptions)
=> _localizationOptions = localizationOptions;
public override Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext)
{
// TODO: Implement GetCulture() to get a culture for the current request
CultureInfo culture = GetCulture();
if (culture is null)
{
return NullProviderCultureResult;
}
lock (_locker)
{
// check if this culture is already supported
var cultureExists = _localizationOptions.SupportedCultures.Contains(culture);
if (!cultureExists)
{
// If not, add this as a supporting culture
_localizationOptions.SupportedCultures.Add(culture);
_localizationOptions.SupportedUICultures.Add(culture);
}
}
return Task.FromResult(new ProviderCultureResult(culture.Name));
}
}
Add your custom culture provider
You can configure RequestLocalizationOptions in a few different ways, this example registers a custom implementation of IConfigureOptions<RequestLocalizationOptions> into DI
public class MyRequestLocalizationOptions : IConfigureOptions<RequestLocalizationOptions>
{
public void Configure(RequestLocalizationOptions options)
{
// TODO: Configure other options parameters
// Add the custom provider,
// in many cases you'll want this to execute before the defaults
options.RequestCultureProviders.Insert(0, new MyCultureProvider(options));
}
}
Then just register these options: Services.ConfigureOptions<MyRequestLocalizationOptions>();
That’s it, now you can have dynamic SupportedCultures in your app!