Reputation: 73
I currently have 3 different cultures.
Actually, my url looks like www.website.com/services, no mater what culture is selected (the culture value is stored in a cookie).
What I would like to do is display the culture directly in the url like this: www.website.com/en/services.
How can I achieve that in .NET6 and with only Razor pages?
Program class
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddMvc().AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix).AddDataAnnotationsLocalization();
builder.Services.Configure<RequestLocalizationOptions>(opt =>
{
var supportedCultures = new List<CultureInfo>
{
new CultureInfo("en"),
new CultureInfo("fr"),
new CultureInfo("nl")
};
opt.DefaultRequestCulture = new RequestCulture("en");
opt.SupportedCultures = supportedCultures;
opt.SupportedUICultures = supportedCultures;
});
builder.Services.AddHttpContextAccessor();
builder.Services.AddLocalization(opt => { opt.ResourcesPath = "Resources"; });
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseRequestLocalization(((IApplicationBuilder)app).ApplicationServices.GetRequiredService<IOptions<RequestLocalizationOptions>>().Value);
app.MapRazorPages();
app.Run();
Upvotes: 2
Views: 978
Reputation: 11322
You need to create a custom IPageRouteModelConvention
:
public class CultureTemplatePageRouteModelConvention : IPageRouteModelConvention
{
public void Apply(PageRouteModel model)
{
var selectorCount = model.Selectors.Count;
for (var i = 0; i < selectorCount; i++)
{
var selector = model.Selectors[i];
model.Selectors.Add(new SelectorModel
{
AttributeRouteModel = new AttributeRouteModel
{
Order = -1,
Template = AttributeRouteModel.CombineTemplates("{culture?}", selector.AttributeRouteModel.Template),
}
});
}
}
}
Then register it using:
builder.Services.AddRazorPages()
.AddRazorPagesOptions(options =>
{
options.Conventions.Add(new CultureTemplatePageRouteModelConvention());
});
Finally configure RequestLocalizationOptions
:
builder.Services.Configure<RequestLocalizationOptions>(opt =>
{
var supportedCultures = new List<CultureInfo>
{
new CultureInfo("en"),
new CultureInfo("fr"),
new CultureInfo("nl")
};
opt.DefaultRequestCulture = new RequestCulture("en");
opt.SupportedCultures = supportedCultures;
opt.SupportedUICultures = supportedCultures;
// add this line
opt.RequestCultureProviders.Insert(0, new RouteDataRequestCultureProvider());
});
To add the culture to your links you can use the asp-route-culture
attribute:
<a asp-route-culture="@Request.RouteValues["culture"]" asp-page="/Contact">Contact</a>
More info about the anchor tag helper and the asp-route-{value}
attribute: https://learn.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/built-in/anchor-tag-helper?view=aspnetcore-6.0#asp-route-value
Source: https://www.mikesdotnetting.com/article/348/razor-pages-localisation-seo-friendly-urls
Upvotes: 3