Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Примечание.
Это не последняя версия этой статьи. Текущий выпуск можно найти в версии этой статьи о .NET 10.
Предупреждение
Эта версия ASP.NET Core больше не поддерживается. Для получения дополнительной информации см. Политику поддержки .NET и .NET Core. Текущий выпуск можно найти в версии этой статьи о .NET 10.
В этой статье объясняется, как предоставить интернационализированное и локализованное содержимое пользователям на разных языках и в разных культурах.
Глобализация и локализация
Для глобализацииBlazor обеспечивает форматирование чисел и дат. Для локализацииBlazor содержимое отображается с помощью системы ресурсов .NET.
Поддерживается ограниченный набор функций локализации ASP.NET Core:
и , а также IStringLocalizer<T> поддерживаются в Blazor приложениях.
Не поддерживается:IHtmlLocalizer и IViewLocalizer являются функциями ASP.NET Core MVC и не поддерживаются в приложениях Blazor.
Для приложений Blazor поддерживаются локализованные сообщения валидации форм при использовании аннотаций данных, если реализованы DisplayAttribute.ResourceType и ValidationAttribute.ErrorMessageResourceType.
В этой статье описывается, как использовать функции глобализации и локализации Blazor на основе следующих элементов:
-
заголовка
Accept-Language, который задается браузером на основе языковых настроек пользователя в параметрах браузера; - Культура, установленная приложением, не основана на значении заголовка
Accept-Language. Параметр может быть статическим для всех пользователей или динамическим в зависимости от логики приложения. Если параметр основан на предпочтениях пользователя, он обычно сохраняется для повторной загрузки при последующих посещениях.
Дополнительные общие сведения см. в следующих ресурсах:
Часто термины язык и культура используются взаимозаменяемо, когда речь идет о концепциях глобализации и локализации.
В этой статье язык относится к выбору, сделанному пользователем в параметрах браузера. Выбранные пользователем языки отправляются в запросах браузера в заголовке Accept-Language. В параметрах пользовательского интерфейса браузера обычно используется слово "язык".
Culture относится к членам API .NET и Blazor. Например, запрос пользователя может включать заголовок Accept-Language с указанием языка с точки зрения пользователя, но в конечном итоге приложение устанавливает свойство CurrentCulture (культура) для языка, запрашиваемого пользователем. API обычно использует слово "культура" в названиях своих членов.
Руководство в этой статье не охватывает настройку атрибута языка HTML страницы (<html lang="...">), который использует средства доступа. Значение можно задать статически, назначив язык lang атрибуту тега <html> или document.documentElement.lang в JavaScript. Вы можете динамически задать значение document.documentElement.lang с помощью взаимодействияJS.
Примечание.
Примеры кода, приведенные в этой статье, используют нуллируемые ссылочные типы (NRTs) и статический анализ null-состояний компилятора .NET, которые поддерживаются в ASP.NET Core в .NET 6 или более поздней версии. При использовании .NET 5 или более ранних версий удалите обозначение типа null (?) из примеров в статье.
Глобализация
Директива атрибута @bind применяет форматы и анализирует значения для вывода на основе первого предпочитаемого пользователем языка, поддерживаемого приложением.
@bind поддерживает параметр @bind:culture, чтобы предоставлять System.Globalization.CultureInfo для анализа и форматирования значения.
Доступ к текущей культуре можно получить из свойства System.Globalization.CultureInfo.CurrentCulture.
CultureInfo.InvariantCulture используется для следующих типов полей (<input type="{TYPE}" />, где заполнитель {TYPE} является типом):
datenumber
Предыдущие типы полей:
- отображаются с использованием соответствующих правил форматирования браузера;
- не могут содержать текст в свободной форме;
- предоставляют характеристики взаимодействия с пользователем в зависимости от реализации браузера.
Blazor предоставляет встроенную поддержку отображения значений в текущей культуре. Поэтому не рекомендуется указывать культуру с помощью @bind:culture, когда используются типы полей date и number.
Следующие типы полей имеют определенные требования к форматированию и не поддерживаются всеми основными браузерами, поэтому они не поддерживаются:Blazor
datetime-localmonthweek
Для получения информации о текущей поддержке вышеперечисленных типов в браузерах см. Can I use.
По умолчанию Blazor загружает подмножество данных глобализации, содержащее культуру приложения. Чтобы загрузить все данные глобализации, установите <BlazorWebAssemblyLoadAllGlobalizationData> в true в файле проекта приложения (.csproj):
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
Поддержка глобализации .NET и международных компонентов Юникода (ICU) (Blazor WebAssembly)
Blazor WebAssembly использует ограниченный API глобализации и встроенные международные компоненты для локалей языковых стандартов Юникода (ICU).
В приложениях WebAssembly (Wasm) при отключении инвариантного режима глобализации загружается файл данных ICU. Существует четыре основных типа этих файлов:
-
icudt.dat: полные данные -
icudt_EFIGS.dat: данные для локалей:en-*,fr-FR,es-ES,it-ITиde-DE. -
icudt_CJK.dat: данные для языковых стандартов:en-*,ja,ko, иzh-*. -
icudt_no_CJK.dat: данные для всех локалей изicudt.dat, за исключениемja,ko, иzh-*.
Укажите один файл для загрузки с помощью свойства MSBuild <BlazorIcuDataFileName> в файле проекта приложения .csproj. Следующий пример загружает icudt_no_CJK.dat файл:
<PropertyGroup>
<BlazorIcuDataFileName>icudt_no_CJK.dat</BlazorIcuDataFileName>
</PropertyGroup>
<BlazorIcuDataFileName> принимает только один файл. Файл может быть пользовательским файлом, созданным разработчиком. Сведения о создании пользовательского файла ICU см. в разделе Глобализация WASM: Пользовательский ICU.
Если файл не указан с помощью <BlazorIcuDataFileName>, проверяется культура приложения, и соответствующий файл ICU загружается для этой культуры. Например, настройка культуры en-US приводит к загрузке файла icudt_EFIGS.dat. Для zh-CNэтого icudt_CJK.dat используется файл.
Дополнительные сведения см. в статье .NET глобализация и ICU, ICU в WebAssembly.
Blazor WebAssembly использует сокращенный API глобализации и набор встроенных международных компонентов для языковых стандартов Юникода (ICU). Для получения дополнительной информации см. документацию .NET глобализация и ICU: ICU в WebAssembly.
Загрузка настраиваемого подмножества языковых стандартов в приложении Blazor WebAssembly поддерживается в .NET 8 или более поздней версии. Дополнительные сведения см. в этом разделе для .NET 8 или более поздней версии этой статьи.
Инвариантная глобализация
Этот раздел относится только к сценариям на стороне Blazor клиента.
Если приложению не требуется локализация, настройте его для поддержки инвариантной культуры, которая обычно основана на американском английском (en-US). Использование инвариантной глобализации сокращает размер загрузки приложения и приводит к более быстрому запуску приложения. Задайте для свойства InvariantGlobalization значение true в файле проекта приложения (.csproj):
<PropertyGroup>
<InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>
Кроме того, инвариантную глобализацию можно настроить с помощью следующих подходов.
В
runtimeconfig.json:{ "runtimeOptions": { "configProperties": { "System.Globalization.Invariant": true } } }С переменной среды:
- Ключ:
DOTNET_SYSTEM_GLOBALIZATION_INVARIANT. - Значение:
trueили1
- Ключ:
Дополнительные сведения см. в разделе Параметры конфигурацииRuntime для глобализации (документация по .NET).
Сведения о часовом поясе
Этот раздел относится только к сценариям на стороне Blazor клиента.
Внедрение инвариантной глобализации приводит только к использованию не локализованных имен часовых поясов. Чтобы обрезать код часового пояса и данные, что сокращает размер загрузки приложения и приводит к более быстрому запуску приложения, примените <InvariantTimezone> свойство MSBuild со значением true в файле проекта приложения:
<PropertyGroup>
<InvariantTimezone>true</InvariantTimezone>
</PropertyGroup>
Примечание.
<BlazorEnableTimeZoneSupport> переопределяет более ранний <InvariantTimezone> параметр. Рекомендуется удалить <BlazorEnableTimeZoneSupport> параметр.
Для обеспечения правильности сведений о часовом поясе включается файл данных. Если приложению не требуется эта функция, попробуйте отключить ее, установив <BlazorEnableTimeZoneSupport> для свойства MSBuild значение false в файле проекта приложения:
<PropertyGroup>
<BlazorEnableTimeZoneSupport>false</BlazorEnableTimeZoneSupport>
</PropertyGroup>
Демонстрационный компонент
Следующий компонент CultureExample1 можно использовать для демонстрации концепций глобализации и локализации Blazor, описываемых в этой статье.
CultureExample1.razor:
@page "/culture-example-1"
@using System.Globalization
<h1>Culture Example 1</h1>
<ul>
<li><b>CurrentCulture</b>: @CultureInfo.CurrentCulture</li>
<li><b>CurrentUICulture</b>: @CultureInfo.CurrentUICulture</li>
</ul>
<h2>Rendered values</h2>
<ul>
<li><b>Date</b>: @dt</li>
<li><b>Number</b>: @number.ToString("N2")</li>
</ul>
<h2><code><input></code> elements that don't set a <code>type</code></h2>
<p>
The following <code><input></code> elements use
<code>CultureInfo.CurrentCulture</code>.
</p>
<ul>
<li><label><b>Date:</b> <input @bind="dt" /></label></li>
<li><label><b>Number:</b> <input @bind="number" /></label></li>
</ul>
<h2><code><input></code> elements that set a <code>type</code></h2>
<p>
The following <code><input></code> elements use
<code>CultureInfo.InvariantCulture</code>.
</p>
<ul>
<li><label><b>Date:</b> <input type="date" @bind="dt" /></label></li>
<li><label><b>Number:</b> <input type="number" @bind="number" /></label></li>
</ul>
@code {
private DateTime dt = DateTime.Now;
private double number = 1999.69;
}
Формат строки чисел (N2) в предыдущем примере (.ToString("N2")) — это описатель standard .NET числовых форматов. Формат N2 поддерживается для всех числовых типов, включает разделитель групп и отображает до двух десятичных знаков.
При необходимости добавьте элемент меню в навигацию в NavMenu компоненте (NavMenu.razor) для CultureExample1 компонента.
Динамическое задание культуры из заголовка Accept-Language
Добавьте пакет Майкрософт.Extensions.Localization в приложение.
ЗаголовокAccept-Language задается браузером и управляется на основе языковых настроек пользователя в параметрах браузера. В параметрах браузера пользователь задает один или несколько необходимых языков в порядке предпочтения. Порядок предпочтения используется браузером для задания значений качества (q, 0–1) для каждого языка в заголовке. В следующем примере указывается английский США, английский и костариканский испанский с предпочтением английского США или просто английского.
Accept-Language: en-US,en; q=0,9,es-CR; q=0.8
Язык и культурные параметры приложения устанавливаются путем выбора первого запрошенного языка, который совпадает с поддерживаемой культурой приложения.
В клиентской разработке задайте BlazorWebAssemblyLoadAllGlobalizationData свойство true в файле проекта клиентского приложения (.csproj):
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
При разработке на стороне клиента динамическое задание культуры из заголовка Accept-Language не поддерживается.
Примечание.
Если спецификация приложения требует ограничения поддерживаемых языков и региональных параметров явным списком, см. раздел Динамическая настройка клиентской культуры в зависимости от предпочтений пользователя этой статьи.
Приложения локализованы с помощью посредника локализации. Добавьте службы локализации в приложение с помощью AddLocalization.
Добавьте следующую строку в Program файл, где зарегистрированы службы:
builder.Services.AddLocalization();
В разработке на стороне сервера укажите поддерживаемые язык и региональные параметры приложения перед любым ПО промежуточного слоя, которое может проверить язык и региональные параметры запроса. Как правило, поместите промежуточное ПО локализации запросов непосредственно перед вызовом MapRazorComponents. В следующем примере настраиваются поддерживаемые языки и культуры для американского английского и коста-риканского испанского.
В серверной стороне разработки укажите поддерживаемые культуры приложения сразу после добавления промежуточного слоя маршрутизации в UseRouting конвейер обработки. Следующий пример настраивает поддерживаемые языки и региональные параметры для английского Соединенных Штатов и испанского языка Коста-Рики с помощью следующего API:
- AddSupportedCultures добавляет набор поддерживаемых культур для глобализации (форматы даты, чисел и валют).
- AddSupportedUICultures добавляет набор поддерживаемых региональных параметров пользовательского интерфейса для локализации (переведенные строки пользовательского интерфейса для отображения содержимого).
app.UseRequestLocalization(new RequestLocalizationOptions()
.AddSupportedCultures(new[] { "en-US", "es-CR" })
.AddSupportedUICultures(new[] { "en-US", "es-CR" }));
В предыдущем примере те же поддерживаемые региональные параметры форматирования и региональные параметры пользовательского интерфейса указываются в узком случае, когда приложение используется только в Соединённых Штатах и Коста-Рике. Альтернативно, приложение может использовать более широкий набор культур для форматирования дат, чисел и валют, но предоставляет только локализованное содержимое для Соединённых Штатов и Коста-Рики, как показано в следующем примере.
var uiCultures = new[] { "en-US", "es-CR" };
var formattingCultures = CultureInfo
.GetCultures(CultureTypes.SpecificCultures)
.Select(c => c.Name)
.ToArray();
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(uiCultures[0])
.AddSupportedCultures(formattingCultures)
.AddSupportedUICultures(uiCultures);
app.UseRequestLocalization(localizationOptions);
В предыдущем примере CultureTypes.SpecificCultures возвращает только культуры, относящиеся к стране или региону, например en-US или fr-FR, которые содержат полные, конкретные данные глобализации (для дат, чисел, календарей и другого культурного пользовательского интерфейса), которые .NET может использовать для точного форматирования и разбора. Нейтральные культуры, такие как en или fr, возможно, не имеют полных данных глобализации, поэтому они не включены в этот список.
Сведения о включении ПО промежуточного слоя локализации в конвейере обработки файла Program см. в разделе ПО промежуточного слоя ASP.NET Core.
Используйте компонент CultureExample1, показанный в разделе Демонстрационный компонент, чтобы изучить принцип работы глобализации. Отправьте запрос на английский Соединённых Штатов (en-US). Перейдите на Коста-Риканский испанский (es-CR) в языковых параметрах браузера. Снова запросите веб-страницу.
Если язык и региональные параметры американский английский (en-US), визуализируемый компонент использует форматирование даты как месяц/день (6/7), 12-часовой формат времени (AM/PM) и разделители тысяч с точкой для десятичной части (1,999.69):
- Дата: 6/7/2021, 6:45:22 AM
- Число: 1,999.69
Если язык и региональные параметры — костариканский испанский (es-CR), отображаемый компонент использует форматирование дат в день/месяц (7/6), 24-часовое время и разделители периодов в числах с запятой для десятичного значения (1.999,69):
- Дата: 7/6/2021 6:49:38
- Число: 1.999,69
Задать зафиксированные язык и региональные параметры на стороне клиента
Задайте для свойства BlazorWebAssemblyLoadAllGlobalizationData значение true в файле проекта приложения (.csproj):
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
Конфигурация компоновщика промежуточный язык (IL) для рендеринга на стороне клиента удаляет информацию по интернационализации, за исключением явно заданных языковых стандартов. Для получения более подробной информации см. раздел Настройка компоновщика для ASP.NET CoreBlazor.
Культуру приложения можно задать в JavaScript, если Blazor запускается с параметром applicationCultureBlazor. В следующем примере приложение настраивается для запуска с использованием культуры американского английского языка (en-US).
Запретите Blazor автозапуск, добавив autostart="false" в тег Blazor<script>.
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
В предыдущем примере маркер {BLAZOR SCRIPT} представляет путь к скрипту и имя файла Blazor. Расположение скрипта см. в разделе ASP.NET Core Blazor структура проекта.
Добавьте следующий <script> блок после Blazorтега <script> и перед закрывающим </body> тегом:
Blazor Web App:
<script>
Blazor.start({
webAssembly: {
applicationCulture: 'en-US'
}
});
</script>
Автономное Blazor WebAssembly:
<script>
Blazor.start({
applicationCulture: 'en-US'
});
</script>
Значение параметра applicationCulture должно соответствовать языковому тегу в формате BCP-47. Дополнительные сведения о запуске Blazor см. в разделе ASP.NET Core Blazor startup.
Альтернативой заданию параметра запуска языка и региональных параметров Blazor является установка языка и региональных параметров в коде C#. Установите CultureInfo.DefaultThreadCurrentCulture и CultureInfo.DefaultThreadCurrentUICulture в файле Program на одну и ту же культурную настройку.
Добавьте пространство имен System.Globalization в файл Program.
using System.Globalization;
Добавьте параметры языка и региональных параметров перед строкой, которая создает и выполняет WebAssemblyHostBuilder (await builder.Build().RunAsync();):
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en-US");
Примечание.
В .NET 9 или более ранних версиях автономные Blazor WebAssembly приложения загружают ресурсы глобализации пользовательского интерфейса на базе CultureInfo.DefaultThreadCurrentCulture. Если вы хотите дополнительно загрузить данные о глобализации для вашей локализации, определенной CultureInfo.DefaultThreadCurrentUICulture, обновите приложение до .NET 10 или более поздней версии.
Используйте компонент CultureExample1, показанный в разделе Демонстрационный компонент, чтобы изучить принцип работы глобализации. Отправьте запрос на американский английский (en-US). Перейдите на Коста-Риканский испанский (es-CR) в языковых параметрах браузера. Снова запросите веб-страницу. Когда запрошенный язык является коста-риканским испанским, язык и региональные параметры приложения остаются на английском языке Соединенных Штатов (en-US).
Статически задать культуру на стороне сервера
Серверные приложения локализуются с помощью промежуточного программного обеспечения локализации. Добавьте службы локализации в приложение с помощью AddLocalization.
В файле Program:
builder.Services.AddLocalization();
Укажите статический язык и региональные параметры в Program файле перед любым ПО промежуточного слоя, которое может проверить язык и региональные параметры запроса. Как правило, поместите промежуточное ПО локализации запросов непосредственно перед MapRazorComponents. В следующем примере настраивается американский вариант английского языка.
Укажите статическую культуру в файле Program, сразу после добавления промежуточного слоя маршрутизации в конвейер обработки UseRouting. В следующем примере настраивается США английский язык:
app.UseRequestLocalization("en-US");
Значение культуры для
Для получения информации об использовании функционала промежуточного слоя локализации в конвейере промежуточного слоя файла Program, см. в разделе ASP.NET Core Middleware.
Серверные приложения локализуются с помощью промежуточного ПО локализации. Добавьте службы локализации в приложение с помощью AddLocalization.
В Startup.ConfigureServices (Startup.cs):
services.AddLocalization();
Укажите статический язык и региональные параметры в Startup.Configure (Startup.cs) сразу после добавления промежуточного ПО маршрутизации в конвейер процессинга. В следующем примере настраивается английский (США):
app.UseRequestLocalization("en-US");
Значение культуры для
Для получения информации о добавлении компонента промежуточного ПО локализации в конвейер обработки Startup.Configure, см. раздел Промежуточное ПО ASP.NET Core.
Используйте компонент CultureExample1, показанный в разделе Демонстрационный компонент, чтобы изучить принцип работы глобализации. Отправьте запрос на английском (США) (en-US). Перейдите на Коста-Риканский испанский (es-CR) в языковых параметрах браузера. Снова запросите веб-страницу. Когда запрашиваемый язык — Costa Rican Spanish, культурные параметры приложения остаются американскими (английский для США) (en-US).
Динамически установить клиентские настройки форматирования по предпочтениям пользователя
Примеры расположений, в которых приложение может хранить предпочтения пользователя, включают локальное хранилище браузера (обычно для клиентских сценариев), службу локализации или базу данных (обычно для серверных сценариев) или внешнюю службу, подключенную к внешней базе данных, доступной через веб API. В следующем примере показано использование локального хранилища в браузере.
Добавьте пакет Майкрософт.Extensions.Localization в приложение.
Примечание.
Рекомендации по добавлению пакетов в приложения .NET можно найти в статьях раздела Установка и управление пакетами на странице Потребление пакетов (документация NuGet). Проверьте правильность версий пакета на сайте NuGet.org.
Задайте для свойства BlazorWebAssemblyLoadAllGlobalizationData значение true в файле проекта:
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
Культура приложения для отрисовки на стороне клиента задается с помощью API Blazor фреймворка. Выбор культуры пользователя можно сохранить в локальном хранилище браузера.
Предоставьте JS функции после тега Blazor<script>, чтобы получить и задать выбор культуры пользователя с использованием локального хранилища браузера.
<script>
window.blazorCulture = {
get: () => window.localStorage['BlazorCulture'],
set: (value) => window.localStorage['BlazorCulture'] = value
};
</script>
Примечание.
В предыдущем примере глобальные функции загрязняют клиента. Более эффективный подход для приложений в рабочей среде приведен в разделе Изоляция JavaScript в модулях JavaScript.
Добавьте пространства имен для System.Globalization и Майкрософт.JSInterop в начало файла Program:
using System.Globalization;
using Microsoft.JSInterop;
Удалите следующую строку:
- await builder.Build().RunAsync();
Замените указанную выше строку следующим кодом. Код добавляет службу локализации Blazor в коллекцию служб приложения с помощью AddLocalization и использует взаимодействие с JS для вызова JS и получения выбора культурных настроек пользователя из локального хранилища. Если локальное хранилище не содержит язык и региональные параметры для пользователя, код задает значение по умолчанию США английский (en-US).
builder.Services.AddLocalization();
var host = builder.Build();
const string defaultCulture = "en-US";
var js = host.Services.GetRequiredService<IJSRuntime>();
var result = await js.InvokeAsync<string>("blazorCulture.get");
var culture = CultureInfo.GetCultureInfo(result ?? defaultCulture);
if (result == null)
{
await js.InvokeVoidAsync("blazorCulture.set", defaultCulture);
}
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
await host.RunAsync();
Примечание.
В .NET 9 или более ранних версиях автономные Blazor WebAssembly приложения загружают ресурсы глобализации пользовательского интерфейса на базе CultureInfo.DefaultThreadCurrentCulture. Если вы хотите дополнительно загрузить данные о глобализации для вашей локализации, определенной CultureInfo.DefaultThreadCurrentUICulture, обновите приложение до .NET 10 или более поздней версии.
В следующем компоненте CultureSelector показано, как выполнять следующие действия.
- Установите выбор культуры пользователя в локальное хранилище браузера через взаимодействие с JS.
- Перезагрузите компонент, который они запросили (
forceLoad: true), использующий обновленную культуру.
CultureSelector.razor:
@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Navigation
<p>
<label>
Select your locale:
<select @bind="selectedCulture" @bind:after="ApplySelectedCultureAsync">
@foreach (var culture in supportedCultures)
{
<option value="@culture">@culture.DisplayName</option>
}
</select>
</label>
</p>
@code
{
private CultureInfo[] supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("es-CR"),
};
private CultureInfo? selectedCulture;
protected override void OnInitialized()
{
selectedCulture = CultureInfo.CurrentCulture;
}
private async Task ApplySelectedCultureAsync()
{
if (CultureInfo.CurrentCulture != selectedCulture)
{
await JS.InvokeVoidAsync("blazorCulture.set", selectedCulture!.Name);
Navigation.NavigateTo(Navigation.Uri, forceLoad: true);
}
}
}
@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Navigation
<p>
<label>
Select your locale:
<select value="@selectedCulture" @onchange="HandleSelectedCultureChanged">
@foreach (var culture in supportedCultures)
{
<option value="@culture">@culture.DisplayName</option>
}
</select>
</label>
</p>
@code
{
private CultureInfo[] supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("es-CR"),
};
private CultureInfo? selectedCulture;
protected override void OnInitialized()
{
selectedCulture = CultureInfo.CurrentCulture;
}
private async Task HandleSelectedCultureChanged(ChangeEventArgs args)
{
selectedCulture = CultureInfo.GetCultureInfo((string)args.Value!);
if (CultureInfo.CurrentCulture != selectedCulture)
{
await JS.InvokeVoidAsync("blazorCulture.set", selectedCulture!.Name);
Navigation.NavigateTo(Navigation.Uri, forceLoad: true);
}
}
}
Примечание.
Дополнительные сведения о IJSInProcessRuntime, см. Вызов функций JavaScript из методов .NET в ASP.NET CoreBlazor.
В закрывающий тег элемента </main> в компоненте MainLayout (MainLayout.razor) добавьте компонент CultureSelector.
<article class="bottom-row px-4">
<CultureSelector />
</article>
Используйте компонент CultureExample1, показанный в разделе Демонстрационный компонент, чтобы изучить принцип работы предыдущих примеров.
Динамически задайте параметры языка и культуры на стороне сервера в соответствии с предпочтениями пользователя.
Примеры расположений, в которых приложение может хранить предпочтения пользователя, включают локальное хранилище браузера (обычно для клиентских сценариев), службу локализации или базу данных (обычно для серверных сценариев) или внешнюю службу, подключенную к внешней базе данных, доступной через веб API. В следующем примере демонстрируется использование локализации cookie.
Примечание.
В следующем примере предполагается, что приложение использует глобальное взаимодействие, указывая интерактивную отрисовку на стороне сервера (интерактивный SSR) для компонента Routes в компоненте App (Components/App.razor):
<Routes @rendermode="InteractiveServer" />
Если приложение использует интерактивность по принципу «на страницу/компонент», ознакомьтесь с замечаниями в конце этого раздела, чтобы настроить режимы отрисовки для компонентов примера.
Добавьте пакет Майкрософт.Extensions.Localization в приложение.
Примечание.
Рекомендации по добавлению пакетов в приложения .NET можно найти в статьях раздела Установка и управление пакетами на странице Потребление пакетов (документация NuGet). Проверьте правильность версий пакета на сайте NuGet.org.
Серверные приложения локализуются с помощью промежуточного программного обеспечения локализации. Добавьте службы локализации в приложение с помощью AddLocalization.
В файле Program:
builder.Services.AddLocalization();
Задайте для приложения стандартные и поддерживаемые языки и региональные параметры с помощью RequestLocalizationOptions.
Перед вызовом MapRazorComponents в конвейере обработки запросов поместите следующий код:
После добавления промежуточного ПО маршрутизации в конвейер обработки запросов вставьте следующий код:
var supportedCultures = new[] { "en-US", "es-CR" };
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
app.UseRequestLocalization(localizationOptions);
Сведения о включении посредника локализации в конвейер посредников см. в разделе Посредники ASP.NET Core.
В следующем примере показано, как задать текущий язык и региональные параметры в файле cookie, который можно прочитать в ПО промежуточного слоя локализации.
Требуются следующие пространства имен для компонента App:
Добавьте следующее в верхнюю часть App файла компонента (Components/App.razor):
@using System.Globalization
@using Microsoft.AspNetCore.Localization
Добавьте следующий @code блок в нижней App части файла компонента:
@code {
[CascadingParameter]
private HttpContext? HttpContext { get; set; }
protected override void OnInitialized()
{
HttpContext?.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(
CultureInfo.CurrentCulture,
CultureInfo.CurrentUICulture)));
}
}
Для внесения изменений в файл Pages/_Host.cshtml требуются следующие пространства имен:
Добавьте в файл следующий код:
@using System.Globalization
@using Microsoft.AspNetCore.Localization
@{
this.HttpContext.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(
CultureInfo.CurrentCulture,
CultureInfo.CurrentUICulture)));
}
Сведения о последовательности размещения ПО промежуточного слоя локализации в конвейерной последовательности ПО промежуточного слоя см. в разделе ASP.NET Core Middleware.
Если приложение не настроено для обработки действий контроллера:
Добавьте службы MVC, вызвав метод AddControllers в коллекции служб в файле
Program.builder.Services.AddControllers();Добавьте маршрутизацию конечных точек контроллера в
Programфайл, вызвав MapControllers на IEndpointRouteBuilder (app):app.MapControllers();
Чтобы предоставить пользовательский интерфейс, позволяющий пользователю выбрать культуру, используйте подход на основе перенаправления в рамках локализации cookie. Приложение сохраняет выбранную пользователем культуру посредством перенаправления к контроллеру. Контроллер устанавливает выбранный пользователем язык и региональные параметры в cookie, а затем перенаправляет пользователя обратно на исходный URI. Процесс аналогичен тому, что происходит в веб-приложении, когда пользователь пытается получить доступ к защищенному ресурсу, где пользователь перенаправляется на страницу входа, а затем обратно к исходному ресурсу.
Controllers/CultureController.cs:
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
[Route("[controller]/[action]")]
public class CultureController : Controller
{
public IActionResult Set(string culture, string redirectUri)
{
if (culture != null)
{
HttpContext.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(culture, culture)));
}
return LocalRedirect(redirectUri);
}
}
Предупреждение
Используйте результат действия LocalRedirect, как показано в предыдущем примере, чтобы предотвратить атаки открытого перенаправления. Дополнительные сведения см. в разделе Предотвращение атак с открытым перенаправлением в ASP.NET Core.
В следующем компоненте CultureSelector показано, как вызвать метод Set класса CultureController с новой культурой. Компонент помещается в папку Shared для использования во всем приложении.
CultureSelector.razor:
@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Navigation
<p>
<label>
Select your locale:
<select @bind="selectedCulture" @bind:after="ApplySelectedCultureAsync">
@foreach (var culture in supportedCultures)
{
<option value="@culture">@culture.DisplayName</option>
}
</select>
</label>
</p>
@code
{
private CultureInfo[] supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("es-CR"),
};
private CultureInfo? selectedCulture;
protected override void OnInitialized()
{
selectedCulture = CultureInfo.CurrentCulture;
}
private async Task ApplySelectedCultureAsync()
{
if (CultureInfo.CurrentCulture != selectedCulture)
{
var uri = new Uri(Navigation.Uri)
.GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
var cultureEscaped = Uri.EscapeDataString(selectedCulture.Name);
var uriEscaped = Uri.EscapeDataString(uri);
Navigation.NavigateTo(
$"Culture/Set?culture={cultureEscaped}&redirectUri={uriEscaped}",
forceLoad: true);
}
}
}
@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Navigation
<p>
<label>
Select your locale:
<select value="@selectedCulture" @onchange="HandleSelectedCultureChanged">
@foreach (var culture in supportedCultures)
{
<option value="@culture">@culture.DisplayName</option>
}
</select>
</label>
</p>
@code
{
private CultureInfo[] supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("es-CR"),
};
private CultureInfo? selectedCulture;
protected override void OnInitialized()
{
selectedCulture = CultureInfo.CurrentCulture;
}
private async Task HandleSelectedCultureChanged(ChangeEventArgs args)
{
selectedCulture = CultureInfo.GetCultureInfo((string)args.Value!);
if (CultureInfo.CurrentCulture != selectedCulture)
{
var uri = new Uri(Navigation.Uri)
.GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
var cultureEscaped = Uri.EscapeDataString(selectedCulture.Name);
var uriEscaped = Uri.EscapeDataString(uri);
Navigation.NavigateTo(
$"Culture/Set?culture={cultureEscaped}&redirectUri={uriEscaped}",
forceLoad: true);
}
}
}
Добавьте компонент CultureSelector в компонент MainLayout. Поместите следующую разметку внутри закрывающего </main> тега Components/Layout/MainLayout.razor в файле:
Добавьте компонент CultureSelector в компонент MainLayout. Поместите следующую разметку внутри закрывающего </main> тега Shared/MainLayout.razor в файле:
<article class="bottom-row px-4">
<CultureSelector />
</article>
Используйте компонент CultureExample1, показанный в разделе Демонстрационный компонент, чтобы изучить принцип работы предыдущих примеров.
В предыдущем примере предполагается, что приложение принимает глобальную интерактивность, указывая режим рендеринга Interactive Server для компонента Routes в компоненте App (Components/App.razor).
<Routes @rendermode="InteractiveServer" />
Если приложение использует интерактивность для каждой страницы/компонента, внесите следующие изменения:
Добавьте режим рендеринга интерактивного сервера
CultureExample1в начало файла компонента (Components/Pages/CultureExample1.razor).@rendermode InteractiveServerВ основном макете приложения (
Components/Layout/MainLayout.razor) примените режим отрисовки интерактивного сервера к компонентуCultureSelector:<CultureSelector @rendermode="InteractiveServer" />
Динамически задать культурные настройки в Blazor Web App в соответствии с предпочтениями пользователя.
Этот раздел относится к Blazor Web App, которые используют Auto (Server и WebAssembly) интерактивность.
Примеры расположений, в которых приложение может хранить предпочтения пользователя, включают локальное хранилище браузера (обычно для клиентских сценариев), локализацию cookie или базу данных (обычно для сценариев на стороне сервера), оба локальное хранилище и локализацию cookie (Blazor Web Appс компонентами сервера и WebAssembly), или во внешней службе, подключенной к внешней базе данных и доступной через веб-API. В следующем примере показано, как использовать локальное хранилище браузера для отрисованных на клиентской стороне компонентов (CSR) и локализацию cookie для отрисованных на стороне сервера компонентов (SSR).
.Client Обновления проекта
Добавьте пакет Майкрософт.Extensions.Localization в проект .Client.
Примечание.
Рекомендации по добавлению пакетов в приложения .NET можно найти в статьях раздела Установка и управление пакетами на странице Потребление пакетов (документация NuGet). Проверьте правильность версий пакета на сайте NuGet.org.
Установите свойство BlazorWebAssemblyLoadAllGlobalizationData на true в .Client файле проекта.
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
Добавьте пространства имен System.Globalization и Майкрософт.JSInterop в начало файла проекта .ClientProgram.
using System.Globalization;
using Microsoft.JSInterop;
Удалите следующую строку:
- await builder.Build().RunAsync();
Замените указанную выше строку следующим кодом. Код добавляет службу локализации Blazor в коллекцию служб приложения с помощью AddLocalization и использует взаимодействие с JS для вызова JS и получения выбора культурных настроек пользователя из локального хранилища. Если локальное хранилище не содержит язык и региональные параметры для пользователя, код задает значение по умолчанию США английский (en-US).
builder.Services.AddLocalization();
var host = builder.Build();
const string defaultCulture = "en-US";
var js = host.Services.GetRequiredService<IJSRuntime>();
var result = await js.InvokeAsync<string>("blazorCulture.get");
var culture = CultureInfo.GetCultureInfo(result ?? defaultCulture);
if (result == null)
{
await js.InvokeVoidAsync("blazorCulture.set", defaultCulture);
}
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
await host.RunAsync();
Примечание.
В .NET 9 или более ранних версиях автономные Blazor WebAssembly приложения загружают ресурсы глобализации пользовательского интерфейса на базе CultureInfo.DefaultThreadCurrentCulture. Если вы хотите дополнительно загрузить данные о глобализации для вашей локализации, определенной CultureInfo.DefaultThreadCurrentUICulture, обновите приложение до .NET 10 или более поздней версии.
Добавьте следующий CultureSelector компонент в .Client проект.
Компонент применяет следующие подходы для работы с компонентами SSR или CSR:
- Отображаемое имя каждой доступной культуры в раскрывающемся списке предоставляется словарем. Это связано с тем, что клиентские данные глобализации включают локализованный текст отображаемых имен культур, предоставляемых серверными данными глобализации. Например, локализация на стороне сервера отображает
English (США), еслиen-US— культура, иIngles ()при использовании другой культуры. Так как локализация отображаемых имен языка и региональных параметров недоступна с помощью Blazor WebAssembly глобализации, отображаемое имя английского языка США на клиенте для любого загруженного языка и региональных параметров простоen-US. Использование пользовательского словаря позволяет компоненту отображать по крайней мере полные англоязычные названия культур. - При изменении языка и региональных параметров JS interop устанавливает эти параметры в локальном хранилище браузера, а действие контроллера обновляет локализацию cookie в соответствии с выбранными параметрами. Контроллер добавляется в приложение позже в разделе обновлений проекта сервера.
Pages/CultureSelector.razor:
@using System.Globalization
@inject IJSRuntime JS
@inject NavigationManager Navigation
<p>
<label>
Select your locale:
<select @bind="@selectedCulture" @bind:after="ApplySelectedCultureAsync">
@foreach (var culture in supportedCultures)
{
<option value="@culture">@cultureDict[culture.Name]</option>
}
</select>
</label>
</p>
@code
{
private Dictionary<string, string> cultureDict =
new()
{
{ "en-US", "English (United States)" },
{ "es-CR", "Spanish (Costa Rica)" }
};
private CultureInfo[] supportedCultures =
[
new CultureInfo("en-US"),
new CultureInfo("es-CR"),
];
private CultureInfo? selectedCulture;
protected override void OnInitialized()
{
selectedCulture = CultureInfo.CurrentCulture;
}
private async Task ApplySelectedCultureAsync()
{
if (CultureInfo.CurrentCulture != selectedCulture)
{
await JS.InvokeVoidAsync("blazorCulture.set", selectedCulture!.Name);
var uri = new Uri(Navigation.Uri)
.GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
var cultureEscaped = Uri.EscapeDataString(selectedCulture.Name);
var uriEscaped = Uri.EscapeDataString(uri);
Navigation.NavigateTo(
$"Culture/Set?culture={cultureEscaped}&redirectUri={uriEscaped}",
forceLoad: true);
}
}
}
В файле .Client проекта _Imports (_Imports.razor) добавьте пространство имен для компонентов, находящихся в папке Pages, и обновите его так, чтобы оно соответствовало пространству имен вашего проекта .Client.
@using BlazorSample.Client.Pages
Примечание.
Дополнительные сведения о IJSInProcessRuntime, см. Вызов функций JavaScript из методов .NET в ASP.NET CoreBlazor.
В проекте .Client добавьте компонент CultureSelector в компонент MainLayout. Поместите следующую разметку внутри закрывающего </main> тега Layout/MainLayout.razor в файле:
<article class="bottom-row px-4">
<CultureSelector @rendermode="InteractiveAuto" />
</article>
.Client В проекте поместите следующий CultureClient компонент для изучения того, как глобализация работает для компонентов CSR.
Pages/CultureClient.razor:
@page "/culture-client"
@rendermode InteractiveWebAssembly
@using System.Globalization
<PageTitle>Culture Client</PageTitle>
<h1>Culture Client</h1>
<ul>
<li><b>CurrentCulture</b>: @CultureInfo.CurrentCulture</li>
<li><b>CurrentUICulture</b>: @CultureInfo.CurrentUICulture</li>
</ul>
<h2>Rendered values</h2>
<ul>
<li><b>Date</b>: @dt</li>
<li><b>Number</b>: @number.ToString("N2")</li>
</ul>
<h2><code><input></code> elements that don't set a <code>type</code></h2>
<p>
The following <code><input></code> elements use
<code>CultureInfo.CurrentCulture</code>.
</p>
<ul>
<li><label><b>Date:</b> <input @bind="dt" /></label></li>
<li><label><b>Number:</b> <input @bind="number" /></label></li>
</ul>
<h2><code><input></code> elements that set a <code>type</code></h2>
<p>
The following <code><input></code> elements use
<code>CultureInfo.InvariantCulture</code>.
</p>
<ul>
<li><label><b>Date:</b> <input type="date" @bind="dt" /></label></li>
<li><label><b>Number:</b> <input type="number" @bind="number" /></label></li>
</ul>
@code {
private DateTime dt = DateTime.Now;
private double number = 1999.69;
}
В проекте .Client поместите следующий компонент CultureServer для изучения того, как глобализация работает для компонентов SSR.
Pages/CultureServer.razor:
@page "/culture-server"
@rendermode InteractiveServer
@using System.Globalization
<PageTitle>Culture Server</PageTitle>
<h1>Culture Server</h1>
<ul>
<li><b>CurrentCulture</b>: @CultureInfo.CurrentCulture</li>
<li><b>CurrentUICulture</b>: @CultureInfo.CurrentUICulture</li>
</ul>
<h2>Rendered values</h2>
<ul>
<li><b>Date</b>: @dt</li>
<li><b>Number</b>: @number.ToString("N2")</li>
</ul>
<h2><code><input></code> elements that don't set a <code>type</code></h2>
<p>
The following <code><input></code> elements use
<code>CultureInfo.CurrentCulture</code>.
</p>
<ul>
<li><label><b>Date:</b> <input @bind="dt" /></label></li>
<li><label><b>Number:</b> <input @bind="number" /></label></li>
</ul>
<h2><code><input></code> elements that set a <code>type</code></h2>
<p>
The following <code><input></code> elements use
<code>CultureInfo.InvariantCulture</code>.
</p>
<ul>
<li><label><b>Date:</b> <input type="date" @bind="dt" /></label></li>
<li><label><b>Number:</b> <input type="number" @bind="number" /></label></li>
</ul>
@code {
private DateTime dt = DateTime.Now;
private double number = 1999.69;
}
Используйте компонент CultureExample1 в папку .Client проекта Pages.
Добавьте компоненты CultureClient, CultureServerи CultureExample1 на боковой панели навигации в Layout/NavMenu.razor:
<div class="nav-item px-3">
<NavLink class="nav-link" href="culture-server">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Culture (Server)
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="culture-client">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Culture (Client)
</NavLink>
</div>
<div class="nav-item px-3">
<NavLink class="nav-link" href="culture-example-1">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Culture (Auto)
</NavLink>
</div>
Обновления проекта сервера
Добавьте пакет Майкрософт.Extensions.Localization в серверный проект.
Примечание.
Рекомендации по добавлению пакетов в приложения .NET можно найти в статьях раздела Установка и управление пакетами на странице Потребление пакетов (документация NuGet). Проверьте правильность версий пакета на сайте NuGet.org.
Серверные приложения локализуются с помощью промежуточного программного обеспечения локализации. Добавьте службы локализации в приложение с помощью AddLocalization.
В файле проекта Program сервера, где зарегистрированы службы:
builder.Services.AddLocalization();
Установите для приложения стандартные и поддерживаемые культуры с помощью RequestLocalizationOptions.
Перед вызовом MapRazorComponents в конвейере обработки запросов поместите следующий код:
var supportedCultures = new[] { "en-US", "es-CR" };
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
app.UseRequestLocalization(localizationOptions);
В следующем примере показано, как задать текущую культуру в cookie, который может быть прочитан промежуточным программным обеспечением локализации.
Следующие пространства имен требуются для компонента App.
Добавьте следующее в верхнюю часть App файла компонента (Components/App.razor):
@using System.Globalization
@using Microsoft.AspNetCore.Localization
Культура приложения для отрисовки на стороне клиента задается с помощью API Blazor фреймворка. Выбор культуры пользователя можно сохранить в локальном хранилище браузера для компонентов CSR.
BlazorПосле тега <script>предоставьте JS функции для получения и настройки выбора культуры пользователя с локальным хранилищем браузера:
<script>
window.blazorCulture = {
get: () => window.localStorage['BlazorCulture'],
set: (value) => window.localStorage['BlazorCulture'] = value
};
</script>
Примечание.
В предыдущем примере глобальные функции загрязняют клиента. Более эффективный подход для приложений в рабочей среде приведен в разделе Изоляция JavaScript в модулях JavaScript.
Добавьте следующий @code блок в нижней App части файла компонента:
@code {
[CascadingParameter]
private HttpContext? HttpContext { get; set; }
protected override void OnInitialized()
{
HttpContext?.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(
CultureInfo.CurrentCulture,
CultureInfo.CurrentUICulture)));
}
}
Если серверный проект не настроен для обработки действий контроллера:
Добавьте службы MVC, вызвав AddControllers на коллекции служб в файле
Program.builder.Services.AddControllers();Добавьте маршрутизацию конечных точек контроллера в файл
Program, вызвав MapControllers на IEndpointRouteBuilder (app).app.MapControllers();
Чтобы разрешить пользователю выбрать культуру для компонентов SSR, используйте подход на основе перенаправления с локализацией cookie. Приложение сохраняет выбранную пользователем культуру через перенаправление к контроллеру. Контроллер устанавливает выбранную культуру пользователя в cookie и перенаправляет пользователя обратно на исходный URI. Процесс аналогичен тому, что происходит в веб-приложении, когда пользователь пытается получить доступ к защищенному ресурсу, где пользователь перенаправляется на страницу входа, а затем обратно к исходному ресурсу.
Controllers/CultureController.cs:
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
[Route("[controller]/[action]")]
public class CultureController : Controller
{
public IActionResult Set(string culture, string redirectUri)
{
if (culture != null)
{
HttpContext.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(culture, culture)));
}
return LocalRedirect(redirectUri);
}
}
Предупреждение
LocalRedirect Используйте результат действия, как показано в предыдущем примере, чтобы предотвратить открытые атаки перенаправления. Дополнительные сведения см. в разделе Предотвращение атак перенаправления с открытым доступом в ASP.NET Core.
Интерактивные компоненты авто
Рекомендации в этом разделе также применимы для компонентов в приложениях, использующих постраничную или покомпонентную отрисовку и задающих интерактивный автоматический режим отрисовки.
@rendermode InteractiveAuto
Локализация
Если приложение еще не поддерживает динамический выбор культуры, добавьте пакет Майкрософт.Extensions.Localization в приложение.
Примечание.
Рекомендации по добавлению пакетов в приложения .NET можно найти в статьях раздела Установка и управление пакетами на странице Потребление пакетов (документация NuGet). Проверьте правильность версий пакета на сайте NuGet.org.
Локализация на стороне клиента
Задайте для свойства BlazorWebAssemblyLoadAllGlobalizationData значение true в файле проекта приложения (.csproj):
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
Добавьте пространство имен System.Globalization в начало Program файла.
using System.Globalization;
Добавьте Blazorслужбу локализации в коллекцию служб приложения с помощью AddLocalization:
builder.Services.AddLocalization();
Локализация на стороне сервера
Используйте Middleware для локализации, чтобы установить культуру приложения.
Если приложение еще не поддерживает динамический выбор языка и региональных параметров:
- Добавьте службы локализации в приложение с помощью AddLocalization.
- Укажите культуры по умолчанию и поддерживаемые культуры приложения в
Programфайле. Следующий пример настраивает поддерживаемые культуры для американского английского и коста-риканского варианта испанского языка.
builder.Services.AddLocalization();
Поместите ПО промежуточного слоя локализации запросов перед любым ПО промежуточного слоя (middleware), которое может проверить культуру запроса. Как правило, разместите посредующее ПО непосредственно перед вызовом MapRazorComponents:
Сразу после добавления ПО промежуточного слоя маршрутизации (UseRouting) в конвейер обработки:
var supportedCultures = new[] { "en-US", "es-CR" };
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
app.UseRequestLocalization(localizationOptions);
Для получения информации о порядке использования промежуточного слоя локализации в конвейере промежуточного слоя, см. раздел ASP.NET Core Middleware.
- Добавьте службы локализации в приложение с помощью AddLocalization.
- Укажите культуры по умолчанию и поддерживаемые культуры приложения в
Startup.Configure(Startup.cs). В следующем примере настраиваются поддерживаемые языки и региональные параметры для английского (США) и испанского (Коста-Рика).
В Startup.ConfigureServices (Startup.cs):
services.AddLocalization();
Сразу Startup.Configure после добавления промежуточного слоя маршрутизации в UseRouting конвейер обработки:
var supportedCultures = new[] { "en-US", "es-CR" };
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
app.UseRequestLocalization(localizationOptions);
Для получения информации о добавлении компонента промежуточного ПО локализации в конвейер обработки Startup.Configure, см. раздел Промежуточное ПО ASP.NET Core.
Если приложение должно локализовать ресурсы на основе культурных настроек пользователя, используйте культуру локализации cookie. Использование cookie гарантирует, что соединение WebSocket сможет правильно учитывать культуру. Если схема локализации основана на URL-адресе или строке запроса, она может не работать с WebSockets и не сохранять культуру. Поэтому рекомендуемым подходом является использование культуры локализации cookie. Просмотрите раздел Динамическая настройка культуры на стороне сервера по предпочтению пользователя в этой статье, чтобы увидеть пример выражения Razor, которое сохраняет выбор культуры пользователя.
Пример локализованных ресурсов
Пример локализованных ресурсов в этом разделе работает с более ранними примерами в этой статье, где поддерживаемые языки и региональные параметры приложения — английский язык (en) в качестве языкового стандарта по умолчанию и испанский язык (es) в качестве альтернативного языкового стандарта, выбираемого пользователем или браузером.
Создайте файл ресурса для каждого языкового стандарта. В следующем примере ресурсы создаются для Greeting строки на английском и испанском языках:
- Английский (
en):Hello, World! - Испанский (
es):¡Hola, Mundo!
Примечание.
Следующий файл ресурсов можно добавить в Visual Studio, щелкнув правой кнопкой мыши папку Pages, выбрав Добавить>Новый элемент>Файл ресурсов. Назовите файл CultureExample2.resx. Когда откроется редактор, укажите данные для новой записи. Установите для Имя значение Greeting, а для Значение - Hello, World!. Сохраните файл.
При использовании Visual Studio Code рекомендуется установить просмотрщик и редактор ResX от Tim Heuer. Добавьте пустой CultureExample2.resx файл в папку Pages . Расширение автоматически берет на себя управление файлом в пользовательском интерфейсе. Нажмите кнопку "Добавить новый ресурс ". Следуйте инструкциям, чтобы добавить запись ( Greeting ключ), Hello, World! (значение) и None (комментарий). Сохраните файл. Закрыв и снова открыв файл, вы можете увидеть ресурс Greeting.
Просмотрщик и редактор ResX от Тима Хьюера не принадлежит и не поддерживается Майкрософт и не покрывается никакими поддержками или лицензиями Майкрософт.
Ниже показан типичный файл ресурсов. Файлы ресурсов можно поместить вручную в папку Pages приложения, если вы предпочитаете не использовать встроенные средства с интегрированной средой разработки (IDE), например встроенным редактором файлов ресурсов Visual Studio или Visual Studio Code расширением для создания и редактирования файлов ресурсов.
Pages/CultureExample2.resx:
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Greeting" xml:space="preserve">
<value>Hello, World!</value>
</data>
</root>
Примечание.
Следующий файл ресурсов можно добавить в Visual Studio, щелкнув правой кнопкой мыши папку Pages, выбрав Добавить>Новый элемент>Файл ресурсов. Назовите файл CultureExample2.es.resx. Когда откроется редактор, укажите данные для новой записи. Установите Название на Greeting, а Значение на ¡Hola, Mundo!. Сохраните файл.
При использовании Visual Studio Code рекомендуется установить Просмотрщик и редактор ResX от Тима Хойера. Добавьте пустой CultureExample2.resx файл в папку Pages . Расширение автоматически берет на себя управление файлом в пользовательском интерфейсе. Нажмите кнопку "Добавить новый ресурс ". Следуйте инструкциям, чтобы добавить запись ( Greeting ключ), ¡Hola, Mundo! (значение) и None (комментарий). Сохраните файл. Если вы закроете и снова откроете файл, вы увидите ресурс Greeting.
Ниже показан типичный файл ресурсов. Файлы ресурсов можно поместить вручную в папку Pages приложения, если вы предпочитаете не использовать встроенные средства с интегрированной средой разработки (IDE), например встроенным редактором файлов ресурсов Visual Studio или Visual Studio Code расширением для создания и редактирования файлов ресурсов.
Pages/CultureExample2.es.resx:
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Greeting" xml:space="preserve">
<value>¡Hola, Mundo!</value>
</data>
</root>
Следующий компонент демонстрирует использование локализованной строки Greeting с IStringLocalizer<T>. Разметка Razor@Loc["Greeting"] в следующем примере используется для локализации строки, привязанной к значению Greeting, установленному в предыдущих файлах ресурсов.
Добавьте пространство имен для Майкрософт.Extensions.Localization в файл _Imports.razor приложения:
@using Microsoft.Extensions.Localization
CultureExample2.razor:
@page "/culture-example-2"
@using System.Globalization
@inject IStringLocalizer<CultureExample2> Loc
<h1>Culture Example 2</h1>
<ul>
<li><b>CurrentCulture</b>: @CultureInfo.CurrentCulture</li>
<li><b>CurrentUICulture</b>: @CultureInfo.CurrentUICulture</li>
</ul>
<h2>Greeting</h2>
<p>
@Loc["Greeting"]
</p>
<p>
@greeting
</p>
@code {
private string? greeting;
protected override void OnInitialized()
{
greeting = Loc["Greeting"];
}
}
При необходимости добавьте элемент меню для CultureExample2 компонента в навигацию в NavMenu компоненте (NavMenu.razor).
Источник документации поставщика региональных настроек WebAssembly
Чтобы больше узнать о том, как инфраструктура Blazor обрабатывает локализацию, см. класс WebAssemblyCultureProvider в источнике ссылок ASP.NET Core.
Примечание.
Ссылки на справочную документацию .NET обычно ведут на ветвь репозитория по умолчанию, которая представляет собой текущую разработку следующего релиза .NET. Чтобы выбрать тег для определенного выпуска, используйте раскрывающийся список Switch branches or tags (Переключение ветвей или тегов). Дополнительные сведения см. в разделе Как выбрать тег версии исходного кода ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Общие ресурсы
Чтобы создать общие ресурсы локализации, выполните следующий подход.
Убедитесь, что проект ссылается на пакет
Майкрософт.Extensions.Localization.Примечание.
Рекомендации по добавлению пакетов в приложения .NET можно найти в статьях раздела Установка и управление пакетами на странице Потребление пакетов (документация NuGet). Проверьте правильность версий пакета на сайте NuGet.org.
Убедитесь, что пространство имен Майкрософт.Extensions.Localization доступно для компонентов Razor проекта с помощью записи в файле
_Importsпроекта:@using Microsoft.Extensions.LocalizationСоздайте фиктивный класс с произвольным именем класса. В следующем примере :
- Приложение использует пространство имен
BlazorSample, а ресурсы локализации используют пространство именBlazorSample.Localization. - Фиктивный класс называется
SharedResource. - Файл класса помещается в
Localizationпапку в корне приложения.
Примечание.
Не используйте автоматически созданный файл конструктора (например,
SharedResources.Designer.cs). Фиктивный класс должен выступать в качестве общего класса ресурсов. Наличие файла конструктора приводит к столкновению пространства имен.Localization/SharedResource.cs:namespace BlazorSample.Localization; public class SharedResource { }- Приложение использует пространство имен
Создайте общие файлы ресурсов, используя действие сборки
. В следующем примере : Файлы помещаются в папку
Localizationс фиктивнымSharedResourceклассом (Localization/SharedResource.cs).Присвойте файлам ресурсов имя фиктивного класса. В следующих примерах приведены файл локализации по умолчанию и файл для локализации испанского языка (
es).Localization/SharedResource.resxLocalization/SharedResource.es.resx
Предупреждение
При выполнении подхода в этом разделе невозможно одновременно задать LocalizationOptions.ResourcesPath и использовать IStringLocalizerFactory.Create для загрузки ресурсов.
Чтобы сослаться на dummy класс для внедренного компонента IStringLocalizer<T> в компоненте Razor, можно либо поместить директиву
@usingдля пространства имен локализации, либо включить пространство имен локализации в ссылку на dummy класс. В следующих примерах:- В первом примере указывается
Localizationпространство имен дляSharedResourceфиктивного класса с директивой@using. - Второй пример явно указывает пространство имен фиктивного класса.
В компоненте Razor используйте любой из следующих подходов:
@using Localization @inject IStringLocalizer<SharedResource> Loc@inject IStringLocalizer<Localization.SharedResource> Loc- В первом примере указывается
Дополнительные рекомендации см. в разделе Globalization и локализация в ASP.NET Core.
Переопределение расположения с помощью области "Датчики" в средствах разработчика
При использовании переопределения расположения с помощью панели Sensors в Google Chrome или средств разработчика в Microsoft Edge резервный язык сбрасывается после предварительного рендеринга. Избегайте настройки языка с помощью области датчиков при тестировании. Задайте язык с помощью параметров языка браузера.
Дополнительные сведения см. в статье Blazor Локализация не поддерживается с InteractiveServer (dotnet/aspnetcore #53707).
Дополнительные ресурсы
- ASP.NET Core Blazor базовый путь приложения
- Глобализация и локализация в ASP.NET Core
- Глобализация и локализация приложений .NET
- Ресурсы в RESX-файлах
- Локализация и Дженерики
-
Вызов
InvokeAsync(StateHasChanged)приводит к возврату страницы к культуре по умолчанию (dotnet/aspnetcore № 28521) -
Blazor Локализация не работает с InteractiveServer (
dotnet/aspnetcore#53707) (переопределение расположения с помощью области "Датчики")
ASP.NET Core