Локализация в ASP.NET Core Razor Pages — Культуры

Автор оригинала: Mike Brind
  • Перевод

Привет, хабр! Прямо сейчас OTUS открывает набор на новый поток курса "C# ASP.NET Core разработчик". В связи с этим традиционно делимся с вами полезным переводом и приглашаем записаться на день открытых дверей, в рамках которого можно будет подробно узнать о курсе, а также задать эксперту интересующие вас вопросы.


Это первая статья из серии, посвященной локализации в ASP.NET Core Razor Pages приложениях. В этой статье мы рассмотрим конфигурацию, необходимую для подготовки сайта к локализации контента, или другими словами, для глобализации сайта. В следующих статьях я расскажу о создании локализованного контента и о том, как преподносить его конечному пользователю.

Глобализация в ASP.NET Core

Глобализация - это подготовка приложения к поддержке различных языков в зависимости от предпочтений пользователя. Локализация - это процесс адаптации контента сайта под разные страны, регионы или культуры. Отправной точкой в глобализации веб-приложения является способность определять язык или культуру для каждого запроса. Далее нам потребуется механизм для выбора контента на основе культуры текущего запроса. В этой статье мы рассмотрим роль, которую играет класс CultureInfo в локализации, и то, как можно реализовать компонент представления, чтобы пользователи могли выбирать для запросов предпочтительную для них культуру.

Приведенные ниже шаги добавляют базовую локализацию к Razor Pages приложению, которое создается из стандартного шаблона веб-приложения ASP.NET Core 3.0 без настроенной аутентификации. Я назвал свое приложение «Localisation». Свое вы можете назвать как вам угодно, но в таком случае не забудьте про пространства имен, если будете копировать код из этой статьи.

1. Начните с открытия файла Startup.cs и добавления туда следующих using директив:

using System.Globalization;
using Microsoft.AspNetCore.Localization;
using Microsoft.Extensions.Options;

2. Локализация - это дополнительная фича. По умолчанию она не включена. Измените метод ConfigureServices, включив AddLocalization, что сделает различные вспомогательные сервисы локализации доступными для системы инжекции зависимостей. Затем добавьте следующий код для конфигурации RequestLocalizationOptions в приложении.

services.Configure<RequestLocalizationOptions>(options =>
{
   var supportedCultures = new[]
    {
        new CultureInfo("en"),
        new CultureInfo("de"),
        new CultureInfo("fr"),
        new CultureInfo("es"),
        new CultureInfo("ru"),
        new CultureInfo("ja"),
        new CultureInfo("ar"),
        new CultureInfo("zh"),
        new CultureInfo("en-GB")
    };
    options.DefaultRequestCulture = new RequestCulture("en-GB");
    options.SupportedCultures = supportedCultures;
    options.SupportedUICultures = supportedCultures;
});

Вам необходимо указать языки или культуры, которые вы планируете поддерживать в своем приложении. Культуры представлены в .NET классом CultureInfo, который содержит информацию о форматировании чисел и дат, календарях, системах письма, порядках сортировки и других вопросах, зависящих от местности проживания конечного пользователя. Перегрузка конструктора класса CultureInfo, используемого здесь, принимает строку, представляющую имя языка и региональных параметров (культуры). Допустимые значения - это коды ISO 639-1, которые представляют язык (например, «en» для английского языка), с необязательным кодом субкультуры ISO 3166, который представляет страну или диалект (например, «en-GB» для Великобритании или «en-ZA» для Южной Африки). В приведенном выше примере поддерживается несколько языков, включая одну субкультуру - британский английский, который был установлен в качестве культуры по умолчанию.

3. Теперь, когда RequestLocalizationOptions настроены, их можно применить к промежуточной прослойке локализации запросов, которую необходимо добавить в метод Configure после app.UseRouting():

app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();

var localizationOptions = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>().Value;
app.UseRequestLocalization(localizationOptions);

Установка культуры запроса

Для определения культуры текущего запроса промежуточный слой локализации запросов используются компоненты, называемые RequestCultureProviders. Три из них добавляются по умолчанию:

  • QueryStringRequestCultureProvider, который получает культуру из строки запроса

  • CookieRequestCultureProvider, который получает культуру из файла cookie

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

1. Первый шаг - создать папку с именем Models и добавить в нее файл класса с именем CultureSwitcherModel.cs.

using System.Collections.Generic;
using System.Globalization;
 
namespace Localisation.Models
{
    public class CultureSwitcherModel
    {
        public CultureInfo CurrentUICulture { get; set; }
        public List<CultureInfo> SupportedCultures { get; set; }
    }
}

2. Добавьте в проект папку с именем ViewComponents и в нее добавьте новый файл класса C# с именем CultureSwitcherViewcomponent.cs. Затем замените содержимое на следующий код:

using Localisation.Models;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using System.Linq;
 
namespace Localisation.ViewComponents
{
    public class CultureSwitcherViewComponent : ViewComponent
    {
        private readonly IOptions<RequestLocalizationOptions> localizationOptions;
        public CultureSwitcherViewComponent(IOptions<RequestLocalizationOptions> localizationOptions) =>
            this.localizationOptions = localizationOptions;
 
        public IViewComponentResult Invoke()
        {
            var cultureFeature = HttpContext.Features.Get<IRequestCultureFeature>();
            var model = new CultureSwitcherModel
            {
                SupportedCultures = localizationOptions.Value.SupportedUICultures.ToList(),
                CurrentUICulture = cultureFeature.RequestCulture.UICulture
            };
            return View(model);
        }
    }
}

3. Добавьте новую папку в папку Pages и назовите ее Components. Внутри добавьте еще одну папку с именем CultureSwitcher. Затем добавьте Razor View в default.cshtml и замените существующее содержимое следующим:

@model CultureSwitcherModel
 
<div>
    <form id="culture-switcher">
        <select name="culture" id="culture-options">
            <option></option>
            @foreach (var culture in Model.SupportedCultures)
            {
                <option value="@culture.Name" selected="@(Model.CurrentUICulture.Name == culture.Name)">@culture.DisplayName</option>
            }
        </select>
    </form>
</div>
 
 
<script>
    document.getElementById("culture-options").addEventListener("change", () => {
        document.getElementById("culture-switcher").submit();
    });
</script>

Компонент представления - это простой select элемент, заполненный поддерживаемыми культурами, которые были настроены в Startup. Представление, в котором он находится, использует дефолтный get метод, что означает, что отправленное значение появится в строке запроса с именем culture. QueryStringRequestCultureProvider предназначен для поиска элемента в строке запроса по ключа culture (и/или ui-culture).

CurrentCulture для запроса определяет местное форматирование которое будет использоваться для таких вещей как даты и числа. CurrentUICulture используется, чтобы выбрать правильный ресурс, содержащий переведенные строки. В следующей статье этой серии я рассмотрю, как использовать ресурсные файлы для локализации статического контента. Для CurrentCulture и CurrentUICulture можно установить разные значения, но чаще имеет смысл, чтобы оба эти значения совпадали. Если установлено только одно из них (например, через одно значение строки запроса), то значение присваивается обоим свойствам.

4. На этом этапе у вас, вероятно, у вас появилось несколько красных волнистых линий в только что созданном представлении - откройте файл  _ViewImports.cshtml и добавьте вторую и третью директивы using, приведенные ниже, вместе с последней строкой, которая позволяет вам использовать tag-хелпер для рендеринга компонент представления:

@using Localisation
@using Localisation.Models
@using System.Globalization
@namespace Localisation.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, Localisation

5. Включите компонент переключателя культуры на страницу макета, используя подход с tag-хелпером, как показано здесь в последней строке.

<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
    <ul class="navbar-nav flex-grow-1">
        <li class="nav-item">
            <a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
        </li>
        <li class="nav-item">
            <a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
        </li>
    </ul>
</div>
<vc:culture-switcher/>

6. Измените Index.cshtml, включив код в блок кода и HTML-код для таблицы, которая отображает различные биты данных:

@page
@using Microsoft.AspNetCore.Localization
@model IndexModel
@{
    ViewData["Title"] = "Home page";
    var requestCultureFeature = HttpContext.Features.Get<IRequestCultureFeature>();
    var requestCulture = requestCultureFeature.RequestCulture;
}
 
<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
 
    <table class="table culture-table">
        <tr>
            <td style="width:50%;">Culture</td>
            <td>@requestCulture.Culture.DisplayName {@requestCulture.Culture.Name}</td>
        </tr>
        <tr>
            <td>UI Culture</td>
            <td>@requestCulture.UICulture.Name</td>
        </tr>
        <tr>
            <td>UICulture Parent</td>
            <td>@requestCulture.UICulture.Parent</td>
        </tr>
        <tr>
            <td>Date</td>
            <td>@DateTime.Now.ToLongDateString()</td>
        </tr>
        <tr>
            <td>Currency</td>
            <td>
                @(12345.00.ToString("c"))
            </td>
        </tr>
        <tr>
            <td>Number</td>
            <td>
                @(123.45m.ToString("F2"))
            </td>
        </tr>
    </table>
</div>

При первом запуске приложения культура для запроса задается AcceptHeadersCultureRequestProvider. Когда вы используете раскрывающийся список для выбора разных культур, культура задается QueryStringCultureRequestProvider. Попробуйте добавить ключ ui-culture в строку запроса с другим значением ключа culture (например, https://localhost:xxxxx/?culture=es&ui-culture=de), чтобы посмотреть, что произойдет.

Резюме

Эта статья представляет собой введение в локализацию в Razor Pages. В ней приведен пример конфигурации культур, которые вы хотите поддерживать в своем приложении, и то, как передать эту конфигурацию промежуточному слою локализации. Она демонстрирует, как культура для текущего запроса работает с точки зрения форматирования содержимого для отображения. Она также демонстрирует, как вы можете позволить своим посетителям изменить культуру в соответствии с их предпочтениями.

Вы могли заметить, что, хотя названия дней и месяцев переводятся автоматически на основе календаря, связанного с текущей культурой, остальное статическое содержимое остается на английском языке. В следующей статье я покажу, как использовать ресурсные файлы (.resx) для управления несколькими переводами для этого типа контента.


Подробнее о курсе.


Читать ещё:

OTUS. Онлайн-образование
Цифровые навыки от ведущих экспертов

Похожие публикации

Комментарии 0

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое