Using .NET Core 7, I need to set a page's culture using the route parameter culture:
builder.Services
.AddRazorPages()
.AddViewLocalization(x => x.ResourcesPath = builder.Environment.WebRootPath);
builder.Services.Configure<RequestLocalizationOptions>(x => {
x.AddSupportedCultures("pt", "en");
x.AddSupportedUICultures("pt", "en");
x.SetDefaultCulture("pt");
x.RequestCultureProviders.Clear();
x.AddInitialRequestCultureProvider(new RouteDataRequestCultureProvider { RouteDataStringKey = "culture" });
});
builder.Services.Configure<RouteOptions>(x => {
x.ConstraintMap.Add("culture", typeof(CultureRouteConstraint));
});
application
.UseRouting()
.UseRequestLocalization();
The CultureRouteConstraint is the following:
public class CultureRouteConstraint : IRouteConstraint
{
private readonly RequestLocalizationOptions _options;
public CultureRouteConstraint(IOptions<RequestLocalizationOptions> options)
{
_options = options.Value;
}
public Boolean Match(HttpContext? httpContext, IRouter? route, String routeKey, RouteValueDictionary values, RouteDirection routeDirection)
{
if (routeKey == null)
throw new ArgumentNullException(nameof(routeKey));
if (values == null)
throw new ArgumentNullException(nameof(values));
if (values.TryGetValue(routeKey, out var value) && value != null)
{
String? culture = Convert.ToString(value, CultureInfo.InvariantCulture);
List<String>? cultures = _options.SupportedCultures?.Select(x => x.TwoLetterISOLanguageName).ToList();
if (culture != null && cultures != null)
return cultures.Contains(culture, StringComparer.InvariantCultureIgnoreCase);
}
return false;
}
}
I have 2 pages (Index and About) which Razor pages routes are:
Index: @page "/{culture}"
About: @page "/{culture}/about"
When I access an URL such as:
http://localhost:5000/en/about
http://localhost:5000/pt/about
The culture is set to the correct value.
When I access the same url without the culture route parameter:
http://localhost:5000/about
the culture is set to the default value, e.g., pt.
But when I access the homepage without the culture route parameter:
http://localhost:5000
I am redirected to:
http://localhost:5000/en
However en is not the default culture. pt is ...
Why does this happen?
Note:
I have breakpoints in CultureRouteConstraint and they are never hit.
Am I missing something?
Update
The full Program.cs:
WebApplicationBuilder builder = WebApplication.CreateBuilder(new WebApplicationOptions {
Args = args,
ApplicationName = typeof(Program).Assembly.FullName,
ContentRootPath = Directory.GetCurrentDirectory(),
WebRootPath = "webroot"
});
builder.Services.AddLocalization(x => x.ResourcesPath = builder.Environment.WebRootPath);
builder.Services
.AddRazorPages()
.AddViewLocalization(x => x.ResourcesPath = builder.Environment.WebRootPath);
builder.Services.Configure<RequestLocalizationOptions>(x => {
x.AddSupportedCultures("pt", "en");
x.AddSupportedUICultures("pt", "en");
x.SetDefaultCulture("pt");
x.RequestCultureProviders.Clear();
x.AddInitialRequestCultureProvider(new RouteDataRequestCultureProvider { RouteDataStringKey = "culture" });
});
builder.Services.Configure<RouteOptions>(x => {
x.ConstraintMap.Add("culture", typeof(CultureRouteConstraint));
});
builder.Services.AddValidatorsFromAssemblyContaining<Program>();
builder.Services.AddResponseCaching(x => { x.UseCaseSensitivePaths = false; x.MaximumBodySize = 2097152; });
builder.Services.AddHealthChecks();
builder.Services.Configure<AppOptions>(builder.Configuration);
WebApplication application = builder.Build();
application
.UseRewriter(new RewriteOptions()
.AddRedirect(@"^$", $"pt", StatusCodes.Status301MovedPermanently)
);
application.UseStatusCodePagesWithReExecute("/error/{0}");
application.UseStaticFiles();
application
.UseRouting()
.UseRequestLocalization();
application.MapRazorPages();
application.UseResponseCaching();
application.MapHealthChecks("/health", new HealthCheckOptions { ResponseWriter = HealthChecksResponse.Write });
application.Run();