Globalizacja i lokalizacja w ASP.NET CoreGlobalization and localization in ASP.NET Core

Rick Anderson, Damien Bowden, Bart Calixto, Nadeem Afanai Hisham bin AteyaBy Rick Anderson, Damien Bowden, Bart Calixto, Nadeem Afana, and Hisham Bin Ateya

Witryna internetowa w wielu językach umożliwia dostęp do szerszego grona użytkowników.A multilingual website allows the site to reach a wider audience. ASP.NET Core udostępnia usługi i oprogramowanie pośredniczące do lokalizowania w różnych językach i kulturach.ASP.NET Core provides services and middleware for localizing into different languages and cultures.

Między innymi są używane globalizacji i lokalizacje.Internationalization involves Globalization and Localization. Globalizacja to proces projektowania aplikacji, które obsługują różne kultury.Globalization is the process of designing apps that support different cultures. Globalizacja dodaje obsługę danych wejściowych, wyświetlanych i wyjściowych zdefiniowanego zestawu skryptów języka, które odnoszą się do określonych obszarów geograficznych.Globalization adds support for input, display, and output of a defined set of language scripts that relate to specific geographic areas.

Lokalizacja to proces adaptacji aplikacji, która została już przetworzona w celu zlokalizowania, do określonej kultury lub ustawień regionalnych.Localization is the process of adapting a globalized app, which you have already processed for localizability, to a particular culture/locale. Aby uzyskać więcej informacji , zobacz sekcję globalizacja i warunki lokalizacji na końcu tego dokumentu.For more information see Globalization and localization terms near the end of this document.

Lokalizacja aplikacji obejmuje następujące elementy:App localization involves the following:

  1. Ustaw lokalizowalność zawartości aplikacjiMake the app's content localizable
  2. Zapewnianie zlokalizowanych zasobów dla obsługiwanych języków i kulturProvide localized resources for the languages and cultures you support
  3. Zaimplementuj strategię, aby wybrać język/kulturę dla każdego żądaniaImplement a strategy to select the language/culture for each request

Wyświetl lub pobierz przykładowy kod (jak pobrać)View or download sample code (how to download)

Ustaw lokalizowalność zawartości aplikacjiMake the app's content localizable

IStringLocalizer i IStringLocalizer<T> zostały zaprojektowane w celu zwiększenia produktywności podczas tworzenia zlokalizowanych aplikacji.IStringLocalizer and IStringLocalizer<T> were architected to improve productivity when developing localized apps. IStringLocalizer używa ResourceManager i ResourceReader w celu zapewnienia zasobów specyficznych dla kultury w czasie wykonywania.IStringLocalizer uses the ResourceManager and ResourceReader to provide culture-specific resources at run time. Interfejs ma indeksator i IEnumerable zwraca zlokalizowane ciągi.The interface has an indexer and an IEnumerable for returning localized strings. IStringLocalizer nie wymaga zapisywania w pliku zasobów domyślnych ciągów języka.IStringLocalizer doesn't require storing the default language strings in a resource file. Możesz tworzyć aplikacje przeznaczone do lokalizacji i nie musisz już tworzyć plików zasobów w fazie opracowywania.You can develop an app targeted for localization and not need to create resource files early in development. Poniższy kod przedstawia sposób zawijania ciągu "informacje o tytule" dla lokalizacji.The code below shows how to wrap the string "About Title" for localization.

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"];
        }
    }
}

W poprzednim kodzie IStringLocalizer<T> implementacja pochodzi z iniekcji zależności.In the preceding code, the IStringLocalizer<T> implementation comes from Dependency Injection. Jeśli zlokalizowana wartość "informacje o tytule" nie zostanie znaleziona, zostanie zwrócony klucz indeksatora, czyli ciąg "informacje o tytule".If the localized value of "About Title" isn't found, then the indexer key is returned, that is, the string "About Title". Możesz pozostawić domyślne ciągi literałów języka w aplikacji i otoczyć je w lokalizatorze, aby można było skupić się na tworzeniu aplikacji.You can leave the default language literal strings in the app and wrap them in the localizer, so that you can focus on developing the app. Tworzysz aplikację przy użyciu języka domyślnego i przygotujesz ją do kroku lokalizacji bez wcześniejszego tworzenia domyślnego pliku zasobów.You develop your app with your default language and prepare it for the localization step without first creating a default resource file. Alternatywnie można użyć tradycyjnego podejścia i podać klucz do pobrania domyślnego ciągu języka.Alternatively, you can use the traditional approach and provide a key to retrieve the default language string. Dla wielu deweloperów nowy przepływ pracy nie ma domyślnego pliku języka . resx i po prostu zawijający literały ciągu może zmniejszyć obciążenie lokalizowania aplikacji.For many developers the new workflow of not having a default language .resx file and simply wrapping the string literals can reduce the overhead of localizing an app. Inni deweloperzy będą wolą tradycyjne przepływy pracy, ponieważ ułatwiają one pracę z dłuższymi literałami ciągów i ułatwiają aktualizowanie zlokalizowanych ciągów.Other developers will prefer the traditional work flow as it can make it easier to work with longer string literals and make it easier to update localized strings.

Użyj IHtmlLocalizer<T> implementacji dla zasobów, które zawierają kod HTML.Use the IHtmlLocalizer<T> implementation for resources that contain HTML. IHtmlLocalizer KOD HTML koduje argumenty, które są sformatowane w ciągu zasobu, ale nie kodu HTML samego samego ciągu zasobu.IHtmlLocalizer HTML encodes arguments that are formatted in the resource string, but doesn't HTML encode the resource string itself. W przykładzie wyróżnionym poniżej tylko wartość name parametru jest zakodowana w formacie HTML.In the sample highlighted below, only the value of name parameter is HTML encoded.

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();
        }

Uwaga

Ogólnie rzecz biorąc, zlokalizowany jest tylko tekst, nie HTML.Generally, only localize text, not HTML.

Na najniższym poziomie można uzyskać możliwość IStringLocalizerFactory iniekcji zależności:At the lowest level, you can get IStringLocalizerFactory out of Dependency Injection:

{
    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."];

Powyższy kod demonstruje każdą z dwóch metod tworzenia fabryk.The code above demonstrates each of the two factory create methods.

Zlokalizowane ciągi można podzielić według kontrolera, obszaru lub tylko jednego kontenera.You can partition your localized strings by controller, area, or have just one container. W aplikacji przykładowej Klasa fikcyjna o nazwie SharedResource jest używana do współużytkowanych zasobów.In the sample app, a dummy class named SharedResource is used for shared resources.

// Dummy class to group shared resources

namespace Localization
{
    public class SharedResource
    {
    }
}

Niektórzy Deweloperzy używają Startup klasy, aby zawierały ciągi globalne lub udostępnione.Some developers use the Startup class to contain global or shared strings. W poniższym przykładzie InfoController SharedResource są używane i lokalizatory:In the sample below, the InfoController and the SharedResource localizers are used:

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;
    }

Wyświetl lokalizacjęView localization

IViewLocalizerUsługa udostępnia zlokalizowane ciągi dla widoku.The IViewLocalizer service provides localized strings for a view. ViewLocalizerKlasa implementuje ten interfejs i odnajduje lokalizację zasobu ze ścieżki pliku widoku.The ViewLocalizer class implements this interface and finds the resource location from the view file path. Poniższy kod pokazuje, jak używać domyślnej implementacji IViewLocalizer :The following code shows how to use the default implementation of 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>

Domyślna implementacja programu IViewLocalizer znajduje plik zasobów na podstawie nazwy pliku widoku.The default implementation of IViewLocalizer finds the resource file based on the view's file name. Nie ma możliwości użycia globalnego pliku zasobów udostępnionych.There's no option to use a global shared resource file. ViewLocalizer implementuje lokalizatora przy użyciu IHtmlLocalizer , dlatego Razor nie KODUJ kodu HTML zlokalizowanego ciągu.ViewLocalizer implements the localizer using IHtmlLocalizer, so Razor doesn't HTML encode the localized string. Można Sparametryzuj ciągi zasobów i IViewLocalizer zakodować w kodzie HTML parametry, ale nie ciąg zasobu.You can parameterize resource strings and IViewLocalizer will HTML encode the parameters, but not the resource string. Rozważ następujące Razor oznakowanie:Consider the following Razor markup:

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

Plik zasobów francuski może zawierać następujące elementy:A French resource file could contain the following:

KluczKey WartośćValue
<i>Hello</i> <b>{0}!</b> <i>Bonjour</i> <b>{0} !</b>

Renderowany widok będzie zawierać znacznik HTML z pliku zasobu.The rendered view would contain the HTML markup from the resource file.

Uwaga

Ogólnie rzecz biorąc, zlokalizowany jest tylko tekst, nie HTML.Generally, only localize text, not HTML.

Aby użyć udostępnionego pliku zasobu w widoku, wstrzyknąć IHtmlLocalizer<T> :To use a shared resource file in a view, inject 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>

Lokalizacja adnotacjiDataAnnotations localization

Komunikaty o błędach DataAnnotations są zlokalizowane przy użyciu IStringLocalizer<T> .DataAnnotations error messages are localized with IStringLocalizer<T>. Korzystając z opcji ResourcesPath = "Resources" , komunikaty o błędach w programie RegisterViewModel mogą być przechowywane w jednej z następujących ścieżek:Using the option ResourcesPath = "Resources", the error messages in RegisterViewModel can be stored in either of the following paths:

  • Zasoby/modele widoków. Account. RegisterViewModel. fr. resxResources/ViewModels.Account.RegisterViewModel.fr.resx
  • Zasoby/modele widoków/Account/RegisterViewModel. fr. resxResources/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; }
}

W ASP.NET Core MVC 1.1.0 i wyższych atrybuty inne niż Walidacja są zlokalizowane.In ASP.NET Core MVC 1.1.0 and higher, non-validation attributes are localized. ASP.NET Core MVC 1,0 nie wyszukuje zlokalizowanych ciągów dla atrybutów niezwiązanych z walidacją.ASP.NET Core MVC 1.0 does not look up localized strings for non-validation attributes.

Używanie jednego ciągu zasobu dla wielu klasUsing one resource string for multiple classes

Poniższy kod przedstawia sposób użycia jednego ciągu zasobu do atrybutów walidacji z wieloma klasami:The following code shows how to use one resource string for validation attributes with multiple classes:

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

W poprzednim kodzie, SharedResource jest klasą odpowiadającą resx, gdzie są przechowywane Twoje wiadomości weryfikacyjne.In the preceding code, SharedResource is the class corresponding to the resx where your validation messages are stored. W tym podejściu DataAnnotations będą używać tylko SharedResource , a nie zasobów dla każdej klasy.With this approach, DataAnnotations will only use SharedResource, rather than the resource for each class.

Zapewnianie zlokalizowanych zasobów dla obsługiwanych języków i kulturProvide localized resources for the languages and cultures you support

SupportedCultures i SupportedUICulturesSupportedCultures and SupportedUICultures

ASP.NET Core pozwala określić dwie wartości kulturowe SupportedCultures i SupportedUICultures .ASP.NET Core allows you to specify two culture values, SupportedCultures and SupportedUICultures. Obiekt CultureInfo dla SupportedCultures określa wyniki funkcji zależnych od kultury, takich jak data, godzina, liczba i formatowanie waluty.The CultureInfo object for SupportedCultures determines the results of culture-dependent functions, such as date, time, number, and currency formatting. SupportedCultures określa również kolejność sortowania tekstu, Konwencji wielkości liter i porównań ciągów.SupportedCultures also determines the sorting order of text, casing conventions, and string comparisons. Zobacz CultureInfo. CurrentCulture , aby uzyskać więcej informacji na temat sposobu, w jaki serwer pobiera kulturę.See CultureInfo.CurrentCulture for more info on how the server gets the Culture. SupportedUICulturesOkreśla, które przetłumaczone ciągi (z plików resx ) są wyszukiwane przez program ResourceManager.The SupportedUICultures determines which translated strings (from .resx files) are looked up by the ResourceManager. ResourceManagerPo prostu wyszukuje ciągi specyficzne dla kultury, które są określane przez CurrentUICulture .The ResourceManager simply looks up culture-specific strings that's determined by CurrentUICulture. Każdy wątek w programie .NET CurrentCulture ma CurrentUICulture obiekty i.Every thread in .NET has CurrentCulture and CurrentUICulture objects. ASP.NET Core sprawdza te wartości podczas renderowania funkcji zależnych od kultury.ASP.NET Core inspects these values when rendering culture-dependent functions. Na przykład, jeśli kultura bieżącego wątku jest ustawiona na wartość "en-US" (angielski, Stany Zjednoczone), DateTime.Now.ToLongDateString() zostanie wyświetlona wartość "czwartek, 18 lutego, 2016", ale jeśli CurrentCulture jest ustawiona na "ES-es" (hiszpański, Hiszpania) dane wyjściowe będą "jueves, 18 de febrero de 2016".For example, if the current thread's culture is set to "en-US" (English, United States), DateTime.Now.ToLongDateString() displays "Thursday, February 18, 2016", but if CurrentCulture is set to "es-ES" (Spanish, Spain) the output will be "jueves, 18 de febrero de 2016".

Pliki zasobówResource files

Plik zasobów jest użytecznym mechanizmem oddzielania lokalizowalnych ciągów od kodu.A resource file is a useful mechanism for separating localizable strings from code. Przetłumaczone ciągi dla języka innego niż domyślny są izolowane w plikach zasobów resx .Translated strings for the non-default language are isolated in .resx resource files. Na przykład możesz chcieć utworzyć plik zasobów hiszpański o nazwie Welcome. es. resx zawierający przetłumaczone ciągi.For example, you might want to create Spanish resource file named Welcome.es.resx containing translated strings. "es" to kod języka w języku hiszpańskim."es" is the language code for Spanish. Aby utworzyć ten plik zasobów w programie Visual Studio:To create this resource file in Visual Studio:

  1. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy folder, który będzie zawierać plik zasobów, > Dodaj > nowy element .In Solution Explorer , right click on the folder which will contain the resource file > Add > New Item .

    Zagnieżdżone menu kontekstowe: w Eksplorator rozwiązań menu kontekstowe jest otwarte dla zasobów.

  2. W polu wyszukiwania zainstalowanych szablonów wprowadź "Resource" i Nazwij plik.In the Search installed templates box, enter "resource" and name the file.

    Okno dialogowe Dodawanie nowego elementu

  3. Wprowadź wartość klucza (ciąg macierzysty) w kolumnie Nazwa i przetłumaczony ciąg w kolumnie wartość .Enter the key value (native string) in the Name column and the translated string in the Value column.

    Welcome. es. resx plik (plik zasobów powitalnych dla języka hiszpańskiego) z słowem Hello w kolumnie Nazwa i słowem Hola (Hello w języku hiszpańskim) w kolumnie wartość

    Program Visual Studio wyświetla plik Welcome. es. resx .Visual Studio shows the Welcome.es.resx file.

    Eksplorator rozwiązań przedstawiający plik zasobów programu Welcome hiszpański (ES)

Nazewnictwo plików zasobówResource file naming

Zasoby są nazwane dla pełnej nazwy typu swojej klasy pomniejszonej o nazwę zestawu.Resources are named for the full type name of their class minus the assembly name. Na przykład zasób francuski w projekcie, którego głównym zestawem jest LocalizationWebsite.Web.dll dla klasy, będzie LocalizationWebsite.Web.Startup nazwany Startup. fr. resx .For example, a French resource in a project whose main assembly is LocalizationWebsite.Web.dll for the class LocalizationWebsite.Web.Startup would be named Startup.fr.resx . Zasób klasy LocalizationWebsite.Web.Controllers.HomeController nosi nazwę controllers. HomeController. fr. resx .A resource for the class LocalizationWebsite.Web.Controllers.HomeController would be named Controllers.HomeController.fr.resx . Jeśli przestrzeń nazw klasy Target nie jest taka sama jak nazwa zestawu, będzie potrzebna pełna nazwa typu.If your targeted class's namespace isn't the same as the assembly name you will need the full type name. Przykładowo w przykładowym projekcie zasób dla typu ExtraNamespace.Tools powinien mieć nazwę ExtraNamespace. Tools. fr. resx .For example, in the sample project a resource for the type ExtraNamespace.Tools would be named ExtraNamespace.Tools.fr.resx .

W przykładowym projekcie ConfigureServices Metoda ustawia ResourcesPath do "zasobów", więc ścieżka względna projektu dla francuskiego pliku zasobów kontrolera głównego to zasoby/kontrolery. HomeController. fr. resx .In the sample project, the ConfigureServices method sets the ResourcesPath to "Resources", so the project relative path for the home controller's French resource file is Resources/Controllers.HomeController.fr.resx . Alternatywnie można użyć folderów do organizowania plików zasobów.Alternatively, you can use folders to organize resource files. W przypadku kontrolera macierzystego ścieżka będzie zawierać zasoby/kontrolery/HomeController. fr. resx .For the home controller, the path would be Resources/Controllers/HomeController.fr.resx . Jeśli ta opcja nie zostanie użyta ResourcesPath , plik . resx zostanie użyty w katalogu bazowym projektu.If you don't use the ResourcesPath option, the .resx file would go in the project base directory. Plik zasobu dla HomeController nosi nazwę controllers. HomeController. fr. resx .The resource file for HomeController would be named Controllers.HomeController.fr.resx . Wybór przy użyciu konwencji nazewnictwa kropka lub ścieżki zależy od tego, w jaki sposób chcesz zorganizować pliki zasobów.The choice of using the dot or path naming convention depends on how you want to organize your resource files.

Nazwa zasobuResource name Nazwa kropka lub ścieżkiDot or path naming
Zasoby/kontrolery. HomeController. fr. resxResources/Controllers.HomeController.fr.resx KropkaDot
Zasoby/kontrolery/HomeController. fr. resxResources/Controllers/HomeController.fr.resx ŚcieżkaPath

Pliki zasobów używające @inject IViewLocalizer w Razor widokach są zgodne z podobnym wzorcem.Resource files using @inject IViewLocalizer in Razor views follow a similar pattern. Plik zasobów dla widoku może być nazwany przy użyciu nazw kropek lub nazw ścieżek.The resource file for a view can be named using either dot naming or path naming. Razor Wyświetl pliki zasobów, aby naśladować ścieżkę skojarzonego pliku widoku.Razor view resource files mimic the path of their associated view file. Przy założeniu, że ustawimy ResourcesPath na "zasoby", plik zasobów francuski skojarzony z widokiem /Home/about. cshtml może mieć jedną z następujących wartości:Assuming we set the ResourcesPath to "Resources", the French resource file associated with the Views/Home/About.cshtml view could be either of the following:

  • Zasoby/widoki/Strona główna/informacje. fr. resxResources/Views/Home/About.fr.resx

  • Zasoby/widoki. Strona główna. informacje. fr. resxResources/Views.Home.About.fr.resx

Jeśli opcja nie zostanie użyta ResourcesPath , plik resx dla widoku powinien znajdować się w tym samym folderze co widok.If you don't use the ResourcesPath option, the .resx file for a view would be located in the same folder as the view.

RootNamespaceAttributeRootNamespaceAttribute

Atrybut RootNamespace udostępnia główną przestrzeń nazw zestawu, gdy główna przestrzeń nazw zestawu jest inna niż nazwa zestawu.The RootNamespace attribute provides the root namespace of an assembly when the root namespace of an assembly is different than the assembly name.

Ostrzeżenie

Taka sytuacja może wystąpić, gdy nazwa projektu nie jest prawidłowym identyfikatorem platformy .NET.This can occur when a project's name is not a valid .NET identifier. Na przykład my-project-name.csproj użyje głównej przestrzeni nazw my_project_name i nazwy zestawu my-project-name prowadzącej do tego błędu.For instance my-project-name.csproj will use the root namespace my_project_name and the assembly name my-project-name leading to this error.

Jeśli główna przestrzeń nazw zestawu jest inna niż nazwa zestawu:If the root namespace of an assembly is different than the assembly name:

  • Lokalizacja nie działa domyślnie.Localization does not work by default.
  • Lokalizowanie nie powiedzie się z powodu sposobu wyszukiwania zasobów w zestawie.Localization fails due to the way resources are searched for within the assembly. RootNamespace jest wartością czasu kompilacji, która nie jest dostępna dla wykonywanego procesu.RootNamespace is a build-time value which is not available to the executing process.

Jeśli RootNamespace różni się od AssemblyName , należy uwzględnić następujące w AssemblyInfo.cs (z wartościami parametrów zamienionymi na wartości rzeczywiste):If the RootNamespace is different from the AssemblyName, include the following in AssemblyInfo.cs (with parameter values replaced with the actual values):

using System.Reflection;
using Microsoft.Extensions.Localization;

[assembly: ResourceLocation("Resource Folder Name")]
[assembly: RootNamespace("App Root Namespace")]

Poprzedni kod umożliwia pomyślne rozpoznanie plików resx.The preceding code enables the successful resolution of resx files.

Zachowanie rezerwowe kulturyCulture fallback behavior

Podczas wyszukiwania zasobu lokalizacja prowadzi do "rezerwy kulturowej".When searching for a resource, localization engages in "culture fallback". Jeśli nie zostanie znaleziona, rozpoczyna się od żądanej kultury, przywraca kulturę nadrzędną tej kultury.Starting from the requested culture, if not found, it reverts to the parent culture of that culture. Poza tym Właściwość CultureInfo. Parent reprezentuje kulturę nadrzędną.As an aside, the CultureInfo.Parent property represents the parent culture. Zwykle (ale nie zawsze) oznacza usunięcie z ISO.This usually (but not always) means removing the national signifier from the ISO. Na przykład dialekt języka hiszpańskiego wymawianego w Meksyku to "es-MX".For example, the dialect of Spanish spoken in Mexico is "es-MX". Jest to wersja Hiszpańska "es", która — nie jest specyficzna dla żadnego z krajów.It has the parent "es"—Spanish non-specific to any country.

Wyobraź sobie, że witryna otrzymuje żądanie dotyczące zasobu "Welcome" przy użyciu kultury "fr-CA".Imagine your site receives a request for a "Welcome" resource using culture "fr-CA". System lokalizacji wyszukuje następujące zasoby w kolejności i wybiera pierwsze dopasowanie:The localization system looks for the following resources, in order, and selects the first match:

  • Welcome.fr — CA. resxWelcome.fr-CA.resx
  • Witamy. fr. resxWelcome.fr.resx
  • Welcome. resx (Jeśli NeutralResourcesLanguage jest "fr-CA")Welcome.resx (if the NeutralResourcesLanguage is "fr-CA")

Na przykład, jeśli usuniesz oznaczenie kultury ". fr" i masz kulturę ustawioną na francuski, domyślny plik zasobów jest odczytywany, a ciągi są zlokalizowane.As an example, if you remove the ".fr" culture designator and you have the culture set to French, the default resource file is read and strings are localized. Menedżer zasobów określa domyślny lub rezerwowy zasób, gdy nic nie spełnia wymaganej kultury.The Resource manager designates a default or fallback resource for when nothing meets your requested culture. Jeśli chcesz po prostu zwrócić klucz, gdy brakuje zasobu dla wymaganej kultury, nie musisz mieć domyślnego pliku zasobów.If you want to just return the key when missing a resource for the requested culture you must not have a default resource file.

Generowanie plików zasobów przy użyciu programu Visual StudioGenerate resource files with Visual Studio

Jeśli utworzysz plik zasobów w programie Visual Studio bez kultury w nazwie pliku (na przykład Welcome. resx ), program Visual Studio utworzy klasę języka C# z właściwością dla każdego ciągu.If you create a resource file in Visual Studio without a culture in the file name (for example, Welcome.resx ), Visual Studio will create a C# class with a property for each string. Zwykle nie jest to możliwe dzięki ASP.NET Core.That's usually not what you want with ASP.NET Core. Zazwyczaj nie istnieje domyślny plik zasobów resx (plik . resx bez nazwy kultury).You typically don't have a default .resx resource file (a .resx file without the culture name). Zalecamy utworzenie pliku resx z nazwą kultury (na przykład Welcome. fr. resx ).We suggest you create the .resx file with a culture name (for example Welcome.fr.resx ). Podczas tworzenia pliku resx przy użyciu nazwy kultury program Visual Studio nie generuje pliku klasy.When you create a .resx file with a culture name, Visual Studio won't generate the class file.

Dodaj inne kulturyAdd other cultures

Każda kombinacja języka i kultury (oprócz języka domyślnego) wymaga unikatowego pliku zasobów.Each language and culture combination (other than the default language) requires a unique resource file. Tworzysz pliki zasobów dla różnych kultur i ustawień regionalnych, tworząc nowe pliki zasobów, w których kody języka ISO są częścią nazwy pliku (na przykład en-us , fr-CA i pl-GB ).You create resource files for different cultures and locales by creating new resource files in which the ISO language codes are part of the file name (for example, en-us , fr-ca , and en-gb ). Te kody ISO są umieszczane między nazwami plików i rozszerzeniem resx , jak w Welcome.es-MX. resx (hiszpański/Meksyk).These ISO codes are placed between the file name and the .resx file extension, as in Welcome.es-MX.resx (Spanish/Mexico).

Zaimplementuj strategię, aby wybrać język/kulturę dla każdego żądaniaImplement a strategy to select the language/culture for each request

Konfigurowanie lokalizacjiConfigure localization

Lokalizacja jest skonfigurowana w ramach Startup.ConfigureServices metody:Localization is configured in the Startup.ConfigureServices method:

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

services.AddMvc()
    .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
    .AddDataAnnotationsLocalization();
  • AddLocalization dodaje usługi lokalizacyjne do kontenera usług.AddLocalization adds the localization services to the services container. Powyższy kod również ustawia ścieżkę zasobów na "zasoby".The code above also sets the resources path to "Resources".

  • AddViewLocalization dodaje obsługę zlokalizowanych plików widoku.AddViewLocalization adds support for localized view files. Ta lokalizacja widoku przykładowego jest oparta na sufiksie pliku widoku.In this sample view localization is based on the view file suffix. Na przykład "fr" w pliku index. fr. cshtml .For example "fr" in the Index.fr.cshtml file.

  • AddDataAnnotationsLocalization dodaje obsługę zlokalizowanych DataAnnotations komunikatów weryfikacyjnych za pomocą IStringLocalizer abstrakcji.AddDataAnnotationsLocalization adds support for localized DataAnnotations validation messages through IStringLocalizer abstractions.

Oprogramowanie pośredniczące lokalizacjiLocalization middleware

Bieżąca kultura w żądaniu jest ustawiana w oprogramowaniu pośredniczącymlokalizacji.The current culture on a request is set in the localization Middleware. Oprogramowanie pośredniczące lokalizacji jest włączone w tej Startup.Configure metodzie.The localization middleware is enabled in the Startup.Configure method. Oprogramowanie pośredniczące lokalizacyjne musi być skonfigurowane przed jakimkolwiek oprogramowanie pośredniczące, które może sprawdzić kulturę żądania (na przykład app.UseMvcWithDefaultRoute() ).The localization middleware must be configured before any middleware which might check the request culture (for example, app.UseMvcWithDefaultRoute()).

var supportedCultures = new[] { "en-US", "fr" };
var localizationOptions = new RequestLocalizationOptions().SetDefaultCulture(supportedCultures[0])
    .AddSupportedCultures(supportedCultures)
    .AddSupportedUICultures(supportedCultures);

app.UseRequestLocalization(localizationOptions);

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

app.UseAuthentication();

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

Jeśli chcesz zobaczyć Komentarze do kodu przetłumaczone na języki inne niż angielski, poinformuj nas o tym problemie z dyskusjąw witrynie GitHub.If you would like to see code comments translated to languages other than English, let us know in this GitHub discussion issue.

UseRequestLocalization Inicjuje RequestLocalizationOptions obiekt.UseRequestLocalization initializes a RequestLocalizationOptions object. Na każdym zażądaniu listy RequestCultureProvider w programie RequestLocalizationOptions jest wyliczany, a pierwszy dostawca, który może pomyślnie ustalić kulturę żądań, jest używany.On every request the list of RequestCultureProvider in the RequestLocalizationOptions is enumerated and the first provider that can successfully determine the request culture is used. Dostawcy domyślnie pochodzą z RequestLocalizationOptions klasy:The default providers come from the RequestLocalizationOptions class:

  1. QueryStringRequestCultureProvider
  2. CookieRequestCultureProvider
  3. AcceptLanguageHeaderRequestCultureProvider

Lista domyślna przechodzi od najbardziej konkretnych do najmniej określonych.The default list goes from most specific to least specific. W dalszej części artykułu zobaczymy, jak można zmienić kolejność, a nawet dodać niestandardowego dostawcę kultury.Later in the article we'll see how you can change the order and even add a custom culture provider. Jeśli żaden z dostawców nie może określić kultury żądania, DefaultRequestCulture jest używana.If none of the providers can determine the request culture, the DefaultRequestCulture is used.

QueryStringRequestCultureProviderQueryStringRequestCultureProvider

Niektóre aplikacje będą używać ciągu zapytania do ustawienia /dotnet/api/system.globalization.cultureinfo?view=netcore-3.1 .Some apps will use a query string to set the /dotnet/api/system.globalization.cultureinfo?view=netcore-3.1. W przypadku aplikacji korzystających z cookie metody nagłówka lub Accept-Language dodanie ciągu zapytania do adresu URL jest przydatne w przypadku debugowania i testowania kodu.For apps that use the cookie or Accept-Language header approach, adding a query string to the URL is useful for debugging and testing code. Domyślnie program QueryStringRequestCultureProvider jest rejestrowany jako pierwszy dostawca lokalizacji na RequestCultureProvider liście.By default, the QueryStringRequestCultureProvider is registered as the first localization provider in the RequestCultureProvider list. Parametry ciągu zapytania są przekazywane culture i ui-culture .You pass the query string parameters culture and ui-culture. Poniższy przykład ustawia określoną kulturę (język i region) na hiszpański/Meksyk:The following example sets the specific culture (language and region) to Spanish/Mexico:

http://localhost:5000/?culture=es-MX&ui-culture=es-MX

Jeśli przekazujesz tylko jeden z dwóch ( culture lub ui-culture ), dostawca ciągu zapytania ustawi obie wartości przy użyciu przekazanego elementu.If you only pass in one of the two (culture or ui-culture), the query string provider will set both values using the one you passed in. Na przykład ustawienie tylko kulturowe ustawi zarówno, Culture jak i UICulture :For example, setting just the culture will set both the Culture and the UICulture:

http://localhost:5000/?culture=es-MX

CookieRequestCultureProviderCookieRequestCultureProvider

Aplikacje produkcyjne często udostępniają mechanizm ustawiania kultury z kulturą ASP.NET Coreową cookie .Production apps will often provide a mechanism to set the culture with the ASP.NET Core culture cookie. Użyj MakeCookieValue metody, aby utworzyć cookie .Use the MakeCookieValue method to create a cookie.

CookieRequestCultureProvider DefaultCookieName Zwraca domyślną cookie nazwę używaną do śledzenia informacji o preferowanej kulturze użytkownika.The CookieRequestCultureProvider DefaultCookieName returns the default cookie name used to track the user's preferred culture information. Nazwa domyślna cookie to .AspNetCore.Culture .The default cookie name is .AspNetCore.Culture.

cookieFormat to c=%LANGCODE%|uic=%LANGCODE% , gdzie c is Culture i uic is UICulture , na przykład:The cookie format is c=%LANGCODE%|uic=%LANGCODE%, where c is Culture and uic is UICulture, for example:

c=en-UK|uic=en-US

Jeśli określisz tylko jedną z informacji o kulturze i kulturze interfejsu użytkownika, określona kultura zostanie użyta dla informacji kultury i kultury interfejsu użytkownika.If you only specify one of culture info and UI culture, the specified culture will be used for both culture info and UI culture.

Accept-Language nagłówek HTTPThe Accept-Language HTTP header

Nagłówek Accept-Language jest settable w większości przeglądarek i był pierwotnie przeznaczony do określenia języka użytkownika.The Accept-Language header is settable in most browsers and was originally intended to specify the user's language. To ustawienie wskazuje, co przeglądarka została ustawiona do wysłania lub która dziedziczy z bazowego systemu operacyjnego.This setting indicates what the browser has been set to send or has inherited from the underlying operating system. Accept-Language nagłówku HTTP z żądania przeglądarki nie jest INFALLIBLE sposób wykrywania preferowanego języka użytkownika (zobacz Ustawianie preferencji językowych w przeglądarce).The Accept-Language HTTP header from a browser request isn't an infallible way to detect the user's preferred language (see Setting language preferences in a browser). Aplikacja produkcyjna powinna uwzględniać sposób, w jaki użytkownik może dostosować wybór kultury.A production app should include a way for a user to customize their choice of culture.

Ustawianie Accept-Language nagłówku HTTP w programie IESet the Accept-Language HTTP header in IE

  1. Na ikonie koła zębatego naciśnij pozycję Opcje internetowe .From the gear icon, tap Internet Options .

  2. Naciśnij pozycję Języki .Tap Languages .

    Opcje internetowe

  3. Naciśnij pozycję Ustaw preferencje językowe .Tap Set Language Preferences .

  4. Naciśnij pozycję Dodaj język .Tap Add a language .

  5. Dodaj język.Add the language.

  6. Naciśnij pozycję język, a następnie naciśnij pozycję Przenieś w górę .Tap the language, then tap Move Up .

Używanie dostawcy niestandardowegoUse a custom provider

Załóżmy, że chcesz zezwolić klientom na przechowywanie w swoich bazach danych językowych i kulturowych.Suppose you want to let your customers store their language and culture in your databases. Można napisać dostawcę, aby wyszukać te wartości dla użytkownika.You could write a provider to look up these values for the user. Poniższy kod pokazuje, jak dodać niestandardowego dostawcę:The following code shows how to add a custom provider:

private const string enUSCulture = "en-US";

services.Configure<RequestLocalizationOptions>(options =>
{
    var supportedCultures = new[]
    {
        new CultureInfo(enUSCulture),
        new CultureInfo("fr")
    };

    options.DefaultRequestCulture = new RequestCulture(culture: enUSCulture, uiCulture: enUSCulture);
    options.SupportedCultures = supportedCultures;
    options.SupportedUICultures = supportedCultures;

    options.AddInitialRequestCultureProvider(new CustomRequestCultureProvider(async context =>
    {
        // My custom request culture logic
        return new ProviderCultureResult("en");
    }));
});

Służy RequestLocalizationOptions do dodawania lub usuwania dostawców lokalizacji.Use RequestLocalizationOptions to add or remove localization providers.

Ustaw kulturę programowoSet the culture programmatically

Ten przykład lokalizacji. StarterWeb projekt w witrynie GitHub zawiera interfejs użytkownika służący do ustawiania Culture .This sample Localization.StarterWeb project on GitHub contains UI to set the Culture. Plik views/Shared/_SelectLanguagePartial. cshtml umożliwia wybranie kultury z listy obsługiwanych kultur:The Views/Shared/_SelectLanguagePartial.cshtml file allows you to select the culture from the list of supported cultures:

@using Microsoft.AspNetCore.Builder
@using Microsoft.AspNetCore.Http.Features
@using Microsoft.AspNetCore.Localization
@using Microsoft.AspNetCore.Mvc.Localization
@using Microsoft.Extensions.Options

@inject IViewLocalizer Localizer
@inject IOptions<RequestLocalizationOptions> LocOptions

@{
    var requestCulture = Context.Features.Get<IRequestCultureFeature>();
    var cultureItems = LocOptions.Value.SupportedUICultures
        .Select(c => new SelectListItem { Value = c.Name, Text = c.DisplayName })
        .ToList();
    var returnUrl = string.IsNullOrEmpty(Context.Request.Path) ? "~/" : $"~{Context.Request.Path.Value}";
}

<div title="@Localizer["Request culture provider:"] @requestCulture?.Provider?.GetType().Name">
    <form id="selectLanguage" asp-controller="Home" 
          asp-action="SetLanguage" asp-route-returnUrl="@returnUrl" 
          method="post" class="form-horizontal" role="form">
        <label asp-for="@requestCulture.RequestCulture.UICulture.Name">@Localizer["Language:"]</label> <select name="culture"
          onchange="this.form.submit();"
          asp-for="@requestCulture.RequestCulture.UICulture.Name" asp-items="cultureItems">
        </select>
    </form>
</div>

Plik views/Shared/_SelectLanguagePartial. cshtml zostanie dodany do footer sekcji pliku układu, więc będzie dostępny dla wszystkich widoków:The Views/Shared/_SelectLanguagePartial.cshtml file is added to the footer section of the layout file so it will be available to all views:

<div class="container body-content" style="margin-top:60px">
    @RenderBody()
    <hr>
    <footer>
        <div class="row">
            <div class="col-md-6">
                <p>&copy; @System.DateTime.Now.Year - Localization</p>
            </div>
            <div class="col-md-6 text-right">
                @await Html.PartialAsync("_SelectLanguagePartial")
            </div>
        </div>
    </footer>
</div>

SetLanguageMetoda ustawia kulturę cookie .The SetLanguage method sets the culture cookie.

[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);
}

Nie można podłączyć _SelectLanguagePartial. cshtml do przykładowego kodu dla tego projektu.You can't plug in the _SelectLanguagePartial.cshtml to sample code for this project. Projekt Lokalizacja. StarterWeb w usłudze GitHub ma kod, który umożliwia RequestLocalizationOptions Razor Przechodzenie do częściowej przez kontener iniekcji zależności .The Localization.StarterWeb project on GitHub has code to flow the RequestLocalizationOptions to a Razor partial through the Dependency Injection container.

Dane tras powiązań modelu i ciągi zapytaniaModel binding route data and query strings

Zobacz zachowanie globalizacji powiązań modelu powiązanie danych i ciągi zapytań.See Globalization behavior of model binding route data and query strings.

Warunki globalizacji i lokalizacjaGlobalization and localization terms

Proces lokalizowania aplikacji wymaga również podstawowej znajomości odpowiednich zestawów znaków, które są często używane w nowoczesnych opracowywaniu oprogramowania i zrozumieniu skojarzonych z nimi problemów.The process of localizing your app also requires a basic understanding of relevant character sets commonly used in modern software development and an understanding of the issues associated with them. Mimo że wszystkie komputery przechowują tekst jako cyfry (kody), różne systemy przechowują ten sam tekst przy użyciu różnych liczb.Although all computers store text as numbers (codes), different systems store the same text using different numbers. Proces lokalizowania dotyczy tłumaczenia interfejsu użytkownika aplikacji (UI) dla określonych kultur/ustawień regionalnych.The localization process refers to translating the app user interface (UI) for a specific culture/locale.

Możliwość lokalizowania to proces pośredni służący do sprawdzania, czy aplikacja globalna jest gotowa do lokalizacji.Localizability is an intermediate process for verifying that a globalized app is ready for localization.

Format RFC 4646 dla nazwy kultury to <languagecode2>-<country/regioncode2> , gdzie <languagecode2> jest kodem języka i <country/regioncode2> jest kodem podkultury.The RFC 4646 format for the culture name is <languagecode2>-<country/regioncode2>, where <languagecode2> is the language code and <country/regioncode2> is the subculture code. Na przykład es-CL w przypadku języka hiszpańskiego (Chile) en-US dla języka angielskiego (Stany Zjednoczone) i en-AU dla języka angielskiego (Australia).For example, es-CL for Spanish (Chile), en-US for English (United States), and en-AU for English (Australia). RFC 4646 jest kombinacją kodu ISO 639 2 litery małymi literami związanymi z językiem i ISO 3166 2 literą w postaci wielkiej litery, skojarzonej z krajem lub regionem.RFC 4646 is a combination of an ISO 639 two-letter lowercase culture code associated with a language and an ISO 3166 two-letter uppercase subculture code associated with a country or region. Zobacz: /previous-versions/commerce-server/ee825488(v=cs.20).See /previous-versions/commerce-server/ee825488(v=cs.20).

Międzynarodowe jest często skracane do "I18N".Internationalization is often abbreviated to "I18N". Skrót przyjmuje pierwszą i ostatnią literę oraz liczbę liter między nimi, więc 18 oznacza liczbę liter między pierwszym "I" i ostatnim "N".The abbreviation takes the first and last letters and the number of letters between them, so 18 stands for the number of letters between the first "I" and the last "N". Dotyczy to zarówno globalizacji (G11N), jak i lokalizacji (L10N).The same applies to Globalization (G11N), and Localization (L10N).

OdsetkTerms:

  • Globalizacja (G11N): proces tworzenia aplikacji w różnych językach i regionach.Globalization (G11N): The process of making an app support different languages and regions.
  • Lokalizacja (L10N): proces dostosowywania aplikacji dla danego języka i regionu.Localization (L10N): The process of customizing an app for a given language and region.
  • Międzynarodowe (I18N): opisuje zarówno globalizację, jak i lokalizację.Internationalization (I18N): Describes both globalization and localization.
  • Kultura: jest to język i, opcjonalnie, region.Culture: It's a language and, optionally, a region.
  • Kultura neutralna: kultura, która ma określony język, ale nie region.Neutral culture: A culture that has a specified language, but not a region. (na przykład "en", "es")(for example "en", "es")
  • Określona kultura: kultura, która ma określony język i region.Specific culture: A culture that has a specified language and region. (na przykład "en-US", "pl-GB", "es-CL")(for example "en-US", "en-GB", "es-CL")
  • Kultura nadrzędna: neutralna kultura, która zawiera określoną kulturę.Parent culture: The neutral culture that contains a specific culture. (na przykład "en" jest kulturą nadrzędną wartości "pl-US" i "pl-GB")(for example, "en" is the parent culture of "en-US" and "en-GB")
  • Ustawienia regionalne: ustawienie regionalne jest takie samo jak kultura.Locale: A locale is the same as a culture.

Uwaga

Wprowadzanie przecinków dziesiętnych w polach dziesiętnych może być niemożna wprowadzić przecinków dziesiętnych.You may not be able to enter decimal commas in decimal fields. Aby obsługiwać sprawdzanie poprawności jQuery dla ustawień regionalnych innych niż angielskie, które używają przecinka (",") dla przecinka dziesiętnego i formatów daty spoza języka AMERYKAŃSKIEgo, należy podjąć kroki w celu zglobalizowania aplikacji.To support jQuery validation for non-English locales that use a comma (",") for a decimal point, and non US-English date formats, you must take steps to globalize your app. Zobacz ten problem GitHub 4076 instrukcje dotyczące dodawania przecinka dziesiętnego.See this GitHub issue 4076 for instructions on adding decimal comma.

Uwaga

Przed ASP.NET aplikacje internetowe Core 3.0 zapisują LogLevel.Warning jeden dziennik typu na żądanie, jeśli żądana kultura nie jest nieobsługiwała.Prior to ASP.NET Core 3.0 web apps write one log of type LogLevel.Warning per request if the requested culture is unsupported. Rejestrowanie LogLevel.Warning jednego na żądanie jest można zrobić duże pliki dziennika z nadmiarowych informacji.Logging one LogLevel.Warning per request is can make large log files with redundant information. To zachowanie zostało zmienione w ASP.NET 3.0.This behavior has been changed in ASP.NET 3.0. Zapisuje RequestLocalizationMiddleware dziennik typu LogLevel.Debug, co zmniejsza rozmiar dzienników produkcji.The RequestLocalizationMiddleware writes a log of type LogLevel.Debug, which reduces the size of production logs.

Dodatkowe zasobyAdditional resources

Rick Anderson, Damien Bowden, Bart Calixto, Nadeem Afanai Hisham bin AteyaBy Rick Anderson, Damien Bowden, Bart Calixto, Nadeem Afana, and Hisham Bin Ateya

Witryna internetowa w wielu językach umożliwia dostęp do szerszego grona użytkowników.A multilingual website allows the site to reach a wider audience. ASP.NET Core udostępnia usługi i oprogramowanie pośredniczące do lokalizowania w różnych językach i kulturach.ASP.NET Core provides services and middleware for localizing into different languages and cultures.

Między innymi są używane globalizacji i lokalizacje.Internationalization involves Globalization and Localization. Globalizacja to proces projektowania aplikacji, które obsługują różne kultury.Globalization is the process of designing apps that support different cultures. Globalizacja dodaje obsługę danych wejściowych, wyświetlanych i wyjściowych zdefiniowanego zestawu skryptów języka, które odnoszą się do określonych obszarów geograficznych.Globalization adds support for input, display, and output of a defined set of language scripts that relate to specific geographic areas.

Lokalizacja to proces adaptacji aplikacji, która została już przetworzona w celu zlokalizowania, do określonej kultury lub ustawień regionalnych.Localization is the process of adapting a globalized app, which you have already processed for localizability, to a particular culture/locale. Aby uzyskać więcej informacji , zobacz sekcję globalizacja i warunki lokalizacji na końcu tego dokumentu.For more information see Globalization and localization terms near the end of this document.

Lokalizacja aplikacji obejmuje następujące elementy:App localization involves the following:

  1. Ustaw lokalizowalność zawartości aplikacjiMake the app's content localizable
  2. Zapewnianie zlokalizowanych zasobów dla obsługiwanych języków i kulturProvide localized resources for the languages and cultures you support
  3. Zaimplementuj strategię, aby wybrać język/kulturę dla każdego żądaniaImplement a strategy to select the language/culture for each request

Wyświetl lub pobierz przykładowy kod (jak pobrać)View or download sample code (how to download)

Ustaw lokalizowalność zawartości aplikacjiMake the app's content localizable

IStringLocalizer i IStringLocalizer<T> zostały zaprojektowane w celu zwiększenia produktywności podczas tworzenia zlokalizowanych aplikacji.IStringLocalizer and IStringLocalizer<T> were architected to improve productivity when developing localized apps. IStringLocalizer używa ResourceManager i ResourceReader w celu zapewnienia zasobów specyficznych dla kultury w czasie wykonywania.IStringLocalizer uses the ResourceManager and ResourceReader to provide culture-specific resources at run time. Interfejs ma indeksator i IEnumerable zwraca zlokalizowane ciągi.The interface has an indexer and an IEnumerable for returning localized strings. IStringLocalizer nie wymaga zapisywania w pliku zasobów domyślnych ciągów języka.IStringLocalizer doesn't require storing the default language strings in a resource file. Możesz tworzyć aplikacje przeznaczone do lokalizacji i nie musisz już tworzyć plików zasobów w fazie opracowywania.You can develop an app targeted for localization and not need to create resource files early in development. Poniższy kod przedstawia sposób zawijania ciągu "informacje o tytule" dla lokalizacji.The code below shows how to wrap the string "About Title" for localization.

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"];
        }
    }
}

W poprzednim kodzie IStringLocalizer<T> implementacja pochodzi z iniekcji zależności.In the preceding code, the IStringLocalizer<T> implementation comes from Dependency Injection. Jeśli zlokalizowana wartość "informacje o tytule" nie zostanie znaleziona, zostanie zwrócony klucz indeksatora, czyli ciąg "informacje o tytule".If the localized value of "About Title" isn't found, then the indexer key is returned, that is, the string "About Title". Możesz pozostawić domyślne ciągi literałów języka w aplikacji i otoczyć je w lokalizatorze, aby można było skupić się na tworzeniu aplikacji.You can leave the default language literal strings in the app and wrap them in the localizer, so that you can focus on developing the app. Tworzysz aplikację przy użyciu języka domyślnego i przygotujesz ją do kroku lokalizacji bez wcześniejszego tworzenia domyślnego pliku zasobów.You develop your app with your default language and prepare it for the localization step without first creating a default resource file. Alternatywnie można użyć tradycyjnego podejścia i podać klucz do pobrania domyślnego ciągu języka.Alternatively, you can use the traditional approach and provide a key to retrieve the default language string. Dla wielu deweloperów nowy przepływ pracy nie ma domyślnego pliku języka . resx i po prostu zawijający literały ciągu może zmniejszyć obciążenie lokalizowania aplikacji.For many developers the new workflow of not having a default language .resx file and simply wrapping the string literals can reduce the overhead of localizing an app. Inni deweloperzy będą wolą tradycyjne przepływy pracy, ponieważ ułatwiają one pracę z dłuższymi literałami ciągów i ułatwiają aktualizowanie zlokalizowanych ciągów.Other developers will prefer the traditional work flow as it can make it easier to work with longer string literals and make it easier to update localized strings.

Użyj IHtmlLocalizer<T> implementacji dla zasobów, które zawierają kod HTML.Use the IHtmlLocalizer<T> implementation for resources that contain HTML. IHtmlLocalizer KOD HTML koduje argumenty, które są sformatowane w ciągu zasobu, ale nie kodu HTML samego samego ciągu zasobu.IHtmlLocalizer HTML encodes arguments that are formatted in the resource string, but doesn't HTML encode the resource string itself. W przykładzie wyróżnionym poniżej tylko wartość name parametru jest zakodowana w formacie HTML.In the sample highlighted below, only the value of name parameter is HTML encoded.

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();
        }

Uwaga

Ogólnie rzecz biorąc, zlokalizowany jest tylko tekst, nie HTML.Generally, only localize text, not HTML.

Na najniższym poziomie można uzyskać możliwość IStringLocalizerFactory iniekcji zależności:At the lowest level, you can get IStringLocalizerFactory out of Dependency Injection:

{
    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."];

Powyższy kod demonstruje każdą z dwóch metod tworzenia fabryk.The code above demonstrates each of the two factory create methods.

Zlokalizowane ciągi można podzielić według kontrolera, obszaru lub tylko jednego kontenera.You can partition your localized strings by controller, area, or have just one container. W aplikacji przykładowej Klasa fikcyjna o nazwie SharedResource jest używana do współużytkowanych zasobów.In the sample app, a dummy class named SharedResource is used for shared resources.

// Dummy class to group shared resources

namespace Localization
{
    public class SharedResource
    {
    }
}

Niektórzy Deweloperzy używają Startup klasy, aby zawierały ciągi globalne lub udostępnione.Some developers use the Startup class to contain global or shared strings. W poniższym przykładzie InfoController SharedResource są używane i lokalizatory:In the sample below, the InfoController and the SharedResource localizers are used:

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;
    }

Wyświetl lokalizacjęView localization

IViewLocalizerUsługa udostępnia zlokalizowane ciągi dla widoku.The IViewLocalizer service provides localized strings for a view. ViewLocalizerKlasa implementuje ten interfejs i odnajduje lokalizację zasobu ze ścieżki pliku widoku.The ViewLocalizer class implements this interface and finds the resource location from the view file path. Poniższy kod pokazuje, jak używać domyślnej implementacji IViewLocalizer :The following code shows how to use the default implementation of 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>

Domyślna implementacja programu IViewLocalizer znajduje plik zasobów na podstawie nazwy pliku widoku.The default implementation of IViewLocalizer finds the resource file based on the view's file name. Nie ma możliwości użycia globalnego pliku zasobów udostępnionych.There's no option to use a global shared resource file. ViewLocalizer implementuje lokalizatora przy użyciu IHtmlLocalizer , dlatego Razor nie KODUJ kodu HTML zlokalizowanego ciągu.ViewLocalizer implements the localizer using IHtmlLocalizer, so Razor doesn't HTML encode the localized string. Można Sparametryzuj ciągi zasobów i IViewLocalizer zakodować w kodzie HTML parametry, ale nie ciąg zasobu.You can parameterize resource strings and IViewLocalizer will HTML encode the parameters, but not the resource string. Rozważ następujące Razor oznakowanie:Consider the following Razor markup:

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

Plik zasobów francuski może zawierać następujące elementy:A French resource file could contain the following:

KluczKey WartośćValue
<i>Hello</i> <b>{0}!</b> <i>Bonjour</i> <b>{0} !</b>

Renderowany widok będzie zawierać znacznik HTML z pliku zasobu.The rendered view would contain the HTML markup from the resource file.

Uwaga

Ogólnie rzecz biorąc, zlokalizowany jest tylko tekst, nie HTML.Generally, only localize text, not HTML.

Aby użyć udostępnionego pliku zasobu w widoku, wstrzyknąć IHtmlLocalizer<T> :To use a shared resource file in a view, inject 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>

Lokalizacja adnotacjiDataAnnotations localization

Komunikaty o błędach DataAnnotations są zlokalizowane przy użyciu IStringLocalizer<T> .DataAnnotations error messages are localized with IStringLocalizer<T>. Korzystając z opcji ResourcesPath = "Resources" , komunikaty o błędach w programie RegisterViewModel mogą być przechowywane w jednej z następujących ścieżek:Using the option ResourcesPath = "Resources", the error messages in RegisterViewModel can be stored in either of the following paths:

  • Zasoby/modele widoków. Account. RegisterViewModel. fr. resxResources/ViewModels.Account.RegisterViewModel.fr.resx
  • Zasoby/modele widoków/Account/RegisterViewModel. fr. resxResources/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; }
}

W ASP.NET Core MVC 1.1.0 i wyższych atrybuty inne niż Walidacja są zlokalizowane.In ASP.NET Core MVC 1.1.0 and higher, non-validation attributes are localized. ASP.NET Core MVC 1,0 nie wyszukuje zlokalizowanych ciągów dla atrybutów niezwiązanych z walidacją.ASP.NET Core MVC 1.0 does not look up localized strings for non-validation attributes.

Używanie jednego ciągu zasobu dla wielu klasUsing one resource string for multiple classes

Poniższy kod przedstawia sposób użycia jednego ciągu zasobu do atrybutów walidacji z wieloma klasami:The following code shows how to use one resource string for validation attributes with multiple classes:

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

W poprzednim kodzie, SharedResource jest klasą odpowiadającą resx, gdzie są przechowywane Twoje wiadomości weryfikacyjne.In the preceding code, SharedResource is the class corresponding to the resx where your validation messages are stored. W tym podejściu DataAnnotations będą używać tylko SharedResource , a nie zasobów dla każdej klasy.With this approach, DataAnnotations will only use SharedResource, rather than the resource for each class.

Zapewnianie zlokalizowanych zasobów dla obsługiwanych języków i kulturProvide localized resources for the languages and cultures you support

SupportedCultures i SupportedUICulturesSupportedCultures and SupportedUICultures

ASP.NET Core pozwala określić dwie wartości kulturowe SupportedCultures i SupportedUICultures .ASP.NET Core allows you to specify two culture values, SupportedCultures and SupportedUICultures. Obiekt CultureInfo dla SupportedCultures określa wyniki funkcji zależnych od kultury, takich jak data, godzina, liczba i formatowanie waluty.The CultureInfo object for SupportedCultures determines the results of culture-dependent functions, such as date, time, number, and currency formatting. SupportedCultures określa również kolejność sortowania tekstu, Konwencji wielkości liter i porównań ciągów.SupportedCultures also determines the sorting order of text, casing conventions, and string comparisons. Zobacz CultureInfo. CurrentCulture , aby uzyskać więcej informacji na temat sposobu, w jaki serwer pobiera kulturę.See CultureInfo.CurrentCulture for more info on how the server gets the Culture. SupportedUICulturesOkreśla, które przetłumaczone ciągi (z plików resx ) są wyszukiwane przez program ResourceManager.The SupportedUICultures determines which translated strings (from .resx files) are looked up by the ResourceManager. ResourceManagerPo prostu wyszukuje ciągi specyficzne dla kultury, które są określane przez CurrentUICulture .The ResourceManager simply looks up culture-specific strings that's determined by CurrentUICulture. Każdy wątek w programie .NET CurrentCulture ma CurrentUICulture obiekty i.Every thread in .NET has CurrentCulture and CurrentUICulture objects. ASP.NET Core sprawdza te wartości podczas renderowania funkcji zależnych od kultury.ASP.NET Core inspects these values when rendering culture-dependent functions. Na przykład, jeśli kultura bieżącego wątku jest ustawiona na wartość "en-US" (angielski, Stany Zjednoczone), DateTime.Now.ToLongDateString() zostanie wyświetlona wartość "czwartek, 18 lutego, 2016", ale jeśli CurrentCulture jest ustawiona na "ES-es" (hiszpański, Hiszpania) dane wyjściowe będą "jueves, 18 de febrero de 2016".For example, if the current thread's culture is set to "en-US" (English, United States), DateTime.Now.ToLongDateString() displays "Thursday, February 18, 2016", but if CurrentCulture is set to "es-ES" (Spanish, Spain) the output will be "jueves, 18 de febrero de 2016".

Pliki zasobówResource files

Plik zasobów jest użytecznym mechanizmem oddzielania lokalizowalnych ciągów od kodu.A resource file is a useful mechanism for separating localizable strings from code. Przetłumaczone ciągi dla języka innego niż domyślny są izolowane w plikach zasobów resx .Translated strings for the non-default language are isolated in .resx resource files. Na przykład możesz chcieć utworzyć plik zasobów hiszpański o nazwie Welcome. es. resx zawierający przetłumaczone ciągi.For example, you might want to create Spanish resource file named Welcome.es.resx containing translated strings. "es" to kod języka w języku hiszpańskim."es" is the language code for Spanish. Aby utworzyć ten plik zasobów w programie Visual Studio:To create this resource file in Visual Studio:

  1. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy folder, który będzie zawierać plik zasobów, > Dodaj > nowy element .In Solution Explorer , right click on the folder which will contain the resource file > Add > New Item .

    Zagnieżdżone menu kontekstowe: w Eksplorator rozwiązań menu kontekstowe jest otwarte dla zasobów.

  2. W polu wyszukiwania zainstalowanych szablonów wprowadź "Resource" i Nazwij plik.In the Search installed templates box, enter "resource" and name the file.

    Okno dialogowe Dodawanie nowego elementu

  3. Wprowadź wartość klucza (ciąg macierzysty) w kolumnie Nazwa i przetłumaczony ciąg w kolumnie wartość .Enter the key value (native string) in the Name column and the translated string in the Value column.

    Welcome. es. resx plik (plik zasobów powitalnych dla języka hiszpańskiego) z słowem Hello w kolumnie Nazwa i słowem Hola (Hello w języku hiszpańskim) w kolumnie wartość

    Program Visual Studio wyświetla plik Welcome. es. resx .Visual Studio shows the Welcome.es.resx file.

    Eksplorator rozwiązań przedstawiający plik zasobów programu Welcome hiszpański (ES)

Nazewnictwo plików zasobówResource file naming

Zasoby są nazwane dla pełnej nazwy typu swojej klasy pomniejszonej o nazwę zestawu.Resources are named for the full type name of their class minus the assembly name. Na przykład zasób francuski w projekcie, którego głównym zestawem jest LocalizationWebsite.Web.dll dla klasy, będzie LocalizationWebsite.Web.Startup nazwany Startup. fr. resx .For example, a French resource in a project whose main assembly is LocalizationWebsite.Web.dll for the class LocalizationWebsite.Web.Startup would be named Startup.fr.resx . Zasób klasy LocalizationWebsite.Web.Controllers.HomeController nosi nazwę controllers. HomeController. fr. resx .A resource for the class LocalizationWebsite.Web.Controllers.HomeController would be named Controllers.HomeController.fr.resx . Jeśli przestrzeń nazw klasy Target nie jest taka sama jak nazwa zestawu, będzie potrzebna pełna nazwa typu.If your targeted class's namespace isn't the same as the assembly name you will need the full type name. Przykładowo w przykładowym projekcie zasób dla typu ExtraNamespace.Tools powinien mieć nazwę ExtraNamespace. Tools. fr. resx .For example, in the sample project a resource for the type ExtraNamespace.Tools would be named ExtraNamespace.Tools.fr.resx .

W przykładowym projekcie ConfigureServices Metoda ustawia ResourcesPath do "zasobów", więc ścieżka względna projektu dla francuskiego pliku zasobów kontrolera głównego to zasoby/kontrolery. HomeController. fr. resx .In the sample project, the ConfigureServices method sets the ResourcesPath to "Resources", so the project relative path for the home controller's French resource file is Resources/Controllers.HomeController.fr.resx . Alternatywnie można użyć folderów do organizowania plików zasobów.Alternatively, you can use folders to organize resource files. W przypadku kontrolera macierzystego ścieżka będzie zawierać zasoby/kontrolery/HomeController. fr. resx .For the home controller, the path would be Resources/Controllers/HomeController.fr.resx . Jeśli ta opcja nie zostanie użyta ResourcesPath , plik . resx zostanie użyty w katalogu bazowym projektu.If you don't use the ResourcesPath option, the .resx file would go in the project base directory. Plik zasobu dla HomeController nosi nazwę controllers. HomeController. fr. resx .The resource file for HomeController would be named Controllers.HomeController.fr.resx . Wybór przy użyciu konwencji nazewnictwa kropka lub ścieżki zależy od tego, w jaki sposób chcesz zorganizować pliki zasobów.The choice of using the dot or path naming convention depends on how you want to organize your resource files.

Nazwa zasobuResource name Nazwa kropka lub ścieżkiDot or path naming
Zasoby/kontrolery. HomeController. fr. resxResources/Controllers.HomeController.fr.resx KropkaDot
Zasoby/kontrolery/HomeController. fr. resxResources/Controllers/HomeController.fr.resx ŚcieżkaPath

Pliki zasobów używające @inject IViewLocalizer w Razor widokach są zgodne z podobnym wzorcem.Resource files using @inject IViewLocalizer in Razor views follow a similar pattern. Plik zasobów dla widoku może być nazwany przy użyciu nazw kropek lub nazw ścieżek.The resource file for a view can be named using either dot naming or path naming. Razor Wyświetl pliki zasobów, aby naśladować ścieżkę skojarzonego pliku widoku.Razor view resource files mimic the path of their associated view file. Przy założeniu, że ustawimy ResourcesPath na "zasoby", plik zasobów francuski skojarzony z widokiem /Home/about. cshtml może mieć jedną z następujących wartości:Assuming we set the ResourcesPath to "Resources", the French resource file associated with the Views/Home/About.cshtml view could be either of the following:

  • Zasoby/widoki/Strona główna/informacje. fr. resxResources/Views/Home/About.fr.resx

  • Zasoby/widoki. Strona główna. informacje. fr. resxResources/Views.Home.About.fr.resx

Jeśli opcja nie zostanie użyta ResourcesPath , plik resx dla widoku powinien znajdować się w tym samym folderze co widok.If you don't use the ResourcesPath option, the .resx file for a view would be located in the same folder as the view.

RootNamespaceAttributeRootNamespaceAttribute

Atrybut RootNamespace udostępnia główną przestrzeń nazw zestawu, gdy główna przestrzeń nazw zestawu jest inna niż nazwa zestawu.The RootNamespace attribute provides the root namespace of an assembly when the root namespace of an assembly is different than the assembly name.

Ostrzeżenie

Taka sytuacja może wystąpić, gdy nazwa projektu nie jest prawidłowym identyfikatorem platformy .NET.This can occur when a project's name is not a valid .NET identifier. Na przykład my-project-name.csproj użyje głównej przestrzeni nazw my_project_name i nazwy zestawu my-project-name prowadzącej do tego błędu.For instance my-project-name.csproj will use the root namespace my_project_name and the assembly name my-project-name leading to this error.

Jeśli główna przestrzeń nazw zestawu jest inna niż nazwa zestawu:If the root namespace of an assembly is different than the assembly name:

  • Lokalizacja nie działa domyślnie.Localization does not work by default.
  • Lokalizowanie nie powiedzie się z powodu sposobu wyszukiwania zasobów w zestawie.Localization fails due to the way resources are searched for within the assembly. RootNamespace jest wartością czasu kompilacji, która nie jest dostępna dla wykonywanego procesu.RootNamespace is a build-time value which is not available to the executing process.

Jeśli RootNamespace różni się od AssemblyName , należy uwzględnić następujące w AssemblyInfo.cs (z wartościami parametrów zamienionymi na wartości rzeczywiste):If the RootNamespace is different from the AssemblyName, include the following in AssemblyInfo.cs (with parameter values replaced with the actual values):

using System.Reflection;
using Microsoft.Extensions.Localization;

[assembly: ResourceLocation("Resource Folder Name")]
[assembly: RootNamespace("App Root Namespace")]

Poprzedni kod umożliwia pomyślne rozpoznanie plików resx.The preceding code enables the successful resolution of resx files.

Zachowanie rezerwowe kulturyCulture fallback behavior

Podczas wyszukiwania zasobu lokalizacja prowadzi do "rezerwy kulturowej".When searching for a resource, localization engages in "culture fallback". Jeśli nie zostanie znaleziona, rozpoczyna się od żądanej kultury, przywraca kulturę nadrzędną tej kultury.Starting from the requested culture, if not found, it reverts to the parent culture of that culture. Poza tym Właściwość CultureInfo. Parent reprezentuje kulturę nadrzędną.As an aside, the CultureInfo.Parent property represents the parent culture. Zwykle (ale nie zawsze) oznacza usunięcie z ISO.This usually (but not always) means removing the national signifier from the ISO. Na przykład dialekt języka hiszpańskiego wymawianego w Meksyku to "es-MX".For example, the dialect of Spanish spoken in Mexico is "es-MX". Jest to wersja Hiszpańska "es", która — nie jest specyficzna dla żadnego z krajów.It has the parent "es"—Spanish non-specific to any country.

Wyobraź sobie, że witryna otrzymuje żądanie dotyczące zasobu "Welcome" przy użyciu kultury "fr-CA".Imagine your site receives a request for a "Welcome" resource using culture "fr-CA". System lokalizacji wyszukuje następujące zasoby w kolejności i wybiera pierwsze dopasowanie:The localization system looks for the following resources, in order, and selects the first match:

  • Welcome.fr — CA. resxWelcome.fr-CA.resx
  • Witamy. fr. resxWelcome.fr.resx
  • Welcome. resx (Jeśli NeutralResourcesLanguage jest "fr-CA")Welcome.resx (if the NeutralResourcesLanguage is "fr-CA")

Na przykład, jeśli usuniesz oznaczenie kultury ". fr" i masz kulturę ustawioną na francuski, domyślny plik zasobów jest odczytywany, a ciągi są zlokalizowane.As an example, if you remove the ".fr" culture designator and you have the culture set to French, the default resource file is read and strings are localized. Menedżer zasobów określa domyślny lub rezerwowy zasób, gdy nic nie spełnia wymaganej kultury.The Resource manager designates a default or fallback resource for when nothing meets your requested culture. Jeśli chcesz po prostu zwrócić klucz, gdy brakuje zasobu dla wymaganej kultury, nie musisz mieć domyślnego pliku zasobów.If you want to just return the key when missing a resource for the requested culture you must not have a default resource file.

Generowanie plików zasobów przy użyciu programu Visual StudioGenerate resource files with Visual Studio

Jeśli utworzysz plik zasobów w programie Visual Studio bez kultury w nazwie pliku (na przykład Welcome. resx ), program Visual Studio utworzy klasę języka C# z właściwością dla każdego ciągu.If you create a resource file in Visual Studio without a culture in the file name (for example, Welcome.resx ), Visual Studio will create a C# class with a property for each string. Zwykle nie jest to możliwe dzięki ASP.NET Core.That's usually not what you want with ASP.NET Core. Zazwyczaj nie istnieje domyślny plik zasobów resx (plik . resx bez nazwy kultury).You typically don't have a default .resx resource file (a .resx file without the culture name). Zalecamy utworzenie pliku resx z nazwą kultury (na przykład Welcome. fr. resx ).We suggest you create the .resx file with a culture name (for example Welcome.fr.resx ). Podczas tworzenia pliku resx przy użyciu nazwy kultury program Visual Studio nie generuje pliku klasy.When you create a .resx file with a culture name, Visual Studio won't generate the class file.

Dodaj inne kulturyAdd other cultures

Każda kombinacja języka i kultury (oprócz języka domyślnego) wymaga unikatowego pliku zasobów.Each language and culture combination (other than the default language) requires a unique resource file. Tworzysz pliki zasobów dla różnych kultur i ustawień regionalnych, tworząc nowe pliki zasobów, w których kody języka ISO są częścią nazwy pliku (na przykład en-us , fr-CA i pl-GB ).You create resource files for different cultures and locales by creating new resource files in which the ISO language codes are part of the file name (for example, en-us , fr-ca , and en-gb ). Te kody ISO są umieszczane między nazwami plików i rozszerzeniem resx , jak w Welcome.es-MX. resx (hiszpański/Meksyk).These ISO codes are placed between the file name and the .resx file extension, as in Welcome.es-MX.resx (Spanish/Mexico).

Zaimplementuj strategię, aby wybrać język/kulturę dla każdego żądaniaImplement a strategy to select the language/culture for each request

Konfigurowanie lokalizacjiConfigure localization

Lokalizacja jest skonfigurowana w ramach Startup.ConfigureServices metody:Localization is configured in the Startup.ConfigureServices method:

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

services.AddMvc()
    .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
    .AddDataAnnotationsLocalization();
  • AddLocalization dodaje usługi lokalizacyjne do kontenera usług.AddLocalization adds the localization services to the services container. Powyższy kod również ustawia ścieżkę zasobów na "zasoby".The code above also sets the resources path to "Resources".

  • AddViewLocalization dodaje obsługę zlokalizowanych plików widoku.AddViewLocalization adds support for localized view files. Ta lokalizacja widoku przykładowego jest oparta na sufiksie pliku widoku.In this sample view localization is based on the view file suffix. Na przykład "fr" w pliku index. fr. cshtml .For example "fr" in the Index.fr.cshtml file.

  • AddDataAnnotationsLocalization dodaje obsługę zlokalizowanych DataAnnotations komunikatów weryfikacyjnych za pomocą IStringLocalizer abstrakcji.AddDataAnnotationsLocalization adds support for localized DataAnnotations validation messages through IStringLocalizer abstractions.

Oprogramowanie pośredniczące lokalizacjiLocalization middleware

Bieżąca kultura w żądaniu jest ustawiana w oprogramowaniu pośredniczącymlokalizacji.The current culture on a request is set in the localization Middleware. Oprogramowanie pośredniczące lokalizacji jest włączone w tej Startup.Configure metodzie.The localization middleware is enabled in the Startup.Configure method. Oprogramowanie pośredniczące lokalizacyjne musi być skonfigurowane przed jakimkolwiek oprogramowanie pośredniczące, które może sprawdzić kulturę żądania (na przykład app.UseMvcWithDefaultRoute() ).The localization middleware must be configured before any middleware which might check the request culture (for example, app.UseMvcWithDefaultRoute()).

var supportedCultures = new[] { "en-US", "fr" };
var localizationOptions = new RequestLocalizationOptions().SetDefaultCulture(supportedCultures[0])
    .AddSupportedCultures(supportedCultures)
    .AddSupportedUICultures(supportedCultures);

app.UseRequestLocalization(localizationOptions);

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

app.UseAuthentication();

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

Jeśli chcesz zobaczyć Komentarze do kodu przetłumaczone na języki inne niż angielski, poinformuj nas o tym problemie z dyskusjąw witrynie GitHub.If you would like to see code comments translated to languages other than English, let us know in this GitHub discussion issue.

UseRequestLocalization Inicjuje RequestLocalizationOptions obiekt.UseRequestLocalization initializes a RequestLocalizationOptions object. Na każdym zażądaniu listy RequestCultureProvider w programie RequestLocalizationOptions jest wyliczany, a pierwszy dostawca, który może pomyślnie ustalić kulturę żądań, jest używany.On every request the list of RequestCultureProvider in the RequestLocalizationOptions is enumerated and the first provider that can successfully determine the request culture is used. Dostawcy domyślnie pochodzą z RequestLocalizationOptions klasy:The default providers come from the RequestLocalizationOptions class:

  1. QueryStringRequestCultureProvider
  2. CookieRequestCultureProvider
  3. AcceptLanguageHeaderRequestCultureProvider

Lista domyślna przechodzi od najbardziej konkretnych do najmniej określonych.The default list goes from most specific to least specific. W dalszej części artykułu zobaczymy, jak można zmienić kolejność, a nawet dodać niestandardowego dostawcę kultury.Later in the article we'll see how you can change the order and even add a custom culture provider. Jeśli żaden z dostawców nie może określić kultury żądania, DefaultRequestCulture jest używana.If none of the providers can determine the request culture, the DefaultRequestCulture is used.

QueryStringRequestCultureProviderQueryStringRequestCultureProvider

Niektóre aplikacje będą używać ciągu zapytania do ustawienia /dotnet/api/system.globalization.cultureinfo?view=netcore-3.1 .Some apps will use a query string to set the /dotnet/api/system.globalization.cultureinfo?view=netcore-3.1. W przypadku aplikacji korzystających z cookie metody nagłówka lub Accept-Language dodanie ciągu zapytania do adresu URL jest przydatne w przypadku debugowania i testowania kodu.For apps that use the cookie or Accept-Language header approach, adding a query string to the URL is useful for debugging and testing code. Domyślnie program QueryStringRequestCultureProvider jest rejestrowany jako pierwszy dostawca lokalizacji na RequestCultureProvider liście.By default, the QueryStringRequestCultureProvider is registered as the first localization provider in the RequestCultureProvider list. Parametry ciągu zapytania są przekazywane culture i ui-culture .You pass the query string parameters culture and ui-culture. Poniższy przykład ustawia określoną kulturę (język i region) na hiszpański/Meksyk:The following example sets the specific culture (language and region) to Spanish/Mexico:

http://localhost:5000/?culture=es-MX&ui-culture=es-MX

Jeśli przekazujesz tylko jeden z dwóch ( culture lub ui-culture ), dostawca ciągu zapytania ustawi obie wartości przy użyciu przekazanego elementu.If you only pass in one of the two (culture or ui-culture), the query string provider will set both values using the one you passed in. Na przykład ustawienie tylko kulturowe ustawi zarówno, Culture jak i UICulture :For example, setting just the culture will set both the Culture and the UICulture:

http://localhost:5000/?culture=es-MX

CookieRequestCultureProviderCookieRequestCultureProvider

Aplikacje produkcyjne często udostępniają mechanizm ustawiania kultury z kulturą ASP.NET Coreową cookie .Production apps will often provide a mechanism to set the culture with the ASP.NET Core culture cookie. Użyj MakeCookieValue metody, aby utworzyć cookie .Use the MakeCookieValue method to create a cookie.

CookieRequestCultureProvider DefaultCookieName Zwraca domyślną cookie nazwę używaną do śledzenia informacji o preferowanej kulturze użytkownika.The CookieRequestCultureProvider DefaultCookieName returns the default cookie name used to track the user's preferred culture information. Nazwa domyślna cookie to .AspNetCore.Culture .The default cookie name is .AspNetCore.Culture.

cookieFormat to c=%LANGCODE%|uic=%LANGCODE% , gdzie c is Culture i uic is UICulture , na przykład:The cookie format is c=%LANGCODE%|uic=%LANGCODE%, where c is Culture and uic is UICulture, for example:

c=en-UK|uic=en-US

Jeśli określisz tylko jedną z informacji o kulturze i kulturze interfejsu użytkownika, określona kultura zostanie użyta dla informacji kultury i kultury interfejsu użytkownika.If you only specify one of culture info and UI culture, the specified culture will be used for both culture info and UI culture.

Accept-Language nagłówek HTTPThe Accept-Language HTTP header

Nagłówek Accept-Language jest settable w większości przeglądarek i był pierwotnie przeznaczony do określenia języka użytkownika.The Accept-Language header is settable in most browsers and was originally intended to specify the user's language. To ustawienie wskazuje, co przeglądarka została ustawiona do wysłania lub która dziedziczy z bazowego systemu operacyjnego.This setting indicates what the browser has been set to send or has inherited from the underlying operating system. Accept-Language nagłówku HTTP z żądania przeglądarki nie jest INFALLIBLE sposób wykrywania preferowanego języka użytkownika (zobacz Ustawianie preferencji językowych w przeglądarce).The Accept-Language HTTP header from a browser request isn't an infallible way to detect the user's preferred language (see Setting language preferences in a browser). Aplikacja produkcyjna powinna uwzględniać sposób, w jaki użytkownik może dostosować wybór kultury.A production app should include a way for a user to customize their choice of culture.

Ustawianie Accept-Language nagłówku HTTP w programie IESet the Accept-Language HTTP header in IE

  1. Na ikonie koła zębatego naciśnij pozycję Opcje internetowe .From the gear icon, tap Internet Options .

  2. Naciśnij pozycję Języki .Tap Languages .

    Opcje internetowe

  3. Naciśnij pozycję Ustaw preferencje językowe .Tap Set Language Preferences .

  4. Naciśnij pozycję Dodaj język .Tap Add a language .

  5. Dodaj język.Add the language.

  6. Naciśnij pozycję język, a następnie naciśnij pozycję Przenieś w górę .Tap the language, then tap Move Up .

Używanie dostawcy niestandardowegoUse a custom provider

Załóżmy, że chcesz zezwolić klientom na przechowywanie w swoich bazach danych językowych i kulturowych.Suppose you want to let your customers store their language and culture in your databases. Można napisać dostawcę, aby wyszukać te wartości dla użytkownika.You could write a provider to look up these values for the user. Poniższy kod pokazuje, jak dodać niestandardowego dostawcę:The following code shows how to add a custom provider:

private const string enUSCulture = "en-US";

services.Configure<RequestLocalizationOptions>(options =>
{
    var supportedCultures = new[]
    {
        new CultureInfo(enUSCulture),
        new CultureInfo("fr")
    };

    options.DefaultRequestCulture = new RequestCulture(culture: enUSCulture, uiCulture: enUSCulture);
    options.SupportedCultures = supportedCultures;
    options.SupportedUICultures = supportedCultures;

    options.RequestCultureProviders.Insert(0, new CustomRequestCultureProvider(async context =>
    {
        // My custom request culture logic
        return new ProviderCultureResult("en");
    }));
});

Służy RequestLocalizationOptions do dodawania lub usuwania dostawców lokalizacji.Use RequestLocalizationOptions to add or remove localization providers.

Ustaw kulturę programowoSet the culture programmatically

Ten przykład lokalizacji. StarterWeb projekt w witrynie GitHub zawiera interfejs użytkownika służący do ustawiania Culture .This sample Localization.StarterWeb project on GitHub contains UI to set the Culture. Plik views/Shared/_SelectLanguagePartial. cshtml umożliwia wybranie kultury z listy obsługiwanych kultur:The Views/Shared/_SelectLanguagePartial.cshtml file allows you to select the culture from the list of supported cultures:

@using Microsoft.AspNetCore.Builder
@using Microsoft.AspNetCore.Http.Features
@using Microsoft.AspNetCore.Localization
@using Microsoft.AspNetCore.Mvc.Localization
@using Microsoft.Extensions.Options

@inject IViewLocalizer Localizer
@inject IOptions<RequestLocalizationOptions> LocOptions

@{
    var requestCulture = Context.Features.Get<IRequestCultureFeature>();
    var cultureItems = LocOptions.Value.SupportedUICultures
        .Select(c => new SelectListItem { Value = c.Name, Text = c.DisplayName })
        .ToList();
    var returnUrl = string.IsNullOrEmpty(Context.Request.Path) ? "~/" : $"~{Context.Request.Path.Value}";
}

<div title="@Localizer["Request culture provider:"] @requestCulture?.Provider?.GetType().Name">
    <form id="selectLanguage" asp-controller="Home" 
          asp-action="SetLanguage" asp-route-returnUrl="@returnUrl" 
          method="post" class="form-horizontal" role="form">
        <label asp-for="@requestCulture.RequestCulture.UICulture.Name">@Localizer["Language:"]</label> <select name="culture"
          onchange="this.form.submit();"
          asp-for="@requestCulture.RequestCulture.UICulture.Name" asp-items="cultureItems">
        </select>
    </form>
</div>

Plik views/Shared/_SelectLanguagePartial. cshtml zostanie dodany do footer sekcji pliku układu, więc będzie dostępny dla wszystkich widoków:The Views/Shared/_SelectLanguagePartial.cshtml file is added to the footer section of the layout file so it will be available to all views:

<div class="container body-content" style="margin-top:60px">
    @RenderBody()
    <hr>
    <footer>
        <div class="row">
            <div class="col-md-6">
                <p>&copy; @System.DateTime.Now.Year - Localization</p>
            </div>
            <div class="col-md-6 text-right">
                @await Html.PartialAsync("_SelectLanguagePartial")
            </div>
        </div>
    </footer>
</div>

SetLanguageMetoda ustawia kulturę cookie .The SetLanguage method sets the culture cookie.

[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);
}

Nie można podłączyć _SelectLanguagePartial. cshtml do przykładowego kodu dla tego projektu.You can't plug in the _SelectLanguagePartial.cshtml to sample code for this project. Projekt Lokalizacja. StarterWeb w usłudze GitHub ma kod, który umożliwia RequestLocalizationOptions Razor Przechodzenie do częściowej przez kontener iniekcji zależności .The Localization.StarterWeb project on GitHub has code to flow the RequestLocalizationOptions to a Razor partial through the Dependency Injection container.

Dane tras powiązań modelu i ciągi zapytaniaModel binding route data and query strings

Zobacz zachowanie globalizacji powiązań modelu powiązanie danych i ciągi zapytań.See Globalization behavior of model binding route data and query strings.

Warunki globalizacji i lokalizacjaGlobalization and localization terms

Proces lokalizowania aplikacji wymaga również podstawowej znajomości odpowiednich zestawów znaków, które są często używane w nowoczesnych opracowywaniu oprogramowania i zrozumieniu skojarzonych z nimi problemów.The process of localizing your app also requires a basic understanding of relevant character sets commonly used in modern software development and an understanding of the issues associated with them. Mimo że wszystkie komputery przechowują tekst jako cyfry (kody), różne systemy przechowują ten sam tekst przy użyciu różnych liczb.Although all computers store text as numbers (codes), different systems store the same text using different numbers. Proces lokalizowania dotyczy tłumaczenia interfejsu użytkownika aplikacji (UI) dla określonych kultur/ustawień regionalnych.The localization process refers to translating the app user interface (UI) for a specific culture/locale.

Możliwość lokalizowania to proces pośredni służący do sprawdzania, czy aplikacja globalna jest gotowa do lokalizacji.Localizability is an intermediate process for verifying that a globalized app is ready for localization.

Format RFC 4646 dla nazwy kultury to <languagecode2>-<country/regioncode2> , gdzie <languagecode2> jest kodem języka i <country/regioncode2> jest kodem podkultury.The RFC 4646 format for the culture name is <languagecode2>-<country/regioncode2>, where <languagecode2> is the language code and <country/regioncode2> is the subculture code. Na przykład es-CL w przypadku języka hiszpańskiego (Chile) en-US dla języka angielskiego (Stany Zjednoczone) i en-AU dla języka angielskiego (Australia).For example, es-CL for Spanish (Chile), en-US for English (United States), and en-AU for English (Australia). RFC 4646 jest kombinacją kodu ISO 639 2 litery małymi literami związanymi z językiem i ISO 3166 2 literą w postaci wielkiej litery, skojarzonej z krajem lub regionem.RFC 4646 is a combination of an ISO 639 two-letter lowercase culture code associated with a language and an ISO 3166 two-letter uppercase subculture code associated with a country or region. Zobacz: /previous-versions/commerce-server/ee825488(v=cs.20).See /previous-versions/commerce-server/ee825488(v=cs.20).

Międzynarodowe jest często skracane do "I18N".Internationalization is often abbreviated to "I18N". Skrót przyjmuje pierwszą i ostatnią literę oraz liczbę liter między nimi, więc 18 oznacza liczbę liter między pierwszym "I" i ostatnim "N".The abbreviation takes the first and last letters and the number of letters between them, so 18 stands for the number of letters between the first "I" and the last "N". Dotyczy to zarówno globalizacji (G11N), jak i lokalizacji (L10N).The same applies to Globalization (G11N), and Localization (L10N).

OdsetkTerms:

  • Globalizacja (G11N): proces tworzenia aplikacji w różnych językach i regionach.Globalization (G11N): The process of making an app support different languages and regions.
  • Lokalizacja (L10N): proces dostosowywania aplikacji dla danego języka i regionu.Localization (L10N): The process of customizing an app for a given language and region.
  • Międzynarodowe (I18N): opisuje zarówno globalizację, jak i lokalizację.Internationalization (I18N): Describes both globalization and localization.
  • Kultura: jest to język i, opcjonalnie, region.Culture: It's a language and, optionally, a region.
  • Kultura neutralna: kultura, która ma określony język, ale nie region.Neutral culture: A culture that has a specified language, but not a region. (na przykład "en", "es")(for example "en", "es")
  • Określona kultura: kultura, która ma określony język i region.Specific culture: A culture that has a specified language and region. (na przykład "en-US", "pl-GB", "es-CL")(for example "en-US", "en-GB", "es-CL")
  • Kultura nadrzędna: neutralna kultura, która zawiera określoną kulturę.Parent culture: The neutral culture that contains a specific culture. (na przykład "en" jest kulturą nadrzędną wartości "pl-US" i "pl-GB")(for example, "en" is the parent culture of "en-US" and "en-GB")
  • Ustawienia regionalne: ustawienie regionalne jest takie samo jak kultura.Locale: A locale is the same as a culture.

Uwaga

Wprowadzanie przecinków dziesiętnych w polach dziesiętnych może być niemożna wprowadzić przecinków dziesiętnych.You may not be able to enter decimal commas in decimal fields. Aby obsługiwać sprawdzanie poprawności jQuery dla ustawień regionalnych innych niż angielskie, które używają przecinka (",") dla przecinka dziesiętnego i formatów daty spoza języka AMERYKAŃSKIEgo, należy podjąć kroki w celu zglobalizowania aplikacji.To support jQuery validation for non-English locales that use a comma (",") for a decimal point, and non US-English date formats, you must take steps to globalize your app. Zobacz ten problem GitHub 4076 instrukcje dotyczące dodawania przecinka dziesiętnego.See this GitHub issue 4076 for instructions on adding decimal comma.

Dodatkowe zasobyAdditional resources

Rick Anderson, Damien Bowden, Bart Calixto, Nadeem Afanai Hisham bin AteyaBy Rick Anderson, Damien Bowden, Bart Calixto, Nadeem Afana, and Hisham Bin Ateya

Witryna internetowa w wielu językach umożliwia dostęp do szerszego grona użytkowników.A multilingual website allows the site to reach a wider audience. ASP.NET Core udostępnia usługi i oprogramowanie pośredniczące do lokalizowania w różnych językach i kulturach.ASP.NET Core provides services and middleware for localizing into different languages and cultures.

Między innymi są używane globalizacji i lokalizacje.Internationalization involves Globalization and Localization. Globalizacja to proces projektowania aplikacji, które obsługują różne kultury.Globalization is the process of designing apps that support different cultures. Globalizacja dodaje obsługę danych wejściowych, wyświetlanych i wyjściowych zdefiniowanego zestawu skryptów języka, które odnoszą się do określonych obszarów geograficznych.Globalization adds support for input, display, and output of a defined set of language scripts that relate to specific geographic areas.

Lokalizacja to proces adaptacji aplikacji, która została już przetworzona w celu zlokalizowania, do określonej kultury lub ustawień regionalnych.Localization is the process of adapting a globalized app, which you have already processed for localizability, to a particular culture/locale. Aby uzyskać więcej informacji , zobacz sekcję globalizacja i warunki lokalizacji na końcu tego dokumentu.For more information see Globalization and localization terms near the end of this document.

Lokalizacja aplikacji obejmuje następujące elementy:App localization involves the following:

  1. Ustaw lokalizowalność zawartości aplikacjiMake the app's content localizable
  2. Zapewnianie zlokalizowanych zasobów dla obsługiwanych języków i kulturProvide localized resources for the languages and cultures you support
  3. Zaimplementuj strategię, aby wybrać język/kulturę dla każdego żądaniaImplement a strategy to select the language/culture for each request

Wyświetl lub pobierz przykładowy kod (jak pobrać)View or download sample code (how to download)

Ustaw lokalizowalność zawartości aplikacjiMake the app's content localizable

IStringLocalizer i IStringLocalizer<T> zostały zaprojektowane w celu zwiększenia produktywności podczas tworzenia zlokalizowanych aplikacji.IStringLocalizer and IStringLocalizer<T> were architected to improve productivity when developing localized apps. IStringLocalizer używa ResourceManager i ResourceReader w celu zapewnienia zasobów specyficznych dla kultury w czasie wykonywania.IStringLocalizer uses the ResourceManager and ResourceReader to provide culture-specific resources at run time. Interfejs ma indeksator i IEnumerable zwraca zlokalizowane ciągi.The interface has an indexer and an IEnumerable for returning localized strings. IStringLocalizer nie wymaga zapisywania w pliku zasobów domyślnych ciągów języka.IStringLocalizer doesn't require storing the default language strings in a resource file. Możesz tworzyć aplikacje przeznaczone do lokalizacji i nie musisz już tworzyć plików zasobów w fazie opracowywania.You can develop an app targeted for localization and not need to create resource files early in development. Poniższy kod przedstawia sposób zawijania ciągu "informacje o tytule" dla lokalizacji.The code below shows how to wrap the string "About Title" for localization.

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"];
        }
    }
}

W poprzednim kodzie IStringLocalizer<T> implementacja pochodzi z iniekcji zależności.In the preceding code, the IStringLocalizer<T> implementation comes from Dependency Injection. Jeśli zlokalizowana wartość "informacje o tytule" nie zostanie znaleziona, zostanie zwrócony klucz indeksatora, czyli ciąg "informacje o tytule".If the localized value of "About Title" isn't found, then the indexer key is returned, that is, the string "About Title". Możesz pozostawić domyślne ciągi literałów języka w aplikacji i otoczyć je w lokalizatorze, aby można było skupić się na tworzeniu aplikacji.You can leave the default language literal strings in the app and wrap them in the localizer, so that you can focus on developing the app. Tworzysz aplikację przy użyciu języka domyślnego i przygotujesz ją do kroku lokalizacji bez wcześniejszego tworzenia domyślnego pliku zasobów.You develop your app with your default language and prepare it for the localization step without first creating a default resource file. Alternatywnie można użyć tradycyjnego podejścia i podać klucz do pobrania domyślnego ciągu języka.Alternatively, you can use the traditional approach and provide a key to retrieve the default language string. Dla wielu deweloperów nowy przepływ pracy nie ma domyślnego pliku języka . resx i po prostu zawijający literały ciągu może zmniejszyć obciążenie lokalizowania aplikacji.For many developers the new workflow of not having a default language .resx file and simply wrapping the string literals can reduce the overhead of localizing an app. Inni deweloperzy będą wolą tradycyjne przepływy pracy, ponieważ ułatwiają one pracę z dłuższymi literałami ciągów i ułatwiają aktualizowanie zlokalizowanych ciągów.Other developers will prefer the traditional work flow as it can make it easier to work with longer string literals and make it easier to update localized strings.

Użyj IHtmlLocalizer<T> implementacji dla zasobów, które zawierają kod HTML.Use the IHtmlLocalizer<T> implementation for resources that contain HTML. IHtmlLocalizer KOD HTML koduje argumenty, które są sformatowane w ciągu zasobu, ale nie kodu HTML samego samego ciągu zasobu.IHtmlLocalizer HTML encodes arguments that are formatted in the resource string, but doesn't HTML encode the resource string itself. W przykładzie wyróżnionym poniżej tylko wartość name parametru jest zakodowana w formacie HTML.In the sample highlighted below, only the value of name parameter is HTML encoded.

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();
        }

Uwaga

Ogólnie rzecz biorąc, zlokalizowany jest tylko tekst, nie HTML.Generally, only localize text, not HTML.

Na najniższym poziomie można uzyskać możliwość IStringLocalizerFactory iniekcji zależności:At the lowest level, you can get IStringLocalizerFactory out of Dependency Injection:

{
    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."];

Powyższy kod demonstruje każdą z dwóch metod tworzenia fabryk.The code above demonstrates each of the two factory create methods.

Zlokalizowane ciągi można podzielić według kontrolera, obszaru lub tylko jednego kontenera.You can partition your localized strings by controller, area, or have just one container. W aplikacji przykładowej Klasa fikcyjna o nazwie SharedResource jest używana do współużytkowanych zasobów.In the sample app, a dummy class named SharedResource is used for shared resources.

// Dummy class to group shared resources

namespace Localization
{
    public class SharedResource
    {
    }
}

Niektórzy Deweloperzy używają Startup klasy, aby zawierały ciągi globalne lub udostępnione.Some developers use the Startup class to contain global or shared strings. W poniższym przykładzie InfoController SharedResource są używane i lokalizatory:In the sample below, the InfoController and the SharedResource localizers are used:

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;
    }

Wyświetl lokalizacjęView localization

IViewLocalizerUsługa udostępnia zlokalizowane ciągi dla widoku.The IViewLocalizer service provides localized strings for a view. ViewLocalizerKlasa implementuje ten interfejs i odnajduje lokalizację zasobu ze ścieżki pliku widoku.The ViewLocalizer class implements this interface and finds the resource location from the view file path. Poniższy kod pokazuje, jak używać domyślnej implementacji IViewLocalizer :The following code shows how to use the default implementation of 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>

Domyślna implementacja programu IViewLocalizer znajduje plik zasobów na podstawie nazwy pliku widoku.The default implementation of IViewLocalizer finds the resource file based on the view's file name. Nie ma możliwości użycia globalnego pliku zasobów udostępnionych.There's no option to use a global shared resource file. ViewLocalizer implementuje lokalizatora przy użyciu IHtmlLocalizer , dlatego Razor nie KODUJ kodu HTML zlokalizowanego ciągu.ViewLocalizer implements the localizer using IHtmlLocalizer, so Razor doesn't HTML encode the localized string. Można Sparametryzuj ciągi zasobów i IViewLocalizer zakodować w kodzie HTML parametry, ale nie ciąg zasobu.You can parameterize resource strings and IViewLocalizer will HTML encode the parameters, but not the resource string. Rozważ następujące Razor oznakowanie:Consider the following Razor markup:

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

Plik zasobów francuski może zawierać następujące elementy:A French resource file could contain the following:

KluczKey WartośćValue
<i>Hello</i> <b>{0}!</b> <i>Bonjour</i> <b>{0} !</b>

Renderowany widok będzie zawierać znacznik HTML z pliku zasobu.The rendered view would contain the HTML markup from the resource file.

Uwaga

Ogólnie rzecz biorąc, zlokalizowany jest tylko tekst, nie HTML.Generally, only localize text, not HTML.

Aby użyć udostępnionego pliku zasobu w widoku, wstrzyknąć IHtmlLocalizer<T> :To use a shared resource file in a view, inject 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>

Lokalizacja adnotacjiDataAnnotations localization

Komunikaty o błędach DataAnnotations są zlokalizowane przy użyciu IStringLocalizer<T> .DataAnnotations error messages are localized with IStringLocalizer<T>. Korzystając z opcji ResourcesPath = "Resources" , komunikaty o błędach w programie RegisterViewModel mogą być przechowywane w jednej z następujących ścieżek:Using the option ResourcesPath = "Resources", the error messages in RegisterViewModel can be stored in either of the following paths:

  • Zasoby/modele widoków. Account. RegisterViewModel. fr. resxResources/ViewModels.Account.RegisterViewModel.fr.resx
  • Zasoby/modele widoków/Account/RegisterViewModel. fr. resxResources/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; }
}

W ASP.NET Core MVC 1.1.0 i wyższych atrybuty inne niż Walidacja są zlokalizowane.In ASP.NET Core MVC 1.1.0 and higher, non-validation attributes are localized. ASP.NET Core MVC 1,0 nie wyszukuje zlokalizowanych ciągów dla atrybutów niezwiązanych z walidacją.ASP.NET Core MVC 1.0 does not look up localized strings for non-validation attributes.

Używanie jednego ciągu zasobu dla wielu klasUsing one resource string for multiple classes

Poniższy kod przedstawia sposób użycia jednego ciągu zasobu do atrybutów walidacji z wieloma klasami:The following code shows how to use one resource string for validation attributes with multiple classes:

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

W poprzednim kodzie, SharedResource jest klasą odpowiadającą resx, gdzie są przechowywane Twoje wiadomości weryfikacyjne.In the preceding code, SharedResource is the class corresponding to the resx where your validation messages are stored. W tym podejściu DataAnnotations będą używać tylko SharedResource , a nie zasobów dla każdej klasy.With this approach, DataAnnotations will only use SharedResource, rather than the resource for each class.

Zapewnianie zlokalizowanych zasobów dla obsługiwanych języków i kulturProvide localized resources for the languages and cultures you support

SupportedCultures i SupportedUICulturesSupportedCultures and SupportedUICultures

ASP.NET Core pozwala określić dwie wartości kulturowe SupportedCultures i SupportedUICultures .ASP.NET Core allows you to specify two culture values, SupportedCultures and SupportedUICultures. Obiekt CultureInfo dla SupportedCultures określa wyniki funkcji zależnych od kultury, takich jak data, godzina, liczba i formatowanie waluty.The CultureInfo object for SupportedCultures determines the results of culture-dependent functions, such as date, time, number, and currency formatting. SupportedCultures określa również kolejność sortowania tekstu, Konwencji wielkości liter i porównań ciągów.SupportedCultures also determines the sorting order of text, casing conventions, and string comparisons. Zobacz CultureInfo. CurrentCulture , aby uzyskać więcej informacji na temat sposobu, w jaki serwer pobiera kulturę.See CultureInfo.CurrentCulture for more info on how the server gets the Culture. SupportedUICulturesOkreśla, które przetłumaczone ciągi (z plików resx ) są wyszukiwane przez program ResourceManager.The SupportedUICultures determines which translated strings (from .resx files) are looked up by the ResourceManager. ResourceManagerPo prostu wyszukuje ciągi specyficzne dla kultury, które są określane przez CurrentUICulture .The ResourceManager simply looks up culture-specific strings that's determined by CurrentUICulture. Każdy wątek w programie .NET CurrentCulture ma CurrentUICulture obiekty i.Every thread in .NET has CurrentCulture and CurrentUICulture objects. ASP.NET Core sprawdza te wartości podczas renderowania funkcji zależnych od kultury.ASP.NET Core inspects these values when rendering culture-dependent functions. Na przykład, jeśli kultura bieżącego wątku jest ustawiona na wartość "en-US" (angielski, Stany Zjednoczone), DateTime.Now.ToLongDateString() zostanie wyświetlona wartość "czwartek, 18 lutego, 2016", ale jeśli CurrentCulture jest ustawiona na "ES-es" (hiszpański, Hiszpania) dane wyjściowe będą "jueves, 18 de febrero de 2016".For example, if the current thread's culture is set to "en-US" (English, United States), DateTime.Now.ToLongDateString() displays "Thursday, February 18, 2016", but if CurrentCulture is set to "es-ES" (Spanish, Spain) the output will be "jueves, 18 de febrero de 2016".

Pliki zasobówResource files

Plik zasobów jest użytecznym mechanizmem oddzielania lokalizowalnych ciągów od kodu.A resource file is a useful mechanism for separating localizable strings from code. Przetłumaczone ciągi dla języka innego niż domyślny są izolowane w plikach zasobów resx .Translated strings for the non-default language are isolated in .resx resource files. Na przykład możesz chcieć utworzyć plik zasobów hiszpański o nazwie Welcome. es. resx zawierający przetłumaczone ciągi.For example, you might want to create Spanish resource file named Welcome.es.resx containing translated strings. "es" to kod języka w języku hiszpańskim."es" is the language code for Spanish. Aby utworzyć ten plik zasobów w programie Visual Studio:To create this resource file in Visual Studio:

  1. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy folder, który będzie zawierać plik zasobów, > Dodaj > nowy element .In Solution Explorer , right click on the folder which will contain the resource file > Add > New Item .

    Zagnieżdżone menu kontekstowe: w Eksplorator rozwiązań menu kontekstowe jest otwarte dla zasobów.

  2. W polu wyszukiwania zainstalowanych szablonów wprowadź "Resource" i Nazwij plik.In the Search installed templates box, enter "resource" and name the file.

    Okno dialogowe Dodawanie nowego elementu

  3. Wprowadź wartość klucza (ciąg macierzysty) w kolumnie Nazwa i przetłumaczony ciąg w kolumnie wartość .Enter the key value (native string) in the Name column and the translated string in the Value column.

    Welcome. es. resx plik (plik zasobów powitalnych dla języka hiszpańskiego) z słowem Hello w kolumnie Nazwa i słowem Hola (Hello w języku hiszpańskim) w kolumnie wartość

    Program Visual Studio wyświetla plik Welcome. es. resx .Visual Studio shows the Welcome.es.resx file.

    Eksplorator rozwiązań przedstawiający plik zasobów programu Welcome hiszpański (ES)

Nazewnictwo plików zasobówResource file naming

Zasoby są nazwane dla pełnej nazwy typu swojej klasy pomniejszonej o nazwę zestawu.Resources are named for the full type name of their class minus the assembly name. Na przykład zasób francuski w projekcie, którego głównym zestawem jest LocalizationWebsite.Web.dll dla klasy, będzie LocalizationWebsite.Web.Startup nazwany Startup. fr. resx .For example, a French resource in a project whose main assembly is LocalizationWebsite.Web.dll for the class LocalizationWebsite.Web.Startup would be named Startup.fr.resx . Zasób klasy LocalizationWebsite.Web.Controllers.HomeController nosi nazwę controllers. HomeController. fr. resx .A resource for the class LocalizationWebsite.Web.Controllers.HomeController would be named Controllers.HomeController.fr.resx . Jeśli przestrzeń nazw klasy Target nie jest taka sama jak nazwa zestawu, będzie potrzebna pełna nazwa typu.If your targeted class's namespace isn't the same as the assembly name you will need the full type name. Przykładowo w przykładowym projekcie zasób dla typu ExtraNamespace.Tools powinien mieć nazwę ExtraNamespace. Tools. fr. resx .For example, in the sample project a resource for the type ExtraNamespace.Tools would be named ExtraNamespace.Tools.fr.resx .

W przykładowym projekcie ConfigureServices Metoda ustawia ResourcesPath do "zasobów", więc ścieżka względna projektu dla francuskiego pliku zasobów kontrolera głównego to zasoby/kontrolery. HomeController. fr. resx .In the sample project, the ConfigureServices method sets the ResourcesPath to "Resources", so the project relative path for the home controller's French resource file is Resources/Controllers.HomeController.fr.resx . Alternatywnie można użyć folderów do organizowania plików zasobów.Alternatively, you can use folders to organize resource files. W przypadku kontrolera macierzystego ścieżka będzie zawierać zasoby/kontrolery/HomeController. fr. resx .For the home controller, the path would be Resources/Controllers/HomeController.fr.resx . Jeśli ta opcja nie zostanie użyta ResourcesPath , plik . resx zostanie użyty w katalogu bazowym projektu.If you don't use the ResourcesPath option, the .resx file would go in the project base directory. Plik zasobu dla HomeController nosi nazwę controllers. HomeController. fr. resx .The resource file for HomeController would be named Controllers.HomeController.fr.resx . Wybór przy użyciu konwencji nazewnictwa kropka lub ścieżki zależy od tego, w jaki sposób chcesz zorganizować pliki zasobów.The choice of using the dot or path naming convention depends on how you want to organize your resource files.

Nazwa zasobuResource name Nazwa kropka lub ścieżkiDot or path naming
Zasoby/kontrolery. HomeController. fr. resxResources/Controllers.HomeController.fr.resx KropkaDot
Zasoby/kontrolery/HomeController. fr. resxResources/Controllers/HomeController.fr.resx ŚcieżkaPath

Pliki zasobów używające @inject IViewLocalizer w Razor widokach są zgodne z podobnym wzorcem.Resource files using @inject IViewLocalizer in Razor views follow a similar pattern. Plik zasobów dla widoku może być nazwany przy użyciu nazw kropek lub nazw ścieżek.The resource file for a view can be named using either dot naming or path naming. Razor Wyświetl pliki zasobów, aby naśladować ścieżkę skojarzonego pliku widoku.Razor view resource files mimic the path of their associated view file. Przy założeniu, że ustawimy ResourcesPath na "zasoby", plik zasobów francuski skojarzony z widokiem /Home/about. cshtml może mieć jedną z następujących wartości:Assuming we set the ResourcesPath to "Resources", the French resource file associated with the Views/Home/About.cshtml view could be either of the following:

  • Zasoby/widoki/Strona główna/informacje. fr. resxResources/Views/Home/About.fr.resx

  • Zasoby/widoki. Strona główna. informacje. fr. resxResources/Views.Home.About.fr.resx

Jeśli opcja nie zostanie użyta ResourcesPath , plik resx dla widoku powinien znajdować się w tym samym folderze co widok.If you don't use the ResourcesPath option, the .resx file for a view would be located in the same folder as the view.

RootNamespaceAttributeRootNamespaceAttribute

Atrybut RootNamespace udostępnia główną przestrzeń nazw zestawu, gdy główna przestrzeń nazw zestawu jest inna niż nazwa zestawu.The RootNamespace attribute provides the root namespace of an assembly when the root namespace of an assembly is different than the assembly name.

Ostrzeżenie

Taka sytuacja może wystąpić, gdy nazwa projektu nie jest prawidłowym identyfikatorem platformy .NET.This can occur when a project's name is not a valid .NET identifier. Na przykład my-project-name.csproj użyje głównej przestrzeni nazw my_project_name i nazwy zestawu my-project-name prowadzącej do tego błędu.For instance my-project-name.csproj will use the root namespace my_project_name and the assembly name my-project-name leading to this error.

Jeśli główna przestrzeń nazw zestawu jest inna niż nazwa zestawu:If the root namespace of an assembly is different than the assembly name:

  • Lokalizacja nie działa domyślnie.Localization does not work by default.
  • Lokalizowanie nie powiedzie się z powodu sposobu wyszukiwania zasobów w zestawie.Localization fails due to the way resources are searched for within the assembly. RootNamespace jest wartością czasu kompilacji, która nie jest dostępna dla wykonywanego procesu.RootNamespace is a build-time value which is not available to the executing process.

Jeśli RootNamespace różni się od AssemblyName , należy uwzględnić następujące w AssemblyInfo.cs (z wartościami parametrów zamienionymi na wartości rzeczywiste):If the RootNamespace is different from the AssemblyName, include the following in AssemblyInfo.cs (with parameter values replaced with the actual values):

using System.Reflection;
using Microsoft.Extensions.Localization;

[assembly: ResourceLocation("Resource Folder Name")]
[assembly: RootNamespace("App Root Namespace")]

Poprzedni kod umożliwia pomyślne rozpoznanie plików resx.The preceding code enables the successful resolution of resx files.

Zachowanie rezerwowe kulturyCulture fallback behavior

Podczas wyszukiwania zasobu lokalizacja prowadzi do "rezerwy kulturowej".When searching for a resource, localization engages in "culture fallback". Jeśli nie zostanie znaleziona, rozpoczyna się od żądanej kultury, przywraca kulturę nadrzędną tej kultury.Starting from the requested culture, if not found, it reverts to the parent culture of that culture. Poza tym Właściwość CultureInfo. Parent reprezentuje kulturę nadrzędną.As an aside, the CultureInfo.Parent property represents the parent culture. Zwykle (ale nie zawsze) oznacza usunięcie z ISO.This usually (but not always) means removing the national signifier from the ISO. Na przykład dialekt języka hiszpańskiego wymawianego w Meksyku to "es-MX".For example, the dialect of Spanish spoken in Mexico is "es-MX". Jest to wersja Hiszpańska "es", która — nie jest specyficzna dla żadnego z krajów.It has the parent "es"—Spanish non-specific to any country.

Wyobraź sobie, że witryna otrzymuje żądanie dotyczące zasobu "Welcome" przy użyciu kultury "fr-CA".Imagine your site receives a request for a "Welcome" resource using culture "fr-CA". System lokalizacji wyszukuje następujące zasoby w kolejności i wybiera pierwsze dopasowanie:The localization system looks for the following resources, in order, and selects the first match:

  • Welcome.fr — CA. resxWelcome.fr-CA.resx
  • Witamy. fr. resxWelcome.fr.resx
  • Welcome. resx (Jeśli NeutralResourcesLanguage jest "fr-CA")Welcome.resx (if the NeutralResourcesLanguage is "fr-CA")

Na przykład, jeśli usuniesz oznaczenie kultury ". fr" i masz kulturę ustawioną na francuski, domyślny plik zasobów jest odczytywany, a ciągi są zlokalizowane.As an example, if you remove the ".fr" culture designator and you have the culture set to French, the default resource file is read and strings are localized. Menedżer zasobów określa domyślny lub rezerwowy zasób, gdy nic nie spełnia wymaganej kultury.The Resource manager designates a default or fallback resource for when nothing meets your requested culture. Jeśli chcesz po prostu zwrócić klucz, gdy brakuje zasobu dla wymaganej kultury, nie musisz mieć domyślnego pliku zasobów.If you want to just return the key when missing a resource for the requested culture you must not have a default resource file.

Generowanie plików zasobów przy użyciu programu Visual StudioGenerate resource files with Visual Studio

Jeśli utworzysz plik zasobów w programie Visual Studio bez kultury w nazwie pliku (na przykład Welcome. resx ), program Visual Studio utworzy klasę języka C# z właściwością dla każdego ciągu.If you create a resource file in Visual Studio without a culture in the file name (for example, Welcome.resx ), Visual Studio will create a C# class with a property for each string. Zwykle nie jest to możliwe dzięki ASP.NET Core.That's usually not what you want with ASP.NET Core. Zazwyczaj nie istnieje domyślny plik zasobów resx (plik . resx bez nazwy kultury).You typically don't have a default .resx resource file (a .resx file without the culture name). Zalecamy utworzenie pliku resx z nazwą kultury (na przykład Welcome. fr. resx ).We suggest you create the .resx file with a culture name (for example Welcome.fr.resx ). Podczas tworzenia pliku resx przy użyciu nazwy kultury program Visual Studio nie generuje pliku klasy.When you create a .resx file with a culture name, Visual Studio won't generate the class file.

Dodaj inne kulturyAdd other cultures

Każda kombinacja języka i kultury (oprócz języka domyślnego) wymaga unikatowego pliku zasobów.Each language and culture combination (other than the default language) requires a unique resource file. Tworzysz pliki zasobów dla różnych kultur i ustawień regionalnych, tworząc nowe pliki zasobów, w których kody języka ISO są częścią nazwy pliku (na przykład en-us , fr-CA i pl-GB ).You create resource files for different cultures and locales by creating new resource files in which the ISO language codes are part of the file name (for example, en-us , fr-ca , and en-gb ). Te kody ISO są umieszczane między nazwami plików i rozszerzeniem resx , jak w Welcome.es-MX. resx (hiszpański/Meksyk).These ISO codes are placed between the file name and the .resx file extension, as in Welcome.es-MX.resx (Spanish/Mexico).

Zaimplementuj strategię, aby wybrać język/kulturę dla każdego żądaniaImplement a strategy to select the language/culture for each request

Konfigurowanie lokalizacjiConfigure localization

Lokalizacja jest skonfigurowana w ramach Startup.ConfigureServices metody:Localization is configured in the Startup.ConfigureServices method:

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

services.AddMvc()
    .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
    .AddDataAnnotationsLocalization();
  • AddLocalization dodaje usługi lokalizacyjne do kontenera usług.AddLocalization adds the localization services to the services container. Powyższy kod również ustawia ścieżkę zasobów na "zasoby".The code above also sets the resources path to "Resources".

  • AddViewLocalization dodaje obsługę zlokalizowanych plików widoku.AddViewLocalization adds support for localized view files. Ta lokalizacja widoku przykładowego jest oparta na sufiksie pliku widoku.In this sample view localization is based on the view file suffix. Na przykład "fr" w pliku index. fr. cshtml .For example "fr" in the Index.fr.cshtml file.

  • AddDataAnnotationsLocalization dodaje obsługę zlokalizowanych DataAnnotations komunikatów weryfikacyjnych za pomocą IStringLocalizer abstrakcji.AddDataAnnotationsLocalization adds support for localized DataAnnotations validation messages through IStringLocalizer abstractions.

Oprogramowanie pośredniczące lokalizacjiLocalization middleware

Bieżąca kultura w żądaniu jest ustawiana w oprogramowaniu pośredniczącymlokalizacji.The current culture on a request is set in the localization Middleware. Oprogramowanie pośredniczące lokalizacji jest włączone w tej Startup.Configure metodzie.The localization middleware is enabled in the Startup.Configure method. Oprogramowanie pośredniczące lokalizacyjne musi być skonfigurowane przed jakimkolwiek oprogramowanie pośredniczące, które może sprawdzić kulturę żądania (na przykład app.UseMvcWithDefaultRoute() ).The localization middleware must be configured before any middleware which might check the request culture (for example, app.UseMvcWithDefaultRoute()).

var supportedCultures = new[] { "en-US", "fr" };
var localizationOptions = new RequestLocalizationOptions().SetDefaultCulture(supportedCultures[0])
    .AddSupportedCultures(supportedCultures)
    .AddSupportedUICultures(supportedCultures);

app.UseRequestLocalization(localizationOptions);

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

app.UseAuthentication();

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

Jeśli chcesz zobaczyć Komentarze do kodu przetłumaczone na języki inne niż angielski, poinformuj nas o tym problemie z dyskusjąw witrynie GitHub.If you would like to see code comments translated to languages other than English, let us know in this GitHub discussion issue.

UseRequestLocalization Inicjuje RequestLocalizationOptions obiekt.UseRequestLocalization initializes a RequestLocalizationOptions object. Na każdym zażądaniu listy RequestCultureProvider w programie RequestLocalizationOptions jest wyliczany, a pierwszy dostawca, który może pomyślnie ustalić kulturę żądań, jest używany.On every request the list of RequestCultureProvider in the RequestLocalizationOptions is enumerated and the first provider that can successfully determine the request culture is used. Dostawcy domyślnie pochodzą z RequestLocalizationOptions klasy:The default providers come from the RequestLocalizationOptions class:

  1. QueryStringRequestCultureProvider
  2. CookieRequestCultureProvider
  3. AcceptLanguageHeaderRequestCultureProvider

Lista domyślna przechodzi od najbardziej konkretnych do najmniej określonych.The default list goes from most specific to least specific. W dalszej części artykułu zobaczymy, jak można zmienić kolejność, a nawet dodać niestandardowego dostawcę kultury.Later in the article we'll see how you can change the order and even add a custom culture provider. Jeśli żaden z dostawców nie może określić kultury żądania, DefaultRequestCulture jest używana.If none of the providers can determine the request culture, the DefaultRequestCulture is used.

QueryStringRequestCultureProviderQueryStringRequestCultureProvider

Niektóre aplikacje będą używać ciągu zapytania do ustawienia CultureInfo .Some apps will use a query string to set the CultureInfo. W przypadku aplikacji korzystających z cookie metody nagłówka lub Accept-Language dodanie ciągu zapytania do adresu URL jest przydatne w przypadku debugowania i testowania kodu.For apps that use the cookie or Accept-Language header approach, adding a query string to the URL is useful for debugging and testing code. Domyślnie program QueryStringRequestCultureProvider jest rejestrowany jako pierwszy dostawca lokalizacji na RequestCultureProvider liście.By default, the QueryStringRequestCultureProvider is registered as the first localization provider in the RequestCultureProvider list. Parametry ciągu zapytania są przekazywane culture i ui-culture .You pass the query string parameters culture and ui-culture. Poniższy przykład ustawia określoną kulturę (język i region) na hiszpański/Meksyk:The following example sets the specific culture (language and region) to Spanish/Mexico:

http://localhost:5000/?culture=es-MX&ui-culture=es-MX

Jeśli przekazujesz tylko jeden z dwóch ( culture lub ui-culture ), dostawca ciągu zapytania ustawi obie wartości przy użyciu przekazanego elementu.If you only pass in one of the two (culture or ui-culture), the query string provider will set both values using the one you passed in. Na przykład ustawienie tylko kulturowe ustawi zarówno, Culture jak i UICulture :For example, setting just the culture will set both the Culture and the UICulture:

http://localhost:5000/?culture=es-MX

CookieRequestCultureProviderCookieRequestCultureProvider

Aplikacje produkcyjne często udostępniają mechanizm ustawiania kultury z kulturą ASP.NET Coreową cookie .Production apps will often provide a mechanism to set the culture with the ASP.NET Core culture cookie. Użyj MakeCookieValue metody, aby utworzyć cookie .Use the MakeCookieValue method to create a cookie.

CookieRequestCultureProvider DefaultCookieName Zwraca domyślną cookie nazwę używaną do śledzenia informacji o preferowanej kulturze użytkownika.The CookieRequestCultureProvider DefaultCookieName returns the default cookie name used to track the user's preferred culture information. Nazwa domyślna cookie to .AspNetCore.Culture .The default cookie name is .AspNetCore.Culture.

cookieFormat to c=%LANGCODE%|uic=%LANGCODE% , gdzie c is Culture i uic is UICulture , na przykład:The cookie format is c=%LANGCODE%|uic=%LANGCODE%, where c is Culture and uic is UICulture, for example:

c=en-UK|uic=en-US

Jeśli określisz tylko jedną z informacji o kulturze i kulturze interfejsu użytkownika, określona kultura zostanie użyta dla informacji kultury i kultury interfejsu użytkownika.If you only specify one of culture info and UI culture, the specified culture will be used for both culture info and UI culture.

Accept-Language nagłówek HTTPThe Accept-Language HTTP header

Nagłówek Accept-Language jest settable w większości przeglądarek i był pierwotnie przeznaczony do określenia języka użytkownika.The Accept-Language header is settable in most browsers and was originally intended to specify the user's language. To ustawienie wskazuje, co przeglądarka została ustawiona do wysłania lub która dziedziczy z bazowego systemu operacyjnego.This setting indicates what the browser has been set to send or has inherited from the underlying operating system. Accept-Language nagłówku HTTP z żądania przeglądarki nie jest INFALLIBLE sposób wykrywania preferowanego języka użytkownika (zobacz Ustawianie preferencji językowych w przeglądarce).The Accept-Language HTTP header from a browser request isn't an infallible way to detect the user's preferred language (see Setting language preferences in a browser). Aplikacja produkcyjna powinna uwzględniać sposób, w jaki użytkownik może dostosować wybór kultury.A production app should include a way for a user to customize their choice of culture.

Ustawianie Accept-Language nagłówku HTTP w programie IESet the Accept-Language HTTP header in IE

  1. Na ikonie koła zębatego naciśnij pozycję Opcje internetowe .From the gear icon, tap Internet Options .

  2. Naciśnij pozycję Języki .Tap Languages .

    Opcje internetowe

  3. Naciśnij pozycję Ustaw preferencje językowe .Tap Set Language Preferences .

  4. Naciśnij pozycję Dodaj język .Tap Add a language .

  5. Dodaj język.Add the language.

  6. Naciśnij pozycję język, a następnie naciśnij pozycję Przenieś w górę .Tap the language, then tap Move Up .

Nagłówek HTTP w języku zawartościThe Content-Language HTTP header

Nagłówek jednostki zawartości w języku :The Content-Language entity header:

  • Służy do opisywania języków przeznaczonych dla odbiorców.Is used to describe the language(s) intended for the audience.
  • Umożliwia użytkownikowi odróżnienie zgodnie z preferowanym językiem użytkownika.Allows a user to differentiate according to the users' own preferred language.

Nagłówki jednostek są używane w żądaniach i odpowiedziach HTTP.Entity headers are used in both HTTP requests and responses.

Content-LanguageNagłówek można dodać przez ustawienie właściwości ApplyCurrentCultureToResponseHeaders .The Content-Language header can be added by setting the property ApplyCurrentCultureToResponseHeaders.

Dodawanie Content-Language nagłówka:Adding the Content-Language header:

  • Zezwala RequestLocalizationMiddleware na ustawienie Content-Language nagłówka przy użyciu CurrentUICulture .Allows the RequestLocalizationMiddleware to set the Content-Language header with the CurrentUICulture.
  • Eliminuje konieczność jawnego ustawiania nagłówka odpowiedzi Content-Language .Eliminates the need to set the response header Content-Language explicitly.
app.UseRequestLocalization(new RequestLocalizationOptions
{
    ApplyCurrentCultureToResponseHeaders = true
});

Używanie dostawcy niestandardowegoUse a custom provider

Załóżmy, że chcesz zezwolić klientom na przechowywanie w swoich bazach danych językowych i kulturowych.Suppose you want to let your customers store their language and culture in your databases. Można napisać dostawcę, aby wyszukać te wartości dla użytkownika.You could write a provider to look up these values for the user. Poniższy kod pokazuje, jak dodać niestandardowego dostawcę:The following code shows how to add a custom provider:

private const string enUSCulture = "en-US";

services.Configure<RequestLocalizationOptions>(options =>
{
    var supportedCultures = new[]
    {
        new CultureInfo(enUSCulture),
        new CultureInfo("fr")
    };

    options.DefaultRequestCulture = new RequestCulture(culture: enUSCulture, uiCulture: enUSCulture);
    options.SupportedCultures = supportedCultures;
    options.SupportedUICultures = supportedCultures;

    options.AddInitialRequestCultureProvider(new CustomRequestCultureProvider(async context =>
    {
        // My custom request culture logic
        return new ProviderCultureResult("en");
    }));
});

Służy RequestLocalizationOptions do dodawania lub usuwania dostawców lokalizacji.Use RequestLocalizationOptions to add or remove localization providers.

Ustaw kulturę programowoSet the culture programmatically

Ten przykład lokalizacji. StarterWeb projekt w witrynie GitHub zawiera interfejs użytkownika służący do ustawiania Culture .This sample Localization.StarterWeb project on GitHub contains UI to set the Culture. Plik views/Shared/_SelectLanguagePartial. cshtml umożliwia wybranie kultury z listy obsługiwanych kultur:The Views/Shared/_SelectLanguagePartial.cshtml file allows you to select the culture from the list of supported cultures:

@using Microsoft.AspNetCore.Builder
@using Microsoft.AspNetCore.Http.Features
@using Microsoft.AspNetCore.Localization
@using Microsoft.AspNetCore.Mvc.Localization
@using Microsoft.Extensions.Options

@inject IViewLocalizer Localizer
@inject IOptions<RequestLocalizationOptions> LocOptions

@{
    var requestCulture = Context.Features.Get<IRequestCultureFeature>();
    var cultureItems = LocOptions.Value.SupportedUICultures
        .Select(c => new SelectListItem { Value = c.Name, Text = c.DisplayName })
        .ToList();
    var returnUrl = string.IsNullOrEmpty(Context.Request.Path) ? "~/" : $"~{Context.Request.Path.Value}";
}

<div title="@Localizer["Request culture provider:"] @requestCulture?.Provider?.GetType().Name">
    <form id="selectLanguage" asp-controller="Home" 
          asp-action="SetLanguage" asp-route-returnUrl="@returnUrl" 
          method="post" class="form-horizontal" role="form">
        <label asp-for="@requestCulture.RequestCulture.UICulture.Name">@Localizer["Language:"]</label> <select name="culture"
          onchange="this.form.submit();"
          asp-for="@requestCulture.RequestCulture.UICulture.Name" asp-items="cultureItems">
        </select>
    </form>
</div>

Plik views/Shared/_SelectLanguagePartial. cshtml zostanie dodany do footer sekcji pliku układu, więc będzie dostępny dla wszystkich widoków:The Views/Shared/_SelectLanguagePartial.cshtml file is added to the footer section of the layout file so it will be available to all views:

<div class="container body-content" style="margin-top:60px">
    @RenderBody()
    <hr>
    <footer>
        <div class="row">
            <div class="col-md-6">
                <p>&copy; @System.DateTime.Now.Year - Localization</p>
            </div>
            <div class="col-md-6 text-right">
                @await Html.PartialAsync("_SelectLanguagePartial")
            </div>
        </div>
    </footer>
</div>

SetLanguageMetoda ustawia kulturę cookie .The SetLanguage method sets the culture cookie.

[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);
}

Nie można podłączyć _SelectLanguagePartial. cshtml do przykładowego kodu dla tego projektu.You can't plug in the _SelectLanguagePartial.cshtml to sample code for this project. Projekt Lokalizacja. StarterWeb w usłudze GitHub ma kod, który umożliwia RequestLocalizationOptions Razor Przechodzenie do częściowej przez kontener iniekcji zależności .The Localization.StarterWeb project on GitHub has code to flow the RequestLocalizationOptions to a Razor partial through the Dependency Injection container.

Dane tras powiązań modelu i ciągi zapytaniaModel binding route data and query strings

Zobacz zachowanie globalizacji powiązań modelu powiązanie danych i ciągi zapytań.See Globalization behavior of model binding route data and query strings.

Warunki globalizacji i lokalizacjaGlobalization and localization terms

Proces lokalizowania aplikacji wymaga również podstawowej znajomości odpowiednich zestawów znaków, które są często używane w nowoczesnych opracowywaniu oprogramowania i zrozumieniu skojarzonych z nimi problemów.The process of localizing your app also requires a basic understanding of relevant character sets commonly used in modern software development and an understanding of the issues associated with them. Mimo że wszystkie komputery przechowują tekst jako cyfry (kody), różne systemy przechowują ten sam tekst przy użyciu różnych liczb.Although all computers store text as numbers (codes), different systems store the same text using different numbers. Proces lokalizowania dotyczy tłumaczenia interfejsu użytkownika aplikacji (UI) dla określonych kultur/ustawień regionalnych.The localization process refers to translating the app user interface (UI) for a specific culture/locale.

Możliwość lokalizowania to proces pośredni służący do sprawdzania, czy aplikacja globalna jest gotowa do lokalizacji.Localizability is an intermediate process for verifying that a globalized app is ready for localization.

Format RFC 4646 dla nazwy kultury to <languagecode2>-<country/regioncode2> , gdzie <languagecode2> jest kodem języka i <country/regioncode2> jest kodem podkultury.The RFC 4646 format for the culture name is <languagecode2>-<country/regioncode2>, where <languagecode2> is the language code and <country/regioncode2> is the subculture code. Na przykład es-CL w przypadku języka hiszpańskiego (Chile) en-US dla języka angielskiego (Stany Zjednoczone) i en-AU dla języka angielskiego (Australia).For example, es-CL for Spanish (Chile), en-US for English (United States), and en-AU for English (Australia). RFC 4646 jest kombinacją kodu ISO 639 2 litery małymi literami związanymi z językiem i ISO 3166 2 literą w postaci wielkiej litery, skojarzonej z krajem lub regionem.RFC 4646 is a combination of an ISO 639 two-letter lowercase culture code associated with a language and an ISO 3166 two-letter uppercase subculture code associated with a country or region. Zobacz: /previous-versions/commerce-server/ee825488(v=cs.20).See /previous-versions/commerce-server/ee825488(v=cs.20).

Międzynarodowe jest często skracane do "I18N".Internationalization is often abbreviated to "I18N". Skrót przyjmuje pierwszą i ostatnią literę oraz liczbę liter między nimi, więc 18 oznacza liczbę liter między pierwszym "I" i ostatnim "N".The abbreviation takes the first and last letters and the number of letters between them, so 18 stands for the number of letters between the first "I" and the last "N". Dotyczy to zarówno globalizacji (G11N), jak i lokalizacji (L10N).The same applies to Globalization (G11N), and Localization (L10N).

OdsetkTerms:

  • Globalizacja (G11N): proces tworzenia aplikacji w różnych językach i regionach.Globalization (G11N): The process of making an app support different languages and regions.
  • Lokalizacja (L10N): proces dostosowywania aplikacji dla danego języka i regionu.Localization (L10N): The process of customizing an app for a given language and region.
  • Międzynarodowe (I18N): opisuje zarówno globalizację, jak i lokalizację.Internationalization (I18N): Describes both globalization and localization.
  • Kultura: jest to język i, opcjonalnie, region.Culture: It's a language and, optionally, a region.
  • Kultura neutralna: kultura, która ma określony język, ale nie region.Neutral culture: A culture that has a specified language, but not a region. (na przykład "en", "es")(for example "en", "es")
  • Określona kultura: kultura, która ma określony język i region.Specific culture: A culture that has a specified language and region. (na przykład "en-US", "pl-GB", "es-CL")(for example "en-US", "en-GB", "es-CL")
  • Kultura nadrzędna: neutralna kultura, która zawiera określoną kulturę.Parent culture: The neutral culture that contains a specific culture. (na przykład "en" jest kulturą nadrzędną wartości "pl-US" i "pl-GB")(for example, "en" is the parent culture of "en-US" and "en-GB")
  • Ustawienia regionalne: ustawienie regionalne jest takie samo jak kultura.Locale: A locale is the same as a culture.

Uwaga

Wprowadzanie przecinków dziesiętnych w polach dziesiętnych może być niemożna wprowadzić przecinków dziesiętnych.You may not be able to enter decimal commas in decimal fields. Aby obsługiwać sprawdzanie poprawności jQuery dla ustawień regionalnych innych niż angielskie, które używają przecinka (",") dla przecinka dziesiętnego i formatów daty spoza języka AMERYKAŃSKIEgo, należy podjąć kroki w celu zglobalizowania aplikacji.To support jQuery validation for non-English locales that use a comma (",") for a decimal point, and non US-English date formats, you must take steps to globalize your app. Zobacz ten problem GitHub 4076 instrukcje dotyczące dodawania przecinka dziesiętnego.See this GitHub issue 4076 for instructions on adding decimal comma.

Uwaga

Przed ASP.NET aplikacje internetowe Core 3.0 zapisują LogLevel.Warning jeden dziennik typu na żądanie, jeśli żądana kultura nie jest nieobsługiwała.Prior to ASP.NET Core 3.0 web apps write one log of type LogLevel.Warning per request if the requested culture is unsupported. Rejestrowanie LogLevel.Warning jednego na żądanie jest można zrobić duże pliki dziennika z nadmiarowych informacji.Logging one LogLevel.Warning per request is can make large log files with redundant information. To zachowanie zostało zmienione w ASP.NET 3.0.This behavior has been changed in ASP.NET 3.0. Zapisuje RequestLocalizationMiddleware dziennik typu LogLevel.Debug, co zmniejsza rozmiar dzienników produkcji.The RequestLocalizationMiddleware writes a log of type LogLevel.Debug, which reduces the size of production logs.

Dodatkowe zasobyAdditional resources