Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Примечание.
Это не последняя версия этой статьи. Текущий выпуск можно найти в версии этой статьи о .NET 10.
Предупреждение
Эта версия ASP.NET Core больше не поддерживается. Для получения дополнительной информации см. Политику поддержки .NET и .NET Core. Текущий выпуск можно найти в версии этой статьи о .NET 10.
В этой статье объясняется, как предоставить интернационализированное и локализованное содержимое пользователям на разных языках и в разных культурах.
Глобализация и локализация
Для глобализацииBlazor обеспечивает форматирование чисел и дат. Для локализацииBlazor содержимое отображается с помощью системы ресурсов .NET.
Поддерживается ограниченный набор функций локализации ASP.NET Core:
и , а также IStringLocalizer поддерживаются в IStringLocalizer<T> приложениях.
Не поддерживается:IHtmlLocalizer и IViewLocalizer являются функциями ASP.NET Core MVC и не поддерживаются в приложениях Blazor.
Для Blazor приложений локализация сообщений проверки для проверки форм с помощью заметок данных поддерживается, если DisplayAttribute.ResourceType и ValidationAttribute.ErrorMessageResourceType реализованы.
Для Blazor приложений локализованные сообщения проверки для проверки форм с помощью заметок данных поддерживаются двумя путями:
- Путь к статическим ресурсам, использующий DisplayAttribute.ResourceType для отображаемых имен и ValidationAttribute.ErrorMessageResourceType для локализованных сообщений об ошибках. Этот подход поддерживается в каждом выпуске.
- Пакет
Microsoft.Extensions.Validation, который обрабатывает сообщения проверки и отображаемые имена через IStringLocalizer. Доступно для приложений Blazor, которые включают новый конвейер проверки с помощьюAddValidation(). Дополнительные сведения см. в разделе Как сделать содержимое приложения ASP.NET Core локализуемым.
В этой статье описывается, как использовать функции глобализации и локализации 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>
Предварительный рендеринг на стороне клиента в Blazor Web App сохраняет культуру сервера
По умолчанию предварительный рендеринг на стороне клиента на сервере (проект .Client в Blazor Web App) сохраняет серверные CurrentCulture и CurrentUICulture в состоянии компонента и применяет их на клиенте до загрузки вспомогательных сборок.
В приложениях, в которых клиент должен выбирать культуру независимо от сервера, можно отказаться от этого с помощью WebAssemblyComponentsOptions.UseCultureFromServer в файле Blazor Web App компонента Program:
builder.Services.AddRazorComponents()
.AddInteractiveWebAssemblyComponents(options =>
{
options.UseCultureFromServer = false;
});
Демонстрационный компонент
Следующий компонент 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
Этот раздел относится к серверным и клиентским Blazor приложениям.
Добавьте пакет Microsoft.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
Задать зафиксированные язык и региональные параметры на стороне клиента
Этот раздел относится к Blazor WebAssembly приложениям и Blazor Web App компонентам, которые применяют режим интерактивной отрисовки WebAssembly.
Этот раздел относится к приложениям Blazor WebAssembly.
Задайте для свойства 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).
Статически задать культуру на стороне сервера
Этот раздел относится к компонентам Blazor Web App, использующим интерактивный режим отрисовки на сервере, а также к приложениям Blazor Server.
Этот раздел относится к приложениям Blazor Server.
Серверные приложения локализуются с помощью промежуточного ПО локализации. Добавьте службы локализации в приложение с помощью AddLocalization.
В файле Program:
builder.Services.AddLocalization();
Укажите статический язык и региональные параметры в Program файле перед любым ПО промежуточного слоя, которое может проверить язык и региональные параметры запроса. Как правило, размещайте промежуточное ПО локализации непосредственно перед MapRazorComponents. В следующем примере настраивается американский вариант английского языка.
Укажите статическую культуру в файле Program сразу после добавления ПО промежуточной обработки маршрутизации (UseRouting) в конвейер обработки запросов. В следующем примере настраивается американский вариант английского языка.
app.UseRequestLocalization("en-US");
Значение культуры для
Сведения о порядке промежуточного ПО локализации в конвейере промежуточного ПО файла Program см. в разделе Промежуточное ПО ASP.NET Core.
Серверные приложения локализуются с помощью промежуточного ПО локализации. Добавьте службы локализации в приложение с помощью AddLocalization.
В Startup.ConfigureServices (Startup.cs):
services.AddLocalization();
Укажите статическую культуру в Startup.Configure (Startup.cs) сразу после добавления middleware маршрутизации в конвейер обработки запросов. В следующем примере настраивается американский вариант английского языка.
app.UseRequestLocalization("en-US");
Значение культуры для
Сведения о порядке промежуточного ПО локализации в конвейере промежуточного ПО Startup.Configure, см. Промежуточное ПО ASP.NET Core.
Используйте компонент CultureExample1, показанный в разделе Демонстрационный компонент, чтобы изучить принцип работы глобализации. Отправьте запрос на английский Соединённых Штатов (en-US). Перейдите на Коста-Риканский испанский (es-CR) в языковых параметрах браузера. Снова запросите веб-страницу. Когда запрошенный язык является коста-риканским испанским, язык и региональные параметры приложения остаются на английском языке Соединенных Штатов (en-US).
Динамически установить клиентские настройки форматирования по предпочтениям пользователя
Этот раздел относится к Blazor WebAssembly приложениям и Blazor Web App компонентам, которые применяют режим интерактивной отрисовки WebAssembly.
Этот раздел относится к приложениям Blazor WebAssembly.
Примеры расположений, в которых приложение может хранить предпочтения пользователя, включают локальное хранилище браузера (обычно для клиентских сценариев), службу локализации или базу данных (обычно для серверных сценариев) или внешнюю службу, подключенную к внешней базе данных, доступной через веб API. В следующем примере показано использование локального хранилища в браузере.
Добавьте пакет Microsoft.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 и Microsoft.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 (selectedCulture is not null &&
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 (selectedCulture is not null &&
CultureInfo.CurrentCulture != selectedCulture)
{
await JS.InvokeVoidAsync("blazorCulture.set", selectedCulture.Name);
Navigation.NavigateTo(Navigation.Uri, forceLoad: true);
}
}
}
Примечание.
Дополнительные сведения о IJSInProcessRuntime, см. Вызов функций JavaScript из методов .NET в ASP.NET CoreBlazor.
В разметке заголовка компонента MainLayout (MainLayout.razor) добавьте компонент CultureSelector:
<CultureSelector />
Используйте компонент CultureExample1, показанный в разделе Демонстрационный компонент, чтобы изучить принцип работы предыдущих примеров.
Динамически задайте параметры языка и культуры на стороне сервера в соответствии с предпочтениями пользователя.
Этот раздел относится к Blazor Web Apps, использующим глобальный режим отрисовки Interactive Server, и приложениям Blazor Server. Рекомендации по Blazor Web App, использующему интерактивность отдельных страниц и компонентов, см. в разделе Динамическая настройка культуры в Blazor Web App в соответствии с предпочтениями пользователя.
Этот раздел относится к приложениям Blazor Server.
Примеры расположений, в которых приложение может хранить предпочтения пользователя, включают локальное хранилище браузера (обычно для клиентских сценариев), службу локализации или базу данных (обычно для серверных сценариев) или внешнюю службу, подключенную к внешней базе данных, доступной через веб API. В следующем примере демонстрируется использование локализации cookie.
Добавьте пакет Microsoft.Extensions.Localization в приложение.
Примечание.
Рекомендации по добавлению пакетов в приложения .NET можно найти в статьях раздела Установка и управление пакетами на странице Потребление пакетов (документация NuGet). Проверьте правильность версий пакета на сайте NuGet.org.
Серверные приложения локализуются с помощью промежуточного ПО локализации. Добавьте службы локализации в приложение с помощью AddLocalization.
В файле Program:
builder.Services.AddLocalization();
Задайте для приложения стандартные и поддерживаемые языки и региональные параметры с помощью RequestLocalizationOptions.
Перед вызовом 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 ПО промежуточного слоя.
В следующем примере показано, как установить текущую культуру в cookie, которую может прочитать ПО промежуточной обработки локализации.
Требуются следующие пространства имен для компонента App:
Добавьте пространства имен System.Globalization и Microsoft.AspNetCore.Localization в верхнюю часть файла компонента 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 требуются следующие пространства имен:
Добавьте в файл следующую Razor разметку:
@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 ПО промежуточного слоя.
Чтобы предоставить пользовательский интерфейс, позволяющий пользователю выбрать культуру, используйте подход на основе перенаправления в рамках локализации cookie. Приложение сохраняет выбранную пользователем культуру через перенаправление на конечную точку Minimal API. Конечная точка устанавливает выбранную пользователем языковую и региональную настройку в файл cookie cookie и перенаправляет пользователя обратно к исходному URI. Процесс аналогичен тому, что происходит в веб-приложении, когда пользователь пытается получить доступ к защищенному ресурсу, где пользователь перенаправляется на страницу входа, а затем обратно к исходному ресурсу.
В начале файла Program добавьте следующую инструкцию using для необходимого пространства имен:
using Microsoft.AspNetCore.Localization;
В конвейере обработки запросов файла приложения Program после вызова UseRequestLocalization:
app.MapGet("/Culture/Set", (string? culture, string redirectUri = "/",
HttpContext context) =>
{
if (!string.IsNullOrWhiteSpace(culture))
{
context.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(culture, culture)));
}
return Results.LocalRedirect(redirectUri);
});
Предупреждение
Используйте результат LocalRedirect, как показано в предыдущем примере, чтобы предотвратить атаки с открытым перенаправлением. Дополнительные сведения см. в разделе Предотвращение атак с открытым перенаправлением в ASP.NET Core.
Если приложение не настроено для обработки действий контроллера:
Добавьте службы 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 с новой культурой. Компонент помещается в папку Components для использования во всем приложении.
Components/CultureSelector.razor:
Следующий компонент CultureSelector показывает, как вызвать конечную точку Set с новыми языковыми и региональными параметрами. Компонент помещается в папку Shared для использования во всем приложении.
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 (selectedCulture is not null &&
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 (selectedCulture is not null &&
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.
В разметке заголовка Components/Layout/MainLayout.razor:
В разметке заголовка Shared/MainLayout.razor:
<CultureSelector />
Используйте компонент 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, использующим интерактивность на уровне отдельных страниц и компонентов.
Примеры расположений, в которых приложение может хранить предпочтения пользователя, включают локальное хранилище браузера (обычно для клиентских сценариев), локализацию cookie или базу данных (обычно для сценариев на стороне сервера), оба локальное хранилище и локализацию cookie (Blazor Web Appс компонентами сервера и WebAssembly), или во внешней службе, подключенной к внешней базе данных и доступной через веб-API. В следующем примере показано, как использовать локальное хранилище браузера для отрисованных на клиентской стороне компонентов (CSR) и локализацию cookie для отрисованных на стороне сервера компонентов (SSR). Инструкции в этом разделе также применимы к компонентам в приложениях, использующих рендеринг на уровне страницы или компонента и указывающих режим рендеринга Interactive Auto (@rendermode InteractiveAuto).
.Client Обновления проекта
Добавьте пакет Microsoft.Extensions.Localization в проект .Client.
Примечание.
Рекомендации по добавлению пакетов в приложения .NET можно найти в статьях раздела Установка и управление пакетами на странице Потребление пакетов (документация NuGet). Проверьте правильность версий пакета на сайте NuGet.org.
Установите свойство BlazorWebAssemblyLoadAllGlobalizationData на true в .Client файле проекта.
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
Добавьте пространства имен System.Globalization и Microsoft.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 в папке Shared.
Shared Если папка не существует в .Client проекте, создайте ее для хранения общих компонентов.
Когда пользователь изменяет культуру, JS межоперационное взаимодействие сохраняет культуру в локальном хранилище браузера, а конечная точка Minimal API обновляет локализацию cookie с учетом культуры. Минимальная конечная точка API добавляется в приложение позже в разделе обновлений проекта сервера .
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 CultureInfo("en-US"),
new CultureInfo("es-CR"),
];
private CultureInfo? selectedCulture;
protected override void OnInitialized()
{
selectedCulture = CultureInfo.CurrentCulture;
}
private async Task ApplySelectedCultureAsync()
{
if (selectedCulture is not null &&
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);
}
}
}
Примечание.
Дополнительные сведения о IJSInProcessRuntime, см. Вызов функций JavaScript из методов .NET в ASP.NET CoreBlazor.
В файле импорта серверного проекта (_Imports.razor) добавьте пространство имен для папки Shared проекта .Client (обновите пространство имен в соответствии с вашим приложением):
@using BlazorSample.Client.Shared
Поместите следующую разметку в содержимое заголовка файла Components/Layout/MainLayout.razor:
<CultureSelector @rendermode="InteractiveAuto" />
.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. В верхней части компонента укажите режим интерактивной автоматической отрисовки:
@rendermode InteractiveAuto
Добавьте компоненты CultureClient, CultureServer и CultureExample1 в навигацию боковой панели в Components/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>
Обновления проекта сервера
Добавьте пакет Microsoft.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, которую может прочитать ПО промежуточной обработки локализации.
Добавьте пространства имён System.Globalization и Microsoft.AspNetCore.Localization в верхнюю часть компонента 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)));
}
}
Чтобы предоставить пользовательский интерфейс, позволяющий пользователю выбрать культуру, используйте подход на основе перенаправления в рамках локализации cookie. Приложение сохраняет выбранную пользователем культуру через перенаправление на конечную точку Minimal API. Конечная точка сохраняет выбранную пользователем культуру в cookie и перенаправляет пользователя обратно на исходный URI. Процесс аналогичен тому, что происходит в веб-приложении, когда пользователь пытается получить доступ к защищенному ресурсу, где пользователь перенаправляется на страницу входа, а затем обратно к исходному ресурсу.
В верхней части файла Program добавьте следующую инструкцию using для необходимого пространства имен:
using Microsoft.AspNetCore.Localization;
В конвейере обработки запросов файла приложения Program после вызова UseRequestLocalization:
app.MapGet("/Culture/Set", (string? culture, string redirectUri = "/",
HttpContext context) =>
{
if (!string.IsNullOrWhiteSpace(culture))
{
context.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(culture, culture)));
}
return Results.LocalRedirect(redirectUri);
});
Предупреждение
Используйте результат LocalRedirect, как показано в предыдущем примере, чтобы предотвратить атаки с открытым перенаправлением. Дополнительные сведения см. в разделе Предотвращение атак с открытым перенаправлением в ASP.NET Core.
Локализация
Если приложение еще не поддерживает динамический выбор культуры, добавьте пакет Microsoft.Extensions.Localization в приложение.
Примечание.
Рекомендации по добавлению пакетов в приложения .NET можно найти в статьях раздела Установка и управление пакетами на странице Потребление пакетов (документация NuGet). Проверьте правильность версий пакета на сайте NuGet.org.
Локализация на стороне клиента
Задайте для свойства BlazorWebAssemblyLoadAllGlobalizationData значение true в файле проекта приложения (.csproj):
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
Добавьте пространство имен Program в начало System.Globalization файла.
using System.Globalization;
Добавьте Blazorслужбу локализации в коллекцию служб приложения с помощью AddLocalization:
builder.Services.AddLocalization();
Локализация на стороне сервера
Используйте промежуточное ПО локализации, чтобы задать региональные параметры приложения.
Если приложение еще не поддерживает динамический выбор языка и региональных параметров:
- Добавьте службы локализации в приложение с помощью AddLocalization.
- Укажите культуры по умолчанию и поддерживаемые культуры приложения в
Programфайле. Следующий пример настраивает поддерживаемые культуры для американского английского и коста-риканского варианта испанского языка.
builder.Services.AddLocalization();
Разместите компонент промежуточного ПО для локализации перед любым компонентом промежуточного ПО, который может проверять культуру запроса. Как правило, разместите посредующее ПО непосредственно перед вызовом 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 ПО промежуточного слоя.
- Добавьте службы локализации в приложение с помощью 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 от Тима Хьюера не принадлежит и не поддерживается Microsoft и не покрывается никакими поддержками или лицензиями Microsoft.
Ниже показан типичный файл ресурсов. Файлы ресурсов можно поместить вручную в папку 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 от Tim Heuer. Добавьте пустой 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, установленному в предыдущих файлах ресурсов.
Добавьте пространство имён для Microsoft.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).
Общие ресурсы
Чтобы создать общие ресурсы локализации, выполните следующий подход.
Убедитесь, что проект ссылается на пакет
Microsoft.Extensions.Localization.Примечание.
Рекомендации по добавлению пакетов в приложения .NET можно найти в статьях раздела Установка и управление пакетами на странице Потребление пакетов (документация NuGet). Проверьте правильность версий пакета на сайте NuGet.org.
Убедитесь, что пространство имен Microsoft.Extensions.Localization доступно компонентам Razor проекта через запись в файле imports проекта (
_Imports.razor):@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
- Локализация DataAnnotations в минимальных API и Blazor
- Минимальные API: локализация сообщений проверки
- Глобализация и локализация приложений .NET
- Ресурсы в RESX-файлах
- Локализация и Дженерики
-
Вызов
InvokeAsync(StateHasChanged)приводит к возврату страницы к культуре по умолчанию (dotnet/aspnetcore#28521) -
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