Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core 7
В прошлой теме мы познакомились с сервисом IStringLocalizer, который эффективно позволяет локализовать строки. Однако все используемые ресурсы были жестко определены в коде. Но, как правило, для хранения локализуемых строк применяются файлы ресурсов. Файл ресурсов позволяет отделить локализуемые строки, которые должны изменяться в зависимости от текущий языковой культуры, от кода приложения. Файлы ресурсов resx использовались широко и в предыдущих версиях ASP.NET и вообще в различных технологиях на платформе .NET. Но в ASP.NET Core их применение имеет свои особенности.
В прошлой теме для локализации была создана реализация интерфейса IStringLocalizer, но ASP.NET Core также уже имеет встроенную реализацию - ResourceManagerStringLocalizer, которая как раз и использует файлы ресурсов.
При определении ресурсов следует учитывать условности в наименовании файлов ресурсов. Так, файлы ресурсов должны называться по имени файла с учетом пространства имен, но без названия проекта, если оно совпадает с именем сборки. Например, ресурс для класса Startup должен представлять файл Startup.[код_культуры].resx.
Определим в проекте ресурсы для контроллера HomeController. Для этого добавим в проект новую папку Resources. А в нее добавим файл ресурса Controllers.HomeController.ru.resx:
Для добавления ресурсов в Visual Studio имеется встроенный шаблон Resources File. Обратите внимание на название файла. По умолчанию HomeController находится в папке Controllers. Поэтому файл ресурсов называется Controllers.HomeController.ru.resx, а суффикс "ru" в конце файла указывает, что ресурсы будут предназначены для русскоязычной культуры.
Для контроллеров также допустимо размещение в папке ресурсов в подкаталоге Controllers. В этом случае файл ресурсов должен отражать только имя контроллера: HomeController.ru.resx. То есть в данном случае для контроллера HomeController допустимо создание файлов ресурсов со следующими путями:
Resources/Controllers.HomeController.ru.resx
Resources/Controllers/HomeController.ru.resx
После добавления файла определим в нем несколько ресурсов:
В данном случае определены два ресурса: Header и Message.
Добавим в папку Resources аналогичные файлы ресурсов для других языков:
То есть получится несколько файлов, которые в названии отличаются только кодом культуры. И все файлы ресурсов имеют одни и те же ключи, только им соответствуют строки на соответствующем языке:
После добавления ресурсов лучше выполнить ребилд (перестроение) проекта.
Далее изменим класс Startup:
using System.Globalization; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Localization; using Microsoft.Extensions.DependencyInjection; namespace LocalizationApp { public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddLocalization(options => options.ResourcesPath = "Resources"); services.AddControllersWithViews(); } public void Configure(IApplicationBuilder app) { app.UseDeveloperExceptionPage(); var supportedCultures = new[] { new CultureInfo("en"), new CultureInfo("ru"), new CultureInfo("de") }; app.UseRequestLocalization(new RequestLocalizationOptions { DefaultRequestCulture = new RequestCulture("ru"), SupportedCultures = supportedCultures, SupportedUICultures = supportedCultures }); app.UseStaticFiles(); app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); } } }
Ключевым моментом здесь является добавление сервисов локализации в методе ConfigureServices:
services.AddLocalization(options => options.ResourcesPath = "Resources");
Свойство options.ResourcesPath здесь указывает на каталог, где размещаются ресурсы. В нашем случае это папка Resources.
Используем эти ресурсы в контроллере HomeController:
using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Localization; namespace LocalizationApp.Controllers { public class HomeController : Controller { private readonly IStringLocalizer<HomeController> _localizer; public HomeController(IStringLocalizer<HomeController> localizer) { _localizer = localizer; } public IActionResult Index() { ViewData["Title"] = _localizer["Header"]; ViewData["Message"] = _localizer["Message"]; return View(); } } }
Сервис IStringLocalizer добавляется вместе с другими сервисами локализации, мы его можем использовать для получения значений. Только в отличие от прошлой темы, где все ресурсы были жестко определены в коде, теперь IStringLocalizer будет извлекать ресурсы из файлов ресурсов.
Также стоит отметить, что теперь объект IStringLocalizer должен типизироваться типом, для которого он используется, то есть типом HomeController.
Для теста пусть в представлении выводятся значения из ViewData:
<h1>@ViewData["Title"]</h1> <h3>@ViewData["Message"]</h3>
Запустим приложение и передадим ему англоязычную культуру: