Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core 7
В прошлых темах для каждой сущности использовались свои ресурсы: для представлений - одни, для контроллеров - другие, для атрибутов модели - третьи. Но также мы можем использовать и некоторые общие ресурсы для различных сущностей. Для этого добавим в корень проекта простой класс SharedResource:
public class SharedResource { }
Этот класс будет пустым.
Затем определим для него общие файлы ресурсов. Для этого в проекте в папку Resources добавим несколько файлов ресурсов для тех языков, которые мы хотим использовать. При этом названия файла ресурсов должны соответствовать пути к файлу SharedResource в рамках проекта. Поскольку этот класс находится в корне проекта, то файлы ресурсов будут иметь имя SharedResource.[код_культуры].resx. Путь к данным файлам ресурсов должен отражать путь к классу SharedResource внутри проекта (как и в случае с ресурсами для контроллеров и представлений).
Например, в моем случае это будут три файла:
SharedResource.ru.resx
SharedResource.en.resx
SharedResource.de.resx
Например, тестовый файл ресурсов для русскоязычной локали:
И тестовый файл для английского языка:
Теперь как мы эти ресурсы можем использовать в приложении? В контроллере мы можем передать данные ресурсы через конструктор посредством параметра типа IStringLocalizer<SharedResource>:
using LocalizationApp.ViewModels; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Localization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Localization; using System; namespace LocalizationApp.Controllers { public class HomeController : Controller { private readonly IStringLocalizer<HomeController> _localizer; private readonly IStringLocalizer<SharedResource> _sharedLocalizer; public HomeController(IStringLocalizer<HomeController> localizer, IStringLocalizer<SharedResource> sharedLocalizer) { _localizer = localizer; _sharedLocalizer = sharedLocalizer; } public string Test() { // получаем ресурс Message string message = _sharedLocalizer["Message"]; return message; } // остальное содержимое контроллера }
В представлении мы можем передать ресурсы через сервис типа IHtmlLocalizer<SharedResource>:
@using Microsoft.AspNetCore.Mvc.Localization @inject IViewLocalizer Localizer @inject IHtmlLocalizer<SharedResource> SharedLocalizer <h3>@SharedLocalizer["Message"]</h3>
Для применения ресурсов к аннотациям данных надо изменить вызов метода AddDataAnnotationsLocalization()
в классе 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() .AddDataAnnotationsLocalization(options => { options.DataAnnotationLocalizerProvider = (type, factory) => factory.Create(typeof(SharedResource)); }) .AddViewLocalization(); services.Configure<RequestLocalizationOptions>(options => { var supportedCultures = new[] { new CultureInfo("en"), new CultureInfo("de"), new CultureInfo("ru") }; options.DefaultRequestCulture = new RequestCulture("ru"); options.SupportedCultures = supportedCultures; options.SupportedUICultures = supportedCultures; }); } public void Configure(IApplicationBuilder app) { app.UseDeveloperExceptionPage(); app.UseRequestLocalization(); app.UseStaticFiles(); app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); } } }
Ключевым моментом здесь является создание объекта IStringLocalizer для ресурса SharedResource с помощью фабрики IStringLocalizerFactory в методе AddDataAnnotationsLocalization:
services.AddControllersWithViews() .AddDataAnnotationsLocalization(options => { options.DataAnnotationLocalizerProvider = (type, factory) => factory.Create(typeof(SharedResource)); })
Таким образом, мы охватим локализацией из общего ресурса контроллеры, представления и аннотации данных.
И если мы обратимся к выше указанному в контроллере действию Test и передадим ему определенную культуру, то он будет использовать соответствующие ресурсы: