Переключение языка приложения

Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core 7

Последнее обновление: 18.12.2019

Ранее мы рассмотрели, как в 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 будет определено несколько файлов ресурсов:

Динамическое переключение языков в ASP.NET Core

Каждый файл ресурсов определяет два ресурса Header и Message. Например, файл ресурсов для русскоязычной локали:

И файл для английского языка:

Запустим приложение и выберем из списка русский язык:

После выбора любого другого языка интерфейс переключится на нужную локаль, при условии если для нее имеются файл ресурсов. Например, переключимся на английский язык:

Таким образом, мы можем создать простейший механизм для переключения языков в приложении ASP.NET Core MVC.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850