Глобализация и локализация

Определение культуры

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

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

Культура в ASP.NET Core, как и в целом в .NET, определяется объектом класса CultureInfo, который находится в пространстве имен System.Globalization. Объект CultureInfo определяет функционал, который зависит от культурного контекста, например, форматирование дат, времени, чисел, валюты, работа с календарем. И при запуске приложения каждый поток в .NET определяет два объекта: CultureInfo.CurrentCulture - текущую языковую культуру и CultureInfo.CurrentUICulture - языковая культура для пользовательского интерфейса. ASP.NET Core использует эти свойства для рендеринга значений, которые зависят от настройки культуры. Например, в зависимости от культуры может меняться отображение даты и времени.

Каждая культура описывается в специальном формате RFC 4646, который позволяет представить культуру в виде:

культура-субкультура

Здесь "культура" представляет двузначный код ISO 639 в нижнем регистре, который ассоциирован с определенным языком. Например, "de" - немецкий язык или "es" - испанский. После дефиса идет второй параметр - "субкультура", который представляет код ISO 3166 в верхнем регистре, ассоциированный со страной или регионом. Например, английский язык в США и английский в Великобритании имеют свои особенности, поэтому для них существуют разные коды: "en-US" и "en-GB". Но если нам не важны региональные особенности, связанные с определенным языком, то мы можем представить культуру с помощью одного кода ISO 639, например, "en".

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

Вначале просто рассмотрим процесс получения и установки культуры. Для этого возьмем проект ASP.NET Core по типу ASP.NET Core Web App (Model-View-Controller) и определим в нем следующий контроллер:

using System;
using Microsoft.AspNetCore.Mvc;
using System.Globalization;

namespace LocalizationApp.Controllers
{
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }

        public string GetCulture(string code = "")
        {
            if (!String.IsNullOrEmpty(code))
            {
                CultureInfo.CurrentCulture = new CultureInfo(code);
                CultureInfo.CurrentUICulture = new CultureInfo(code);
            }
            return $"CurrentCulture:{CultureInfo.CurrentCulture.Name}, CurrentUICulture:{CultureInfo.CurrentUICulture.Name}";
        }
    }
}

Метод GetCulture принимает в виде параметра код и с его помощью устанавливает текущую культуру. Затем установленные значения выводятся в браузере.

Если методу GetCulture не передать параметра code, то он будет использовать культуру по умолчанию:

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

Изменим текущую культуру на немецкоязычную, то есть на "de":

CultureInfo.CurrentCulture в ASP.NET Core

Как мы видим, получение и установка культуры не вызывают никакой сложности. И мы вполне можем написать свой компонент middleware, который сможет взять тот же код, который передается методу GetCulture, из различных источников - куки, сессии, строки запроса, отправленных форм и т.д., и установить культуру.

Например, добавим в проект новый класс, который назовем CultureMiddleware:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using System.Globalization;
using System.Threading.Tasks;

namespace LocalizationApp
{
    public class CultureMiddleware
    {
        private readonly RequestDelegate _next;

        public CultureMiddleware(RequestDelegate next)
        {
            this._next = next;
        }

        public async Task Invoke(HttpContext context)
        {
            var lang = context.Request.Query["lang"].ToString();
            if (!string.IsNullOrEmpty(lang))
            {
                try
                {
                    CultureInfo.CurrentCulture = new CultureInfo(lang);
                    CultureInfo.CurrentUICulture = new CultureInfo(lang);
                }
                catch (CultureNotFoundException) { }
            }
            await _next.Invoke(context);
        }
    }

    public static class CultureExtensions
    {
        public static IApplicationBuilder UseCulture(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<CultureMiddleware>();
        }
    }
}

Этот компонент получает из строки запроса параметр lang и использует его значение для установки культуры. Но кроме параметров мы можем использовать множество других источников для установки культуры - куки, сессии, кэш, данные отправленных форм, какие-то другие хранилища.

Для упрощения его внедрения в конвейер определен метод расширения UseCulture.

Используем этот middleware в классе Startup:

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;

namespace LocalizationApp
{
    public class Startup
    {   
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
        }
        
        public void Configure(IApplicationBuilder app)
        {
            app.UseDeveloperExceptionPage();

            app.UseCulture();

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

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

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

Установка культуры и локали в ASP.NET Core MVC
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850