Страницы ASP.NET Core Razor — как установить культуру по умолчанию, отличную от en-US, для локализации запросов

У меня есть веб-приложение с именем WebApplication2, созданное с помощью веб-приложения ASP.NET Core (Razor Pages) с целевой платформой .NET 8.0.

Я могу заставить локализацию запроса работать с параметром URL, например ?culture=fr-FR, ИЛИ установить язык приложения по умолчанию fr-FR, но не то и другое. Вот версия, в которой культурой по умолчанию является en-US, хотя я пытаюсь установить ее на fr-FR.

Программа.cs

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();
// Add localization services
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");


string[] supportedCultures = [ "fr-FR", "en-US", "es-ES" ];
builder.Services.Configure<RequestLocalizationOptions>(options =>
{
    options.DefaultRequestCulture = new RequestCulture("fr-FR");
    options.SetDefaultCulture("fr-FR")
           .AddSupportedCultures(supportedCultures)
           .AddSupportedUICultures(supportedCultures);
});

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/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();
}

var localizationOptions = app.Services.GetService<IOptions<RequestLocalizationOptions>>()?.Value;
if (localizationOptions != null)
{
    localizationOptions.AddSupportedCultures(supportedCultures);
    localizationOptions.DefaultRequestCulture = new RequestCulture("fr-FR");
    app.UseRequestLocalization(localizationOptions);
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

Другой вариант — исправить культуру на fr-FR, но тогда URL-адреса типа ?culture=en-US больше не будут работать. Это можно сделать, внеся следующие изменения в приведенный выше пример кода:

/* Comment these lines and replace it with single app.UseRequestLocalization call */
var localizationOptions = app.Services.GetService<IOptions<RequestLocalizationOptions>>()?.Value;
if (localizationOptions != null)
{
    localizationOptions.AddSupportedCultures(supportedCultures);
    localizationOptions.DefaultRequestCulture = new RequestCulture("fr-FR");
    app.UseRequestLocalization(localizationOptions);
}
*/
/* This has effect but then URL like `?culture=en-US` doesn't work */
app.UseRequestLocalization("fr-FR");

Обратите внимание, что локализация работает в обоих случаях. Правильные переводы показаны на странице. Проблема в том, что у меня не может быть другого языка по умолчанию, кроме en-US, если я хочу, чтобы URL-адреса с культурой работали.

В корне проекта есть папка Resources, содержащая 3 файла, каждый из которых имеет только 1 строку StrLearnAbout:

  • Ресурсы
    • SharedResource.en-US.resx
    • SharedResource.es-ES.resx
    • SharedResource.fr-FR.resx

Еще у меня есть пустой класс SharedResource в корневой папке:

namespace WebApplication2
{
    public class SharedResource
    {
    }
}

Индекс.cshtml

@using Microsoft.Extensions.Localization
@inject IStringLocalizer<SharedResource> Localizer

@{
    ViewData["Title"] = "Home Page";
}

<div class = "text-center">
    <h1 class = "display-4">Welcome</h1
    <p>@Localizer["StrLearnAbout"]</p>
    <p>Learn about <a href = "https://learn.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

Несмотря на то, что вы уже решили эту проблему, я обновлю этот вопрос, потому что это может быть полезно другим.

char m 02.09.2024 11:17
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
1
64
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Согласно документам,

UseRequestLocalization инициализирует объект RequestLocalizationOptions. При каждом запросе перечисляется список RequestCultureProvider в RequestLocalizationOptions, и используется первый поставщик, который может успешно определить культуру запроса. Поставщики по умолчанию берутся из класса RequestLocalizationOptions:

  1. QueryStringRequestCultureProvider
  2. CookieRequestCultureProvider
  3. AcceptLanguageHeaderRequestCultureProvider

По умолчанию браузер устанавливает Accept-language:en-US в заголовке запроса, в результате чего локализация работает некорректно, если вы устанавливаете язык по умолчанию, отличный от EN.

Я бы рекомендовал вам предоставить RequestCultureProviders:

  1. Укажите необходимого поставщика культуры запроса.
  2. Укажите порядок поставщиков в RequestCultureProviders (поставщик выполняет последовательность от первого до последнего)
  3. Создайте свой собственный поставщик запросов для обработки локализации, если подходы 1 и 2 не подходят для вашего сценария.

В моем случае я использую подход 1:

builder.Services.Configure<RequestLocalizationOptions>(options =>
{
    options.DefaultRequestCulture = new RequestCulture("fr-FR");
    options.SetDefaultCulture("fr-FR")
           .AddSupportedCultures(supportedCultures)
           .AddSupportedUICultures(supportedCultures);

    options.RequestCultureProviders = new List<IRequestCultureProvider>
    {
        new QueryStringRequestCultureProvider(),
        new CookieRequestCultureProvider()
    };
});

Кроме,

Код app.UseRequestLocalization(); можно преобразовать в одну строку с помощью:

app.UseRequestLocalization(app.Services.GetService<IOptions<RequestLocalizationOptions>>().Value);

Вам не нужно снова указывать культуру по умолчанию, как это было сделано при добавлении/регистрации экземпляра RequestLocalizationOptions.

Спасибо! Я тоже пробовал этот подход, но это не помогло. Я попробую сейчас еще раз. Обновлено: Он работает отлично!

char m 02.09.2024 10:51

Чтобы правильно настроить локализацию запроса в ASP.NET Core, чтобы была установлена ​​культура по умолчанию (fr-FR) и ее можно было изменить с помощью параметров URL-адреса, выполните следующие действия:

Упростите настройку локализации: вам нужно только настроить RequestLocalizationOptions один раз, и после настройки служб нет необходимости повторно добавлять поддерживаемые языки и региональные параметры или язык и региональные параметры по умолчанию.

Убедитесь, что промежуточное программное обеспечение размещено правильно. Убедитесь, что app.UseRequestLocalization вызывается перед маршрутизацией и другим промежуточным программным обеспечением, которое может зависеть от культуры запроса.

Вот обновленный и оптимизированный код:

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddLocalization(options => options.ResourcesPath = 
"Resources");

string[] supportedCultures = { "fr-FR", "en-US", "es-ES" };

builder.Services.Configure<RequestLocalizationOptions>(options =>
{
options.DefaultRequestCulture = new RequestCulture("fr-FR");
options.SetDefaultCulture("fr-FR")
       .AddSupportedCultures(supportedCultures)
       .AddSupportedUICultures(supportedCultures);
});

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

// Apply the localization settings before other middlewares.
app.UseRequestLocalization();

app.UseAuthorization();

app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

Объяснение: Промежуточное программное обеспечение локализации: app.UseRequestLocalization() размещается перед app.UseRouting(), чтобы гарантировать, что настройки языка и региональных параметров применяются на ранних этапах конвейера запросов. Культура запроса по умолчанию: Культура запроса по умолчанию установлена ​​на fr-FR, и она будет использоваться, если не будет переопределена параметром URL-адреса, например ?cultural=fr-FR. Упрощенная конфигурация: нет необходимости перенастраивать RequestLocalizationOptions после добавления его в контейнер службы. Это должно гарантировать, что ваше приложение использует fr-FR в качестве языка и региональных параметров по умолчанию, но при этом позволяет вносить изменения через параметры URL-адреса.

Другие вопросы по теме