Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core 7
Ранее мы рассмотрели, как в ASP.NET Core устанавливать культуру в приложении. В частности, при использовании RequestLocalizationMiddleware мы можем задействовать для установки культуры три механизма: параметры строки запроса, куки и заголовок accept-language. Используем куки для установки культуры. Для этого определим в контроллере специальный метод SetLanguage:
using System; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Localization; using Microsoft.AspNetCore.Mvc; namespace LocalizationApp.Controllers { public class HomeController : Controller { public IActionResult Index() { return View(); } [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); } } }
Этот метод в качестве параметров принимает код устанавливаемой культуры и адрес, на который надо вернуться после установки культуры.
В самом методе происходит установка куки с помощью метода Response.Cookies.Append
. При рассмотрении RequestLocalizationMiddleware упоминалось,
что куки, применяемая для локализации, по умолчанию имеет имя ".AspNetCore.Culture" и формат "c=%LANGCODE%|uic=%LANGCODE%". И мы могли бы написать:
Response.Cookies.Append(".AspNetCore.Culture", "c=ru|uic=ru");
Но в данном случае мы используем методы провайдера CookieRequestCultureProvider.
Непосредственно для установки культуры на уровне пользовательского интерфейса определим выпадающий список, в котором пользователь из списка доступных языков сможет выбрать нужный. Для этой цели создадим частичное представление в папке Views/Shared, которое пусть называется _SelectLanguagePartial.cshtml, и определим в нем следующий код:
@using Microsoft.AspNetCore.Builder @using Microsoft.AspNetCore.Localization @using Microsoft.AspNetCore.Mvc.Localization @using Microsoft.Extensions.Options @inject IViewLocalizer Localizer @inject IOptions<RequestLocalizationOptions> LocOptions @{ // получаем сервис IRequestCultureFeature var requestCulture = Context.Features.Get<IRequestCultureFeature>(); // получаем список поддерживаемых культур var cultureItems = LocOptions.Value.SupportedUICultures .Select(c => new SelectListItem { Value = c.Name, Text = c.NativeName }) .ToList(); } <form asp-controller="Home" asp-action="SetLanguage" style="margin-top:20px;" asp-route-returnUrl="@Context.Request.Path" method="post" class="form-horizontal"> Language: <select name="culture" onchange="this.form.submit();" asp-for="@requestCulture.RequestCulture.UICulture.Name" asp-items="cultureItems"></select> </form>
С помощью объекта IOptions<RequestLocalizationOptions> получаем список поддерживаемых культур и создаем из них список, который потом передается в элемент select для построения выпадающего списка.
Также получаем сервис IRequestCultureFeature, который позволяет получить текущую культуру.
Далее встроим это представление на мастер-станицу _Layout.cshtml, например, где нибудь вверху перед основным содержанием:
<div class="container body-content"> <div> @await Html.PartialAsync("_SelectLanguagePartial") </div> @RenderBody()
В частичном представлении "_SelectLanguagePartial.cshtml" мы получаем объект IOptions<RequestLocalizationOptions>, который необходим для построения списка доступных языков. Однако на данный момент этот объект пока еще нигде не определяется и не передается в приложение. Поэтому изменим класс 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() .AddViewLocalization(); services.Configur<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?}"); }); } } }
В методе ConfigureServices()
с помощью вызова services.Configure()
устанавливается объект RequestLocalizationOptions,
который затем мы сможем получить в классах приложения. В частности, этому объекту передается список поддерживаемых культур и культура по умолчанию.
Через менахизм DependencyInjection этот объект будет передаваться в RequestLocalizationMiddleware.
Для динамического переключения языков все готово. Теперь мы можем протестировать этот функционал. Пусть в представлении Views/Home/Index.cshtml с помощью сервиса IViewLocalizer выводятся значения ресурсов:
@using Microsoft.AspNetCore.Mvc.Localization @inject IViewLocalizer Localizer <h1>@Localizer["Header"]</h1> <h3>@Localizer["Message"]</h3>
Пусть для этого представления в папке Resources будет определено несколько файлов ресурсов:
Каждый файл ресурсов определяет два ресурса Header и Message. Например, файл ресурсов для русскоязычной локали:
И файл для английского языка:
Запустим приложение и выберем из списка русский язык:
После выбора любого другого языка интерфейс переключится на нужную локаль, при условии если для нее имеются файл ресурсов. Например, переключимся на английский язык:
Таким образом, мы можем создать простейший механизм для переключения языков в приложении ASP.NET Core MVC.