Сначала измените определение маршрутизации:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "LocalizedDefault",
template: "{culture:regex(^[a-zA-Z]{{2}}(?:-[a-zA-Z]{{2}})*$)}/{controller=Home}/{action=Index}/{id?}"
);
routes.MapRoute(
name: "default",
template: "{controller}/{action}/{id?}",
defaults: new { controller = "Home", action = "RedirectToDefaultLanguage" }
);
});
Вы не хотите использовать универсальный маршрут, чтобы избежать слишком большого количества перенаправлений. Обратите внимание, что я использую ограничение регулярных выражений, чтобы убедиться, что культура представлена в формате двух буклетов (en, it, fr) или имен с тегами basi c (en-US, it-IT, ...). Если вам нужна полная совместимость с rfc4647, вам нужно изменить регулярное выражение в ^[A-Za-z]{1,8}(?:-[A-Za-z0-9]{1,8})*$
, но я думаю, что это будет слишком много (если вы не планируете предоставлять веб-сайт i-klingon XD).
Тогда действие RedirectToDefaultLanguage в HomeController:
public IActionResult RedirectToDefaultLanguage()
{
var currentCulture = Request.RouteValues["culture"];
var dest = Request.Path.Value == "/" ? "" : Request.Path.Value;
if (!string.IsNullOrWhiteSpace(Request.QueryString.Value))
dest += $"?{Request.QueryString}";
if (currentCulture == null)
{
return RedirectPermanent($"/en{dest}");
}
return RedirectToActionPermanent($"{currentCulture}{dest}");
}