Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Note
Это не последняя версия этой статьи. В текущей версии см. версию .NET 10 этой статьи.
Warning
Эта версия ASP.NET Core больше не поддерживается. Дополнительные сведения см. в политике поддержки .NET и .NET Core. В текущей версии см. версию .NET 10 этой статьи.
Авторы: Рик Андерсон (Rick Anderson), Дэмиен Боуден (Damien Bowden), Барт Каликсто (Bart Calixto), Надим Афана (Nadeem Afana) и Хишам Бин Атея (Hisham Bin Ateya)
Многоязычный веб-сайт позволяет веб-сайту достичь более широкой аудитории. ASP.NET Core предоставляет службы и промежуточное программное обеспечение для локализации на разные языки и для разных региональных параметров.
Для получения инструкций Blazor по локализации, которые дополняют или заменяют рекомендации, изложенные в этой статье, см. глобализацию и локализацию в ASP.NET CoreBlazor.
Terms
- Глобализация (G11N): процесс подготовки приложения к поддержке различных языков и регионов. Сокращение происходит от первых и последних букв и количества букв между ними.
- Локализация (L10N): процесс настройки глобального приложения для определенных языков и регионов.
- Интернационализация (I18N): глобализация и локализация.
- Культура: язык и, при необходимости, регион.
- Нейтральная культура: культура, в которой указан язык, но не регион (например, "en", "es").
- Конкретная культура: культура с заданным языком и регионом (например, «en-US», «en-GB», «es-CL»).
- Родительская культура: нейтральная культура, содержащая определённую культуру (например, "en" является родительской культурой для "en-US" и "en-GB").
- Локаль: это то же самое, что и культура.
Коды языка и страны или региона
Формат RFC 4646 для названия культуры <language code>-<country/region code>, где <language code> определяет язык и <country/region code> определяет субкультуру. Примеры: es-CL для испанского языка (Чили), en-US для английского языка (США), en-AU для английского языка (Австралия).
RFC 4646 — это комбинация двухбуквенного кода культуры ISO 639 в нижнем регистре (он связан с языком) и двухбуквенного кода субкультуры ISO 3166 в верхнем регистре (он связан со страной или регионом). Дополнительные сведения см. в разделе System.Globalization.CultureInfo.
Задачи локализации приложения
Глобализация и локализация приложения включает следующие задачи:
- Сделайте содержимое приложения ASP.NET Core локализуемым.
- Предоставление локализованных ресурсов для культур, поддерживаемых приложением
- Реализовать стратегию по выбору культуры для каждого запроса
Просмотреть или скачать образец кода (описание загрузки)
Дополнительные ресурсы
- Поставщик культур для URL, использующий промежуточное программное обеспечение в качестве фильтров в ASP.NET Core
- Глобальное применение CultureProvider RouteDataRequest посредствам промежуточного слоя в качестве фильтров
-
IStringLocalizer: использует ResourceManager и ResourceReader для предоставления ресурсов, зависящих от языка и региональных параметров, во время выполнения. Этот интерфейс имеет индексатор и интерфейсIEnumerableдля возврата локализованных строк. -
IHtmlLocalizer: для ресурсов, содержащих HTML. - Просмотр и аннотации данных
- Устранение неполадок локализации ASP.NET Core
- Глобализация и локализация приложений .NET
- Ресурсы в RESX-файлах
- Локализация и дженерики
Авторы: Рик Андерсон (Rick Anderson), Дэмиен Боуден (Damien Bowden), Барт Каликсто (Bart Calixto), Надим Афана (Nadeem Afana) и Хишам Бин Атея (Hisham Bin Ateya)
Многоязычный веб-сайт позволяет веб-сайту достичь более широкой аудитории. ASP.NET Core предоставляет службы и промежуточное программное обеспечение для локализации на разные языки и культурные параметры.
Terms
- Глобализация (G11N): процесс подготовки приложения к поддержке различных языков и регионов. Сокращение происходит от первых и последних букв и количества букв между ними.
- Локализация (L10N): процесс настройки глобального приложения для определенных языков и регионов.
- Интернационализация (I18N): глобализация и локализация.
- Культура: Язык и, при желании, регион.
- Нейтральная культура: культура, для которой указан язык, но не указан регион (например, "en", "es").
- Конкретная культура: культура с заданным языком и регионом (например, «en-US», «en-GB», «es-CL»).
- Родительская культура: нейтральная культура, содержащая определённую культуру (например, "en" является родительской культурой для "en-US" и "en-GB").
- Локаль: это то же самое, что и культура.
Коды языка и страны или региона
Формат RFC 4646 для названия культуры <language code>-<country/region code>, где <language code> определяет язык и <country/region code> определяет субкультуру. Примеры: es-CL для испанского языка (Чили), en-US для английского языка (США), en-AU для английского языка (Австралия).
RFC 4646 — это комбинация двухбуквенного кода культуры ISO 639 в нижнем регистре (он связан с языком) и двухбуквенного кода субкультуры ISO 3166 в верхнем регистре (он связан со страной или регионом). Дополнительные сведения см. в разделе System.Globalization.CultureInfo.
Задачи локализации приложения
Глобализация и локализация приложения включает следующие задачи:
- Сделайте содержимое приложения ASP.NET Core локализуемым.
- Предоставление локализованных ресурсов для культур, поддерживаемых приложением
- Реализовать стратегию по выбору культуры для каждого запроса
Просмотреть или скачать образец кода (описание загрузки)
Дополнительные ресурсы
- Сделать содержимое приложения ASP.NET Core локализуемым
- Предоставление локализованных ресурсов для языков и культур в приложении ASP.NET Core
- Стратегии выбора языка и культуры в локализованном приложении ASP.NET Core
- Устранение неполадок локализации ASP.NET Core
- Глобализация и локализация приложений .NET
- Проект Localization.StarterWeb, используемый в этой статье.
- Ресурсы в RESX-файлах
- Локализация и дженерики
Авторы: Рик Андерсон (Rick Anderson), Дэмиен Боуден (Damien Bowden), Барт Каликсто (Bart Calixto), Надим Афана (Nadeem Afana) и Хишам Бин Атея (Hisham Bin Ateya)
Создание многоязычного веб-сайта позволит расширить аудиторию. ASP.NET Core предоставляет службы и промежуточное программное обеспечение для локализации на разные языки и культурные параметры.
В интернационализацию входит System.Globalization и локализация. Глобализация — это процесс разработки приложений, которые поддерживают разные культуры. Глобализация добавляет поддержку ввода отображения и вывода определенного набора языковых сценариев, относящихся к конкретным регионам.
Локализация — это процесс адаптации глобализованного приложения, уже подготовленного к локализации, к определенному языку, языковому стандарту и региональным параметрам. Дополнительные сведения см. в разделе Термины, относящиеся к глобализации и локализации ближе к концу этого документа.
Локализация приложения включает следующие задачи:
- обеспечение возможности локализации для содержимого приложения;
- Предоставление локализованных ресурсов для поддерживаемых языков и культур
- Реализуйте стратегию по выбору языка/культуры для каждого запроса.
Просмотреть или скачать образец кода (описание загрузки)
Обеспечение возможности локализации содержимого приложения
IStringLocalizer и IStringLocalizer<T> создавались для повышения производительность при разработке локализованных приложений.
IStringLocalizer использует классы ResourceManager и ResourceReader для предоставления культурно-специфических ресурсов в процессе выполнения. Этот интерфейс имеет индексатор и интерфейс IEnumerable для возврата локализованных строк.
IStringLocalizer не требует сохранять строки на языке по умолчанию в файле ресурсов. Вы можете разрабатывать приложение, предназначенное для локализации, не создавая файлы ресурсов на ранних этапах разработки. В коде ниже показано, как обернуть строку "About Title" для локализации.
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
namespace Localization.Controllers
{
[Route("api/[controller]")]
public class AboutController : Controller
{
private readonly IStringLocalizer<AboutController> _localizer;
public AboutController(IStringLocalizer<AboutController> localizer)
{
_localizer = localizer;
}
[HttpGet]
public string Get()
{
return _localizer["About Title"];
}
}
}
В предыдущем коде реализация IStringLocalizer<T> получена в результате внедрения зависимостей. Если локализованное значение для строки "About Title" не найдено, возвращается ключ индексатора, то есть строка "About Title". Вы можете оставить литеральные строки языка по умолчанию и заключить их в локализатор, чтобы сосредоточиться на разработке приложения. Вы разрабатываете приложение на языке по умолчанию и подготавливаете его к локализации, не создавая предварительно файл ресурсов по умолчанию. Вы также можете выбрать традиционный подход и предоставить ключ для извлечения строки на языке по умолчанию. Для многих разработчиков новый рабочий процесс, который не требует наличия файла RESX на языке по умолчанию и позволяет просто заключать строки для дальнейшей обработки, может помочь снизить затраты на локализацию приложения. Другие разработчики могут предпочесть традиционный рабочий процесс, так как он упрощает работу с более длинными строками и обновление локализованных строк.
Используйте реализацию IHtmlLocalizer<T> для ресурсов, содержащих код HTML.
IHtmlLocalizer HTML-кодирует аргументы, которые форматируются в строке ресурса, но не кодирует в HTML саму строку ресурса. В выделенной ниже строке в HTML кодируется только значение параметра name.
using System;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Localization;
namespace Localization.Controllers
{
public class BookController : Controller
{
private readonly IHtmlLocalizer<BookController> _localizer;
public BookController(IHtmlLocalizer<BookController> localizer)
{
_localizer = localizer;
}
public IActionResult Hello(string name)
{
ViewData["Message"] = _localizer["<b>Hello</b><i> {0}</i>", name];
return View();
}
Note
Как правило, требуется локализовать только текст, но не код HTML.
На базовом уровне вы можете получить IStringLocalizerFactory из внедрения зависимостей:
{
public class TestController : Controller
{
private readonly IStringLocalizer _localizer;
private readonly IStringLocalizer _localizer2;
public TestController(IStringLocalizerFactory factory)
{
var type = typeof(SharedResource);
var assemblyName = new AssemblyName(type.GetTypeInfo().Assembly.FullName);
_localizer = factory.Create(type);
_localizer2 = factory.Create("SharedResource", assemblyName.Name);
}
public IActionResult About()
{
ViewData["Message"] = _localizer["Your application description page."]
+ " loc 2: " + _localizer2["Your application description page."];
В приведенном выше коде демонстрируются оба фабричных метода создания.
Вы можете разбивать локализованные строки по контроллеру, области или использовать всего один конвейер. В примере приложения для общих ресурсов используется класс-заглушка с именем SharedResource.
// Dummy class to group shared resources
namespace Localization
{
public class SharedResource
{
}
}
Некоторые разработчики используют класс Startup для хранения глобальных или общих строк. В примере ниже используются средства локализации InfoController и SharedResource.
public class InfoController : Controller
{
private readonly IStringLocalizer<InfoController> _localizer;
private readonly IStringLocalizer<SharedResource> _sharedLocalizer;
public InfoController(IStringLocalizer<InfoController> localizer,
IStringLocalizer<SharedResource> sharedLocalizer)
{
_localizer = localizer;
_sharedLocalizer = sharedLocalizer;
}
public string TestLoc()
{
string msg = "Shared resx: " + _sharedLocalizer["Hello!"] +
" Info resx " + _localizer["Hello!"];
return msg;
}
Просмотр локализации
Служба IViewLocalizer предоставляет локализованные строки для представления. Класс ViewLocalizer реализует этот интерфейс и находит расположение ресурсов по пути к файлу представления. В следующем примере кода демонстрируется использование реализации IViewLocalizer по умолчанию:
@using Microsoft.AspNetCore.Mvc.Localization
@inject IViewLocalizer Localizer
@{
ViewData["Title"] = Localizer["About"];
}
<h2>@ViewData["Title"].</h2>
<h3>@ViewData["Message"]</h3>
<p>@Localizer["Use this area to provide additional information."]</p>
Реализация IViewLocalizer по умолчанию определяет файл ресурсов на основе имени файла представления. Возможности использовать глобальный общий файл ресурсов нет.
ViewLocalizer реализует средство локализации с помощью интерфейса IHtmlLocalizer, поэтому Razor не кодирует локализованную строку в HTML. Вы можете параметризовать строки ресурсов, и IViewLocalizer будет кодировать в HTML параметры, но не строки ресурсов. Рассмотрим следующую разметку Razor:
@Localizer["<i>Hello</i> <b>{0}!</b>", UserManager.GetUserName(User)]
Файл ресурсов на французском языке может содержать следующие ресурсы:
| Key | Value |
|---|---|
<i>Hello</i> <b>{0}!</b> |
<i>Bonjour</i> <b>{0} !</b> |
Преобразованное для просмотра представление будет содержать разметку HTML из файла ресурсов.
Note
Как правило, требуется локализовать только текст, но не код HTML.
Чтобы использовать в представлении общий файл ресурсов, внедрите IHtmlLocalizer<T>:
@using Microsoft.AspNetCore.Mvc.Localization
@using Localization.Services
@inject IViewLocalizer Localizer
@inject IHtmlLocalizer<SharedResource> SharedLocalizer
@{
ViewData["Title"] = Localizer["About"];
}
<h2>@ViewData["Title"].</h2>
<h1>@SharedLocalizer["Hello!"]</h1>
Локализация DataAnnotations
Сообщения об ошибках DataAnnotations локализуются с помощью IStringLocalizer<T>. При использовании параметра ResourcesPath = "Resources" сообщения об ошибках в RegisterViewModel могут сохраняться по одному из следующих путей:
- Resources/ViewModels.Account.RegisterViewModel.fr.resx
- Resources/ViewModels/Account/RegisterViewModel.fr.resx
public class RegisterViewModel
{
[Required(ErrorMessage = "The Email field is required.")]
[EmailAddress(ErrorMessage = "The Email field is not a valid email address.")]
[Display(Name = "Email")]
public string Email { get; set; }
[Required(ErrorMessage = "The Password field is required.")]
[StringLength(8, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
Локализованы атрибуты, не связанные с проверкой.
Использование одной строки ресурса для нескольких классов
В следующем коде показано, как использовать одну строку ресурса для атрибутов проверки с несколькими классами:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.AddDataAnnotationsLocalization(options => {
options.DataAnnotationLocalizerProvider = (type, factory) =>
factory.Create(typeof(SharedResource));
});
}
В предыдущем коде SharedResource — это класс, соответствующий файлу RESX, в котором хранятся сообщения о проверке. При таком подходе DataAnnotations будут использовать только SharedResource, вместо ресурса для каждого класса.
Предоставление локализованных ресурсов для поддерживаемых языков и культур
SupportedCultures и SupportedUICultures
ASP.NET Core позволяет указывать два значения культуры: SupportedCultures и SupportedUICultures. Объект CultureInfo для SupportedCultures определяет результаты функций, зависящих от языка и региональных параметров, таких как форматирование дат, времени, чисел и валют.
SupportedCultures также определяет порядок сортировки текста, соглашения о регистре символов и способы сравнения строк. Дополнительные сведения о том, как сервер получает культуру, см. в статьях о CultureInfo.CurrentCulture и CultureInfo.CurrentUICulture.
SupportedUICultures определяет, какие переведенные строки (из файлов .resx) будет искать ResourceManager.
ResourceManager ищет культурно-специфичные строки, которые определяются CurrentUICulture. Каждый поток в .NET имеет объекты CurrentCulture и CurrentUICulture. Фреймворк проверяет эти значения при обработке культура-зависимых функций. Если для языка и региональных параметров текущего потока задано значение en-US (английский, США), DateTime.Now.ToLongDateString() отображает Thursday, February 18, 2016. Но если CurrentCulture имеет значение es-ES (испанский, Испания), результатом будет jueves, 18 de febrero de 2016.
Файлы ресурсов
Файл ресурсов — это полезное средство для отделения локализуемых строк от кода. Переведенные строки на языках, отличных от языка по умолчанию, содержатся в отдельных файлах ресурсов с расширением RESX. Например, вам нужно создать файл ресурсов для испанского языка с именем Welcome.es.resx, который будет содержать переведенные строки. "es" — это код испанского языка. Чтобы создать этот файл ресурсов в Visual Studio, выполните указанные ниже действия.
В Обозревателе решений щелкните правой кнопкой мыши папку, которая будет содержать файл ресурсов, а затем выберите пункты >Добавить>Новый элемент.
В поле Поиск установленных шаблонов введите слово "ресурс" и укажите имя файла.
Введите значение ключа (строку на исходном языке) в столбце Имя и переведенную строку в столбце Значение.
В Visual Studio отобразится файл Welcome.es.resx.
Именование файлов ресурсов
Имена ресурсов представляют собой полные имена типов соответствующего класса за исключением имени сборки. Например, ресурс на французском языке в проекте, главная сборка которого имеет имя LocalizationWebsite.Web.dll, для класса LocalizationWebsite.Web.Startup будет иметь имя Startup.fr.resx. Ресурс для класса LocalizationWebsite.Web.Controllers.HomeController будет иметь имя Controllers.HomeController.fr.resx. Если пространство имен целевого класса не совпадает с именем сборки, необходимо использовать полное имя типа. Например, в образце проекта ресурс для типа ExtraNamespace.Tools будет иметь имя ExtraNamespace.Tools.fr.resx.
В примере проекта метод ConfigureServices задает для ResourcesPath значение Resources, поэтому относительный путь проекта для французского файла ресурсов контроллера дома — Resources/Controllers.HomeController.fr.resx. Кроме того, для упорядочения файлов ресурсов можно использовать папки. Для домашнего контроллера путь будет Resources/Controllers/HomeController.fr.resx. Если параметр ResourcesPath не используется, файл RESX будет находиться в базовом каталоге проекта. Файл ресурса для HomeController будет иметь имя Controllers.HomeController.fr.resx. Выбор соглашения об именовании на основе точечной нотации или пути зависит от того, как следует упорядочивать файлы ресурсов.
| Имя ресурса | Точечная нотация или путь |
|---|---|
| Resources/Controllers.HomeController.fr.resx | Dot |
| Resources/Controllers/HomeController.fr.resx | Path |
Файлы ресурсов, для которых используется директива @inject IViewLocalizer в представлениях Razor, следуют той же модели. Файлу ресурсов для представления может присваиваться имя на основе либо точечной нотации, либо пути. В файле ресурсов для представления Razor имитируется путь к связанному файлу представления. Если для ResourcesPath задано значение Resources, то файл ресурсов на французском языке, связанный с представлением Views/Home/About.cshtml, может иметь одно из следующих имен.
Resources/Views/Home/About.fr.resx
Ресурсы и представления.Home. About.fr.resx
Если параметр ResourcesPath не используется, файл RESX для представления будет находиться в той же папке, что и представление.
RootNamespaceAttribute
Атрибут RootNamespaceAttribute предоставляет корневое пространство имен сборки, если корневое пространство имен сборки отличается от имени сборки.
Warning
Это может произойти, если имя проекта — недопустимый идентификатор .NET. Например, my-project-name.csproj будет использовать корневое пространство имен my_project_name и имя сборки my-project-name, что повлечет эту ошибку.
Если корневое пространство имен сборки отличается от имени сборки
- Локализация не работает по умолчанию.
- Локализация не удаётся из-за способа поиска ресурсов в сборке.
RootNamespace— это значение во время сборки, которое недоступно выполняющемуся процессу.
Если RootNamespace отличается от AssemblyName, включите следующее в файл AssemblyInfo.cs (со значениями параметров, замененными фактическими значениями).
using System.Reflection;
using Microsoft.Extensions.Localization;
[assembly: ResourceLocation("Resource Folder Name")]
[assembly: RootNamespace("App Root Namespace")]
Приведенный выше код обеспечивает успешное разрешение RESX-файлов.
Поведение резервирования культуры
При поиске ресурса локализация использует "резервирование культуры". Если запрошенная культура не найдена, производится возврат к родительской культуре этой культуры. Кстати, свойство CultureInfo.Parent представляет родительскую культуру. Обычно (но не всегда) это означает удаление национального символа из ISO. Например, диалект испанского в Мексике — es-MX. Родительский элемент "es" — испанский язык, не привязанный к какой-либо конкретной стране.
Допустим, ваш сайт получает запрос на ресурс "Добро пожаловать" с использованием культуры "fr-CA". Система локализации ищет в следующих ресурсах по порядку и выбирает первое совпадение:
- Welcome.fr-CA.resx
- Welcome.fr.resx
-
Welcome.resx (если
NeutralResourcesLanguage— fr-CA)
Если вы удалите идентификатор ".fr" для культуры и при этом установлена культура на французскую, считывается файл ресурсов по умолчанию, и строки локализуются. Диспетчер ресурсов назначает ресурс по умолчанию или резервный ресурс, если не найдено соответствий запрошенной культуре. Если нужно, чтобы при отсутствии ресурса для запрошенной культуры просто возвращался ключ, не используйте ресурс по умолчанию.
Создание файлов ресурсов с помощью Visual Studio
Если вы создаете в Visual Studio файл ресурсов без указания культуры в имени файла (например, Welcome.resx), Visual Studio создаст класс C# со свойством для каждой строки. В ASP.NET Core обычно требуется иное поведение. Как правило, файл ресурса .resx без имени культуры (файл .resx без указания языка и региональных параметров) обычно отсутствует. Мы рекомендуем создать файл .resx с именем культуры (например, Welcome.fr.resx). При создании файла .resx с указанием имени культуры среда Visual Studio не создает файл класса.
Добавление других культур
Каждое сочетание языка и культуры (кроме языка по умолчанию) требует уникального файла ресурсов. Вы создаете файлы ресурсов для различных культур и локализаций, включая коды языков ISO в их имена (например, en-us, fr-ca и en-gb). Эти коды ISO помещаются между именем файла и расширением RESX, например Welcome.es-MX.resx (испанский, Мексика).
Реализуйте стратегию по выбору языка/культуры для каждого запроса.
Настройка локализации
Локализация настраивается в методе Startup.ConfigureServices:
services.AddLocalization(options => options.ResourcesPath = "Resources");
services.AddMvc()
.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
.AddDataAnnotationsLocalization();
Метод
AddLocalizationдобавляет службы локализации в контейнер служб. В приведенном выше коде также задается путь к ресурсам "Resources".Метод
AddViewLocalizationдобавляет поддержку файлов локализованных представлений. В этом примере локализация представления основана на суффиксе этого файла представления. Например, fr вIndex.fr.cshtmlфайле.Метод
AddDataAnnotationsLocalizationдобавляет поддержку локализованных сообщений проверкиDataAnnotationsпосредством абстракцийIStringLocalizer.
Промежуточное программное обеспечение для локализации
Текущая культура в запросе задается в Middleware локализации. Промежуточный слой локализации включается в методе Startup.Configure. Промежуточное ПО локализации должно настраиваться перед другим промежуточным ПО, которое может проверять культуру запроса (например, app.UseMvcWithDefaultRoute()). ПО промежуточного слоя локализации должно находиться после ПО промежуточного слоя маршрутизации, если используется RouteDataRequestCultureProvider. Дополнительные сведения о порядке ПО промежуточного слоя см. в статье ПО промежуточного слоя ASP.NET Core.
var supportedCultures = new[] { "en-US", "fr" };
var localizationOptions = new RequestLocalizationOptions().SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
app.UseRequestLocalization(localizationOptions);
UseRequestLocalization инициализирует объект RequestLocalizationOptions. При каждом запросе перечисляется список RequestCultureProvider в объекте RequestLocalizationOptions, и используется первый поставщик, который может успешно определить культуру запроса. Поставщики по умолчанию берутся из класса RequestLocalizationOptions:
QueryStringRequestCultureProviderCookieRequestCultureProviderAcceptLanguageHeaderRequestCultureProvider
В списке по умолчанию элементы располагаются от наиболее конкретных к наименее конкретным. Далее в этой статье вы узнаете, как можно изменить порядок и даже добавить пользовательский поставщик культурных настроек. Если ни один из поставщиков не может определить культуру запроса, используется DefaultRequestCulture.
QueryStringRequestCultureProvider
Некоторые приложения используют строку запроса для задания CultureInfo. Если в приложениях используется cookie или заголовок Accept-Language, добавление строки запроса к URL-адресу может быть полезным для отладки и тестирования кода. По умолчанию поставщик QueryStringRequestCultureProvider регистрируется в качестве первого поставщика локализации в списке RequestCultureProvider. Вы передаете параметры строки запроса culture и ui-culture. В следующем примере задаётся конкретная культура (язык и регион) на испанский/Мексика:
http://localhost:5000/?culture=es-MX&ui-culture=es-MX
Если передан только один из двух параметров (culture или ui-culture), поставщик строки запроса задаст с его помощью оба значения. Например, установка только культуры задаст оба значения Culture и UICulture.
http://localhost:5000/?culture=es-MX
CookieRequestCultureProvider
Рабочие приложения часто предоставляют механизм для установки культурных параметров с помощью ASP.NET Core cookie. Используйте метод MakeCookieValue, чтобы создать cookie.
CookieRequestCultureProvider
DefaultCookieName возвращает имя cookie по умолчанию, используемое для отслеживания предпочтительной информации о культуре пользователя. Имя cookie по умолчанию — .AspNetCore.Culture.
Файл cookie имеет формат c=%LANGCODE%|uic=%LANGCODE%, где c — это Culture, а uic — это UICulture, например:
c=en-UK|uic=en-US
Если указаны только параметры культуры или только параметры культуры пользовательского интерфейса, указанные параметры будут использоваться для обоих случаев.
Заголовок HTTP Accept-Language
Заголовок Accept-Language может задаваться в большинстве браузеров и изначально предназначался для указания языка пользователя. Эта настройка указывает, что задано для отправки браузеру или унаследовано от базовой операционной системы. Заголовок HTTP Accept-Language в запросе из браузера — это не самый надежный способ определения предпочтительного языка пользователя (см. статью Настройка языковых предпочтений в браузере). В приложении в эксплуатации должна быть возможность выбора культурных настроек пользователем.
Установите заголовок HTTP Accept-Language в Internet Explorer
Щелкните значок шестеренки и выберите пункт Свойства браузера.
Коснитесь языков.
Нажмите Задать предпочитаемые языки.
Нажмите Добавить язык.
Добавьте язык.
Выберите язык, а затем нажмите кнопку Вверх.
Использование пользовательского поставщика
Предположим, вы хотите позволить вашим клиентам сохранять свои языковые и культурные данные в ваших базах данных. Вы можете написать провайдер, который будет искать эти значения для пользователя. В следующем коде показано, как добавить пользовательского поставщика.
private const string enUSCulture = "en-US";
services.Configure<RequestLocalizationOptions>(options =>
{
var supportedCultures = new[]
{
new CultureInfo(enUSCulture),
new CultureInfo("fr")
};
options.DefaultRequestCulture = new RequestCulture(culture: enUSCulture, uiCulture: enUSCulture);
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
options.AddInitialRequestCultureProvider(new CustomRequestCultureProvider(async context =>
{
// My custom request culture logic
return await Task.FromResult(new ProviderCultureResult("en"));
}));
});
Для добавления или удаления поставщиков локализации используйте объект RequestLocalizationOptions.
Изменение порядка поставщиков языка и региональных параметров запроса
В RequestLocalizationOptions имеются три поставщика культурной информации по умолчанию: QueryStringRequestCultureProvider, CookieRequestCultureProvider и AcceptLanguageHeaderRequestCultureProvider. Чтобы изменить порядок этих поставщиков, используйте свойство [RequestLocalizationOptions.RequestCultureProviders]](xref:Microsoft.AspNetCore.Builder.RequestLocalizationOptions.RequestCultureProviders), как показано ниже:
app.UseRequestLocalization(options =>
{
var questStringCultureProvider = options.RequestCultureProviders[0];
options.RequestCultureProviders.RemoveAt(0);
options.RequestCultureProviders.Insert(1, questStringCultureProvider);
});
В приведенном выше примере порядок QueryStringRequestCultureProvider и CookieRequestCultureProvider изменен, поэтому RequestLocalizationMiddleware сначала ищет язык и региональные параметры из файлов cookie, а затем из строки запроса.
Как уже упоминалось, нужно добавить пользовательский поставщик с помощью метода AddInitialRequestCultureProvider, который назначает приоритет 0, чтобы этот поставщик имел приоритет над другими.
Установить язык и региональные параметры программно
В образце проекта Localization.StarterWeb в GitHub есть пользовательский интерфейс для задания значения Culture. Файл Views/Shared/_SelectLanguagePartial.cshtml позволяет выбрать языковые и культурные параметры из списка поддерживаемых культур:
@using Microsoft.AspNetCore.Builder
@using Microsoft.AspNetCore.Http.Features
@using Microsoft.AspNetCore.Localization
@using Microsoft.AspNetCore.Mvc.Localization
@using Microsoft.Extensions.Options
@inject IViewLocalizer Localizer
@inject IOptions<RequestLocalizationOptions> LocOptions
@{
var requestCulture = Context.Features.Get<IRequestCultureFeature>();
var cultureItems = LocOptions.Value.SupportedUICultures
.Select(c => new SelectListItem { Value = c.Name, Text = c.DisplayName })
.ToList();
var returnUrl = string.IsNullOrEmpty(Context.Request.Path) ? "~/" : $"~{Context.Request.Path.Value}";
}
<div title="@Localizer["Request culture provider:"] @requestCulture?.Provider?.GetType().Name">
<form id="selectLanguage" asp-controller="Home"
asp-action="SetLanguage" asp-route-returnUrl="@returnUrl"
method="post" class="form-horizontal" role="form">
<label asp-for="@requestCulture.RequestCulture.UICulture.Name">@Localizer["Language:"]</label> <select name="culture"
onchange="this.form.submit();"
asp-for="@requestCulture.RequestCulture.UICulture.Name" asp-items="cultureItems">
</select>
</form>
</div>
Файл Views/Shared/_SelectLanguagePartial.cshtml добавляется в раздел footer файла макета, поэтому он доступен всем представлениям:
<div class="container body-content" style="margin-top:60px">
@RenderBody()
<hr>
<footer>
<div class="row">
<div class="col-md-6">
<p>© @System.DateTime.Now.Year - Localization</p>
</div>
<div class="col-md-6 text-right">
@await Html.PartialAsync("_SelectLanguagePartial")
</div>
</div>
</footer>
</div>
Метод SetLanguage задает культуру cookie.
[HttpPost]
public IActionResult SetLanguage(string culture, string returnUrl)
{
Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)),
new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) }
);
return LocalRedirect(returnUrl);
}
Вы не можете вставить _SelectLanguagePartial.cshtml образец кода в этот проект. В проекте Localization.StarterWeb в GitHub есть код для передачи объекта RequestLocalizationOptions в частичное представление Razor посредством контейнера внедрения зависимостей.
Данные маршрутов привязки модели и строки запросов
См. раздел Поведение глобализации для данных маршрутов привязки модели и строк запросов.
Термины, относящиеся к глобализации и локализации
Процесс локализации приложения требует базового понимания распространенных кодировок, часто используемых при разработке современного программного обеспечения, и связанных с ними проблем. Хотя на всех компьютерах текст сохраняется в виде цифр (кодов), в разных системах эти коды для одного и того же текста различаются. Под процессом локализации понимается перевод пользовательского интерфейса приложения для определенного языка и региональных параметров.
Возможность локализации — это определяемое на промежуточной стадии состояние готовности глобализованного приложения к локализации.
Формат RFC 4646 для имени культуры имеет вид <languagecode2>-<country/regioncode2>, где <languagecode2> — это код языка, а <country/regioncode2> — код субкультуры. Примеры: es-CL для испанского языка (Чили), en-US для английского языка (США), en-AU для английского языка (Австралия).
RFC 4646 — это комбинация двухбуквенного кода культуры ISO 639 в нижнем регистре (он связан с языком) и двухбуквенного кода субкультуры ISO 3166 в верхнем регистре (он связан со страной или регионом). Дополнительные сведения см. в разделе System.Globalization.CultureInfo.
Слово "интернационализация" часто сокращают до аббревиатуры "I18N". В аббревиатуру включаются первая и последняя буквы слова, а также число букв между ними, то есть 18 — это число букв между первой ("I") и последней ("N") буквами. То же самое касается глобализации (Globalization — G11N) и локализации (Localization — L10N).
Terms:
- Глобализация (G11N): процесс подготовки приложения к поддержке различных языков и регионов.
- Локализация (L10N): процесс настройки приложения для работы с конкретным языком и регионом.
- Интернационализация (I18N): включает в себя глобализацию и локализацию.
- Культура: это язык и, при необходимости, регион.
- Нейтральная культура: культура, для которой указан язык, но не указана страна. (например, "en", "es").
- Специфическая культура: культура, для которой указаны язык и регион. (например, "en-US", "en-GB", "es-CL").
- Базовая культура: нейтральная культура, содержащая конкретную культуру. (например, "en" — это родительская культура для "en-US" и "en-GB").
- Локаль: это то же самое, что и культура.
Note
Возможно, вы не сможете вводить десятичные запятые в полях для десятичных чисел. Чтобы поддерживать валидацию jQuery для неанглоязычных локалей, которые используют запятую (",") в качестве десятичного разделителя и отличные от американского английского форматы дат, необходимо предпринять шаги по глобализации вашего приложения. См. этот комментарий GitHub 4076 для инструкций по добавлению десятичной запятой.
Note
До ASP.NET Core 3.0 веб-приложения записывали по одному журналу типа LogLevel.Warning на запрос, если запрашиваемая культура не поддерживалась. Записывать по одному LogLevel.Warning на каждый запрос может привести к созданию объёмных файлов журнала с избыточной информацией. Это поведение было изменено в ASP.NET Core 3.0.
RequestLocalizationMiddleware записывает журнал типа LogLevel.Debug, который сокращает размер рабочих журналов.
Дополнительные ресурсы
ASP.NET Core