Nastavení lokalizovatelného obsahu aplikace ASP.NET Core

Hisham Bin Ateya, Damien Bowden, Bart Calixto a Nadeem Afana

Jednou z úloh lokalizace aplikace je zabalení lokalizovatelného obsahu kódem, který usnadňuje nahrazení obsahu pro různé jazykové verze.

IStringLocalizer

IStringLocalizer byly IStringLocalizer<T> navrženy tak, aby zlepšily produktivitu při vývoji lokalizovaných aplikací. IStringLocalizerResourceManager používá prostředky ResourceReader specifické pro jazykovou verzi za běhu. Rozhraní má indexer a pro IEnumerable vrácení lokalizovaných řetězců. IStringLocalizer nevyžaduje uložení výchozích řetězců jazyka do souboru prostředků. Můžete vyvíjet aplikaci určenou pro lokalizaci a nemusíte vytvářet soubory prostředků v rané fázi vývoje.

Následující příklad kódu ukazuje, jak zabalit řetězec "About Title" pro lokalizaci.

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;

namespace Localization.Controllers;

[Route("api/[controller]")]
public class AboutController : Controller
{
    private readonly IStringLocalizer<AboutController> _localizer;

    public AboutController(IStringLocalizer<AboutController> localizer)
    {
        _localizer = localizer;
    }

    [HttpGet]
    public string Get()
    {
        return _localizer["About Title"];
    }
}

V předchozím kódu IStringLocalizer<T> pochází implementace z injektáže závislostí. Pokud se lokalizovaná hodnota "O názvu" nenajde, vrátí se klíč indexeru, tj. řetězec "O názvu".

V aplikaci můžete ponechat výchozí řetězce literálů jazyka a zabalit je do lokalizátoru, abyste se mohli soustředit na vývoj aplikace. Aplikaci vyvíjíte s výchozím jazykem a připravíte ji na krok lokalizace, aniž byste nejdřív vytvořili výchozí soubor prostředků.

Případně můžete použít tradiční přístup a zadat klíč k načtení výchozího řetězce jazyka. Pro mnoho vývojářů může nový pracovní postup, který nemá výchozí soubor .resx jazyka a jednoduše zabalit řetězcové literály, snížit režii při lokalizaci aplikace. Jiní vývojáři dávají přednost tradičnímu pracovnímu postupu, protože může být jednodušší pracovat s dlouhými řetězcovými literály a snadněji aktualizovat lokalizované řetězce.

IHtmlLocalizer

Použijte implementaci IHtmlLocalizer<TResource> pro prostředky, které obsahují kód HTML. IHtmlLocalizer Kóduje argumenty ve formátu HTML, které jsou formátovány v řetězci prostředku, ale nezakóduje samotný řetězec prostředku HTML. V následujícím zvýrazněném kódu je pouze hodnota parametru name zakódovaná ve formátu HTML.

using System;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Localization;

namespace Localization.Controllers;

public class BookController : Controller
{
    private readonly IHtmlLocalizer<BookController> _localizer;

    public BookController(IHtmlLocalizer<BookController> localizer)
    {
        _localizer = localizer;
    }

    public IActionResult Hello(string name)
    {
        ViewData["Message"] = _localizer["<b>Hello</b><i> {0}</i>", name];

        return View();
    }

POZNÁMKA: Obecně platí, že pouze lokalizovat text, nikoli HTML.

IStringLocalizerFactory

Na nejnižší úrovni IStringLocalizerFactory lze načíst z injektáže závislostí:

public class TestController : Controller
{
    private readonly IStringLocalizer _localizer;
    private readonly IStringLocalizer _localizer2;

    public TestController(IStringLocalizerFactory factory)
    {
        var type = typeof(SharedResource);
        var assemblyName = new AssemblyName(type.GetTypeInfo().Assembly.FullName);
        _localizer = factory.Create(type);
        _localizer2 = factory.Create("SharedResource", assemblyName.Name);
    }       

    public IActionResult About()
    {
        ViewData["Message"] = _localizer["Your application description page."] 
            + " loc 2: " + _localizer2["Your application description page."];

        return View();
    }

Předchozí kód ukazuje každou ze dvou metod vytvoření továrny.

Sdílené prostředky

Lokalizované řetězce můžete rozdělit podle kontroleru nebo oblasti nebo mít pouze jeden kontejner. V ukázkové aplikaci se pro sdílené prostředky používá třída značky s názvem SharedResource . Třída značky se nikdy nevolá:

// Dummy class to group shared resources

namespace Localization;

public class SharedResource
{
}

V následující ukázce InfoController se používají lokalizátory:SharedResource

public class InfoController : Controller
{
    private readonly IStringLocalizer<InfoController> _localizer;
    private readonly IStringLocalizer<SharedResource> _sharedLocalizer;

    public InfoController(IStringLocalizer<InfoController> localizer,
                   IStringLocalizer<SharedResource> sharedLocalizer)
    {
        _localizer = localizer;
        _sharedLocalizer = sharedLocalizer;
    }

    public string TestLoc()
    {
        string msg = "Shared resx: " + _sharedLocalizer["Hello!"] +
                     " Info resx " + _localizer["Hello!"];
        return msg;
    }

Zobrazit lokalizaci

Služba IViewLocalizer poskytuje lokalizované řetězce pro zobrazení. Třída ViewLocalizer implementuje toto rozhraní a najde umístění prostředku z cesty k souboru zobrazení. Následující kód ukazuje, jak použít výchozí implementaci IViewLocalizer:

@using Microsoft.AspNetCore.Mvc.Localization

@inject IViewLocalizer Localizer

@{
    ViewData["Title"] = Localizer["About"];
}
<h2>@ViewData["Title"].</h2>
<h3>@ViewData["Message"]</h3>

<p>@Localizer["Use this area to provide additional information."]</p>

Výchozí implementace IViewLocalizer najde soubor prostředků na základě názvu souboru zobrazení. Není možné použít globální sdílený soubor prostředků. ViewLocalizer implementuje lokalizátor pomocí IHtmlLocalizer, takže Razor html kóduje lokalizovaný řetězec. Můžete parametrizovat řetězce prostředků a IViewLocalizer html kóduje parametry, ale ne řetězec prostředku. Vezměte v úvahu následující Razor kód:

@Localizer["<i>Hello</i> <b>{0}!</b>", UserManager.GetUserName(User)]

Soubor francouzského prostředku může obsahovat následující hodnoty:

Key Hodnota
<i>Hello</i> <b>{0}!</b> <i>Bonjour</i> <b>{0} !</b>

Vykreslené zobrazení by obsahovalo kód HTML ze souboru prostředků.

Obecně platí, že pouze lokalizujete text, nikoli HTML.

Pokud chcete použít sdílený soubor prostředků v zobrazení, zadejte IHtmlLocalizer<T>:

@using Microsoft.AspNetCore.Mvc.Localization
@using Localization.Services

@inject IViewLocalizer Localizer
@inject IHtmlLocalizer<SharedResource> SharedLocalizer

@{
    ViewData["Title"] = Localizer["About"];
}
<h2>@ViewData["Title"].</h2>

<h1>@SharedLocalizer["Hello!"]</h1>

Lokalizace dataAnnotations

Chybové zprávy DataAnnotations jsou lokalizovány s IStringLocalizer<T>. Pomocí této možnosti ResourcesPath = "Resources"lze chybové zprávy uložit do RegisterViewModel některé z následujících cest:

  • Prostředky/ViewModels.Account.RegisterViewModel.fr.resx
  • Prostředky/ ViewModels/Account/RegisterViewModel.fr.resx
using System.ComponentModel.DataAnnotations;

namespace Localization.ViewModels.Account;

public class RegisterViewModel
{
    [Required(ErrorMessage = "The Email field is required.")]
    [EmailAddress(ErrorMessage = "The Email field is not a valid email address.")]
    [Display(Name = "Email")]
    public string Email { get; set; }

    [Required(ErrorMessage = "The Password field is required.")]
    [StringLength(8, ErrorMessage = "The {0} must be at least {2} characters long.",
                                                                 MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Confirm password")]
    [Compare("Password", ErrorMessage =
                            "The password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }
}

Atributy bez ověření jsou lokalizovány.

Použití jednoho řetězce prostředků pro více tříd

Následující kód ukazuje, jak použít jeden řetězec prostředku pro ověřovací atributy s více třídami:

    services.AddMvc()
        .AddDataAnnotationsLocalization(options => {
            options.DataAnnotationLocalizerProvider = (type, factory) =>
                factory.Create(typeof(SharedResource));
        });

V předchozím kódu je třída odpovídající souboru .resx, SharedResource kde jsou uloženy ověřovací zprávy. Při tomto přístupu dataAnnotations používá SharedResourcemísto prostředku pro každou třídu pouze prostředek.

Konfigurace lokalizačních služeb

Lokalizační služby jsou nakonfigurované v Program.cs:

builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");

builder.Services.AddMvc()
    .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
    .AddDataAnnotationsLocalization();
  • AddLocalization přidá lokalizační služby do kontejneru služeb, včetně implementací pro IStringLocalizer<T> a IStringLocalizerFactory. Předchozí kód také nastaví cestu k prostředkům na "Resources".

  • AddViewLocalization přidává podporu lokalizovaných souborů zobrazení. V této ukázce je lokalizace zobrazení založená na příponě souboru zobrazení. Například "fr" v Index.fr.cshtml souboru.

  • AddDataAnnotationsLocalization přidává podporu lokalizovaných DataAnnotations ověřovacích zpráv prostřednictvím IStringLocalizer abstrakcí.

Poznámka:

V desetinných polích možná nebudete moct zadávat desetinné čárky. Pokud chcete podporovat ověřování jQuery pro neanglické národní prostředí, které používají čárku (",") pro desetinnou čárku a jiné formáty kalendářních dat než v angličtině, musíte provést kroky ke globalizaci aplikace. Pokyny k přidání desetinné čárky najdete v tomto komentáři GitHubu 4076 .

Další kroky

Lokalizace aplikace zahrnuje také následující úlohy:

Další materiály

Rick Anderson, Damien Bowden, Bart Calixto, Nadeem Afana a Hisham Bin Ateya

Jednou z úloh lokalizace aplikace je zabalení lokalizovatelného obsahu kódem, který usnadňuje nahrazení obsahu pro různé jazykové verze.

IStringLocalizer

IStringLocalizer byly IStringLocalizer<T> navrženy tak, aby zlepšily produktivitu při vývoji lokalizovaných aplikací. IStringLocalizerResourceManager používá prostředky ResourceReader specifické pro jazykovou verzi za běhu. Rozhraní má indexer a pro IEnumerable vrácení lokalizovaných řetězců. IStringLocalizer nevyžaduje uložení výchozích řetězců jazyka do souboru prostředků. Můžete vyvíjet aplikaci určenou pro lokalizaci a nemusíte vytvářet soubory prostředků v rané fázi vývoje.

Následující příklad kódu ukazuje, jak zabalit řetězec "About Title" pro lokalizaci.

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;

namespace Localization.Controllers
{
    [Route("api/[controller]")]
    public class AboutController : Controller
    {
        private readonly IStringLocalizer<AboutController> _localizer;

        public AboutController(IStringLocalizer<AboutController> localizer)
        {
            _localizer = localizer;
        }

        [HttpGet]
        public string Get()
        {
            return _localizer["About Title"];
        }
    }
}

V předchozím kódu IStringLocalizer<T> pochází implementace z injektáže závislostí. Pokud se lokalizovaná hodnota "O názvu" nenajde, vrátí se klíč indexeru, tj. řetězec "O názvu".

V aplikaci můžete ponechat výchozí řetězce literálů jazyka a zabalit je do lokalizátoru, abyste se mohli soustředit na vývoj aplikace. Aplikaci vyvíjíte s výchozím jazykem a připravíte ji na krok lokalizace, aniž byste nejdřív vytvořili výchozí soubor prostředků.

Případně můžete použít tradiční přístup a zadat klíč k načtení výchozího řetězce jazyka. Pro mnoho vývojářů může nový pracovní postup, který nemá výchozí soubor .resx jazyka a jednoduše zabalit řetězcové literály, snížit režii při lokalizaci aplikace. Jiní vývojáři dávají přednost tradičnímu pracovnímu postupu, protože může být jednodušší pracovat s dlouhými řetězcovými literály a snadněji aktualizovat lokalizované řetězce.

IHtmlLocalizer

Použijte implementaci IHtmlLocalizer<T> pro prostředky, které obsahují kód HTML. IHtmlLocalizer Kóduje argumenty ve formátu HTML, které jsou formátovány v řetězci prostředku, ale nezakóduje samotný řetězec prostředku HTML. V následujícím zvýrazněném kódu je pouze hodnota parametru name zakódovaná ve formátu HTML.

using System;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Localization;

namespace Localization.Controllers
{
    public class BookController : Controller
    {
        private readonly IHtmlLocalizer<BookController> _localizer;

        public BookController(IHtmlLocalizer<BookController> localizer)
        {
            _localizer = localizer;
        }

        public IActionResult Hello(string name)
        {
            ViewData["Message"] = _localizer["<b>Hello</b><i> {0}</i>", name];

            return View();
        }

Poznámka:

Obecně platí, že pouze lokalizujete text, nikoli HTML.

IStringLocalizerFactory

Na nejnižší úrovni se můžete IStringLocalizerFactory dostat z injektáže závislostí:

{
    public class TestController : Controller
    {
        private readonly IStringLocalizer _localizer;
        private readonly IStringLocalizer _localizer2;

        public TestController(IStringLocalizerFactory factory)
        {
            var type = typeof(SharedResource);
            var assemblyName = new AssemblyName(type.GetTypeInfo().Assembly.FullName);
            _localizer = factory.Create(type);
            _localizer2 = factory.Create("SharedResource", assemblyName.Name);
        }       

        public IActionResult About()
        {
            ViewData["Message"] = _localizer["Your application description page."] 
                + " loc 2: " + _localizer2["Your application description page."];

Předchozí kód ukazuje každou ze dvou metod vytvoření továrny.

Sdílené prostředky

Lokalizované řetězce můžete rozdělit podle kontroleru nebo oblasti nebo mít pouze jeden kontejner. V ukázkové aplikaci se pro sdílené prostředky používá fiktivní třída s názvem SharedResource .

// Dummy class to group shared resources

namespace Localization
{
    public class SharedResource
    {
    }
}

Někteří vývojáři používají Startup třídu k zahrnutí globálních nebo sdílených řetězců. V následující ukázce InfoController se používají lokalizátory:SharedResource

public class InfoController : Controller
{
    private readonly IStringLocalizer<InfoController> _localizer;
    private readonly IStringLocalizer<SharedResource> _sharedLocalizer;

    public InfoController(IStringLocalizer<InfoController> localizer,
                   IStringLocalizer<SharedResource> sharedLocalizer)
    {
        _localizer = localizer;
        _sharedLocalizer = sharedLocalizer;
    }

    public string TestLoc()
    {
        string msg = "Shared resx: " + _sharedLocalizer["Hello!"] +
                     " Info resx " + _localizer["Hello!"];
        return msg;
    }

Zobrazit lokalizaci

Služba IViewLocalizer poskytuje lokalizované řetězce pro zobrazení. Třída ViewLocalizer implementuje toto rozhraní a najde umístění prostředku z cesty k souboru zobrazení. Následující kód ukazuje, jak použít výchozí implementaci IViewLocalizer:

@using Microsoft.AspNetCore.Mvc.Localization

@inject IViewLocalizer Localizer

@{
    ViewData["Title"] = Localizer["About"];
}
<h2>@ViewData["Title"].</h2>
<h3>@ViewData["Message"]</h3>

<p>@Localizer["Use this area to provide additional information."]</p>

Výchozí implementace IViewLocalizer najde soubor prostředků na základě názvu souboru zobrazení. Není možné použít globální sdílený soubor prostředků. ViewLocalizer implementuje lokalizátor pomocí IHtmlLocalizer, takže Razor html kóduje lokalizovaný řetězec. Můžete parametrizovat řetězce prostředků a IViewLocalizer html kóduje parametry, ale ne řetězec prostředku. Vezměte v úvahu následující Razor kód:

@Localizer["<i>Hello</i> <b>{0}!</b>", UserManager.GetUserName(User)]

Soubor francouzského prostředku může obsahovat následující hodnoty:

Key Hodnota
<i>Hello</i> <b>{0}!</b> <i>Bonjour</i> <b>{0} !</b>

Vykreslené zobrazení by obsahovalo kód HTML ze souboru prostředků.

Poznámka:

Obecně platí, že pouze lokalizujete text, nikoli HTML.

Pokud chcete použít sdílený soubor prostředků v zobrazení, zadejte IHtmlLocalizer<T>:

@using Microsoft.AspNetCore.Mvc.Localization
@using Localization.Services

@inject IViewLocalizer Localizer
@inject IHtmlLocalizer<SharedResource> SharedLocalizer

@{
    ViewData["Title"] = Localizer["About"];
}
<h2>@ViewData["Title"].</h2>

<h1>@SharedLocalizer["Hello!"]</h1>

Lokalizace dataAnnotations

Chybové zprávy DataAnnotations jsou lokalizovány s IStringLocalizer<T>. Pomocí této možnosti ResourcesPath = "Resources"lze chybové zprávy uložit do RegisterViewModel některé z následujících cest:

  • Prostředky/ViewModels.Account.RegisterViewModel.fr.resx
  • Prostředky/ ViewModels/Account/RegisterViewModel.fr.resx
public class RegisterViewModel
{
    [Required(ErrorMessage = "The Email field is required.")]
    [EmailAddress(ErrorMessage = "The Email field is not a valid email address.")]
    [Display(Name = "Email")]
    public string Email { get; set; }

    [Required(ErrorMessage = "The Password field is required.")]
    [StringLength(8, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Confirm password")]
    [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }
}

V ASP.NET Core MVC 1.1.0 a novějších se lokalizují atributy bez ověření.

Použití jednoho řetězce prostředků pro více tříd

Následující kód ukazuje, jak použít jeden řetězec prostředku pro ověřovací atributy s více třídami:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc()
        .AddDataAnnotationsLocalization(options => {
            options.DataAnnotationLocalizerProvider = (type, factory) =>
                factory.Create(typeof(SharedResource));
        });
}

V předchozím kódu je třída odpovídající souboru .resx, SharedResource kde jsou uloženy ověřovací zprávy. Při tomto přístupu dataAnnotations používá SharedResourcemísto prostředku pro každou třídu pouze prostředek.

Konfigurace lokalizačních služeb

Lokalizační služby se konfigurují v Startup.ConfigureServices metodě:

services.AddLocalization(options => options.ResourcesPath = "Resources");

services.AddMvc()
    .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
    .AddDataAnnotationsLocalization();
  • AddLocalization přidá lokalizační služby do kontejneru služeb, včetně implementací pro IStringLocalizer<T> a IStringLocalizerFactory. Předchozí kód také nastaví cestu k prostředkům na "Resources".

  • AddViewLocalization přidává podporu lokalizovaných souborů zobrazení. V této ukázce je lokalizace zobrazení založená na příponě souboru zobrazení. Například "fr" v Index.fr.cshtml souboru.

  • AddDataAnnotationsLocalization přidává podporu lokalizovaných DataAnnotations ověřovacích zpráv prostřednictvím IStringLocalizer abstrakcí.

Poznámka:

V desetinných polích možná nebudete moct zadávat desetinné čárky. Pokud chcete podporovat ověřování jQuery pro neanglické národní prostředí, které používají čárku (",") pro desetinnou čárku a jiné formáty kalendářních dat než v angličtině, musíte provést kroky ke globalizaci aplikace. Pokyny k přidání desetinné čárky najdete v tomto komentáři GitHubu 4076 .

Další kroky

Lokalizace aplikace zahrnuje také následující úlohy:

Další materiály